Reconnect to all hidl sensors HALs am: 4b26b7fb46

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

Change-Id: Ic44ce2c047db999b1e7e462b2cbef701c180f5b0
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 8bcb1e5..eb9a51d 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,4 +1,5 @@
 [Builtin Hooks]
+bpfmt = true
 clang_format = true
 
 [Builtin Hooks Options]
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 01c4723..34ccb21 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -282,6 +282,21 @@
     chmod 0666 /sys/kernel/debug/tracing/per_cpu/cpu23/trace
     chmod 0666 /sys/kernel/tracing/per_cpu/cpu23/trace
 
+# Setup synthetic events
+    chmod 0666 /sys/kernel/tracing/synthetic_events
+    chmod 0666 /sys/kernel/debug/tracing/synthetic_events
+
+    # rss_stat_throttled
+    write /sys/kernel/tracing/synthetic_events "rss_stat_throttled unsigned int mm_id; unsigned int curr; int member; long size"
+    write /sys/kernel/debug/tracing/synthetic_events "rss_stat_throttled unsigned int mm_id; unsigned int curr; int member; long size"
+
+# Set up histogram triggers
+    # rss_stat_throttled (bucket size == 512KB)
+    chmod 0666 /sys/kernel/tracing/events/kmem/rss_stat/trigger
+    chmod 0666 /sys/kernel/debug/tracing/events/kmem/rss_stat/trigger
+    write /sys/kernel/tracing/events/kmem/rss_stat/trigger "hist:keys=mm_id,member:bucket=size/0x80000:onchange($$bucket).rss_stat_throttled(mm_id,curr,member,size)"
+    write /sys/kernel/debug/tracing/events/kmem/rss_stat/trigger "hist:keys=mm_id,member:bucket=size/0x80000:onchange($$bucket).rss_stat_throttled(mm_id,curr,member,size)"
+
 # Only create the tracing instance if persist.mm_events.enabled
 # Attempting to remove the tracing instance after it has been created
 # will likely fail with EBUSY as it would be in use by traced_probes.
diff --git a/cmds/cmd/Android.bp b/cmds/cmd/Android.bp
index c900a24..c3d2601 100644
--- a/cmds/cmd/Android.bp
+++ b/cmds/cmd/Android.bp
@@ -49,6 +49,7 @@
         "liblog",
         "libselinux",
         "libbinder",
+        "packagemanager_aidl-cpp",
     ],
 
     cflags: [
diff --git a/cmds/cmd/cmd.cpp b/cmds/cmd/cmd.cpp
index be2c702..8f1c01a 100644
--- a/cmds/cmd/cmd.cpp
+++ b/cmds/cmd/cmd.cpp
@@ -52,7 +52,7 @@
 }
 
 struct SecurityContext_Delete {
-    void operator()(security_context_t p) const {
+    void operator()(char* p) const {
         freecon(p);
     }
 };
@@ -108,7 +108,7 @@
         }
         if (is_selinux_enabled() && seLinuxContext.size() > 0) {
             String8 seLinuxContext8(seLinuxContext);
-            security_context_t tmp = nullptr;
+            char* tmp = nullptr;
             getfilecon(fullPath.string(), &tmp);
             Unique_SecurityContext context(tmp);
             if (checkWrite) {
diff --git a/cmds/cmd/fuzzer/Android.bp b/cmds/cmd/fuzzer/Android.bp
new file mode 100644
index 0000000..a65f6de
--- /dev/null
+++ b/cmds/cmd/fuzzer/Android.bp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_cmds_cmd_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_cmds_cmd_license"],
+}
+
+cc_fuzz {
+    name: "cmd_fuzzer",
+    srcs: [
+        "cmd_fuzzer.cpp",
+    ],
+    static_libs: [
+        "libcmd",
+        "liblog",
+        "libselinux",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libutils",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-media-fuzzing-reports@google.com",
+        ],
+        componentid: 155276,
+    },
+}
diff --git a/cmds/cmd/fuzzer/README.md b/cmds/cmd/fuzzer/README.md
new file mode 100644
index 0000000..db37ece
--- /dev/null
+++ b/cmds/cmd/fuzzer/README.md
@@ -0,0 +1,51 @@
+# Fuzzer for libcmd_fuzzer
+
+## Plugin Design Considerations
+The fuzzer plugin for libcmd is designed based on the understanding of the library and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+libcmd supports the following parameters:
+1. In (parameter name: `in`)
+2. Out (parameter name: `out`)
+3. Err (parameter name: `err`)
+4. Run Mode (parameter name: `runMode`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `in` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider|
+| `out` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider|
+| `err` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider|
+| `runMode` | 1.`RunMode::kStandalone` 2. `RunMode::kLibrary` | Value chosen from valid values using FuzzedDataProvider|
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the cmd module.
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build cmd_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) cmd_fuzzer
+```
+#### Steps to run
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/${TARGET_ARCH}/cmd_fuzzer/cmd_fuzzer
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/cmds/cmd/fuzzer/cmd_fuzzer.cpp b/cmds/cmd/fuzzer/cmd_fuzzer.cpp
new file mode 100644
index 0000000..ab514a1
--- /dev/null
+++ b/cmds/cmd/fuzzer/cmd_fuzzer.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/TextOutput.h>
+#include <cmd.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string>
+#include <vector>
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+using namespace std;
+using namespace android;
+
+class TestTextOutput : public TextOutput {
+public:
+    TestTextOutput() {}
+    virtual ~TestTextOutput() {}
+
+    virtual status_t print(const char* /*txt*/, size_t /*len*/) { return NO_ERROR; }
+    virtual void moveIndent(int /*delta*/) { return; }
+    virtual void pushBundle() { return; }
+    virtual void popBundle() { return; }
+};
+
+class CmdFuzzer {
+public:
+    void process(const uint8_t* data, size_t size);
+
+private:
+    FuzzedDataProvider* mFDP = nullptr;
+};
+
+void CmdFuzzer::process(const uint8_t* data, size_t size) {
+    mFDP = new FuzzedDataProvider(data, size);
+    vector<string> arguments;
+    if (mFDP->ConsumeBool()) {
+        if (mFDP->ConsumeBool()) {
+            arguments = {"-w", "media.aaudio"};
+        } else {
+            arguments = {"-l"};
+        }
+    } else {
+        while (mFDP->remaining_bytes() > 0) {
+            size_t sizestr = mFDP->ConsumeIntegralInRange<size_t>(1, mFDP->remaining_bytes());
+            string argument = mFDP->ConsumeBytesAsString(sizestr);
+            arguments.emplace_back(argument);
+        }
+    }
+    vector<string_view> argSV;
+    for (auto& argument : arguments) {
+        argSV.emplace_back(argument.c_str());
+    }
+    int32_t in = open("/dev/null", O_RDWR | O_CREAT);
+    int32_t out = open("/dev/null", O_RDWR | O_CREAT);
+    int32_t err = open("/dev/null", O_RDWR | O_CREAT);
+    TestTextOutput output;
+    TestTextOutput error;
+    RunMode runMode = mFDP->ConsumeBool() ? RunMode::kStandalone : RunMode::kLibrary;
+    cmdMain(argSV, output, error, in, out, err, runMode);
+    delete mFDP;
+    close(in);
+    close(out);
+    close(err);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    CmdFuzzer cmdFuzzer;
+    cmdFuzzer.process(data, size);
+    return 0;
+}
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index aff32c3..74dbf4b 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -100,6 +100,7 @@
         "liblog",
         "libutils",
         "libbinderdebug",
+        "packagemanager_aidl-cpp",
     ],
     srcs: [
         "DumpstateService.cpp",
@@ -173,7 +174,6 @@
     test_suites: ["device-tests"],
 }
 
-
 // =======================#
 // dumpstate_test_fixture #
 // =======================#
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 2d11b90..eab72f4 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1237,22 +1237,29 @@
         std::string path(title);
         path.append(" - ").append(String8(service).c_str());
         size_t bytes_written = 0;
-        status_t status = dumpsys.startDumpThread(Dumpsys::Type::DUMP, service, args);
-        if (status == OK) {
-            dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority);
-            std::chrono::duration<double> elapsed_seconds;
-            if (priority == IServiceManager::DUMP_FLAG_PRIORITY_HIGH &&
-                service == String16("meminfo")) {
-                // Use a longer timeout for meminfo, since 30s is not always enough.
-                status = dumpsys.writeDump(STDOUT_FILENO, service, 60s,
-                                           /* as_proto = */ false, elapsed_seconds, bytes_written);
-            } else {
-                status = dumpsys.writeDump(STDOUT_FILENO, service, service_timeout,
-                                           /* as_proto = */ false, elapsed_seconds, bytes_written);
+        if (PropertiesHelper::IsDryRun()) {
+             dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority);
+             dumpsys.writeDumpFooter(STDOUT_FILENO, service, std::chrono::milliseconds(1));
+        } else {
+            status_t status = dumpsys.startDumpThread(Dumpsys::TYPE_DUMP, service, args);
+            if (status == OK) {
+                dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority);
+                std::chrono::duration<double> elapsed_seconds;
+                if (priority == IServiceManager::DUMP_FLAG_PRIORITY_HIGH &&
+                    service == String16("meminfo")) {
+                    // Use a longer timeout for meminfo, since 30s is not always enough.
+                    status = dumpsys.writeDump(STDOUT_FILENO, service, 60s,
+                                               /* as_proto = */ false, elapsed_seconds,
+                                                bytes_written);
+                } else {
+                    status = dumpsys.writeDump(STDOUT_FILENO, service, service_timeout,
+                                               /* as_proto = */ false, elapsed_seconds,
+                                                bytes_written);
+                }
+                dumpsys.writeDumpFooter(STDOUT_FILENO, service, elapsed_seconds);
+                bool dump_complete = (status == OK);
+                dumpsys.stopDumpThread(dump_complete);
             }
-            dumpsys.writeDumpFooter(STDOUT_FILENO, service, elapsed_seconds);
-            bool dump_complete = (status == OK);
-            dumpsys.stopDumpThread(dump_complete);
         }
 
         auto elapsed_duration = std::chrono::duration_cast<std::chrono::milliseconds>(
@@ -1316,7 +1323,7 @@
             path.append("_HIGH");
         }
         path.append(kProtoExt);
-        status_t status = dumpsys.startDumpThread(Dumpsys::Type::DUMP, service, args);
+        status_t status = dumpsys.startDumpThread(Dumpsys::TYPE_DUMP, service, args);
         if (status == OK) {
             status = ds.AddZipEntryFromFd(path, dumpsys.getDumpFd(), service_timeout);
             bool dumpTerminated = (status == OK);
@@ -1836,8 +1843,10 @@
     }
 
     /* Run some operations that require root. */
-    ds.tombstone_data_ = GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX, !ds.IsZipping());
-    ds.anr_data_ = GetDumpFds(ANR_DIR, ANR_FILE_PREFIX, !ds.IsZipping());
+    if (!PropertiesHelper::IsDryRun()) {
+        ds.tombstone_data_ = GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX, !ds.IsZipping());
+        ds.anr_data_ = GetDumpFds(ANR_DIR, ANR_FILE_PREFIX, !ds.IsZipping());
+    }
 
     ds.AddDir(RECOVERY_DIR, true);
     ds.AddDir(RECOVERY_DATA_DIR, true);
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 83e6787..3722383 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -38,11 +38,6 @@
 #include "DumpPool.h"
 #include "TaskQueue.h"
 
-// Workaround for const char *args[MAX_ARGS_ARRAY_SIZE] variables until they're converted to
-// std::vector<std::string>
-// TODO: remove once not used
-#define MAX_ARGS_ARRAY_SIZE 1000
-
 // TODO: move everything under this namespace
 // TODO: and then remove explicitly android::os::dumpstate:: prefixes
 namespace android {
diff --git a/cmds/dumpsys/Android.bp b/cmds/dumpsys/Android.bp
index 6ab6b7f..ceb16cb 100644
--- a/cmds/dumpsys/Android.bp
+++ b/cmds/dumpsys/Android.bp
@@ -64,6 +64,10 @@
     srcs: [
         "main.cpp",
     ],
+
+    shared_libs: [
+        "packagemanager_aidl-cpp",
+    ],
 }
 
 cc_binary {
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index ba1c449..3d2bdf1 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -21,9 +21,12 @@
 
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
+#include <android-base/strings.h>
 #include <android-base/unique_fd.h>
+#include <binder/BpBinder.h>
 #include <binder/Parcel.h>
 #include <binder/ProcessState.h>
+#include <binder/Stability.h>
 #include <binder/TextOutput.h>
 #include <binderdebug/BinderDebug.h>
 #include <serviceutils/PriorityDumper.h>
@@ -57,25 +60,30 @@
 }
 
 static void usage() {
-    fprintf(stderr,
-            "usage: dumpsys\n"
-            "         To dump all services.\n"
-            "or:\n"
-            "       dumpsys [-t TIMEOUT] [--priority LEVEL] [--pid] [--thread] [--help | -l | "
-            "--skip SERVICES "
-            "| SERVICE [ARGS]]\n"
-            "         --help: shows this help\n"
-            "         -l: only list services, do not dump them\n"
-            "         -t TIMEOUT_SEC: TIMEOUT to use in seconds instead of default 10 seconds\n"
-            "         -T TIMEOUT_MS: TIMEOUT to use in milliseconds instead of default 10 seconds\n"
-            "         --pid: dump PID instead of usual dump\n"
-            "         --thread: dump thread usage instead of usual dump\n"
-            "         --proto: filter services that support dumping data in proto format. Dumps\n"
-            "               will be in proto format.\n"
-            "         --priority LEVEL: filter services based on specified priority\n"
-            "               LEVEL must be one of CRITICAL | HIGH | NORMAL\n"
-            "         --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
-            "         SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
+    fprintf(
+        stderr,
+        "usage: dumpsys\n"
+        "         To dump all services.\n"
+        "or:\n"
+        "       dumpsys [-t TIMEOUT] [--priority LEVEL] [--clients] [--dump] [--pid] [--thread] "
+        "[--help | "
+        "-l | --skip SERVICES "
+        "| SERVICE [ARGS]]\n"
+        "         --help: shows this help\n"
+        "         -l: only list services, do not dump them\n"
+        "         -t TIMEOUT_SEC: TIMEOUT to use in seconds instead of default 10 seconds\n"
+        "         -T TIMEOUT_MS: TIMEOUT to use in milliseconds instead of default 10 seconds\n"
+        "         --clients: dump client PIDs instead of usual dump\n"
+        "         --dump: ask the service to dump itself (this is the default)\n"
+        "         --pid: dump PID instead of usual dump\n"
+        "         --proto: filter services that support dumping data in proto format. Dumps\n"
+        "               will be in proto format.\n"
+        "         --priority LEVEL: filter services based on specified priority\n"
+        "               LEVEL must be one of CRITICAL | HIGH | NORMAL\n"
+        "         --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
+        "         --stability: dump binder stability information instead of usual dump\n"
+        "         --thread: dump thread usage instead of usual dump\n"
+        "         SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
 }
 
 static bool IsSkipped(const Vector<String16>& skipped, const String16& service) {
@@ -125,16 +133,15 @@
     bool showListOnly = false;
     bool skipServices = false;
     bool asProto = false;
-    Type type = Type::DUMP;
+    int dumpTypeFlags = 0;
     int timeoutArgMs = 10000;
     int priorityFlags = IServiceManager::DUMP_FLAG_PRIORITY_ALL;
-    static struct option longOptions[] = {{"thread", no_argument, 0, 0},
-                                          {"pid", no_argument, 0, 0},
-                                          {"priority", required_argument, 0, 0},
-                                          {"proto", no_argument, 0, 0},
-                                          {"skip", no_argument, 0, 0},
-                                          {"help", no_argument, 0, 0},
-                                          {0, 0, 0, 0}};
+    static struct option longOptions[] = {
+        {"help", no_argument, 0, 0},           {"clients", no_argument, 0, 0},
+        {"dump", no_argument, 0, 0},           {"pid", no_argument, 0, 0},
+        {"priority", required_argument, 0, 0}, {"proto", no_argument, 0, 0},
+        {"skip", no_argument, 0, 0},           {"stability", no_argument, 0, 0},
+        {"thread", no_argument, 0, 0},         {0, 0, 0, 0}};
 
     // Must reset optind, otherwise subsequent calls will fail (wouldn't happen on main.cpp, but
     // happens on test cases).
@@ -165,10 +172,16 @@
                     usage();
                     return -1;
                 }
+            } else if (!strcmp(longOptions[optionIndex].name, "dump")) {
+                dumpTypeFlags |= TYPE_DUMP;
             } else if (!strcmp(longOptions[optionIndex].name, "pid")) {
-                type = Type::PID;
+                dumpTypeFlags |= TYPE_PID;
+            } else if (!strcmp(longOptions[optionIndex].name, "stability")) {
+                dumpTypeFlags |= TYPE_STABILITY;
             } else if (!strcmp(longOptions[optionIndex].name, "thread")) {
-                type = Type::THREAD;
+                dumpTypeFlags |= TYPE_THREAD;
+            } else if (!strcmp(longOptions[optionIndex].name, "clients")) {
+                dumpTypeFlags |= TYPE_CLIENTS;
             }
             break;
 
@@ -206,6 +219,10 @@
         }
     }
 
+    if (dumpTypeFlags == 0) {
+        dumpTypeFlags = TYPE_DUMP;
+    }
+
     for (int i = optind; i < argc; i++) {
         if (skipServices) {
             skippedServices.add(String16(argv[i]));
@@ -258,7 +275,7 @@
         const String16& serviceName = services[i];
         if (IsSkipped(skippedServices, serviceName)) continue;
 
-        if (startDumpThread(type, serviceName, args) == OK) {
+        if (startDumpThread(dumpTypeFlags, serviceName, args) == OK) {
             bool addSeparator = (N > 1);
             if (addSeparator) {
                 writeDumpHeader(STDOUT_FILENO, serviceName, priorityFlags);
@@ -325,16 +342,24 @@
     }
 }
 
-static status_t dumpPidToFd(const sp<IBinder>& service, const unique_fd& fd) {
+static status_t dumpPidToFd(const sp<IBinder>& service, const unique_fd& fd, bool exclusive) {
      pid_t pid;
      status_t status = service->getDebugPid(&pid);
      if (status != OK) {
          return status;
      }
+     if (!exclusive) {
+        WriteStringToFd("Service host process PID: ", fd.get());
+     }
      WriteStringToFd(std::to_string(pid) + "\n", fd.get());
      return OK;
 }
 
+static status_t dumpStabilityToFd(const sp<IBinder>& service, const unique_fd& fd) {
+     WriteStringToFd("Stability: " + internal::Stability::debugToString(service) + "\n", fd);
+     return OK;
+}
+
 static status_t dumpThreadsToFd(const sp<IBinder>& service, const unique_fd& fd) {
     pid_t pid;
     status_t status = service->getDebugPid(&pid);
@@ -352,7 +377,43 @@
     return OK;
 }
 
-status_t Dumpsys::startDumpThread(Type type, const String16& serviceName,
+static status_t dumpClientsToFd(const sp<IBinder>& service, const unique_fd& fd) {
+    std::string clientPids;
+    const auto remoteBinder = service->remoteBinder();
+    if (remoteBinder == nullptr) {
+        WriteStringToFd("Client PIDs are not available for local binders.\n", fd.get());
+        return OK;
+    }
+    const auto handle = remoteBinder->getDebugBinderHandle();
+    if (handle == std::nullopt) {
+        return OK;
+    }
+    std::vector<pid_t> pids;
+    pid_t myPid = getpid();
+    pid_t servicePid;
+    status_t status = service->getDebugPid(&servicePid);
+    if (status != OK) {
+        return status;
+    }
+    status =
+        getBinderClientPids(BinderDebugContext::BINDER, myPid, servicePid, handle.value(), &pids);
+    if (status != OK) {
+        return status;
+    }
+    pids.erase(std::remove_if(pids.begin(), pids.end(), [&](pid_t pid) { return pid == myPid; }),
+               pids.end());
+    WriteStringToFd("Client PIDs: " + ::android::base::Join(pids, ", ") + "\n", fd.get());
+    return OK;
+}
+
+static void reportDumpError(const String16& serviceName, status_t error, const char* context) {
+    if (error == OK) return;
+
+    std::cerr << "Error with service '" << serviceName << "' while " << context << ": "
+              << statusToString(error) << std::endl;
+}
+
+status_t Dumpsys::startDumpThread(int dumpTypeFlags, const String16& serviceName,
                                   const Vector<String16>& args) {
     sp<IBinder> service = sm_->checkService(serviceName);
     if (service == nullptr) {
@@ -373,26 +434,27 @@
 
     // dump blocks until completion, so spawn a thread..
     activeThread_ = std::thread([=, remote_end{std::move(remote_end)}]() mutable {
-        status_t err = 0;
-
-        switch (type) {
-        case Type::DUMP:
-            err = service->dump(remote_end.get(), args);
-            break;
-        case Type::PID:
-            err = dumpPidToFd(service, remote_end);
-            break;
-        case Type::THREAD:
-            err = dumpThreadsToFd(service, remote_end);
-            break;
-        default:
-            std::cerr << "Unknown dump type" << static_cast<int>(type) << std::endl;
-            return;
+        if (dumpTypeFlags & TYPE_PID) {
+            status_t err = dumpPidToFd(service, remote_end, dumpTypeFlags == TYPE_PID);
+            reportDumpError(serviceName, err, "dumping PID");
+        }
+        if (dumpTypeFlags & TYPE_STABILITY) {
+            status_t err = dumpStabilityToFd(service, remote_end);
+            reportDumpError(serviceName, err, "dumping stability");
+        }
+        if (dumpTypeFlags & TYPE_THREAD) {
+            status_t err = dumpThreadsToFd(service, remote_end);
+            reportDumpError(serviceName, err, "dumping thread info");
+        }
+        if (dumpTypeFlags & TYPE_CLIENTS) {
+            status_t err = dumpClientsToFd(service, remote_end);
+            reportDumpError(serviceName, err, "dumping clients info");
         }
 
-        if (err != OK) {
-            std::cerr << "Error dumping service info status_t: " << statusToString(err) << " "
-                 << serviceName << std::endl;
+        // other types always act as a header, this is usually longer
+        if (dumpTypeFlags & TYPE_DUMP) {
+            status_t err = service->dump(remote_end.get(), args);
+            reportDumpError(serviceName, err, "dumping");
         }
     });
     return OK;
diff --git a/cmds/dumpsys/dumpsys.h b/cmds/dumpsys/dumpsys.h
index 349947c..6ab1a7d 100644
--- a/cmds/dumpsys/dumpsys.h
+++ b/cmds/dumpsys/dumpsys.h
@@ -51,23 +51,26 @@
      */
     static void setServiceArgs(Vector<String16>& args, bool asProto, int priorityFlags);
 
-    enum class Type {
-        DUMP,    // dump using `dump` function
-        PID,     // dump pid of server only
-        THREAD,  // dump thread usage of server only
+    enum Type {
+        TYPE_DUMP = 0x1,       // dump using `dump` function
+        TYPE_PID = 0x2,        // dump pid of server only
+        TYPE_STABILITY = 0x4,  // dump stability information of server
+        TYPE_THREAD = 0x8,     // dump thread usage of server only
+        TYPE_CLIENTS = 0x10,   // dump pid of clients
     };
 
     /**
      * Starts a thread to connect to a service and get its dump output. The thread redirects
      * the output to a pipe. Thread must be stopped by a subsequent call to {@code
      * stopDumpThread}.
+     * @param dumpTypeFlags operations to perform
      * @param serviceName
      * @param args list of arguments to pass to service dump method.
      * @return {@code OK} thread is started successfully.
      *         {@code NAME_NOT_FOUND} service could not be found.
      *         {@code != OK} error
      */
-    status_t startDumpThread(Type type, const String16& serviceName,
+    status_t startDumpThread(int dumpTypeFlags, const String16& serviceName,
                              const Vector<String16>& args);
 
     /**
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index c9d2dbb..677d6c7 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -60,6 +60,7 @@
     MOCK_METHOD1(isDeclared, bool(const String16&));
     MOCK_METHOD1(getDeclaredInstances, Vector<String16>(const String16&));
     MOCK_METHOD1(updatableViaApex, std::optional<String16>(const String16&));
+    MOCK_METHOD1(getConnectionInfo, std::optional<ConnectionInfo>(const String16&));
   protected:
     MOCK_METHOD0(onAsBinder, IBinder*());
 };
@@ -200,7 +201,7 @@
         CaptureStdout();
         CaptureStderr();
         dump_.setServiceArgs(args, supportsProto, priorityFlags);
-        status_t status = dump_.startDumpThread(Dumpsys::Type::DUMP, serviceName, args);
+        status_t status = dump_.startDumpThread(Dumpsys::TYPE_DUMP, serviceName, args);
         EXPECT_THAT(status, Eq(0));
         status = dump_.writeDump(STDOUT_FILENO, serviceName, std::chrono::milliseconds(500), false,
                                  elapsedDuration, bytesWritten);
@@ -582,6 +583,27 @@
     AssertOutput(std::to_string(getpid()) + "\n");
 }
 
+// Tests 'dumpsys --stability'
+TEST_F(DumpsysTest, ListAllServicesWithStability) {
+    ExpectListServices({"Locksmith", "Valet"});
+    ExpectCheckService("Locksmith");
+    ExpectCheckService("Valet");
+
+    CallMain({"--stability"});
+
+    AssertRunningServices({"Locksmith", "Valet"});
+    AssertOutputContains("stability");
+}
+
+// Tests 'dumpsys --stability service_name'
+TEST_F(DumpsysTest, ListServiceWithStability) {
+    ExpectCheckService("Locksmith");
+
+    CallMain({"--stability", "Locksmith"});
+
+    AssertOutputContains("stability");
+}
+
 // Tests 'dumpsys --thread'
 TEST_F(DumpsysTest, ListAllServicesWithThread) {
     ExpectListServices({"Locksmith", "Valet"});
@@ -606,6 +628,51 @@
     AssertOutputFormat(format);
 }
 
+// Tests 'dumpsys --clients'
+TEST_F(DumpsysTest, ListAllServicesWithClients) {
+    ExpectListServices({"Locksmith", "Valet"});
+    ExpectCheckService("Locksmith");
+    ExpectCheckService("Valet");
+
+    CallMain({"--clients"});
+
+    AssertRunningServices({"Locksmith", "Valet"});
+
+    const std::string format("(.|\n)*((Client PIDs are not available for local binders.)(.|\n)*){2}");
+    AssertOutputFormat(format);
+}
+
+// Tests 'dumpsys --clients service_name'
+TEST_F(DumpsysTest, ListServiceWithClients) {
+    ExpectCheckService("Locksmith");
+
+    CallMain({"--clients", "Locksmith"});
+
+    const std::string format("Client PIDs are not available for local binders.\n");
+    AssertOutputFormat(format);
+}
+// Tests 'dumpsys --thread --stability'
+TEST_F(DumpsysTest, ListAllServicesWithMultipleOptions) {
+    ExpectListServices({"Locksmith", "Valet"});
+    ExpectCheckService("Locksmith");
+    ExpectCheckService("Valet");
+
+    CallMain({"--pid", "--stability"});
+    AssertRunningServices({"Locksmith", "Valet"});
+
+    AssertOutputContains(std::to_string(getpid()));
+    AssertOutputContains("stability");
+}
+
+// Tests 'dumpsys --pid --stability service_name'
+TEST_F(DumpsysTest, ListServiceWithMultipleOptions) {
+    ExpectCheckService("Locksmith");
+    CallMain({"--pid", "--stability", "Locksmith"});
+
+    AssertOutputContains(std::to_string(getpid()));
+    AssertOutputContains("stability");
+}
+
 TEST_F(DumpsysTest, GetBytesWritten) {
     const char* serviceName = "service2";
     const char* dumpContents = "dump1";
diff --git a/cmds/idlcli/Android.bp b/cmds/idlcli/Android.bp
index ec3bc61..c18d3f5 100644
--- a/cmds/idlcli/Android.bp
+++ b/cmds/idlcli/Android.bp
@@ -24,7 +24,7 @@
 cc_defaults {
     name: "idlcli-defaults",
     shared_libs: [
-        "android.hardware.vibrator-V2-ndk_platform",
+        "android.hardware.vibrator-V2-ndk",
         "android.hardware.vibrator@1.0",
         "android.hardware.vibrator@1.1",
         "android.hardware.vibrator@1.2",
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 74be7ce..39ef0b5 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -25,6 +25,7 @@
 #include <functional>
 #include <inttypes.h>
 #include <regex>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/capability.h>
@@ -281,34 +282,31 @@
 }
 
 status_t InstalldNativeService::dump(int fd, const Vector<String16> & /* args */) {
-    auto out = std::fstream(StringPrintf("/proc/self/fd/%d", fd));
     const binder::Status dump_permission = checkPermission(kDump);
     if (!dump_permission.isOk()) {
-        out << dump_permission.toString8() << endl;
+        dprintf(fd, "%s\n", dump_permission.toString8().c_str());
         return PERMISSION_DENIED;
     }
-    std::lock_guard<std::recursive_mutex> lock(mLock);
 
-    out << "installd is happy!" << endl;
+    std::lock_guard<std::recursive_mutex> lock(mLock);
 
     {
         std::lock_guard<std::recursive_mutex> lock(mMountsLock);
-        out << endl << "Storage mounts:" << endl;
+        dprintf(fd, "Storage mounts:\n");
         for (const auto& n : mStorageMounts) {
-            out << "    " << n.first << " = " << n.second << endl;
+            dprintf(fd, "    %s = %s\n", n.first.c_str(), n.second.c_str());
         }
     }
 
     {
         std::lock_guard<std::recursive_mutex> lock(mQuotasLock);
-        out << endl << "Per-UID cache quotas:" << endl;
+        dprintf(fd, "Per-UID cache quotas:\n");
         for (const auto& n : mCacheQuotas) {
-            out << "    " << n.first << " = " << n.second << endl;
+            dprintf(fd, "    %d = %" PRId64 "\n", n.first, n.second);
         }
     }
 
-    out << endl;
-    out.flush();
+    dprintf(fd, "is_dexopt_blocked:%d\n", android::installd::is_dexopt_blocked());
 
     return NO_ERROR;
 }
@@ -424,9 +422,131 @@
     return true;
 }
 
+static bool chown_app_dir(const std::string& path, uid_t uid, uid_t previousUid, gid_t cacheGid) {
+    FTS* fts;
+    char *argv[] = { (char*) path.c_str(), nullptr };
+    if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr))) {
+        return false;
+    }
+    for (FTSENT* p; (p = fts_read(fts)) != nullptr;) {
+        if (p->fts_info == FTS_D && p->fts_level == 1
+            && (strcmp(p->fts_name, "cache") == 0
+                || strcmp(p->fts_name, "code_cache") == 0)) {
+            // Mark cache dirs
+            p->fts_number = 1;
+        } else {
+            // Inherit parent's number
+            p->fts_number = p->fts_parent->fts_number;
+        }
+
+        switch (p->fts_info) {
+        case FTS_D:
+        case FTS_F:
+        case FTS_SL:
+        case FTS_SLNONE:
+            if (p->fts_statp->st_uid == previousUid) {
+                if (lchown(p->fts_path, uid, p->fts_number ? cacheGid : uid) != 0) {
+                    PLOG(WARNING) << "Failed to lchown " << p->fts_path;
+                }
+            } else {
+                LOG(WARNING) << "Ignoring " << p->fts_path << " with unexpected UID "
+                        << p->fts_statp->st_uid << " instead of " << previousUid;
+            }
+            break;
+        }
+    }
+    fts_close(fts);
+    return true;
+}
+
+static void chown_app_profile_dir(const std::string &packageName, int32_t appId, int32_t userId) {
+    uid_t uid = multiuser_get_uid(userId, appId);
+    gid_t sharedGid = multiuser_get_shared_gid(userId, appId);
+
+    const std::string profile_dir =
+            create_primary_current_profile_package_dir_path(userId, packageName);
+    char *argv[] = { (char*) profile_dir.c_str(), nullptr };
+    if (FTS* fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr)) {
+        for (FTSENT* p; (p = fts_read(fts)) != nullptr;) {
+            switch (p->fts_info) {
+            case FTS_D:
+            case FTS_F:
+            case FTS_SL:
+            case FTS_SLNONE:
+                if (lchown(p->fts_path, uid, uid) != 0) {
+                    PLOG(WARNING) << "Failed to lchown " << p->fts_path;
+                }
+                break;
+            }
+        }
+        fts_close(fts);
+    }
+
+    const std::string ref_profile_path =
+            create_primary_reference_profile_package_dir_path(packageName);
+    argv[0] = (char *) ref_profile_path.c_str();
+    if (FTS* fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr)) {
+        for (FTSENT* p; (p = fts_read(fts)) != nullptr;) {
+            if (p->fts_info == FTS_D && p->fts_level == 0) {
+                if (chown(p->fts_path, AID_SYSTEM, sharedGid) != 0) {
+                    PLOG(WARNING) << "Failed to chown " << p->fts_path;
+                }
+                continue;
+            }
+            switch (p->fts_info) {
+            case FTS_D:
+            case FTS_F:
+            case FTS_SL:
+            case FTS_SLNONE:
+                if (lchown(p->fts_path, sharedGid, sharedGid) != 0) {
+                    PLOG(WARNING) << "Failed to lchown " << p->fts_path;
+                }
+                break;
+            }
+        }
+        fts_close(fts);
+    }
+}
+
+static binder::Status createAppDataDirs(const std::string& path,
+        int32_t uid, int32_t* previousUid, int32_t cacheGid,
+        const std::string& seInfo, mode_t targetMode) {
+    struct stat st{};
+    bool existing = (stat(path.c_str(), &st) == 0);
+    if (existing) {
+        if (*previousUid < 0) {
+            // If previousAppId is -1 in CreateAppDataArgs, we will assume the current owner
+            // of the directory as previousUid. This is required because it is not always possible
+            // to chown app data during app upgrade (e.g. secondary users' CE storage not unlocked)
+            *previousUid = st.st_uid;
+        }
+        if (*previousUid != uid) {
+            if (!chown_app_dir(path, uid, *previousUid, cacheGid)) {
+                return error("Failed to chown " + path);
+            }
+        }
+    }
+
+    if (prepare_app_dir(path, targetMode, uid) ||
+            prepare_app_cache_dir(path, "cache", 02771, uid, cacheGid) ||
+            prepare_app_cache_dir(path, "code_cache", 02771, uid, cacheGid)) {
+        return error("Failed to prepare " + path);
+    }
+
+    // Consider restorecon over contents if label changed
+    if (restorecon_app_data_lazy(path, seInfo, uid, existing) ||
+            restorecon_app_data_lazy(path, "cache", seInfo, uid, existing) ||
+            restorecon_app_data_lazy(path, "code_cache", seInfo, uid, existing)) {
+        return error("Failed to restorecon " + path);
+    }
+
+    return ok();
+}
+
 binder::Status InstalldNativeService::createAppData(const std::optional<std::string>& uuid,
         const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
-        const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) {
+        int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion,
+        int64_t* _aidl_return) {
     ENFORCE_UID(AID_SYSTEM);
     CHECK_ARGUMENT_UUID(uuid);
     CHECK_ARGUMENT_PACKAGE_NAME(packageName);
@@ -439,6 +559,14 @@
     if (_aidl_return != nullptr) *_aidl_return = -1;
 
     int32_t uid = multiuser_get_uid(userId, appId);
+
+    // If previousAppId < 0, we will use the existing app data owner as previousAppUid
+    // If previousAppId == 0, we use uid as previousUid (no data migration will happen)
+    // if previousAppId > 0, an app is upgrading and changing its app ID
+    int32_t previousUid = previousAppId > 0
+        ? (int32_t) multiuser_get_uid(userId, previousAppId)
+        : (previousAppId == 0 ? uid : -1);
+
     int32_t cacheGid = multiuser_get_cache_gid(userId, appId);
     mode_t targetMode = targetSdkVersion >= MIN_RESTRICTED_HOME_SDK_VERSION ? 0700 : 0751;
 
@@ -449,19 +577,13 @@
 
     if (flags & FLAG_STORAGE_CE) {
         auto path = create_data_user_ce_package_path(uuid_, userId, pkgname);
-        bool existing = (access(path.c_str(), F_OK) == 0);
 
-        if (prepare_app_dir(path, targetMode, uid) ||
-                prepare_app_cache_dir(path, "cache", 02771, uid, cacheGid) ||
-                prepare_app_cache_dir(path, "code_cache", 02771, uid, cacheGid)) {
-            return error("Failed to prepare " + path);
+        auto status = createAppDataDirs(path, uid, &previousUid, cacheGid, seInfo, targetMode);
+        if (!status.isOk()) {
+            return status;
         }
-
-        // Consider restorecon over contents if label changed
-        if (restorecon_app_data_lazy(path, seInfo, uid, existing) ||
-                restorecon_app_data_lazy(path, "cache", seInfo, uid, existing) ||
-                restorecon_app_data_lazy(path, "code_cache", seInfo, uid, existing)) {
-            return error("Failed to restorecon " + path);
+        if (previousUid != uid) {
+            chown_app_profile_dir(packageName, appId, userId);
         }
 
         // Remember inode numbers of cache directories so that we can clear
@@ -483,19 +605,10 @@
     }
     if (flags & FLAG_STORAGE_DE) {
         auto path = create_data_user_de_package_path(uuid_, userId, pkgname);
-        bool existing = (access(path.c_str(), F_OK) == 0);
 
-        if (prepare_app_dir(path, targetMode, uid) ||
-                prepare_app_cache_dir(path, "cache", 02771, uid, cacheGid) ||
-                prepare_app_cache_dir(path, "code_cache", 02771, uid, cacheGid)) {
-            return error("Failed to prepare " + path);
-        }
-
-        // Consider restorecon over contents if label changed
-        if (restorecon_app_data_lazy(path, seInfo, uid, existing) ||
-                restorecon_app_data_lazy(path, "cache", seInfo, uid, existing) ||
-                restorecon_app_data_lazy(path, "code_cache", seInfo, uid, existing)) {
-            return error("Failed to restorecon " + path);
+        auto status = createAppDataDirs(path, uid, &previousUid, cacheGid, seInfo, targetMode);
+        if (!status.isOk()) {
+            return status;
         }
 
         if (!prepare_app_profile_dir(packageName, appId, userId)) {
@@ -505,7 +618,6 @@
     return ok();
 }
 
-
 binder::Status InstalldNativeService::createAppData(
         const android::os::CreateAppDataArgs& args,
         android::os::CreateAppDataResult* _aidl_return) {
@@ -514,7 +626,7 @@
 
     int64_t ceDataInode = -1;
     auto status = createAppData(args.uuid, args.packageName, args.userId, args.flags, args.appId,
-                                args.seInfo, args.targetSdkVersion, &ceDataInode);
+            args.previousAppId, args.seInfo, args.targetSdkVersion, &ceDataInode);
     _aidl_return->ceDataInode = ceDataInode;
     _aidl_return->exceptionCode = status.exceptionCode();
     _aidl_return->exceptionMessage = status.exceptionMessage();
@@ -528,7 +640,7 @@
     std::lock_guard<std::recursive_mutex> lock(mLock);
 
     std::vector<android::os::CreateAppDataResult> results;
-    for (auto arg : args) {
+    for (const auto &arg : args) {
         android::os::CreateAppDataResult result;
         createAppData(arg, &result);
         results.push_back(result);
@@ -626,14 +738,11 @@
         }
     }
     if (flags & FLAG_STORAGE_DE) {
-        std::string suffix = "";
-        bool only_cache = false;
+        std::string suffix;
         if (flags & FLAG_CLEAR_CACHE_ONLY) {
             suffix = CACHE_DIR_POSTFIX;
-            only_cache = true;
         } else if (flags & FLAG_CLEAR_CODE_CACHE_ONLY) {
             suffix = CODE_CACHE_DIR_POSTFIX;
-            only_cache = true;
         }
 
         auto path = create_data_user_de_package_path(uuid_, userId, pkgname) + suffix;
@@ -1228,7 +1337,7 @@
         }
 
         if (!createAppData(toUuid, packageName, user, FLAG_STORAGE_CE | FLAG_STORAGE_DE, appId,
-                seInfo, targetSdkVersion, nullptr).isOk()) {
+                /* previousAppId */ -1, seInfo, targetSdkVersion, nullptr).isOk()) {
             res = error("Failed to create package target");
             goto fail;
         }
@@ -2401,7 +2510,8 @@
         const std::optional<std::string>& seInfo, bool downgrade, int32_t targetSdkVersion,
         const std::optional<std::string>& profileName,
         const std::optional<std::string>& dexMetadataPath,
-        const std::optional<std::string>& compilationReason) {
+        const std::optional<std::string>& compilationReason,
+        bool* aidl_return) {
     ENFORCE_UID(AID_SYSTEM);
     CHECK_ARGUMENT_UUID(uuid);
     CHECK_ARGUMENT_PATH(apkPath);
@@ -2429,12 +2539,20 @@
     const char* dm_path = getCStr(dexMetadataPath);
     const char* compilation_reason = getCStr(compilationReason);
     std::string error_msg;
+    bool completed = false; // not necessary but for compiler
     int res = android::installd::dexopt(apk_path, uid, pkgname, instruction_set, dexoptNeeded,
             oat_dir, dexFlags, compiler_filter, volume_uuid, class_loader_context, se_info,
-            downgrade, targetSdkVersion, profile_name, dm_path, compilation_reason, &error_msg);
+            downgrade, targetSdkVersion, profile_name, dm_path, compilation_reason, &error_msg,
+            &completed);
+    *aidl_return = completed;
     return res ? error(res, error_msg) : ok();
 }
 
+binder::Status InstalldNativeService::controlDexOptBlocking(bool block) {
+    android::installd::control_dexopt_blocking(block);
+    return ok();
+}
+
 binder::Status InstalldNativeService::compileLayouts(const std::string& apkPath,
                                                      const std::string& packageName,
                                                      const std ::string& outDexFile, int uid,
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index ea0c945..8cfda01 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -47,7 +47,8 @@
 
     binder::Status createAppData(const std::optional<std::string>& uuid,
             const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
-            const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return);
+            int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion,
+            int64_t* _aidl_return);
 
     binder::Status createAppData(
             const android::os::CreateAppDataArgs& args,
@@ -117,7 +118,10 @@
             const std::optional<std::string>& seInfo, bool downgrade,
             int32_t targetSdkVersion, const std::optional<std::string>& profileName,
             const std::optional<std::string>& dexMetadataPath,
-            const std::optional<std::string>& compilationReason);
+            const std::optional<std::string>& compilationReason,
+            bool* aidl_return);
+
+    binder::Status controlDexOptBlocking(bool block);
 
     binder::Status compileLayouts(const std::string& apkPath, const std::string& packageName,
                                   const std::string& outDexFile, int uid, bool* _aidl_return);
diff --git a/cmds/installd/OWNERS b/cmds/installd/OWNERS
index d6807ff..643b2c2 100644
--- a/cmds/installd/OWNERS
+++ b/cmds/installd/OWNERS
@@ -4,7 +4,6 @@
 jsharkey@android.com
 maco@google.com
 mast@google.com
-mathieuc@google.com
 narayan@google.com
 ngeoffray@google.com
 rpl@google.com
diff --git a/cmds/installd/binder/android/os/CreateAppDataArgs.aidl b/cmds/installd/binder/android/os/CreateAppDataArgs.aidl
index 96d7faa..d5e8ee5 100644
--- a/cmds/installd/binder/android/os/CreateAppDataArgs.aidl
+++ b/cmds/installd/binder/android/os/CreateAppDataArgs.aidl
@@ -23,6 +23,7 @@
     int userId;
     int flags;
     int appId;
+    int previousAppId;
     @utf8InCpp String seInfo;
     int targetSdkVersion;
 }
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 3d32f61..637a9f2 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -55,7 +55,8 @@
             @utf8InCpp String packageName, int appId,
             @utf8InCpp String seInfo, int targetSdkVersion, @utf8InCpp String fromCodePath);
 
-    void dexopt(@utf8InCpp String apkPath, int uid, @nullable @utf8InCpp String packageName,
+    // Returns false if it is cancelled. Returns true if it is completed or have other errors.
+    boolean dexopt(@utf8InCpp String apkPath, int uid, @nullable @utf8InCpp String packageName,
             @utf8InCpp String instructionSet, int dexoptNeeded,
             @nullable @utf8InCpp String outputPath, int dexFlags,
             @utf8InCpp String compilerFilter, @nullable @utf8InCpp String uuid,
@@ -64,6 +65,9 @@
             @nullable @utf8InCpp String profileName,
             @nullable @utf8InCpp String dexMetadataPath,
             @nullable @utf8InCpp String compilationReason);
+    // Blocks (when block is true) or unblock (when block is false) dexopt.
+    // Blocking also invloves cancelling the currently running dexopt.
+    void controlDexOptBlocking(boolean block);
     boolean compileLayouts(@utf8InCpp String apkPath, @utf8InCpp String packageName,
             @utf8InCpp String outDexFile, int uid);
 
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index d678281..f3ec63f 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -15,8 +15,8 @@
  */
 #define LOG_TAG "installd"
 
-#include <array>
 #include <fcntl.h>
+#include <signal.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/capability.h>
@@ -28,10 +28,14 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include <array>
 #include <iomanip>
+#include <mutex>
+#include <unordered_set>
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/no_destructor.h>
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
@@ -47,6 +51,7 @@
 #include <selinux/android.h>
 #include <server_configurable_flags/get_flags.h>
 #include <system/thread_defs.h>
+#include <utils/Mutex.h>
 
 #include "dexopt.h"
 #include "dexopt_return_codes.h"
@@ -69,6 +74,76 @@
 using android::base::WriteFully;
 using android::base::unique_fd;
 
+namespace {
+
+class DexOptStatus {
+ public:
+    // Check if dexopt is cancelled and fork if it is not cancelled.
+    // cancelled is set to true if cancelled. Otherwise it will be set to false.
+    // If it is not cancelled, it will return the return value of fork() call.
+    // If cancelled, fork will not happen and it will return -1.
+    pid_t check_cancellation_and_fork(/* out */ bool *cancelled) {
+        std::lock_guard<std::mutex> lock(dexopt_lock_);
+        if (dexopt_blocked_) {
+            *cancelled = true;
+            return -1;
+        }
+        pid_t pid = fork();
+        *cancelled = false;
+        if (pid > 0) { // parent
+            dexopt_pids_.insert(pid);
+        }
+        return pid;
+    }
+
+    // Returns true if pid was killed (is in killed list). It could have finished if killing
+    // happened after the process is finished.
+    bool check_if_killed_and_remove_dexopt_pid(pid_t pid) {
+        std::lock_guard<std::mutex> lock(dexopt_lock_);
+        dexopt_pids_.erase(pid);
+        if (dexopt_killed_pids_.erase(pid) == 1) {
+            return true;
+        }
+        return false;
+    }
+
+    // Tells whether dexopt is blocked or not.
+    bool is_dexopt_blocked() {
+        std::lock_guard<std::mutex> lock(dexopt_lock_);
+        return dexopt_blocked_;
+    }
+
+    // Enable or disable dexopt blocking.
+    void control_dexopt_blocking(bool block) {
+        std::lock_guard<std::mutex> lock(dexopt_lock_);
+        dexopt_blocked_ = block;
+        if (!block) {
+            return;
+        }
+        // Blocked, also kill currently running tasks
+        for (auto pid : dexopt_pids_) {
+            LOG(INFO) << "control_dexopt_blocking kill pid:" << pid;
+            kill(pid, SIGKILL);
+            dexopt_killed_pids_.insert(pid);
+        }
+        dexopt_pids_.clear();
+    }
+
+ private:
+    std::mutex dexopt_lock_;
+    // when true, dexopt is blocked and will not run.
+    bool dexopt_blocked_ GUARDED_BY(dexopt_lock_) = false;
+    // PIDs of child process while runinng dexopt.
+    // If the child process is finished, it should be removed.
+    std::unordered_set<pid_t> dexopt_pids_ GUARDED_BY(dexopt_lock_);
+    // PIDs of child processes killed by cancellation.
+    std::unordered_set<pid_t> dexopt_killed_pids_ GUARDED_BY(dexopt_lock_);
+};
+
+android::base::NoDestructor<DexOptStatus> dexopt_status_;
+
+} // namespace
+
 namespace android {
 namespace installd {
 
@@ -1525,23 +1600,46 @@
     return ss.str();
 }
 
+void control_dexopt_blocking(bool block) {
+    dexopt_status_->control_dexopt_blocking(block);
+}
+
+bool is_dexopt_blocked() {
+    return dexopt_status_->is_dexopt_blocked();
+}
+
+enum SecondaryDexOptProcessResult {
+    kSecondaryDexOptProcessOk = 0,
+    kSecondaryDexOptProcessCancelled = 1,
+    kSecondaryDexOptProcessError = 2
+};
+
 // Processes the dex_path as a secondary dex files and return true if the path dex file should
-// be compiled. Returns false for errors (logged) or true if the secondary dex path was process
-// successfully.
-// When returning true, the output parameters will be:
+// be compiled.
+// Returns: kSecondaryDexOptProcessError for errors (logged).
+//          kSecondaryDexOptProcessOk if the secondary dex path was process successfully.
+//          kSecondaryDexOptProcessCancelled if the processing was cancelled.
+//
+// When returning kSecondaryDexOptProcessOk, the output parameters will be:
 //   - is_public_out: whether or not the oat file should not be made public
 //   - dexopt_needed_out: valid OatFileAsssitant::DexOptNeeded
 //   - oat_dir_out: the oat dir path where the oat file should be stored
-static bool process_secondary_dex_dexopt(const std::string& dex_path, const char* pkgname,
-        int dexopt_flags, const char* volume_uuid, int uid, const char* instruction_set,
-        const char* compiler_filter, bool* is_public_out, int* dexopt_needed_out,
-        std::string* oat_dir_out, bool downgrade, const char* class_loader_context,
-        const std::vector<std::string>& context_dex_paths, /* out */ std::string* error_msg) {
+static SecondaryDexOptProcessResult process_secondary_dex_dexopt(const std::string& dex_path,
+        const char* pkgname, int dexopt_flags, const char* volume_uuid, int uid,
+        const char* instruction_set, const char* compiler_filter, bool* is_public_out,
+        int* dexopt_needed_out, std::string* oat_dir_out, bool downgrade,
+        const char* class_loader_context, const std::vector<std::string>& context_dex_paths,
+        /* out */ std::string* error_msg) {
     LOG(DEBUG) << "Processing secondary dex path " << dex_path;
+
+    if (dexopt_status_->is_dexopt_blocked()) {
+        return kSecondaryDexOptProcessCancelled;
+    }
+
     int storage_flag;
     if (!validate_dexopt_storage_flags(dexopt_flags, &storage_flag, error_msg)) {
         LOG(ERROR) << *error_msg;
-        return false;
+        return kSecondaryDexOptProcessError;
     }
     // Compute the oat dir as it's not easy to extract it from the child computation.
     char oat_path[PKG_PATH_MAX];
@@ -1550,11 +1648,15 @@
     if (!create_secondary_dex_oat_layout(
             dex_path, instruction_set, oat_dir, oat_isa_dir, oat_path, error_msg)) {
         LOG(ERROR) << "Could not create secondary odex layout: " << *error_msg;
-        return false;
+        return kSecondaryDexOptProcessError;
     }
     oat_dir_out->assign(oat_dir);
 
-    pid_t pid = fork();
+    bool cancelled = false;
+    pid_t pid = dexopt_status_->check_cancellation_and_fork(&cancelled);
+    if (cancelled) {
+        return kSecondaryDexOptProcessCancelled;
+    }
     if (pid == 0) {
         // child -- drop privileges before continuing.
         drop_capabilities(uid);
@@ -1623,12 +1725,17 @@
 
     /* parent */
     int result = wait_child(pid);
+    cancelled = dexopt_status_->check_if_killed_and_remove_dexopt_pid(pid);
     if (!WIFEXITED(result)) {
+        if ((WTERMSIG(result) == SIGKILL) && cancelled) {
+            LOG(INFO) << "dexoptanalyzer cancelled for path:" << dex_path;
+            return kSecondaryDexOptProcessCancelled;
+        }
         *error_msg = StringPrintf("dexoptanalyzer failed for path %s: 0x%04x",
                                   dex_path.c_str(),
                                   result);
         LOG(ERROR) << *error_msg;
-        return false;
+        return kSecondaryDexOptProcessError;
     }
     result = WEXITSTATUS(result);
     // Check that we successfully executed dexoptanalyzer.
@@ -1656,7 +1763,7 @@
     // It is ok to check this flag outside in the parent process.
     *is_public_out = ((dexopt_flags & DEXOPT_PUBLIC) != 0) && is_file_public(dex_path);
 
-    return success;
+    return success ? kSecondaryDexOptProcessOk : kSecondaryDexOptProcessError;
 }
 
 static std::string format_dexopt_error(int status, const char* dex_path) {
@@ -1670,17 +1777,29 @@
   return StringPrintf("Dex2oat invocation for %s failed with 0x%04x", dex_path, status);
 }
 
+
 int dexopt(const char* dex_path, uid_t uid, const char* pkgname, const char* instruction_set,
         int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter,
         const char* volume_uuid, const char* class_loader_context, const char* se_info,
         bool downgrade, int target_sdk_version, const char* profile_name,
-        const char* dex_metadata_path, const char* compilation_reason, std::string* error_msg) {
+        const char* dex_metadata_path, const char* compilation_reason, std::string* error_msg,
+        /* out */ bool* completed) {
     CHECK(pkgname != nullptr);
     CHECK(pkgname[0] != 0);
     CHECK(error_msg != nullptr);
     CHECK_EQ(dexopt_flags & ~DEXOPT_MASK, 0)
         << "dexopt flags contains unknown fields: " << dexopt_flags;
 
+    bool local_completed; // local placeholder for nullptr case
+    if (completed == nullptr) {
+        completed = &local_completed;
+    }
+    *completed = true;
+    if (dexopt_status_->is_dexopt_blocked()) {
+        *completed = false;
+        return 0;
+    }
+
     if (!validate_dex_path_size(dex_path)) {
         *error_msg = StringPrintf("Failed to validate %s", dex_path);
         return -1;
@@ -1712,14 +1831,19 @@
             *error_msg = "Failed acquiring context dex paths";
             return -1;  // We had an error, logged in the process method.
         }
-
-        if (process_secondary_dex_dexopt(dex_path, pkgname, dexopt_flags, volume_uuid, uid,
-                instruction_set, compiler_filter, &is_public, &dexopt_needed, &oat_dir_str,
-                downgrade, class_loader_context, context_dex_paths, error_msg)) {
+        SecondaryDexOptProcessResult sec_dex_result = process_secondary_dex_dexopt(dex_path,
+                pkgname, dexopt_flags, volume_uuid, uid,instruction_set, compiler_filter,
+                &is_public, &dexopt_needed, &oat_dir_str, downgrade, class_loader_context,
+                context_dex_paths, error_msg);
+        if (sec_dex_result == kSecondaryDexOptProcessOk) {
             oat_dir = oat_dir_str.c_str();
             if (dexopt_needed == NO_DEXOPT_NEEDED) {
                 return 0;  // Nothing to do, report success.
             }
+        } else if (sec_dex_result == kSecondaryDexOptProcessCancelled) {
+            // cancelled, not an error.
+            *completed = false;
+            return 0;
         } else {
             if (error_msg->empty()) {  // TODO: Make this a CHECK.
                 *error_msg = "Failed processing secondary.";
@@ -1849,7 +1973,11 @@
                       use_jitzygote_image,
                       compilation_reason);
 
-    pid_t pid = fork();
+    bool cancelled = false;
+    pid_t pid = dexopt_status_->check_cancellation_and_fork(&cancelled);
+    if (cancelled) {
+        return 0;
+    }
     if (pid == 0) {
         // Need to set schedpolicy before dropping privileges
         // for cgroup migration. See details at b/175178520.
@@ -1867,9 +1995,16 @@
         runner.Exec(DexoptReturnCodes::kDex2oatExec);
     } else {
         int res = wait_child(pid);
+        bool cancelled = dexopt_status_->check_if_killed_and_remove_dexopt_pid(pid);
         if (res == 0) {
             LOG(VERBOSE) << "DexInv: --- END '" << dex_path << "' (success) ---";
         } else {
+            if ((WTERMSIG(res) == SIGKILL) && cancelled) {
+                LOG(VERBOSE) << "DexInv: --- END '" << dex_path << "' --- cancelled";
+                // cancelled, not an error
+                *completed = false;
+                return 0;
+            }
             LOG(VERBOSE) << "DexInv: --- END '" << dex_path << "' --- status=0x"
                          << std::hex << std::setw(4) << res << ", process failed";
             *error_msg = format_dexopt_error(res, dex_path);
@@ -1877,12 +2012,14 @@
         }
     }
 
+    // TODO(b/156537504) Implement SWAP of completed files
     // We've been successful, don't delete output.
     out_oat.DisableCleanup();
     out_vdex.DisableCleanup();
     out_image.DisableCleanup();
     reference_profile.DisableCleanup();
 
+    *completed = true;
     return 0;
 }
 
diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h
index 5a637b1..12579b0 100644
--- a/cmds/installd/dexopt.h
+++ b/cmds/installd/dexopt.h
@@ -121,11 +121,18 @@
         const std::string& pkgname, int uid, const std::optional<std::string>& volume_uuid,
         int storage_flag, std::vector<uint8_t>* out_secondary_dex_hash);
 
+// completed pass false if it is canceled. Otherwise it will be true even if there is other
+// error.
 int dexopt(const char *apk_path, uid_t uid, const char *pkgName, const char *instruction_set,
         int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* compiler_filter,
         const char* volume_uuid, const char* class_loader_context, const char* se_info,
         bool downgrade, int target_sdk_version, const char* profile_name,
-        const char* dexMetadataPath, const char* compilation_reason, std::string* error_msg);
+        const char* dexMetadataPath, const char* compilation_reason, std::string* error_msg,
+        /* out */ bool* completed = nullptr);
+
+bool is_dexopt_blocked();
+
+void control_dexopt_blocking(bool block);
 
 bool calculate_oat_file_path_default(char path[PKG_PATH_MAX], const char *oat_dir,
         const char *apk_path, const char *instruction_set);
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index 7e7e513..a937436 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -232,6 +232,7 @@
 
     virtual void TearDown() {
         if (!kDebug) {
+            service_->controlDexOptBlocking(false);
             service_->destroyAppData(
                 volume_uuid_, package_name_, kTestUserId, kAppDataFlags, ce_data_inode_);
             run_cmd("rm -rf " + app_apk_dir_);
@@ -286,6 +287,7 @@
                 kTestUserId,
                 kAppDataFlags,
                 kTestAppUid,
+                0 /* previousAppId */,
                 se_info_,
                 kOSdkVersion,
                 &ce_data_inode_);
@@ -347,7 +349,7 @@
     void CompileSecondaryDex(const std::string& path, int32_t dex_storage_flag,
             bool should_binder_call_succeed, bool should_dex_be_compiled = true,
             /*out */ binder::Status* binder_result = nullptr, int32_t uid = -1,
-            const char* class_loader_context = nullptr) {
+            const char* class_loader_context = nullptr, bool expect_completed = true) {
         if (uid == -1) {
             uid = kTestAppUid;
         }
@@ -364,6 +366,7 @@
         std::optional<std::string> dm_path;
         std::optional<std::string> compilation_reason;
 
+        bool completed = false;
         binder::Status result = service_->dexopt(path,
                                                  uid,
                                                  package_name_,
@@ -379,8 +382,10 @@
                                                  target_sdk_version,
                                                  profile_name,
                                                  dm_path,
-                                                 compilation_reason);
+                                                 compilation_reason,
+                                                 &completed);
         ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
+        ASSERT_EQ(expect_completed, completed);
         int expected_access = should_dex_be_compiled ? 0 : -1;
         std::string odex = GetSecondaryDexArtifact(path, "odex");
         std::string vdex = GetSecondaryDexArtifact(path, "vdex");
@@ -431,6 +436,11 @@
         ASSERT_EQ(mode, st.st_mode);
     }
 
+    void AssertNoFile(const std::string& file) {
+        struct stat st;
+        ASSERT_EQ(-1, stat(file.c_str(), &st));
+    }
+
     void CompilePrimaryDexOk(std::string compiler_filter,
                              int32_t dex_flags,
                              const char* oat_dir,
@@ -447,6 +457,7 @@
                           dm_path,
                           downgrade,
                           true,
+                          true,
                           binder_result);
     }
 
@@ -466,6 +477,27 @@
                           dm_path,
                           downgrade,
                           false,
+                          true,
+                          binder_result);
+    }
+
+    void CompilePrimaryDexCancelled(std::string compiler_filter,
+                               int32_t dex_flags,
+                               const char* oat_dir,
+                               int32_t uid,
+                               int32_t dexopt_needed,
+                               binder::Status* binder_result = nullptr,
+                               const char* dm_path = nullptr,
+                               bool downgrade = false) {
+        CompilePrimaryDex(compiler_filter,
+                          dex_flags,
+                          oat_dir,
+                          uid,
+                          dexopt_needed,
+                          dm_path,
+                          downgrade,
+                          true, // should_binder_call_succeed
+                          false, // expect_completed
                           binder_result);
     }
 
@@ -477,6 +509,7 @@
                            const char* dm_path,
                            bool downgrade,
                            bool should_binder_call_succeed,
+                           bool expect_completed,
                            /*out */ binder::Status* binder_result) {
         std::optional<std::string> out_path = oat_dir ? std::make_optional<std::string>(oat_dir) : std::nullopt;
         std::string class_loader_context = "PCL[]";
@@ -491,6 +524,7 @@
                 dm_path_opt, &prof_result));
         ASSERT_TRUE(prof_result);
 
+        bool completed = false;
         binder::Status result = service_->dexopt(apk_path_,
                                                  uid,
                                                  package_name_,
@@ -506,8 +540,10 @@
                                                  target_sdk_version,
                                                  profile_name,
                                                  dm_path_opt,
-                                                 compilation_reason);
+                                                 compilation_reason,
+                                                 &completed);
         ASSERT_EQ(should_binder_call_succeed, result.isOk()) << result.toString8().c_str();
+        ASSERT_EQ(expect_completed, completed);
 
         if (!should_binder_call_succeed) {
             if (binder_result != nullptr) {
@@ -525,11 +561,20 @@
 
         bool is_public = (dex_flags & DEXOPT_PUBLIC) != 0;
         mode_t mode = S_IFREG | (is_public ? 0644 : 0640);
-        CheckFileAccess(odex, kSystemUid, uid, mode);
-        CheckFileAccess(vdex, kSystemUid, uid, mode);
+        if (expect_completed) {
+            CheckFileAccess(odex, kSystemUid, uid, mode);
+            CheckFileAccess(vdex, kSystemUid, uid, mode);
+        } else {
+            AssertNoFile(odex);
+            AssertNoFile(vdex);
+        }
 
         if (compiler_filter == "speed-profile") {
-            CheckFileAccess(art, kSystemUid, uid, mode);
+            if (expect_completed) {
+                CheckFileAccess(art, kSystemUid, uid, mode);
+            } else {
+                AssertNoFile(art);
+            }
         }
         if (binder_result != nullptr) {
             *binder_result = result;
@@ -750,6 +795,28 @@
                         empty_dm_file_.c_str());
 }
 
+TEST_F(DexoptTest, DexoptBlockPrimary) {
+    LOG(INFO) << "DexoptPrimaryPublic";
+    service_->controlDexOptBlocking(true);
+    CompilePrimaryDexCancelled("verify",
+                        DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
+                        app_oat_dir_.c_str(),
+                        kTestAppGid,
+                        DEX2OAT_FROM_SCRATCH, nullptr, nullptr);
+    service_->controlDexOptBlocking(false);
+}
+
+TEST_F(DexoptTest, DexoptUnblockPrimary) {
+    LOG(INFO) << "DexoptPrimaryPublic";
+    service_->controlDexOptBlocking(true);
+    service_->controlDexOptBlocking(false);
+    CompilePrimaryDexOk("verify",
+                        DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
+                        app_oat_dir_.c_str(),
+                        kTestAppGid,
+                        DEX2OAT_FROM_SCRATCH, nullptr, nullptr);
+}
+
 TEST_F(DexoptTest, DeleteDexoptArtifactsData) {
     LOG(INFO) << "DeleteDexoptArtifactsData";
     TestDeleteOdex(/*in_dalvik_cache=*/ false);
@@ -1191,6 +1258,7 @@
             kTestUserId,
             kAppDataFlags,
             kTestAppUid,
+            0 /* previousAppId */,
             se_info_,
             kOSdkVersion,
             &ce_data_inode_));
@@ -1254,6 +1322,7 @@
                     kTestUserId,
                     kAppDataFlags,
                     kTestAppUid,
+                    0 /* previousAppId */,
                     se_info_,
                     kOSdkVersion,
                     &ce_data_inode));
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index 2722e21..ff73c94 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -28,6 +28,7 @@
 #include <sstream>
 
 #include <android-base/file.h>
+#include <android-base/hex.h>
 #include <android-base/logging.h>
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <hidl-hash/Hash.h>
@@ -691,8 +692,7 @@
             }
 
             auto&& hashArray = hashChain[hashIndex];
-            std::vector<uint8_t> hashVec{hashArray.data(), hashArray.data() + hashArray.size()};
-            entry->hash = Hash::hexString(hashVec);
+            entry->hash = android::base::HexString(hashArray.data(), hashArray.size());
         });
         if (!hashRet.isOk()) {
             handleError(TRANSACTION_ERROR, "getHashChain failed: " + hashRet.description());
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index bc99f4d..a5f98c2 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -142,12 +142,10 @@
         }
     }
 
-    PipeRelay relay(out, err, interfaceName, instanceName);
-
-    if (relay.initCheck() != OK) {
-        std::string msg = "PipeRelay::initCheck() FAILED w/ " + std::to_string(relay.initCheck());
-        err << msg << std::endl;
-        LOG(ERROR) << msg;
+    auto relay = PipeRelay::create(out, err, interfaceName + "/" + instanceName);
+    if (!relay.ok()) {
+        err << "Unable to create PipeRelay: " << relay.error() << std::endl;
+        LOG(ERROR) << "Unable to create PipeRelay: " << relay.error();
         return IO_ERROR;
     }
 
@@ -155,7 +153,7 @@
         native_handle_create(1 /* numFds */, 0 /* numInts */),
         native_handle_delete);
 
-    fdHandle->data[0] = relay.fd();
+    fdHandle->data[0] = relay.value()->fd().get();
 
     hardware::Return<void> ret = base->debug(fdHandle.get(), convert(options));
 
diff --git a/cmds/lshal/PipeRelay.cpp b/cmds/lshal/PipeRelay.cpp
index 4e97636..863490d 100644
--- a/cmds/lshal/PipeRelay.cpp
+++ b/cmds/lshal/PipeRelay.cpp
@@ -16,143 +16,94 @@
 
 #include "PipeRelay.h"
 
-#include <sys/select.h>
-#include <sys/time.h>
+#include <sys/poll.h>
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <atomic>
+#include <chrono>
+#include <optional>
 
-#include <utils/Thread.h>
+#include <android-base/unique_fd.h>
+
+using android::base::borrowed_fd;
+using android::base::Result;
+using android::base::unique_fd;
+using std::chrono_literals::operator""ms;
 
 namespace android {
 namespace lshal {
-
-static constexpr struct timeval READ_TIMEOUT { .tv_sec = 1, .tv_usec = 0 };
-
-static std::string getThreadName(std::string interfaceName, const std::string &instanceName) {
-    auto dot = interfaceName.rfind(".");
-    if (dot != std::string::npos) interfaceName = interfaceName.substr(dot + 1);
-    return "RelayThread_" + interfaceName + "_" + instanceName;
+Result<std::unique_ptr<PipeRelay>> PipeRelay::create(std::ostream& os,
+                                                     const NullableOStream<std::ostream>& err,
+                                                     const std::string& fqName) {
+    auto pipeRelay = std::unique_ptr<PipeRelay>(new PipeRelay());
+    unique_fd rfd;
+    if (!android::base::Pipe(&rfd, &pipeRelay->mWrite)) {
+        return android::base::ErrnoError() << "pipe()";
+    }
+    // Workaround for b/111997867: need a separate FD trigger because rfd can't receive POLLHUP
+    // when the write end is closed after the write end was sent through hwbinder.
+    unique_fd rfdTrigger;
+    if (!android::base::Pipe(&rfdTrigger, &pipeRelay->mWriteTrigger)) {
+        return android::base::ErrnoError() << "pipe() for trigger";
+    }
+    pipeRelay->mThread =
+            std::make_unique<std::thread>(&PipeRelay::thread, std::move(rfd), std::move(rfdTrigger),
+                                          &os, &err, fqName);
+    return pipeRelay;
 }
 
-struct PipeRelay::RelayThread : public Thread {
-    explicit RelayThread(int fd, std::ostream &os, const NullableOStream<std::ostream> &err,
-                         const std::string &fqName);
+void PipeRelay::thread(unique_fd rfd, unique_fd rfdTrigger, std::ostream* out,
+                       const NullableOStream<std::ostream>* err, std::string fqName) {
+    while (true) {
+        pollfd pfd[2];
+        pfd[0] = {.fd = rfd.get(), .events = POLLIN};
+        pfd[1] = {.fd = rfdTrigger.get(), .events = 0};
 
-    bool threadLoop() override;
-    void setFinished();
-
-private:
-    int mFd;
-    std::ostream &mOutStream;
-    NullableOStream<std::ostream> mErrStream;
-
-    // If we were to use requestExit() and exitPending() instead, threadLoop()
-    // may not run at all by the time ~PipeRelay is called (i.e. debug() has
-    // returned from HAL). By using our own flag, we ensure that select() and
-    // read() are executed until data are drained.
-    std::atomic_bool mFinished;
-
-    std::string mFqName;
-
-    DISALLOW_COPY_AND_ASSIGN(RelayThread);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-PipeRelay::RelayThread::RelayThread(int fd, std::ostream &os,
-                                    const NullableOStream<std::ostream> &err,
-                                    const std::string &fqName)
-      : mFd(fd), mOutStream(os), mErrStream(err), mFinished(false), mFqName(fqName) {}
-
-bool PipeRelay::RelayThread::threadLoop() {
-    char buffer[1024];
-
-    fd_set set;
-    FD_ZERO(&set);
-    FD_SET(mFd, &set);
-
-    struct timeval timeout = READ_TIMEOUT;
-
-    int res = TEMP_FAILURE_RETRY(select(mFd + 1, &set, nullptr, nullptr, &timeout));
-    if (res < 0) {
-        mErrStream << "debug " << mFqName << ": select() failed";
-        return false;
-    }
-
-    if (res == 0 || !FD_ISSET(mFd, &set)) {
-        if (mFinished) {
-            mErrStream << "debug " << mFqName
-                       << ": timeout reading from pipe, output may be truncated.";
-            return false;
+        int pollRes = poll(pfd, arraysize(pfd), -1 /* infinite timeout */);
+        if (pollRes < 0) {
+            int savedErrno = errno;
+            (*err) << "debug " << fqName << ": poll() failed: " << strerror(savedErrno)
+                   << std::endl;
+            break;
         }
-        // timeout, but debug() has not returned, so wait for HAL to finish.
-        return true;
-    }
 
-    // FD_ISSET(mFd, &set) == true. Data available, start reading
-    ssize_t n = TEMP_FAILURE_RETRY(read(mFd, buffer, sizeof(buffer)));
-
-    if (n < 0) {
-        mErrStream << "debug " << mFqName << ": read() failed";
-    }
-
-    if (n <= 0) {
-        return false;
-    }
-
-    mOutStream.write(buffer, n);
-
-    return true;
-}
-
-void PipeRelay::RelayThread::setFinished() {
-    mFinished = true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-PipeRelay::PipeRelay(std::ostream &os, const NullableOStream<std::ostream> &err,
-                     const std::string &interfaceName, const std::string &instanceName)
-      : mInitCheck(NO_INIT) {
-    int res = pipe(mFds);
-
-    if (res < 0) {
-        mInitCheck = -errno;
-        return;
-    }
-
-    mThread = new RelayThread(mFds[0], os, err, interfaceName + "/" + instanceName);
-    mInitCheck = mThread->run(getThreadName(interfaceName, instanceName).c_str());
-}
-
-void PipeRelay::CloseFd(int *fd) {
-    if (*fd >= 0) {
-        close(*fd);
-        *fd = -1;
+        if (pfd[0].revents & POLLIN) {
+            char buffer[1024];
+            ssize_t n = TEMP_FAILURE_RETRY(read(rfd.get(), buffer, sizeof(buffer)));
+            if (n < 0) {
+                int savedErrno = errno;
+                (*err) << "debug " << fqName << ": read() failed: " << strerror(savedErrno)
+                       << std::endl;
+                break;
+            }
+            if (n == 0) {
+                (*err) << "Warning: debug " << fqName << ": poll() indicates POLLIN but no data"
+                       << std::endl;
+                continue;
+            }
+            out->write(buffer, n);
+            continue;
+        }
+        if (pfd[0].revents & POLLHUP) {
+            break;
+        }
+        if (pfd[1].revents & POLLHUP) {
+            // ~PipeRelay is called on the main thread. |mWrite| has been flushed and closed.
+            // Ensure that our read end of the pipe doesn't have pending data, then exit.
+            if ((pfd[0].revents & POLLIN) == 0) {
+                break;
+            }
+        }
     }
 }
 
 PipeRelay::~PipeRelay() {
-    CloseFd(&mFds[1]);
-
-    if (mThread != nullptr) {
-        mThread->setFinished();
+    mWrite.reset();
+    mWriteTrigger.reset();
+    if (mThread != nullptr && mThread->joinable()) {
         mThread->join();
-        mThread.clear();
     }
-
-    CloseFd(&mFds[0]);
 }
 
-status_t PipeRelay::initCheck() const {
-    return mInitCheck;
-}
-
-int PipeRelay::fd() const {
-    return mFds[1];
-}
-
-}  // namespace lshal
-}  // namespace android
+} // namespace lshal
+} // namespace android
diff --git a/cmds/lshal/PipeRelay.h b/cmds/lshal/PipeRelay.h
index bd994b4..45ba982 100644
--- a/cmds/lshal/PipeRelay.h
+++ b/cmds/lshal/PipeRelay.h
@@ -16,42 +16,43 @@
 
 #pragma once
 
+#include <thread>
+
 #include <android-base/macros.h>
-#include <ostream>
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
+#include <ostream>
 
 #include "NullableOStream.h"
 
 namespace android {
 namespace lshal {
 
-/* Creates an AF_UNIX socketpair and spawns a thread that relays any data
+/**
+ * Creates a pipe and spawns a thread that relays any data
  * written to the "write"-end of the pair to the specified output stream "os".
  */
 struct PipeRelay {
-    explicit PipeRelay(std::ostream& os,
-                       const NullableOStream<std::ostream>& err,
-                       const std::string& interfaceName,
-                       const std::string& instanceName);
+    static android::base::Result<std::unique_ptr<PipeRelay>> create(
+            std::ostream& os, const NullableOStream<std::ostream>& err, const std::string& fqName);
     ~PipeRelay();
 
-    status_t initCheck() const;
-
     // Returns the file descriptor corresponding to the "write"-end of the
     // connection.
-    int fd() const;
+    android::base::borrowed_fd fd() const { return mWrite; }
 
 private:
-    struct RelayThread;
-
-    status_t mInitCheck;
-    int mFds[2];
-    sp<RelayThread> mThread;
-
-    static void CloseFd(int *fd);
-
+    PipeRelay() = default;
     DISALLOW_COPY_AND_ASSIGN(PipeRelay);
+    static void thread(android::base::unique_fd rfd, android::base::unique_fd rfdTrigger,
+                       std::ostream* out, const NullableOStream<std::ostream>* err,
+                       std::string fqName);
+
+    android::base::unique_fd mWrite;
+    android::base::unique_fd mWriteTrigger;
+    std::unique_ptr<std::thread> mThread;
 };
 
 }  // namespace lshal
diff --git a/cmds/lshal/TableEntry.cpp b/cmds/lshal/TableEntry.cpp
index 8e21975..1753343 100644
--- a/cmds/lshal/TableEntry.cpp
+++ b/cmds/lshal/TableEntry.cpp
@@ -18,6 +18,7 @@
 
 #include <map>
 
+#include <android-base/hex.h>
 #include <android-base/strings.h>
 #include <hidl-hash/Hash.h>
 #include <vintf/parse_string.h>
@@ -104,7 +105,8 @@
 }
 
 std::string TableEntry::isReleased() const {
-    static const std::string unreleased = Hash::hexString(Hash::kEmptyHash);
+    static const std::string unreleased = android::base::HexString(Hash::kEmptyHash.data(),
+                                                                   Hash::kEmptyHash.size());
 
     if (hash.empty()) {
         return "?";
diff --git a/cmds/lshal/test.cpp b/cmds/lshal/test.cpp
index 6f08f74..cba7c4b 100644
--- a/cmds/lshal/test.cpp
+++ b/cmds/lshal/test.cpp
@@ -22,9 +22,10 @@
 #include <thread>
 #include <vector>
 
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
+#include <android-base/parseint.h>
 #include <android/hardware/tests/inheritance/1.0/IChild.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
 #include <hidl/HidlTransportSupport.h>
 #include <vintf/parse_xml.h>
 
@@ -77,6 +78,13 @@
             content += "\n";
             content += option.c_str();
         }
+        if (options.size() > 0) {
+            uint64_t len;
+            if (android::base::ParseUint(options[0], &len)) {
+                content += "\n";
+                content += std::string(len, 'X');
+            }
+        }
         ssize_t written = write(fd, content.c_str(), content.size());
         if (written != (ssize_t)content.size()) {
             LOG(WARNING) << "SERVER(Child) debug writes " << written << " bytes < "
@@ -189,6 +197,16 @@
     EXPECT_THAT(err.str(), HasSubstr("does not exist"));
 }
 
+TEST_F(DebugTest, DebugLarge) {
+    EXPECT_EQ(0u, callMain(lshal, {
+        "lshal", "debug", "android.hardware.tests.inheritance@1.0::IChild/default", "10000"
+    }));
+    EXPECT_THAT(out.str(),
+                StrEq("android.hardware.tests.inheritance@1.0::IChild\n10000\n" +
+                      std::string(10000, 'X')));
+    EXPECT_THAT(err.str(), IsEmpty());
+}
+
 TEST_F(DebugTest, DebugParent) {
     EXPECT_EQ(0u, callMain(lshal, {
         "lshal", "debug", "android.hardware.tests.inheritance@1.0::IParent", "calling parent"
diff --git a/cmds/rss_hwm_reset/rss_hwm_reset.rc b/cmds/rss_hwm_reset/rss_hwm_reset.rc
index fbbc820..271cbf8 100644
--- a/cmds/rss_hwm_reset/rss_hwm_reset.rc
+++ b/cmds/rss_hwm_reset/rss_hwm_reset.rc
@@ -18,7 +18,7 @@
     oneshot
     user nobody
     group nobody readproc
-    writepid /dev/cpuset/system-background/tasks
+    task_profiles ServiceCapacityLow
     capabilities DAC_OVERRIDE
 
 on property:sys.rss_hwm_reset.on=1
diff --git a/cmds/service/Android.bp b/cmds/service/Android.bp
index 3e8e3f6..21ac11b 100644
--- a/cmds/service/Android.bp
+++ b/cmds/service/Android.bp
@@ -52,3 +52,21 @@
         "-Werror",
     ],
 }
+
+cc_binary_host {
+    name: "aservice",
+
+    srcs: ["service.cpp"],
+
+    shared_libs: [
+        "libcutils",
+        "libutils",
+        "libbinder",
+    ],
+
+    cflags: [
+        "-DXP_UNIX",
+        "-Wall",
+        "-Werror",
+    ],
+}
diff --git a/cmds/service/service.cpp b/cmds/service/service.cpp
index 18b6b58..fe417a3 100644
--- a/cmds/service/service.cpp
+++ b/cmds/service/service.cpp
@@ -45,37 +45,14 @@
     }
 }
 
-// get the name of the generic interface we hold a reference to
-static String16 get_interface_name(sp<IBinder> service)
-{
-    if (service != nullptr) {
-        Parcel data, reply;
-        status_t err = service->transact(IBinder::INTERFACE_TRANSACTION, data, &reply);
-        if (err == NO_ERROR) {
-            return reply.readString16();
-        }
-    }
-    return String16();
-}
-
-static String8 good_old_string(const String16& src)
-{
-    String8 name8;
-    char ch8[2];
-    ch8[1] = 0;
-    for (unsigned j = 0; j < src.size(); j++) {
-        char16_t ch = src[j];
-        if (ch < 128) ch8[0] = (char)ch;
-        name8.append(ch8);
-    }
-    return name8;
-}
-
 int main(int argc, char* const argv[])
 {
     bool wantsUsage = false;
     int result = 0;
 
+    /* Strip path off the program name. */
+    char* prog_name = basename(argv[0]);
+
     while (1) {
         int ic = getopt(argc, argv, "h?");
         if (ic < 0)
@@ -87,7 +64,7 @@
             wantsUsage = true;
             break;
         default:
-            aerr << "service: Unknown option -" << ic << endl;
+            aerr << prog_name << ": Unknown option -" << ic << endl;
             wantsUsage = true;
             result = 10;
             break;
@@ -96,10 +73,13 @@
 #ifdef VENDORSERVICES
     ProcessState::initWithDriver("/dev/vndbinder");
 #endif
+#ifndef __ANDROID__
+    setDefaultServiceManager(createRpcDelegateServiceManager({.maxOutgoingThreads = 1}));
+#endif
     sp<IServiceManager> sm = defaultServiceManager();
     fflush(stdout);
     if (sm == nullptr) {
-        aerr << "service: Unable to get default service manager!" << endl;
+        aerr << prog_name << ": Unable to get default service manager!" << endl;
         return 20;
     }
 
@@ -113,7 +93,7 @@
                 aout << "Service " << argv[optind] <<
                     (service == nullptr ? ": not found" : ": found") << endl;
             } else {
-                aerr << "service: No service specified for check" << endl;
+                aerr << prog_name << ": No service specified for check" << endl;
                 wantsUsage = true;
                 result = 10;
             }
@@ -125,8 +105,8 @@
                 String16 name = services[i];
                 sp<IBinder> service = sm->checkService(name);
                 aout << i
-                     << "\t" << good_old_string(name)
-                     << ": [" << good_old_string(get_interface_name(service)) << "]"
+                     << "\t" << name
+                     << ": [" << (service ? service->getInterfaceDescriptor() : String16()) << "]"
                      << endl;
             }
         } else if (strcmp(argv[optind], "call") == 0) {
@@ -134,10 +114,11 @@
             if (optind+1 < argc) {
                 int serviceArg = optind;
                 sp<IBinder> service = sm->checkService(String16(argv[optind++]));
-                String16 ifName = get_interface_name(service);
+                String16 ifName = (service ? service->getInterfaceDescriptor() : String16());
                 int32_t code = atoi(argv[optind++]);
                 if (service != nullptr && ifName.size() > 0) {
                     Parcel data, reply;
+                    data.markForBinder(service);
 
                     // the interface name is first
                     data.writeInterfaceToken(ifName);
@@ -147,7 +128,7 @@
                         if (strcmp(argv[optind], "i32") == 0) {
                             optind++;
                             if (optind >= argc) {
-                                aerr << "service: no integer supplied for 'i32'" << endl;
+                                aerr << prog_name << ": no integer supplied for 'i32'" << endl;
                                 wantsUsage = true;
                                 result = 10;
                                 break;
@@ -156,7 +137,7 @@
                         } else if (strcmp(argv[optind], "i64") == 0) {
                             optind++;
                             if (optind >= argc) {
-                                aerr << "service: no integer supplied for 'i64'" << endl;
+                                aerr << prog_name << ": no integer supplied for 'i64'" << endl;
                                 wantsUsage = true;
                                 result = 10;
                                 break;
@@ -165,7 +146,7 @@
                         } else if (strcmp(argv[optind], "s16") == 0) {
                             optind++;
                             if (optind >= argc) {
-                                aerr << "service: no string supplied for 's16'" << endl;
+                                aerr << prog_name << ": no string supplied for 's16'" << endl;
                                 wantsUsage = true;
                                 result = 10;
                                 break;
@@ -174,7 +155,7 @@
                         } else if (strcmp(argv[optind], "f") == 0) {
                             optind++;
                             if (optind >= argc) {
-                                aerr << "service: no number supplied for 'f'" << endl;
+                                aerr << prog_name << ": no number supplied for 'f'" << endl;
                                 wantsUsage = true;
                                 result = 10;
                                 break;
@@ -183,7 +164,7 @@
                         } else if (strcmp(argv[optind], "d") == 0) {
                             optind++;
                             if (optind >= argc) {
-                                aerr << "service: no number supplied for 'd'" << endl;
+                                aerr << prog_name << ": no number supplied for 'd'" << endl;
                                 wantsUsage = true;
                                 result = 10;
                                 break;
@@ -195,7 +176,7 @@
                         } else if (strcmp(argv[optind], "fd") == 0) {
                             optind++;
                             if (optind >= argc) {
-                                aerr << "service: no path supplied for 'fd'" << endl;
+                                aerr << prog_name << ": no path supplied for 'fd'" << endl;
                                 wantsUsage = true;
                                 result = 10;
                                 break;
@@ -203,7 +184,7 @@
                             const char *path = argv[optind++];
                             int fd = open(path, O_RDONLY);
                             if (fd < 0) {
-                                aerr << "service: could not open '" << path << "'" << endl;
+                                aerr << prog_name << ": could not open '" << path << "'" << endl;
                                 wantsUsage = true;
                                 result = 10;
                                 break;
@@ -212,7 +193,7 @@
                         } else if (strcmp(argv[optind], "afd") == 0) {
                             optind++;
                             if (optind >= argc) {
-                                aerr << "service: no path supplied for 'afd'" << endl;
+                                aerr << prog_name << ": no path supplied for 'afd'" << endl;
                                 wantsUsage = true;
                                 result = 10;
                                 break;
@@ -221,7 +202,8 @@
                             int fd = open(path, O_RDONLY);
                             struct stat statbuf;
                             if (fd < 0 || fstat(fd, &statbuf) != 0) {
-                                aerr << "service: could not open or stat '" << path << "'" << endl;
+                                aerr << prog_name << ": could not open or stat"
+                                    << " '" << path << "'" << endl;
                                 wantsUsage = true;
                                 result = 10;
                                 break;
@@ -229,13 +211,14 @@
                             int afd = ashmem_create_region("test", statbuf.st_size);
                             void* ptr = mmap(NULL, statbuf.st_size,
                                    PROT_READ | PROT_WRITE, MAP_SHARED, afd, 0);
-                            read(fd, ptr, statbuf.st_size);
+                            (void)read(fd, ptr, statbuf.st_size);
                             close(fd);
                             data.writeFileDescriptor(afd, true /* take ownership */);
                         } else if (strcmp(argv[optind], "nfd") == 0) {
                             optind++;
                             if (optind >= argc) {
-                                aerr << "service: no file descriptor supplied for 'nfd'" << endl;
+                                aerr << prog_name << ": no file descriptor supplied for"
+                                    << " 'nfd'" << endl;
                                 wantsUsage = true;
                                 result = 10;
                                 break;
@@ -322,7 +305,7 @@
                             // for now just set the extra field to be null.
                             data.writeInt32(-1);
                         } else {
-                            aerr << "service: unknown option " << argv[optind] << endl;
+                            aerr << prog_name << ": unknown option " << argv[optind] << endl;
                             wantsUsage = true;
                             result = 10;
                             break;
@@ -332,44 +315,44 @@
                     service->transact(code, data, &reply);
                     aout << "Result: " << reply << endl;
                 } else {
-                    aerr << "service: Service " << argv[serviceArg]
+                    aerr << prog_name << ": Service " << argv[serviceArg]
                         << " does not exist" << endl;
                     result = 10;
                 }
             } else {
                 if (optind < argc) {
-                    aerr << "service: No service specified for call" << endl;
+                    aerr << prog_name << ": No service specified for call" << endl;
                 } else {
-                    aerr << "service: No code specified for call" << endl;
+                    aerr << prog_name << ": No code specified for call" << endl;
                 }
                 wantsUsage = true;
                 result = 10;
             }
         } else {
-            aerr << "service: Unknown command " << argv[optind] << endl;
+            aerr << prog_name << ": Unknown command " << argv[optind] << endl;
             wantsUsage = true;
             result = 10;
         }
     }
 
     if (wantsUsage) {
-        aout << "Usage: service [-h|-?]\n"
-                "       service list\n"
-                "       service check SERVICE\n"
-                "       service call SERVICE CODE [i32 N | i64 N | f N | d N | s16 STR | null"
-                " | fd f | nfd n | afd f ] ...\n"
+        aout << "Usage: " << prog_name << " [-h|-?]\n"
+                "       " << prog_name << " list\n"
+                "       " << prog_name << " check SERVICE\n"
+                "       " << prog_name << " call SERVICE CODE [i32 N | i64 N | f N | d N | s16 STR"
+                " | null | fd f | nfd n | afd f ] ...\n"
                 "Options:\n"
                 "   i32: Write the 32-bit integer N into the send parcel.\n"
                 "   i64: Write the 64-bit integer N into the send parcel.\n"
-                "   f:   Write the 32-bit single-precision number N into the send parcel.\n"
-                "   d:   Write the 64-bit double-precision number N into the send parcel.\n"
+                "     f: Write the 32-bit single-precision number N into the send parcel.\n"
+                "     d: Write the 64-bit double-precision number N into the send parcel.\n"
                 "   s16: Write the UTF-16 string STR into the send parcel.\n"
                 "  null: Write a null binder into the send parcel.\n"
-                "    fd: Write a file descriptor for the file f to the send parcel.\n"
-                "   nfd: Write file descriptor n to the send parcel.\n"
-                "   afd: Write an ashmem file descriptor for a region containing the data from"
-                " file f to the send parcel.\n";
-//                "   intent: Write and Intent int the send parcel. ARGS can be\n"
+                "    fd: Write a file descriptor for the file f into the send parcel.\n"
+                "   nfd: Write the file descriptor n into the send parcel.\n"
+                "   afd: Write an ashmem file descriptor for a region containing the data from\n"
+                "          file f into the send parcel.\n";
+//                "   intent: Write an Intent into the send parcel. ARGS can be\n"
 //                "       action=STR data=STR type=STR launchFlags=INT component=STR categories=STR[,STR,...]\n";
         return result;
     }
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 90db509..4e44ac7 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -121,6 +121,35 @@
     return updatableViaApex;
 }
 
+static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) {
+    AidlName aname;
+    if (!AidlName::fill(name, &aname)) return std::nullopt;
+
+    std::optional<std::string> ip;
+    std::optional<uint64_t> port;
+    forEachManifest([&](const ManifestWithDescription& mwd) {
+        mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
+            if (manifestInstance.format() != vintf::HalFormat::AIDL) return true;
+            if (manifestInstance.package() != aname.package) return true;
+            if (manifestInstance.interface() != aname.iface) return true;
+            if (manifestInstance.instance() != aname.instance) return true;
+            ip = manifestInstance.ip();
+            port = manifestInstance.port();
+            return false; // break (libvintf uses opposite convention)
+        });
+        return false; // continue
+    });
+
+    if (ip.has_value() && port.has_value()) {
+        ConnectionInfo info;
+        info.ipAddress = *ip;
+        info.port = *port;
+        return std::make_optional<ConnectionInfo>(info);
+    } else {
+        return std::nullopt;
+    }
+}
+
 static std::vector<std::string> getVintfInstances(const std::string& interface) {
     size_t lastDot = interface.rfind('.');
     if (lastDot == std::string::npos) {
@@ -437,6 +466,22 @@
     return Status::ok();
 }
 
+Status ServiceManager::getConnectionInfo(const std::string& name,
+                                         std::optional<ConnectionInfo>* outReturn) {
+    auto ctx = mAccess->getCallingContext();
+
+    if (!mAccess->canFind(ctx, name)) {
+        return Status::fromExceptionCode(Status::EX_SECURITY);
+    }
+
+    *outReturn = std::nullopt;
+
+#ifndef VENDORSERVICEMANAGER
+    *outReturn = getVintfConnectionInfo(name);
+#endif
+    return Status::ok();
+}
+
 void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
                                     ServiceCallbackMap::iterator* it,
                                     bool* found) {
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 4f23c21..5e40319 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -24,6 +24,7 @@
 
 namespace android {
 
+using os::ConnectionInfo;
 using os::IClientCallback;
 using os::IServiceCallback;
 using os::ServiceDebugInfo;
@@ -48,6 +49,8 @@
     binder::Status getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) override;
     binder::Status updatableViaApex(const std::string& name,
                                     std::optional<std::string>* outReturn) override;
+    binder::Status getConnectionInfo(const std::string& name,
+                                     std::optional<ConnectionInfo>* outReturn) override;
     binder::Status registerClientCallback(const std::string& name, const sp<IBinder>& service,
                                           const sp<IClientCallback>& cb) override;
     binder::Status tryUnregisterService(const std::string& name, const sp<IBinder>& binder) override;
diff --git a/cmds/servicemanager/servicemanager.rc b/cmds/servicemanager/servicemanager.rc
index 6d5070f..0dd29e0 100644
--- a/cmds/servicemanager/servicemanager.rc
+++ b/cmds/servicemanager/servicemanager.rc
@@ -9,5 +9,5 @@
     onrestart class_restart main
     onrestart class_restart hal
     onrestart class_restart early_hal
-    writepid /dev/cpuset/system-background/tasks
+    task_profiles ServiceCapacityLow
     shutdown critical
diff --git a/cmds/servicemanager/vndservicemanager.rc b/cmds/servicemanager/vndservicemanager.rc
index 756f6c3..c9305a1 100644
--- a/cmds/servicemanager/vndservicemanager.rc
+++ b/cmds/servicemanager/vndservicemanager.rc
@@ -2,7 +2,7 @@
     class core
     user system
     group system readproc
-    writepid /dev/cpuset/system-background/tasks
+    task_profiles ServiceCapacityLow
     onrestart class_restart main
     onrestart class_restart hal
     onrestart class_restart early_hal
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index c0cbad8..af8f718 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -7,12 +7,241 @@
     default_applicable_licenses: ["frameworks_native_license"],
 }
 
+prebuilt_defaults {
+    name: "frameworks_native_data_etc_defaults",
+    relative_install_path: "permissions",
+    soc_specific: true,
+}
+
+// Modules use the 'prebuilt.xml' suffix to prevent conflicting
+// overridden paths, so that this Android.bp can exist alongside
+// devices that use PRODUCT_COPY_FILES for these files.
+//
+// This override prevention is also possible using a soong_namespace,
+// but that requires every dependent module (e.g. an APEX that includes
+// one of these files) to also reference this namespace, and so on
+// for all dependent modules. It is simpler to just use new path names.
+
 prebuilt_etc {
-    name: "android.hardware.biometrics.face.xml",
-    product_specific: true,
-    sub_dir: "permissions",
+    name: "android.hardware.audio.low_latency.prebuilt.xml",
+    src: "android.hardware.audio.low_latency.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.biometrics.face.prebuilt.xml",
     src: "android.hardware.biometrics.face.xml",
-    filename_from_src: true,
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.bluetooth_le.prebuilt.xml",
+    src: "android.hardware.bluetooth_le.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.bluetooth.prebuilt.xml",
+    src: "android.hardware.bluetooth.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.camera.concurrent.prebuilt.xml",
+    src: "android.hardware.camera.concurrent.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.camera.flash-autofocus.prebuilt.xml",
+    src: "android.hardware.camera.flash-autofocus.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.camera.front.prebuilt.xml",
+    src: "android.hardware.camera.front.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.camera.full.prebuilt.xml",
+    src: "android.hardware.camera.full.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.camera.raw.prebuilt.xml",
+    src: "android.hardware.camera.raw.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.ethernet.prebuilt.xml",
+    src: "android.hardware.ethernet.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.faketouch.prebuilt.xml",
+    src: "android.hardware.faketouch.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.fingerprint.prebuilt.xml",
+    src: "android.hardware.fingerprint.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.location.gps.prebuilt.xml",
+    src: "android.hardware.location.gps.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.reboot_escrow.prebuilt.xml",
+    src: "android.hardware.reboot_escrow.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.sensor.ambient_temperature.prebuilt.xml",
+    src: "android.hardware.sensor.ambient_temperature.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.sensor.barometer.prebuilt.xml",
+    src: "android.hardware.sensor.barometer.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.sensor.gyroscope.prebuilt.xml",
+    src: "android.hardware.sensor.gyroscope.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.sensor.hinge_angle.prebuilt.xml",
+    src: "android.hardware.sensor.hinge_angle.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.sensor.light.prebuilt.xml",
+    src: "android.hardware.sensor.light.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.sensor.proximity.prebuilt.xml",
+    src: "android.hardware.sensor.proximity.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.sensor.relative_humidity.prebuilt.xml",
+    src: "android.hardware.sensor.relative_humidity.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.telephony.gsm.prebuilt.xml",
+    src: "android.hardware.telephony.gsm.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.telephony.ims.prebuilt.xml",
+    src: "android.hardware.telephony.ims.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.usb.accessory.prebuilt.xml",
+    src: "android.hardware.usb.accessory.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.usb.host.prebuilt.xml",
+    src: "android.hardware.usb.host.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.vulkan.level-0.prebuilt.xml",
+    src: "android.hardware.vulkan.level-0.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.vulkan.version-1_0_3.prebuilt.xml",
+    src: "android.hardware.vulkan.version-1_0_3.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.wifi.prebuilt.xml",
+    src: "android.hardware.wifi.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.hardware.wifi.passpoint.prebuilt.xml",
+    src: "android.hardware.wifi.passpoint.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.software.device_id_attestation.prebuilt.xml",
+    src: "android.software.device_id_attestation.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.software.ipsec_tunnels.prebuilt.xml",
+    src: "android.software.ipsec_tunnels.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.software.opengles.deqp.level-2021-03-01.prebuilt.xml",
+    src: "android.software.opengles.deqp.level-2021-03-01.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.software.sip.voip.prebuilt.xml",
+    src: "android.software.sip.voip.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.software.verified_boot.prebuilt.xml",
+    src: "android.software.verified_boot.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "android.software.vulkan.deqp.level-2021-03-01.prebuilt.xml",
+    src: "android.software.vulkan.deqp.level-2021-03-01.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "aosp_excluded_hardware.prebuilt.xml",
+    src: "aosp_excluded_hardware.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
+}
+
+prebuilt_etc {
+    name: "handheld_core_hardware.prebuilt.xml",
+    src: "handheld_core_hardware.xml",
+    defaults: ["frameworks_native_data_etc_defaults"],
 }
 
 prebuilt_etc {
diff --git a/data/etc/apex/Android.bp b/data/etc/apex/Android.bp
new file mode 100644
index 0000000..8c4929c
--- /dev/null
+++ b/data/etc/apex/Android.bp
@@ -0,0 +1,34 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
+apex_key {
+    name: "com.android.hardware.core_permissions.key",
+    public_key: "com.android.hardware.core_permissions.avbpubkey",
+    private_key: "com.android.hardware.core_permissions.pem",
+}
+
+android_app_certificate {
+    name: "com.android.hardware.core_permissions.certificate",
+    certificate: "com.android.hardware.core_permissions",
+}
+
+apex {
+    name: "com.android.hardware.core_permissions",
+    manifest: "apex_manifest.json",
+    key: "com.android.hardware.core_permissions.key",
+    certificate: ":com.android.hardware.core_permissions.certificate",
+    file_contexts: "file_contexts",
+    updatable: false,
+    // Install the apex in /vendor/apex
+    soc_specific: true,
+    prebuilts: [
+        "handheld_core_hardware.prebuilt.xml",
+        "aosp_excluded_hardware.prebuilt.xml",
+    ],
+}
diff --git a/data/etc/apex/apex_manifest.json b/data/etc/apex/apex_manifest.json
new file mode 100644
index 0000000..5bbf229
--- /dev/null
+++ b/data/etc/apex/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+  "name": "com.android.hardware.core_permissions",
+  "version": 1
+}
diff --git a/data/etc/apex/com.android.hardware.core_permissions.avbpubkey b/data/etc/apex/com.android.hardware.core_permissions.avbpubkey
new file mode 100644
index 0000000..b9164fb
--- /dev/null
+++ b/data/etc/apex/com.android.hardware.core_permissions.avbpubkey
Binary files differ
diff --git a/data/etc/apex/com.android.hardware.core_permissions.pem b/data/etc/apex/com.android.hardware.core_permissions.pem
new file mode 100644
index 0000000..7e2826d
--- /dev/null
+++ b/data/etc/apex/com.android.hardware.core_permissions.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKgIBAAKCAgEAuJjZgFCp6uX+xgKET1FsXYqEPGfYEWUWJ4VSP+Y5fgth/Om3
+XCRBhKSD4CPyL/E9ohh7eSLRqIzw/idUazgCqk+yYLiVkYZiuY02jcui1/Vze9er
+Nwi0ZSwA+zcvKCEOwZ3PBT6W1kehiQ5PU0IS+78po8LoUrvycmvbXJTHlVt1x2bo
+y2DQmxRjIH9xfACwFwh/JnKyr1O2NGjFbk+z3CYx9l7c0Ew9U/kGL3teSbMEi1le
+2PApAHYUA+kXiwjF07aRUN+zzSdZsI7goQXEsmqGXNy7Fzdp/UDocayBmCdI3a35
+igcPRUryBIf1YdSS+E9DwoXRR7pwzs4ajvVTrzuv7UohTnhPwj95TD0E3Z64r7S7
+AT4jtm9gbkAsKNkKOqioGTEIdmvj2prOA4wOUmVBGwOjGcjsyEPJaa56s0WEXUop
++OD2ZMV3StAIwQ5c/gpFzxWl+qATv3MH9MgwAIjT1TDyXv0R+q9JbFbgTtO748RS
+MZUb1i2odggNQCWRtv8fqJ7c51H7pUpHXCXElXHysFq2oBOY4J1jXr1craxsPn1P
+RcImVwAYTV80jOfmYtWhdJhDavDeD4uinLw+4HeZnFNwZXqCJl0LtLxMDRxoDCr7
+YgT2znh9BM6XXg8jekfkDYb5wyloU1eOZJMxF04pGecDB9n1w/OFBA4v0WECAwEA
+AQKCAgEArjhsRsNaqvzo6L7lWurxCJO73Drx3PD36NLWXsKNjl113LpEOO1q/KI8
+aKXkZMUdM0hB+IEZOSfUJzq9XPge49iV9N0hJJidwpv5WfhQN9xLYx2YVTec8kOG
+pZJeqlQQ1kF3am6484HlfjIIQf8BZaH0zb8df0AtQTp0bTtp5pfMYCbLHW/BUiv6
+pmhBlhQcHZECWCo2ZGzwcSRU+Zi1mthdnTXI17qswv0rjlK0GYCgkFgHwV1ghTPs
+DgjHFIxyES+klJyc2MoDxzQB41dLXkxVhX06Al5lZQUGnIqAQTcKeVZCRrgE/JQQ
+OKCMwglbsIk23XdonnbjEvvIaxY1JHjcnPBpOC4+O11fE0DiHXK3GBj5KlfVvB5D
+oMWko3R/Ky/T/KJhHYXbC1H71oYueCaY57kHFKk2k3qRJG4DU4MY20cfUZ0vp14H
+KJ++gDy0pxxjl4ZUiryBCti5k5GPU8Mm46MLJ/YPdX6Dj1nMtOgGpZkGQYIKPhEI
+qZjZBRyZlHeTJsTMc8Eh3/Krimmra5ID95HfJnTTHHshbRcLwL6/zMTU5fkwarsC
+f4HQ0602/9HqyI8Ty1S9Z4oByjwfW2uDcosnuOPfk/8XwfLWxrf2+TsAd3cXhOKw
+rwUfELzcgYNueLGTJOCsEJfo8NIIEGJCNSgMnWXmIAUIAlrMP8ECggEBAOt9X4Lb
+fkrQLjcQ+K1oOI0Q+43htNRYXiG2IDhmDlA+UnqPP+9j2cVyuo4QYhKTFXRbbezR
+blUHAowd4hKHtODaHMuq90KbeByVNB8idcIb+ELAOK4Ff+qd9ijrBIOuZZQB+KOo
+SlxVjy1LM0QGtUTJRHx4dkCmp+hMqrIc4LQOWd4hV5h85Oj8kp1L1eMvxEStUtwP
+tYR80OoOdDxgXcBHLdPs4rc0WunRabGE+cnCMrTy31D95OWg6aw/+XKSTUS5Hfdy
+4jDIwP8DR6JU71qNgen+fwrHFeDienM40sSpi85/WQndQW5TwOMbDlEfmgn6D4+s
+rVWqFk1XElfwwSkCggEBAMisvdv5fH4UeH+tz5cF5f3ZNY+NX8uj85wCsJAPaAVx
+i3t8BqEKUPA6FPt9SDMWg4QtgSSl0NmhH2F9CcAZUCiTZUrtgqyIo80ALONW1FR9
+ofElvZEeV2IzKn3Ci4HA2pKRtMcjjVLwxzdoHakbPS9CbdCGKYE3W75Huw410IW6
+gV4zQ2mWHT+FxXaatl6Arj0x7DHLeSrMV33uxcYWoclmrAK24uhq2gwhtC8U0SvY
+rtJ7+KpCRd5v3Cyzo2AEbZKyJYVKbMDu9RHDZwkZw6wVqaOKBPJVyC++yidksexX
+ZT0WGX0f23t+2jbbsNY6H27pJm9ApLuAYwiMGv9n/XkCggEADLlAcNyVLUukQ5tq
+JExuScjyHo9kati/dUjW4tU4zsMfR7n3tWKKwK1bQRPHiMNjtF7ASLxkHrn7PEDd
+Fy0367I9Pg/lvjaSPdEd+NSu0icaudiS92wapj2UsE9Kdib1HBMjMQyFwAlrbAIV
+KgbGwomxZpxHn2Shy95glrESvwfLeUIJ7pZI9AG5lkAjtVu+WguXX4aFwzvPOeZA
+B4cZaasu4bV55nYwt1N2R34s1ObmQHqi8EhXlsSj+4eVXchj3mO2J8mQSRx/uQef
+VjkKmbTtoQv8J0PsfbMe9JzMXo3enPCqiernfyONV3f9xQpVE1bsglHNJ8TB4bnj
+pta+SQKCAQEArDqNrFkAftkk3jgXnX9jeC3O6UilugoZj4FDdjCyz1E3LCEzM02+
+T58Z2QoaSDZ/Y5cGaqShjdbaLvp4vtU61chDPD6CU3/mTZBj9i3UiDtXHLeObhlD
+WDWft1WcFB2nufmx1OPvbArYf/Ys1rFZHtF9nGU5A/y2EaZQpY6MS+nZFDcdGWbL
+7XPrGLMJ6Cu63yyUkdwXPyMnyB6AwVU1P7yNzrqWHnFueNEIawwLxfzvdhkOP1on
+yxPoPLlkc4j5XdjlmPNaSXANB1TUfpwNMwlYkdJoEnCLImc16v9iMPyFGBt6fsgz
+wFcMA98jc4lo5vDVmtA5Ue+Lj49nsGLYyQKCAQEAoB21vLDm7sLcZhzHFnh7h3L0
+wLMFMyQ0QDMWOqrlABcME21CWhibu8XwouF+hHLKX9GjaBB3ujkyeun1x8MpGQwT
+1SrMVN4osHpFrCh85uK5mabsqC8YjICIncU1U1ykxDV9v7TXuXgMtUIMKPFcUQLv
+ckf/PNE1Fvt5ESn2GIxk+ibM0L2kzHgDFgwiPx+k8GmJt5VZSXwehPmH6jgyCBIv
+kPHos1Q/z2LtfdUZcGhwX88mBNBpk3UXjiU8qO+ddoXCRgbThFDqYvOcdacbKGc0
+upFMhNsTWocn7CW0rbzusTsTt6bSWCGas8f9G9CMNN6rp8SW7Qc04m6sXVjPbw==
+-----END RSA PRIVATE KEY-----
diff --git a/data/etc/apex/com.android.hardware.core_permissions.pk8 b/data/etc/apex/com.android.hardware.core_permissions.pk8
new file mode 100644
index 0000000..4497844
--- /dev/null
+++ b/data/etc/apex/com.android.hardware.core_permissions.pk8
Binary files differ
diff --git a/data/etc/apex/com.android.hardware.core_permissions.x509.pem b/data/etc/apex/com.android.hardware.core_permissions.x509.pem
new file mode 100644
index 0000000..57a311d
--- /dev/null
+++ b/data/etc/apex/com.android.hardware.core_permissions.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF7zCCA9cCFD7UZbcK7ZVyJegJvOs8e5T/n0DLMA0GCSqGSIb3DQEBCwUAMIGy
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEuMCwGA1UEAwwlY29t
+LmFuZHJvaWQuaGFyZHdhcmUuY29yZV9wZXJtaXNzaW9uczAgFw0yMTA4MjYyMDM2
+NTBaGA80NzU5MDcyMzIwMzY1MFowgbIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApD
+YWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRy
+b2lkMRAwDgYDVQQLDAdBbmRyb2lkMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFu
+ZHJvaWQuY29tMS4wLAYDVQQDDCVjb20uYW5kcm9pZC5oYXJkd2FyZS5jb3JlX3Bl
+cm1pc3Npb25zMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1ZGPs2s2
+R9/+jd3dHLH0nt4Z5WWduQ4Wqy6H9oojktTCv0IJekfiC6L0VHOvW9DKtSEGWTJg
+sJdoEpd2KDhNxAdjbE6k50AfKD0CAE0MAX2MyJIpUz7b6p6p7kxB7xpJohSGDOSZ
+otuMJ16W99PElwOtQr99Wztf+WehmEkKYDUVA0V3+UP3s0quAo3ZrFYgZxXy51YF
+/rcM+HFNrpBRNZRhm3n/2uM4vqt+HTjUFvPuxFIq44DH64ofD7OYBOTbq7rU3lFr
+jEP4IlVH1mjyirh0pWIzXtqhcj2yfV8HjqnwHz+DhIA7kI1hZNOTotTiYKZszboy
+mvo8YA+fuSDCohFxVJVHZGFu+FA+m353ZPLTDTee+d3F9JGbLxa3NoPAgDIyU/tR
+KD7+fKxfr32coZzf3bDi9T4CHBoHKoikRWqOAhkZ/xGvjX12bI6eS1QP9THGu3d6
+o+ZzSZDPR9GSu8ggFtkRGgaIIbgV3y4XUKqLK3+pyg14tHwqvSYMItZ7oOYKMT47
+R9qb8MlvAWS2ooZlJwSkGSM3y0pTwy3rKXug+Cpvx7zjc3Nm/srzdPAmrEvBTZZN
+k0J1oYKqiNHV1N3PIlMRE2d4g7MVF4GEwrAgL126JZOOmzefkP59eAPNrH6Coyka
+3pAVnifemHYZlhWpbKO6pnuxEwvBGXvJlgkCAwEAATANBgkqhkiG9w0BAQsFAAOC
+AgEAfc6TD6fURc9sKHn5TSi30rIlarR6h1TbxFL4PQroEXWafkNmOMujdyV6YZlZ
+j/lzU4ko+Pn3y1aU4r88PkrjkR2Ttf01H3wj8IkTVyl3kN3o/Ud2jJygL3SbjMS1
+CAxiotvPA3lst3KN3nnyFLe02EB4OIi8fS14/kUVFVz+djpGDhi/lJUzcTCzO1NR
+yoC3RuAHBrly1+0QYcXiRTtvgnXrUqsZery8pysR7OK8fWkJzQ6I6OipElrcRzfK
+qoRq/u7nn9FJxXauVjM5HNCPq1VsB8+/FQqP2CgvxNPtkxy8AkXS3hKMBC0Id0Mo
+sDsAr88QDnCb5DqrWSMDKTKA0k+2a6QwS72ANkK5Uq2Hf/xUVjn+yHLSFuo4pCYe
+TX4ZCjK8My+XPWEiHBV/AELAWA9SxxZFhHmyuPj3MwN5uJcPNPsQepnhpeGv0Dlp
+J7UfzkdAZvOyQ+9CAQfu8+e2MilLHC3uqfnGLpHGkcHoN93rmH1x14JdapKKk3XL
+4Wo0RzEjGQekjMF0topQSqDTukOMdtZ1T0WTVOstYLlNqlhn0ZVbwVANGklN/fDW
+d6OpayLPuuaLBAM6Ivnv7n4XA49ojd9Gw305Ha/ATEoH9KwImFjvUa4d9SkR0haP
+hAiGhpaWViEe2zXOpzLhePgqc2gJ/IO7vIgrVks0iVeBoWE=
+-----END CERTIFICATE-----
diff --git a/data/etc/apex/file_contexts b/data/etc/apex/file_contexts
new file mode 100644
index 0000000..6524a5e
--- /dev/null
+++ b/data/etc/apex/file_contexts
@@ -0,0 +1,2 @@
+(/.*)?		u:object_r:vendor_file:s0
+/etc(/.*)?	u:object_r:vendor_configs_file:s0
diff --git a/docs/Doxyfile b/docs/Doxyfile
index a1bd960..ea22337 100644
--- a/docs/Doxyfile
+++ b/docs/Doxyfile
@@ -1638,6 +1638,7 @@
     "__attribute__(x)=" \
     __ANDROID__ \
     __BIONIC__ \
+    "U_IN_DOXYGEN=1" \ # Required by the ICU4C module only
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
 # this tag can be used to specify a list of macro names that should be expanded.
diff --git a/include/android/input.h b/include/android/input.h
index bb98beb..7642215 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -947,9 +947,10 @@
  * and {@link AMotionEvent_fromJava()}.
  * After returning, the specified AInputEvent* object becomes invalid and should no longer be used.
  * The underlying Java object remains valid and does not change its state.
+ *
+ * Available since API level 31.
  */
-
-void AInputEvent_release(const AInputEvent* event);
+void AInputEvent_release(const AInputEvent* event) __INTRODUCED_IN(31);
 
 /*** Accessors for key events only. ***/
 
@@ -1001,8 +1002,10 @@
  * Creates a native AInputEvent* object that is a copy of the specified Java android.view.KeyEvent.
  * The result may be used with generic and KeyEvent-specific AInputEvent_* functions. The object
  * returned by this function must be disposed using {@link AInputEvent_release()}.
+ *
+ * Available since API level 31.
  */
-const AInputEvent* AKeyEvent_fromJava(JNIEnv* env, jobject keyEvent);
+const AInputEvent* AKeyEvent_fromJava(JNIEnv* env, jobject keyEvent) __INTRODUCED_IN(31);
 
 /*** Accessors for motion events only. ***/
 
@@ -1324,8 +1327,10 @@
  * android.view.MotionEvent. The result may be used with generic and MotionEvent-specific
  * AInputEvent_* functions. The object returned by this function must be disposed using
  * {@link AInputEvent_release()}.
+ *
+ * Available since API level 31.
  */
-const AInputEvent* AMotionEvent_fromJava(JNIEnv* env, jobject motionEvent);
+const AInputEvent* AMotionEvent_fromJava(JNIEnv* env, jobject motionEvent) __INTRODUCED_IN(31);
 
 struct AInputQueue;
 /**
diff --git a/include/binder/Enum.h b/include/binder/Enum.h
deleted file mode 100644
index 4c25654..0000000
--- a/include/binder/Enum.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#error Do not rely on global include files. All Android cc_* programs are given access to \
-    include_dirs for frameworks/native/include via global configuration, but this is legacy \
-    configuration. Instead, you should have a direct dependency on libbinder OR one of your \
-    dependencies should re-export libbinder headers with export_shared_lib_headers.
diff --git a/include/ftl/NamedEnum.h b/include/ftl/NamedEnum.h
index f50ff46..6e98fee 100644
--- a/include/ftl/NamedEnum.h
+++ b/include/ftl/NamedEnum.h
@@ -49,6 +49,10 @@
 
     // Example (cont'd): V = android::test::TestEnums::ONE
     view = view.substr(valStart);
+    // Check invalid enum values with cast, like V = (android::test::TestEnums)8.
+    if (view.find('(') != std::string::npos) {
+        return std::nullopt;
+    }
     size_t nameStart = view.rfind("::");
     if (nameStart == std::string::npos) {
         return std::nullopt;
diff --git a/libs/android_runtime_lazy/Android.bp b/libs/android_runtime_lazy/Android.bp
index b74923c..ac3e5b8 100644
--- a/libs/android_runtime_lazy/Android.bp
+++ b/libs/android_runtime_lazy/Android.bp
@@ -42,12 +42,13 @@
 cc_library {
     name: "libandroid_runtime_lazy",
     vendor_available: true,
+    recovery_available: true,
     double_loadable: true,
     host_supported: true,
     target: {
         darwin: {
             enabled: false,
-        }
+        },
     },
 
     cflags: [
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index ec697a0..8270ae5 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -25,6 +25,7 @@
     name: "libbinder_headers",
     export_include_dirs: ["include"],
     vendor_available: true,
+    recovery_available: true,
     host_supported: true,
     // TODO(b/153609531): remove when no longer needed.
     native_bridge_supported: true,
@@ -68,11 +69,14 @@
 cc_library {
     name: "libbinder",
 
+    version_script: "libbinder.map",
+
     // for vndbinder
     vendor_available: true,
     vndk: {
         enabled: true,
     },
+    recovery_available: true,
     double_loadable: true,
     host_supported: true,
     // TODO(b/153609531): remove when no longer needed.
@@ -96,6 +100,7 @@
         "BpBinder.cpp",
         "BufferedTextOutput.cpp",
         "Debug.cpp",
+        "FdTrigger.cpp",
         "IInterface.cpp",
         "IMemory.cpp",
         "IPCThreadState.cpp",
@@ -111,16 +116,15 @@
         "ParcelFileDescriptor.cpp",
         "PersistableBundle.cpp",
         "ProcessState.cpp",
-        "RpcAddress.cpp",
         "RpcSession.cpp",
         "RpcServer.cpp",
         "RpcState.cpp",
+        "RpcTransportRaw.cpp",
         "Static.cpp",
         "Stability.cpp",
         "Status.cpp",
         "TextOutput.cpp",
         "Utils.cpp",
-        ":packagemanager_aidl",
         ":libbinder_aidl",
     ],
 
@@ -133,50 +137,29 @@
                 enabled: false,
             },
         },
-        android_arm64: {
-            // b/189438896 Sampling PGO restricted to arm64, arm32 in sc-dev
-            pgo: {
-                sampling: true,
-                profile_file: "libbinder/libbinder.profdata",
-            },
-            // b/189438896 Add exported symbols in a map file for ABI stability
-            version_script: "libbinder.arm64.map",
-            target: {
-                vendor: {
-                    version_script: "libbinder.arm64.vendor.map",
-                },
-            },
-        },
-        android_arm: {
-            // b/189438896 Sampling PGO restricted to arm64, arm32 in sc-dev
-            pgo: {
-                sampling: true,
-                profile_file: "libbinder/libbinder.profdata",
-            },
-            // b/189438896 Add exported symbols in a map file for ABI stability
-            version_script: "libbinder.arm32.map",
-            target: {
-                vendor: {
-                    version_script: "libbinder.arm32.vendor.map",
-                },
-            },
-        },
         vendor: {
             exclude_srcs: libbinder_device_interface_sources,
         },
         darwin: {
             enabled: false,
         },
+        host: {
+            srcs: [
+                "ServiceManagerHost.cpp",
+                "UtilsHost.cpp",
+            ],
+        },
+        recovery: {
+            exclude_header_libs: [
+                "libandroid_runtime_vm_headers",
+            ],
+        },
     },
 
     aidl: {
         export_aidl_headers: true,
     },
 
-    // TODO(b/142684679): for com.android.media which is compiled
-    // as vendor and used as system code.
-    use_apex_name_macro: true,
-
     cflags: [
         "-Wall",
         "-Wextra",
@@ -190,6 +173,10 @@
         binder32bit: {
             cflags: ["-DBINDER_IPC_32BIT=1"],
         },
+
+        debuggable: {
+            cflags: ["-DBINDER_RPC_DEV_SERVERS"],
+        },
     },
 
     shared_libs: [
@@ -198,8 +185,13 @@
         "libutils",
     ],
 
+    static_libs: [
+        "libbase",
+    ],
+
     header_libs: [
         "libbinder_headers",
+        "libandroid_runtime_vm_headers",
     ],
 
     export_header_lib_headers: [
@@ -232,12 +224,67 @@
         "performance*",
         "portability*",
     ],
+
+    pgo: {
+        sampling: true,
+        profile_file: "libbinder/libbinder.profdata",
+    },
+}
+
+cc_defaults {
+    name: "libbinder_tls_shared_deps",
+    shared_libs: [
+        "libbinder",
+        "libcrypto",
+        "liblog",
+        "libssl",
+        "libutils",
+    ],
+}
+
+cc_defaults {
+    name: "libbinder_tls_defaults",
+    defaults: ["libbinder_tls_shared_deps"],
+    host_supported: true,
+
+    header_libs: [
+        "libbinder_headers",
+    ],
+    export_header_lib_headers: [
+        "libbinder_headers",
+    ],
+    export_shared_lib_headers: [
+        "libssl",
+    ],
+    export_include_dirs: ["include_tls"],
+    static_libs: [
+        "libbase",
+    ],
+    srcs: [
+        "RpcTransportTls.cpp",
+        "RpcTlsUtils.cpp",
+    ],
+}
+
+cc_library_shared {
+    name: "libbinder_tls",
+    defaults: ["libbinder_tls_defaults"],
+}
+
+// For testing
+cc_library_static {
+    name: "libbinder_tls_static",
+    defaults: ["libbinder_tls_defaults"],
+    visibility: [
+        ":__subpackages__",
+    ],
 }
 
 // AIDL interface between libbinder and framework.jar
 filegroup {
     name: "libbinder_aidl",
     srcs: [
+        "aidl/android/os/ConnectionInfo.aidl",
         "aidl/android/os/IClientCallback.aidl",
         "aidl/android/os/IServiceCallback.aidl",
         "aidl/android/os/IServiceManager.aidl",
@@ -246,14 +293,27 @@
     path: "aidl",
 }
 
-filegroup {
+aidl_interface {
     name: "packagemanager_aidl",
+    unstable: true,
+    local_include_dir: "aidl",
+    host_supported: true,
     srcs: [
         "aidl/android/content/pm/IPackageChangeObserver.aidl",
         "aidl/android/content/pm/IPackageManagerNative.aidl",
         "aidl/android/content/pm/PackageChangeEvent.aidl",
+        "aidl/android/content/pm/IStagedApexObserver.aidl",
+        "aidl/android/content/pm/ApexStagedEvent.aidl",
+        "aidl/android/content/pm/StagedApexInfo.aidl",
     ],
-    path: "aidl",
+    backend: {
+        rust: {
+            apex_available: [
+                "com.android.virt",
+            ],
+            enabled: true,
+        },
+    },
 }
 
 aidl_interface {
@@ -269,6 +329,37 @@
     },
 }
 
+// TODO(b/184872979): remove once the Rust API is created.
+cc_library {
+    name: "libbinder_rpc_unstable",
+    srcs: ["libbinder_rpc_unstable.cpp"],
+    defaults: ["libbinder_ndk_host_user"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libbinder_ndk",
+        "liblog",
+        "libutils",
+    ],
+    export_include_dirs: ["include_rpc_unstable"],
+
+    // enumerate stable entry points, for apex use
+    stubs: {
+        symbol_file: "libbinder_rpc_unstable.map.txt",
+    },
+
+    // This library is intentionally limited to these targets, and it will be removed later.
+    // Do not expand the visibility.
+    visibility: [
+        "//packages/modules/Virtualization:__subpackages__",
+    ],
+}
+
+filegroup {
+    name: "libbinder_rpc_unstable_header",
+    srcs: ["include_rpc_unstable/binder_rpc_unstable.hpp"],
+}
+
 // libbinder historically contained additional interfaces that provided specific
 // functionality in the platform but have nothing to do with binder itself. These
 // are moved out of libbinder in order to avoid the overhead of their vtables.
@@ -321,3 +412,18 @@
         export_aidl_headers: true,
     },
 }
+
+cc_binary {
+    name: "servicedispatcher",
+    host_supported: false,
+    srcs: [
+        "servicedispatcher.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "liblog",
+        "libutils",
+        "android.debug_aidl-cpp",
+    ],
+}
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index d5bdd1c..ec9d554 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -17,16 +17,25 @@
 #include <binder/Binder.h>
 
 #include <atomic>
-#include <utils/misc.h>
+#include <set>
+
+#include <android-base/unique_fd.h>
 #include <binder/BpBinder.h>
 #include <binder/IInterface.h>
+#include <binder/IPCThreadState.h>
 #include <binder/IResultReceiver.h>
 #include <binder/IShellCallback.h>
 #include <binder/Parcel.h>
+#include <binder/RpcServer.h>
+#include <private/android_filesystem_config.h>
+#include <utils/misc.h>
 
+#include <inttypes.h>
 #include <linux/sched.h>
 #include <stdio.h>
 
+#include "RpcState.h"
+
 namespace android {
 
 // Service implementations inherit from BBinder and IBinder, and this is frozen
@@ -39,6 +48,12 @@
 static_assert(sizeof(BBinder) == 20);
 #endif
 
+#ifdef BINDER_RPC_DEV_SERVERS
+constexpr const bool kEnableRpcDevServers = true;
+#else
+constexpr const bool kEnableRpcDevServers = false;
+#endif
+
 // ---------------------------------------------------------------------------
 
 IBinder::IBinder()
@@ -136,8 +151,79 @@
     return OK;
 }
 
+status_t IBinder::setRpcClientDebug(android::base::unique_fd socketFd,
+                                    const sp<IBinder>& keepAliveBinder) {
+    if constexpr (!kEnableRpcDevServers) {
+        ALOGW("setRpcClientDebug disallowed because RPC is not enabled");
+        return INVALID_OPERATION;
+    }
+
+    BBinder* local = this->localBinder();
+    if (local != nullptr) {
+        return local->BBinder::setRpcClientDebug(std::move(socketFd), keepAliveBinder);
+    }
+
+    BpBinder* proxy = this->remoteBinder();
+    LOG_ALWAYS_FATAL_IF(proxy == nullptr, "binder object must be either local or remote");
+
+    Parcel data;
+    Parcel reply;
+    status_t status;
+    if (status = data.writeBool(socketFd.ok()); status != OK) return status;
+    if (socketFd.ok()) {
+        // writeUniqueFileDescriptor currently makes an unnecessary dup().
+        status = data.writeFileDescriptor(socketFd.release(), true /* own */);
+        if (status != OK) return status;
+    }
+    if (status = data.writeStrongBinder(keepAliveBinder); status != OK) return status;
+    return transact(SET_RPC_CLIENT_TRANSACTION, data, &reply);
+}
+
+void IBinder::withLock(const std::function<void()>& doWithLock) {
+    BBinder* local = localBinder();
+    if (local) {
+        local->withLock(doWithLock);
+        return;
+    }
+    BpBinder* proxy = this->remoteBinder();
+    LOG_ALWAYS_FATAL_IF(proxy == nullptr, "binder object must be either local or remote");
+    proxy->withLock(doWithLock);
+}
+
 // ---------------------------------------------------------------------------
 
+class BBinder::RpcServerLink : public IBinder::DeathRecipient {
+public:
+    // On binder died, calls RpcServer::shutdown on @a rpcServer, and removes itself from @a binder.
+    RpcServerLink(const sp<RpcServer>& rpcServer, const sp<IBinder>& keepAliveBinder,
+                  const wp<BBinder>& binder)
+          : mRpcServer(rpcServer), mKeepAliveBinder(keepAliveBinder), mBinder(binder) {}
+    void binderDied(const wp<IBinder>&) override {
+        LOG_RPC_DETAIL("RpcServerLink: binder died, shutting down RpcServer");
+        if (mRpcServer == nullptr) {
+            ALOGW("RpcServerLink: Unable to shut down RpcServer because it does not exist.");
+        } else {
+            ALOGW_IF(!mRpcServer->shutdown(),
+                     "RpcServerLink: RpcServer did not shut down properly. Not started?");
+        }
+        mRpcServer.clear();
+
+        auto promoted = mBinder.promote();
+        if (promoted == nullptr) {
+            ALOGW("RpcServerLink: Unable to remove link from parent binder object because parent "
+                  "binder object is gone.");
+        } else {
+            promoted->removeRpcServerLink(sp<RpcServerLink>::fromExisting(this));
+        }
+        mBinder.clear();
+    }
+
+private:
+    sp<RpcServer> mRpcServer;
+    sp<IBinder> mKeepAliveBinder; // hold to avoid automatically unlinking
+    wp<BBinder> mBinder;
+};
+
 class BBinder::Extras
 {
 public:
@@ -150,14 +236,13 @@
 
     // for below objects
     Mutex mLock;
+    std::set<sp<RpcServerLink>> mRpcServerLinks;
     BpBinder::ObjectManager mObjects;
 };
 
 // ---------------------------------------------------------------------------
 
-BBinder::BBinder() : mExtras(nullptr), mStability(0)
-{
-}
+BBinder::BBinder() : mExtras(nullptr), mStability(0), mParceled(false) {}
 
 bool BBinder::isBinderAlive() const
 {
@@ -199,6 +284,10 @@
         case DEBUG_PID_TRANSACTION:
             err = reply->writeInt32(getDebugPid());
             break;
+        case SET_RPC_CLIENT_TRANSACTION: {
+            err = setRpcClientDebug(data);
+            break;
+        }
         default:
             err = onTransact(code, data, reply, flags);
             break;
@@ -233,15 +322,13 @@
     return NO_ERROR;
 }
 
-void BBinder::attachObject(
-    const void* objectID, void* object, void* cleanupCookie,
-    object_cleanup_func func)
-{
+void* BBinder::attachObject(const void* objectID, void* object, void* cleanupCookie,
+                            object_cleanup_func func) {
     Extras* e = getOrCreateExtras();
-    if (!e) return; // out of memory
+    LOG_ALWAYS_FATAL_IF(!e, "no memory");
 
     AutoMutex _l(e->mLock);
-    e->mObjects.attach(objectID, object, cleanupCookie, func);
+    return e->mObjects.attach(objectID, object, cleanupCookie, func);
 }
 
 void* BBinder::findObject(const void* objectID) const
@@ -253,13 +340,20 @@
     return e->mObjects.find(objectID);
 }
 
-void BBinder::detachObject(const void* objectID)
-{
+void* BBinder::detachObject(const void* objectID) {
     Extras* e = mExtras.load(std::memory_order_acquire);
-    if (!e) return;
+    if (!e) return nullptr;
 
     AutoMutex _l(e->mLock);
-    e->mObjects.detach(objectID);
+    return e->mObjects.detach(objectID);
+}
+
+void BBinder::withLock(const std::function<void()>& doWithLock) {
+    Extras* e = getOrCreateExtras();
+    LOG_ALWAYS_FATAL_IF(!e, "no memory");
+
+    AutoMutex _l(e->mLock);
+    doWithLock();
 }
 
 BBinder* BBinder::localBinder()
@@ -276,6 +370,10 @@
 
 void BBinder::setRequestingSid(bool requestingSid)
 {
+    LOG_ALWAYS_FATAL_IF(mParceled,
+                        "setRequestingSid() should not be called after a binder object "
+                        "is parceled/sent to another process");
+
     Extras* e = mExtras.load(std::memory_order_acquire);
 
     if (!e) {
@@ -298,6 +396,10 @@
 }
 
 void BBinder::setMinSchedulerPolicy(int policy, int priority) {
+    LOG_ALWAYS_FATAL_IF(mParceled,
+                        "setMinSchedulerPolicy() should not be called after a binder object "
+                        "is parceled/sent to another process");
+
     switch (policy) {
     case SCHED_NORMAL:
       LOG_ALWAYS_FATAL_IF(priority < -20 || priority > 19, "Invalid priority for SCHED_NORMAL: %d", priority);
@@ -345,6 +447,10 @@
 }
 
 void BBinder::setInheritRt(bool inheritRt) {
+    LOG_ALWAYS_FATAL_IF(mParceled,
+                        "setInheritRt() should not be called after a binder object "
+                        "is parceled/sent to another process");
+
     Extras* e = mExtras.load(std::memory_order_acquire);
 
     if (!e) {
@@ -364,10 +470,107 @@
 }
 
 void BBinder::setExtension(const sp<IBinder>& extension) {
+    LOG_ALWAYS_FATAL_IF(mParceled,
+                        "setExtension() should not be called after a binder object "
+                        "is parceled/sent to another process");
+
     Extras* e = getOrCreateExtras();
     e->mExtension = extension;
 }
 
+bool BBinder::wasParceled() {
+    return mParceled;
+}
+
+void BBinder::setParceled() {
+    mParceled = true;
+}
+
+status_t BBinder::setRpcClientDebug(const Parcel& data) {
+    if constexpr (!kEnableRpcDevServers) {
+        ALOGW("%s: disallowed because RPC is not enabled", __PRETTY_FUNCTION__);
+        return INVALID_OPERATION;
+    }
+    uid_t uid = IPCThreadState::self()->getCallingUid();
+    if (uid != AID_ROOT) {
+        ALOGE("%s: not allowed because client %" PRIu32 " is not root", __PRETTY_FUNCTION__, uid);
+        return PERMISSION_DENIED;
+    }
+    status_t status;
+    bool hasSocketFd;
+    android::base::unique_fd clientFd;
+
+    if (status = data.readBool(&hasSocketFd); status != OK) return status;
+    if (hasSocketFd) {
+        if (status = data.readUniqueFileDescriptor(&clientFd); status != OK) return status;
+    }
+    sp<IBinder> keepAliveBinder;
+    if (status = data.readNullableStrongBinder(&keepAliveBinder); status != OK) return status;
+
+    return setRpcClientDebug(std::move(clientFd), keepAliveBinder);
+}
+
+status_t BBinder::setRpcClientDebug(android::base::unique_fd socketFd,
+                                    const sp<IBinder>& keepAliveBinder) {
+    if constexpr (!kEnableRpcDevServers) {
+        ALOGW("%s: disallowed because RPC is not enabled", __PRETTY_FUNCTION__);
+        return INVALID_OPERATION;
+    }
+
+    const int socketFdForPrint = socketFd.get();
+    LOG_RPC_DETAIL("%s(fd=%d)", __PRETTY_FUNCTION__, socketFdForPrint);
+
+    if (!socketFd.ok()) {
+        ALOGE("%s: No socket FD provided.", __PRETTY_FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    if (keepAliveBinder == nullptr) {
+        ALOGE("%s: No keepAliveBinder provided.", __PRETTY_FUNCTION__);
+        return UNEXPECTED_NULL;
+    }
+
+    size_t binderThreadPoolMaxCount = ProcessState::self()->getThreadPoolMaxThreadCount();
+    if (binderThreadPoolMaxCount <= 1) {
+        ALOGE("%s: ProcessState thread pool max count is %zu. RPC is disabled for this service "
+              "because RPC requires the service to support multithreading.",
+              __PRETTY_FUNCTION__, binderThreadPoolMaxCount);
+        return INVALID_OPERATION;
+    }
+
+    // Weak ref to avoid circular dependency:
+    // BBinder -> RpcServerLink ----> RpcServer -X-> BBinder
+    //                          `-X-> BBinder
+    auto weakThis = wp<BBinder>::fromExisting(this);
+
+    Extras* e = getOrCreateExtras();
+    AutoMutex _l(e->mLock);
+    auto rpcServer = RpcServer::make();
+    LOG_ALWAYS_FATAL_IF(rpcServer == nullptr, "RpcServer::make returns null");
+    auto link = sp<RpcServerLink>::make(rpcServer, keepAliveBinder, weakThis);
+    if (auto status = keepAliveBinder->linkToDeath(link, nullptr, 0); status != OK) {
+        ALOGE("%s: keepAliveBinder->linkToDeath returns %s", __PRETTY_FUNCTION__,
+              statusToString(status).c_str());
+        return status;
+    }
+    rpcServer->setRootObjectWeak(weakThis);
+    if (auto status = rpcServer->setupExternalServer(std::move(socketFd)); status != OK) {
+        return status;
+    }
+    rpcServer->setMaxThreads(binderThreadPoolMaxCount);
+    rpcServer->start();
+    e->mRpcServerLinks.emplace(link);
+    LOG_RPC_DETAIL("%s(fd=%d) successful", __PRETTY_FUNCTION__, socketFdForPrint);
+    return OK;
+}
+
+void BBinder::removeRpcServerLink(const sp<RpcServerLink>& link) {
+    Extras* e = mExtras.load(std::memory_order_acquire);
+    if (!e) return;
+    AutoMutex _l(e->mLock);
+    (void)e->mRpcServerLinks.erase(link);
+}
+
 BBinder::~BBinder()
 {
     Extras* e = mExtras.load(std::memory_order_relaxed);
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 6471aa6..06542f0 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -37,7 +37,7 @@
 
 Mutex BpBinder::sTrackingLock;
 std::unordered_map<int32_t, uint32_t> BpBinder::sTrackingMap;
-std::unordered_map<int32_t, uint32_t> sLastLimitCallbackMap;
+std::unordered_map<int32_t, uint32_t> BpBinder::sLastLimitCallbackMap;
 int BpBinder::sNumTrackedUids = 0;
 std::atomic_bool BpBinder::sCountByUidEnabled(false);
 binder_proxy_limit_callback BpBinder::sLimitCallback;
@@ -62,22 +62,22 @@
     kill();
 }
 
-void BpBinder::ObjectManager::attach(
-    const void* objectID, void* object, void* cleanupCookie,
-    IBinder::object_cleanup_func func)
-{
+void* BpBinder::ObjectManager::attach(const void* objectID, void* object, void* cleanupCookie,
+                                      IBinder::object_cleanup_func func) {
     entry_t e;
     e.object = object;
     e.cleanupCookie = cleanupCookie;
     e.func = func;
 
-    if (mObjects.indexOfKey(objectID) >= 0) {
-        ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
-                objectID, this,  object);
-        return;
+    if (ssize_t idx = mObjects.indexOfKey(objectID); idx >= 0) {
+        ALOGI("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object "
+              "ID already in use",
+              objectID, this, object);
+        return mObjects[idx].object;
     }
 
     mObjects.add(objectID, e);
+    return nullptr;
 }
 
 void* BpBinder::ObjectManager::find(const void* objectID) const
@@ -87,9 +87,12 @@
     return mObjects.valueAt(i).object;
 }
 
-void BpBinder::ObjectManager::detach(const void* objectID)
-{
-    mObjects.removeItem(objectID);
+void* BpBinder::ObjectManager::detach(const void* objectID) {
+    ssize_t idx = mObjects.indexOfKey(objectID);
+    if (idx < 0) return nullptr;
+    void* value = mObjects[idx].object;
+    mObjects.removeItemsAt(idx, 1);
+    return value;
 }
 
 void BpBinder::ObjectManager::kill()
@@ -149,7 +152,7 @@
     return sp<BpBinder>::make(BinderHandle{handle}, trackedUid);
 }
 
-sp<BpBinder> BpBinder::create(const sp<RpcSession>& session, const RpcAddress& address) {
+sp<BpBinder> BpBinder::create(const sp<RpcSession>& session, uint64_t address) {
     LOG_ALWAYS_FATAL_IF(session == nullptr, "BpBinder::create null session");
 
     // These are not currently tracked, since there is no UID or other
@@ -186,7 +189,7 @@
     return std::holds_alternative<RpcHandle>(mHandle);
 }
 
-const RpcAddress& BpBinder::rpcAddress() const {
+uint64_t BpBinder::rpcAddress() const {
     return std::get<RpcHandle>(mHandle).address;
 }
 
@@ -198,6 +201,14 @@
     return std::get<BinderHandle>(mHandle).handle;
 }
 
+std::optional<int32_t> BpBinder::getDebugBinderHandle() const {
+    if (!isRpcBinder()) {
+        return binderHandle();
+    } else {
+        return std::nullopt;
+    }
+}
+
 bool BpBinder::isDescriptorCached() const {
     Mutex::Autolock _l(mLock);
     return mDescriptorCache.size() ? true : false;
@@ -271,22 +282,23 @@
         if (code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION) {
             using android::internal::Stability;
 
-            auto category = Stability::getCategory(this);
+            int16_t stability = Stability::getRepr(this);
             Stability::Level required = privateVendor ? Stability::VENDOR
                 : Stability::getLocalLevel();
 
-            if (CC_UNLIKELY(!Stability::check(category, required))) {
+            if (CC_UNLIKELY(!Stability::check(stability, required))) {
                 ALOGE("Cannot do a user transaction on a %s binder (%s) in a %s context.",
-                    category.debugString().c_str(),
-                    String8(getInterfaceDescriptor()).c_str(),
-                    Stability::levelString(required).c_str());
+                      Stability::levelString(stability).c_str(),
+                      String8(getInterfaceDescriptor()).c_str(),
+                      Stability::levelString(required).c_str());
                 return BAD_TYPE;
             }
         }
 
         status_t status;
         if (CC_UNLIKELY(isRpcBinder())) {
-            status = rpcSession()->transact(rpcAddress(), code, data, reply, flags);
+            status = rpcSession()->transact(sp<IBinder>::fromExisting(this), code, data, reply,
+                                            flags);
         } else {
             status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags);
         }
@@ -418,14 +430,11 @@
     recipient->binderDied(wp<BpBinder>::fromExisting(this));
 }
 
-
-void BpBinder::attachObject(
-    const void* objectID, void* object, void* cleanupCookie,
-    object_cleanup_func func)
-{
+void* BpBinder::attachObject(const void* objectID, void* object, void* cleanupCookie,
+                             object_cleanup_func func) {
     AutoMutex _l(mLock);
     ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
-    mObjects.attach(objectID, object, cleanupCookie, func);
+    return mObjects.attach(objectID, object, cleanupCookie, func);
 }
 
 void* BpBinder::findObject(const void* objectID) const
@@ -434,10 +443,14 @@
     return mObjects.find(objectID);
 }
 
-void BpBinder::detachObject(const void* objectID)
-{
+void* BpBinder::detachObject(const void* objectID) {
     AutoMutex _l(mLock);
-    mObjects.detach(objectID);
+    return mObjects.detach(objectID);
+}
+
+void BpBinder::withLock(const std::function<void()>& doWithLock) {
+    AutoMutex _l(mLock);
+    doWithLock();
 }
 
 BpBinder* BpBinder::remoteBinder()
@@ -493,7 +506,7 @@
 {
     ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, binderHandle());
     if (CC_UNLIKELY(isRpcBinder())) {
-        (void)rpcSession()->sendDecStrong(rpcAddress());
+        (void)rpcSession()->sendDecStrong(this);
         return;
     }
     IF_ALOGV() {
diff --git a/libs/binder/Debug.cpp b/libs/binder/Debug.cpp
index 8676955..e4ac4b4 100644
--- a/libs/binder/Debug.cpp
+++ b/libs/binder/Debug.cpp
@@ -26,22 +26,6 @@
 
 namespace android {
 
-std::string hexString(const void* bytes, size_t len) {
-    if (bytes == nullptr) return "<null>";
-
-    const uint8_t* bytes8 = static_cast<const uint8_t*>(bytes);
-    const char chars[] = "0123456789abcdef";
-    std::string result;
-    result.resize(len * 2);
-
-    for (size_t i = 0; i < len; i++) {
-        result[2 * i] = chars[bytes8[i] >> 4];
-        result[2 * i + 1] = chars[bytes8[i] & 0xf];
-    }
-
-    return result;
-}
-
 // ---------------------------------------------------------------------
 
 static const char indentStr[] =
diff --git a/libs/binder/Debug.h b/libs/binder/Debug.h
index 7ca087e..262dfba 100644
--- a/libs/binder/Debug.h
+++ b/libs/binder/Debug.h
@@ -23,8 +23,6 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-std::string hexString(const void* data, size_t size);
-
 const char* stringForIndent(int32_t indentLevel);
 
 typedef void (*debugPrintFunc)(void* cookie, const char* txt);
diff --git a/libs/binder/FdTrigger.cpp b/libs/binder/FdTrigger.cpp
new file mode 100644
index 0000000..5e22593
--- /dev/null
+++ b/libs/binder/FdTrigger.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "FdTrigger"
+#include <log/log.h>
+
+#include "FdTrigger.h"
+
+#include <poll.h>
+
+#include <android-base/macros.h>
+
+#include "RpcState.h"
+namespace android {
+
+std::unique_ptr<FdTrigger> FdTrigger::make() {
+    auto ret = std::make_unique<FdTrigger>();
+    if (!android::base::Pipe(&ret->mRead, &ret->mWrite)) {
+        ALOGE("Could not create pipe %s", strerror(errno));
+        return nullptr;
+    }
+    return ret;
+}
+
+void FdTrigger::trigger() {
+    mWrite.reset();
+}
+
+bool FdTrigger::isTriggered() {
+    return mWrite == -1;
+}
+
+status_t FdTrigger::triggerablePoll(base::borrowed_fd fd, int16_t event) {
+    LOG_ALWAYS_FATAL_IF(event == 0, "triggerablePoll %d with event 0 is not allowed", fd.get());
+    pollfd pfd[]{{.fd = fd.get(), .events = static_cast<int16_t>(event), .revents = 0},
+                 {.fd = mRead.get(), .events = 0, .revents = 0}};
+    int ret = TEMP_FAILURE_RETRY(poll(pfd, arraysize(pfd), -1));
+    if (ret < 0) {
+        return -errno;
+    }
+    LOG_ALWAYS_FATAL_IF(ret == 0, "poll(%d) returns 0 with infinite timeout", fd.get());
+
+    // At least one FD has events. Check them.
+
+    // Detect explicit trigger(): DEAD_OBJECT
+    if (pfd[1].revents & POLLHUP) {
+        return DEAD_OBJECT;
+    }
+    // See unknown flags in trigger FD's revents (POLLERR / POLLNVAL).
+    // Treat this error condition as UNKNOWN_ERROR.
+    if (pfd[1].revents != 0) {
+        ALOGE("Unknown revents on trigger FD %d: revents = %d", pfd[1].fd, pfd[1].revents);
+        return UNKNOWN_ERROR;
+    }
+
+    // pfd[1].revents is 0, hence pfd[0].revents must be set, and only possible values are
+    // a subset of event | POLLHUP | POLLERR | POLLNVAL.
+
+    // POLLNVAL: invalid FD number, e.g. not opened.
+    if (pfd[0].revents & POLLNVAL) {
+        return BAD_VALUE;
+    }
+
+    // Error condition. It wouldn't be possible to do I/O on |fd| afterwards.
+    // Note: If this is the write end of a pipe then POLLHUP may also be set simultaneously. We
+    //   still want DEAD_OBJECT in this case.
+    if (pfd[0].revents & POLLERR) {
+        LOG_RPC_DETAIL("poll() incoming FD %d results in revents = %d", pfd[0].fd, pfd[0].revents);
+        return DEAD_OBJECT;
+    }
+
+    // Success condition; event flag(s) set. Even though POLLHUP may also be set,
+    // treat it as a success condition to ensure data is drained.
+    if (pfd[0].revents & event) {
+        return OK;
+    }
+
+    // POLLHUP: Peer closed connection. Treat as DEAD_OBJECT.
+    // This is a very common case, so don't log.
+    return DEAD_OBJECT;
+}
+
+} // namespace android
diff --git a/libs/binder/FdTrigger.h b/libs/binder/FdTrigger.h
new file mode 100644
index 0000000..a545d6c
--- /dev/null
+++ b/libs/binder/FdTrigger.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+/** This is not a pipe. */
+class FdTrigger {
+public:
+    /** Returns nullptr for error case */
+    static std::unique_ptr<FdTrigger> make();
+
+    /**
+     * Close the write end of the pipe so that the read end receives POLLHUP.
+     * Not threadsafe.
+     */
+    void trigger();
+
+    /**
+     * Check whether this has been triggered by checking the write end. Note:
+     * this has no internal locking, and it is inherently racey, but this is
+     * okay, because if we accidentally return false when a trigger has already
+     * happened, we can imagine that instead, the scheduler actually executed
+     * the code which is polling isTriggered earlier.
+     */
+    [[nodiscard]] bool isTriggered();
+
+    /**
+     * Poll for a read event.
+     *
+     * event - for pollfd
+     *
+     * Return:
+     *   true - time to read!
+     *   false - trigger happened
+     */
+    [[nodiscard]] status_t triggerablePoll(base::borrowed_fd fd, int16_t event);
+
+private:
+    base::unique_fd mWrite;
+    base::unique_fd mRead;
+};
+} // namespace android
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index c415ea0..55d3d70 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -366,19 +366,46 @@
 
 pid_t IPCThreadState::getCallingPid() const
 {
+    checkContextIsBinderForUse(__func__);
     return mCallingPid;
 }
 
 const char* IPCThreadState::getCallingSid() const
 {
+    checkContextIsBinderForUse(__func__);
     return mCallingSid;
 }
 
 uid_t IPCThreadState::getCallingUid() const
 {
+    checkContextIsBinderForUse(__func__);
     return mCallingUid;
 }
 
+const IPCThreadState::SpGuard* IPCThreadState::pushGetCallingSpGuard(const SpGuard* guard) {
+    const SpGuard* orig = mServingStackPointerGuard;
+    mServingStackPointerGuard = guard;
+    return orig;
+}
+
+void IPCThreadState::restoreGetCallingSpGuard(const SpGuard* guard) {
+    mServingStackPointerGuard = guard;
+}
+
+void IPCThreadState::checkContextIsBinderForUse(const char* use) const {
+    if (LIKELY(mServingStackPointerGuard == nullptr)) return;
+
+    if (!mServingStackPointer || mServingStackPointerGuard->address < mServingStackPointer) {
+        LOG_ALWAYS_FATAL("In context %s, %s does not make sense (binder sp: %p, guard: %p).",
+                         mServingStackPointerGuard->context, use, mServingStackPointer,
+                         mServingStackPointerGuard->address);
+    }
+
+    // in the case mServingStackPointer is deeper in the stack than the guard,
+    // we must be serving a binder transaction (maybe nested). This is a binder
+    // context, so we don't abort
+}
+
 int64_t IPCThreadState::clearCallingIdentity()
 {
     // ignore mCallingSid for legacy reasons
@@ -845,6 +872,7 @@
 IPCThreadState::IPCThreadState()
       : mProcess(ProcessState::self()),
         mServingStackPointer(nullptr),
+        mServingStackPointerGuard(nullptr),
         mWorkSource(kUnsetWorkSource),
         mPropagateWorkSource(false),
         mIsLooper(false),
@@ -1226,7 +1254,7 @@
                 tr.offsets_size/sizeof(binder_size_t), freeBuffer);
 
             const void* origServingStackPointer = mServingStackPointer;
-            mServingStackPointer = &origServingStackPointer; // anything on the stack
+            mServingStackPointer = __builtin_frame_address(0);
 
             const pid_t origPid = mCallingPid;
             const char* origSid = mCallingSid;
@@ -1382,23 +1410,6 @@
         }
 }
 
-status_t IPCThreadState::getProcessFreezeInfo(pid_t pid, bool *sync_received, bool *async_received)
-{
-    int ret = 0;
-    binder_frozen_status_info info;
-    info.pid = pid;
-
-#if defined(__ANDROID__)
-    if (ioctl(self()->mProcess->mDriverFD, BINDER_GET_FROZEN_INFO, &info) < 0)
-        ret = -errno;
-#endif
-    *sync_received = info.sync_recv;
-    *async_received = info.async_recv;
-
-    return ret;
-}
-
-#ifndef __ANDROID_VNDK__
 status_t IPCThreadState::getProcessFreezeInfo(pid_t pid, uint32_t *sync_received,
                                               uint32_t *async_received)
 {
@@ -1415,7 +1426,6 @@
 
     return ret;
 }
-#endif
 
 status_t IPCThreadState::freeze(pid_t pid, bool enable, uint32_t timeout_ms) {
     struct binder_freeze_info info;
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index f684cf6..81e61da 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -35,6 +35,8 @@
 
 #ifdef __ANDROID__
 #include <cutils/properties.h>
+#else
+#include "ServiceManagerHost.h"
 #endif
 
 #include "Static.h"
@@ -76,6 +78,7 @@
     bool isDeclared(const String16& name) override;
     Vector<String16> getDeclaredInstances(const String16& interface) override;
     std::optional<String16> updatableViaApex(const String16& name) override;
+    std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override;
 
     // for legacy ABI
     const String16& getInterfaceDescriptor() const override {
@@ -84,8 +87,19 @@
     IBinder* onAsBinder() override {
         return IInterface::asBinder(mTheRealServiceManager).get();
     }
-private:
+
+protected:
     sp<AidlServiceManager> mTheRealServiceManager;
+
+    // Directly get the service in a way that, for lazy services, requests the service to be started
+    // if it is not currently started. This way, calls directly to ServiceManagerShim::getService
+    // will still have the 5s delay that is expected by a large amount of Android code.
+    //
+    // When implementing ServiceManagerShim, use realGetService instead of
+    // mTheRealServiceManager->getService so that it can be overridden in ServiceManagerHostShim.
+    virtual Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
+        return mTheRealServiceManager->getService(name, _aidl_return);
+    }
 };
 
 [[clang::no_destroy]] static std::once_flag gSmOnce;
@@ -129,8 +143,7 @@
     return checkCallingPermission(permission, nullptr, nullptr);
 }
 
-static String16 _permission("permission");
-
+static StaticString16 _permission(u"permission");
 
 bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
 {
@@ -142,8 +155,7 @@
     return checkPermission(permission, pid, uid);
 }
 
-bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
-{
+bool checkPermission(const String16& permission, pid_t pid, uid_t uid, bool logPermissionFailure) {
     static Mutex gPermissionControllerLock;
     static sp<IPermissionController> gPermissionController;
 
@@ -168,8 +180,10 @@
 
             // Is this a permission failure, or did the controller go away?
             if (IInterface::asBinder(pc)->isBinderAlive()) {
-                ALOGW("Permission failure: %s from uid=%d pid=%d",
-                        String8(permission).string(), uid, pid);
+                if (logPermissionFailure) {
+                    ALOGW("Permission failure: %s from uid=%d pid=%d", String8(permission).string(),
+                          uid, pid);
+                }
                 return false;
             }
 
@@ -320,14 +334,18 @@
     const std::string name = String8(name16).c_str();
 
     sp<IBinder> out;
-    if (!mTheRealServiceManager->getService(name, &out).isOk()) {
+    if (Status status = realGetService(name, &out); !status.isOk()) {
+        ALOGW("Failed to getService in waitForService for %s: %s", name.c_str(),
+              status.toString8().c_str());
         return nullptr;
     }
     if (out != nullptr) return out;
 
     sp<Waiter> waiter = sp<Waiter>::make();
-    if (!mTheRealServiceManager->registerForNotifications(
-            name, waiter).isOk()) {
+    if (Status status = mTheRealServiceManager->registerForNotifications(name, waiter);
+        !status.isOk()) {
+        ALOGW("Failed to registerForNotifications in waitForService for %s: %s", name.c_str(),
+              status.toString8().c_str());
         return nullptr;
     }
     Defer unregister ([&] {
@@ -360,7 +378,9 @@
         // - init gets death signal, but doesn't know it needs to restart
         //   the service
         // - we need to request service again to get it to start
-        if (!mTheRealServiceManager->getService(name, &out).isOk()) {
+        if (Status status = realGetService(name, &out); !status.isOk()) {
+            ALOGW("Failed to getService in waitForService on later try for %s: %s", name.c_str(),
+                  status.toString8().c_str());
             return nullptr;
         }
         if (out != nullptr) return out;
@@ -369,7 +389,10 @@
 
 bool ServiceManagerShim::isDeclared(const String16& name) {
     bool declared;
-    if (!mTheRealServiceManager->isDeclared(String8(name).c_str(), &declared).isOk()) {
+    if (Status status = mTheRealServiceManager->isDeclared(String8(name).c_str(), &declared);
+        !status.isOk()) {
+        ALOGW("Failed to get isDeclard for %s: %s", String8(name).c_str(),
+              status.toString8().c_str());
         return false;
     }
     return declared;
@@ -377,7 +400,11 @@
 
 Vector<String16> ServiceManagerShim::getDeclaredInstances(const String16& interface) {
     std::vector<std::string> out;
-    if (!mTheRealServiceManager->getDeclaredInstances(String8(interface).c_str(), &out).isOk()) {
+    if (Status status =
+                mTheRealServiceManager->getDeclaredInstances(String8(interface).c_str(), &out);
+        !status.isOk()) {
+        ALOGW("Failed to getDeclaredInstances for %s: %s", String8(interface).c_str(),
+              status.toString8().c_str());
         return {};
     }
 
@@ -391,10 +418,68 @@
 
 std::optional<String16> ServiceManagerShim::updatableViaApex(const String16& name) {
     std::optional<std::string> declared;
-    if (!mTheRealServiceManager->updatableViaApex(String8(name).c_str(), &declared).isOk()) {
+    if (Status status = mTheRealServiceManager->updatableViaApex(String8(name).c_str(), &declared);
+        !status.isOk()) {
+        ALOGW("Failed to get updatableViaApex for %s: %s", String8(name).c_str(),
+              status.toString8().c_str());
         return std::nullopt;
     }
     return declared ? std::optional<String16>(String16(declared.value().c_str())) : std::nullopt;
 }
 
+std::optional<IServiceManager::ConnectionInfo> ServiceManagerShim::getConnectionInfo(
+        const String16& name) {
+    std::optional<os::ConnectionInfo> connectionInfo;
+    if (Status status =
+                mTheRealServiceManager->getConnectionInfo(String8(name).c_str(), &connectionInfo);
+        !status.isOk()) {
+        ALOGW("Failed to get ConnectionInfo for %s: %s", String8(name).c_str(),
+              status.toString8().c_str());
+    }
+    return connectionInfo.has_value()
+            ? std::make_optional<IServiceManager::ConnectionInfo>(
+                      {connectionInfo->ipAddress, static_cast<unsigned int>(connectionInfo->port)})
+            : std::nullopt;
+}
+
+#ifndef __ANDROID__
+// ServiceManagerShim for host. Implements the old libbinder android::IServiceManager API.
+// The internal implementation of the AIDL interface android::os::IServiceManager calls into
+// on-device service manager.
+class ServiceManagerHostShim : public ServiceManagerShim {
+public:
+    ServiceManagerHostShim(const sp<AidlServiceManager>& impl,
+                           const RpcDelegateServiceManagerOptions& options)
+          : ServiceManagerShim(impl), mOptions(options) {}
+    // ServiceManagerShim::getService is based on checkService, so no need to override it.
+    sp<IBinder> checkService(const String16& name) const override {
+        return getDeviceService({String8(name).c_str()}, mOptions);
+    }
+
+protected:
+    // Override realGetService for ServiceManagerShim::waitForService.
+    Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
+        *_aidl_return = getDeviceService({"-g", name}, mOptions);
+        return Status::ok();
+    }
+
+private:
+    RpcDelegateServiceManagerOptions mOptions;
+};
+sp<IServiceManager> createRpcDelegateServiceManager(
+        const RpcDelegateServiceManagerOptions& options) {
+    auto binder = getDeviceService({"manager"}, options);
+    if (binder == nullptr) {
+        ALOGE("getDeviceService(\"manager\") returns null");
+        return nullptr;
+    }
+    auto interface = AidlServiceManager::asInterface(binder);
+    if (interface == nullptr) {
+        ALOGE("getDeviceService(\"manager\") returns non service manager");
+        return nullptr;
+    }
+    return sp<ServiceManagerHostShim>::make(interface, options);
+}
+#endif
+
 } // namespace android
diff --git a/libs/binder/OWNERS b/libs/binder/OWNERS
index 350994a..f954e74 100644
--- a/libs/binder/OWNERS
+++ b/libs/binder/OWNERS
@@ -1,5 +1,6 @@
-arve@google.com
+# Bug component: 32456
 ctate@google.com
 hackbod@google.com
 maco@google.com
 smoreland@google.com
+tkjos@google.com
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 617708f..745d9e9 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -98,13 +98,12 @@
     BLOB_ASHMEM_MUTABLE = 2,
 };
 
-static void acquire_object(const sp<ProcessState>& proc,
-    const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
-{
+static void acquire_object(const sp<ProcessState>& proc, const flat_binder_object& obj,
+                           const void* who) {
     switch (obj.hdr.type) {
         case BINDER_TYPE_BINDER:
             if (obj.binder) {
-                LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
+                LOG_REFS("Parcel %p acquiring reference on local %llu", who, obj.cookie);
                 reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
             }
             return;
@@ -117,13 +116,6 @@
             return;
         }
         case BINDER_TYPE_FD: {
-            if ((obj.cookie != 0) && (outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
-                // If we own an ashmem fd, keep track of how much memory it refers to.
-                int size = ashmem_get_size_region(obj.handle);
-                if (size > 0) {
-                    *outAshmemSize += size;
-                }
-            }
             return;
         }
     }
@@ -131,13 +123,12 @@
     ALOGD("Invalid object type 0x%08x", obj.hdr.type);
 }
 
-static void release_object(const sp<ProcessState>& proc,
-    const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
-{
+static void release_object(const sp<ProcessState>& proc, const flat_binder_object& obj,
+                           const void* who) {
     switch (obj.hdr.type) {
         case BINDER_TYPE_BINDER:
             if (obj.binder) {
-                LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
+                LOG_REFS("Parcel %p releasing reference on local %llu", who, obj.cookie);
                 reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
             }
             return;
@@ -151,16 +142,6 @@
         }
         case BINDER_TYPE_FD: {
             if (obj.cookie != 0) { // owned
-                if ((outAshmemSize != nullptr) && ashmem_valid(obj.handle)) {
-                    int size = ashmem_get_size_region(obj.handle);
-                    if (size > 0) {
-                        // ashmem size might have changed since last time it was accounted for, e.g.
-                        // in acquire_object(). Value of *outAshmemSize is not critical since we are
-                        // releasing the object anyway. Check for integer overflow condition.
-                        *outAshmemSize -= std::min(*outAshmemSize, static_cast<size_t>(size));
-                    }
-                }
-
                 close(obj.handle);
             }
             return;
@@ -173,8 +154,8 @@
 status_t Parcel::finishFlattenBinder(const sp<IBinder>& binder)
 {
     internal::Stability::tryMarkCompilationUnit(binder.get());
-    auto category = internal::Stability::getCategory(binder.get());
-    return writeInt32(category.repr());
+    int16_t rep = internal::Stability::getRepr(binder.get());
+    return writeInt32(rep);
 }
 
 status_t Parcel::finishUnflattenBinder(
@@ -184,7 +165,8 @@
     status_t status = readInt32(&stability);
     if (status != OK) return status;
 
-    status = internal::Stability::setRepr(binder.get(), stability, true /*log*/);
+    status = internal::Stability::setRepr(binder.get(), static_cast<int16_t>(stability),
+                                          true /*log*/);
     if (status != OK) return status;
 
     *out = binder;
@@ -195,16 +177,20 @@
     return (priority & FLAT_BINDER_FLAG_PRIORITY_MASK) | ((policy & 3) << FLAT_BINDER_FLAG_SCHED_POLICY_SHIFT);
 }
 
-status_t Parcel::flattenBinder(const sp<IBinder>& binder)
-{
+status_t Parcel::flattenBinder(const sp<IBinder>& binder) {
+    BBinder* local = nullptr;
+    if (binder) local = binder->localBinder();
+    if (local) local->setParceled();
+
     if (isForRpc()) {
         if (binder) {
             status_t status = writeInt32(1); // non-null
             if (status != OK) return status;
-            RpcAddress address = RpcAddress::zero();
+            uint64_t address;
+            // TODO(b/167966510): need to undo this if the Parcel is not sent
             status = mSession->state()->onBinderLeaving(mSession, binder, &address);
             if (status != OK) return status;
-            status = address.writeToParcel(this);
+            status = writeUint64(address);
             if (status != OK) return status;
         } else {
             status_t status = writeInt32(0); // null
@@ -222,18 +208,17 @@
     }
 
     if (binder != nullptr) {
-        BBinder *local = binder->localBinder();
         if (!local) {
             BpBinder *proxy = binder->remoteBinder();
             if (proxy == nullptr) {
                 ALOGE("null proxy");
             } else {
                 if (proxy->isRpcBinder()) {
-                    ALOGE("Sending a socket binder over RPC is prohibited");
+                    ALOGE("Sending a socket binder over kernel binder is prohibited");
                     return INVALID_OPERATION;
                 }
             }
-            const int32_t handle = proxy ? proxy->getPrivateAccessorForId().binderHandle() : 0;
+            const int32_t handle = proxy ? proxy->getPrivateAccessor().binderHandle() : 0;
             obj.hdr.type = BINDER_TYPE_HANDLE;
             obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
             obj.handle = handle;
@@ -275,17 +260,21 @@
     if (isForRpc()) {
         LOG_ALWAYS_FATAL_IF(mSession == nullptr, "RpcSession required to read from remote parcel");
 
-        int32_t isNull;
-        status_t status = readInt32(&isNull);
+        int32_t isPresent;
+        status_t status = readInt32(&isPresent);
         if (status != OK) return status;
 
         sp<IBinder> binder;
 
-        if (isNull & 1) {
-            auto addr = RpcAddress::zero();
-            status_t status = addr.readFromParcel(*this);
-            if (status != OK) return status;
-            binder = mSession->state()->onBinderEntering(mSession, addr);
+        if (isPresent & 1) {
+            uint64_t addr;
+            if (status_t status = readUint64(&addr); status != OK) return status;
+            if (status_t status = mSession->state()->onBinderEntering(mSession, addr, &binder);
+                status != OK)
+                return status;
+            if (status_t status = mSession->state()->flushExcessBinderRefs(mSession, addr, binder);
+                status != OK)
+                return status;
         }
 
         return finishUnflattenBinder(binder, out);
@@ -422,8 +411,9 @@
 
 status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len)
 {
-    if (parcel->isForRpc() != isForRpc()) {
-        ALOGE("Cannot append Parcel of one format to another.");
+    if (mSession != parcel->mSession) {
+        ALOGE("Cannot append Parcel from one context to another. They may be different formats, "
+              "and objects are specific to a context.");
         return BAD_TYPE;
     }
 
@@ -504,7 +494,7 @@
 
             flat_binder_object* flat
                 = reinterpret_cast<flat_binder_object*>(mData + off);
-            acquire_object(proc, *flat, this, &mOpenAshmemSize);
+            acquire_object(proc, *flat, this);
 
             if (flat->hdr.type == BINDER_TYPE_FD) {
                 // If this is a file descriptor, we need to dup it so the
@@ -531,6 +521,25 @@
     return memcmp(data(), other.data(), size);
 }
 
+status_t Parcel::compareDataInRange(size_t thisOffset, const Parcel& other, size_t otherOffset,
+                                    size_t len, int* result) const {
+    if (len > INT32_MAX || thisOffset > INT32_MAX || otherOffset > INT32_MAX) {
+        // Don't accept size_t values which may have come from an inadvertent conversion from a
+        // negative int.
+        return BAD_VALUE;
+    }
+    size_t thisLimit;
+    if (__builtin_add_overflow(thisOffset, len, &thisLimit) || thisLimit > mDataSize) {
+        return BAD_VALUE;
+    }
+    size_t otherLimit;
+    if (__builtin_add_overflow(otherOffset, len, &otherLimit) || otherLimit > other.mDataSize) {
+        return BAD_VALUE;
+    }
+    *result = memcmp(data() + thisOffset, other.data() + otherOffset, len);
+    return NO_ERROR;
+}
+
 bool Parcel::allowFds() const
 {
     return mAllowFds;
@@ -558,6 +567,33 @@
     return mHasFds;
 }
 
+status_t Parcel::hasFileDescriptorsInRange(size_t offset, size_t len, bool* result) const {
+    if (len > INT32_MAX || offset > INT32_MAX) {
+        // Don't accept size_t values which may have come from an inadvertent conversion from a
+        // negative int.
+        return BAD_VALUE;
+    }
+    size_t limit;
+    if (__builtin_add_overflow(offset, len, &limit) || limit > mDataSize) {
+        return BAD_VALUE;
+    }
+    *result = false;
+    for (size_t i = 0; i < mObjectsSize; i++) {
+        size_t pos = mObjects[i];
+        if (pos < offset) continue;
+        if (pos + sizeof(flat_binder_object) > offset + len) {
+          if (mObjectsSorted) break;
+          else continue;
+        }
+        const flat_binder_object* flat = reinterpret_cast<const flat_binder_object*>(mData + pos);
+        if (flat->hdr.type == BINDER_TYPE_FD) {
+            *result = true;
+            break;
+        }
+    }
+    return NO_ERROR;
+}
+
 void Parcel::markSensitive() const
 {
     mDeallocZero = true;
@@ -567,7 +603,7 @@
     LOG_ALWAYS_FATAL_IF(mData != nullptr, "format must be set before data is written");
 
     if (binder && binder->remoteBinder() && binder->remoteBinder()->isRpcBinder()) {
-        markForRpc(binder->remoteBinder()->getPrivateAccessorForId().rpcSession());
+        markForRpc(binder->remoteBinder()->getPrivateAccessor().rpcSession());
     }
 }
 
@@ -594,6 +630,8 @@
 
 #if defined(__ANDROID_VNDK__)
 constexpr int32_t kHeader = B_PACK_CHARS('V', 'N', 'D', 'R');
+#elif defined(__ANDROID_RECOVERY__)
+constexpr int32_t kHeader = B_PACK_CHARS('R', 'E', 'C', 'O');
 #else
 constexpr int32_t kHeader = B_PACK_CHARS('S', 'Y', 'S', 'T');
 #endif
@@ -1327,7 +1365,7 @@
         // Need to write meta-data?
         if (nullMetaData || val.binder != 0) {
             mObjects[mObjectsSize] = mDataPos;
-            acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
+            acquire_object(ProcessState::self(), val, this);
             mObjectsSize++;
         }
 
@@ -1466,6 +1504,29 @@
     return nullptr;
 }
 
+status_t Parcel::readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const {
+    if (status_t status = readInt32(size); status != OK) return status;
+    if (*size < 0) return OK; // may be null, client to handle
+
+    LOG_ALWAYS_FATAL_IF(elmSize > INT32_MAX, "Cannot have element as big as %zu", elmSize);
+
+    // approximation, can't know max element size (e.g. if it makes heap
+    // allocations)
+    static_assert(sizeof(int) == sizeof(int32_t), "Android is LP64");
+    int32_t allocationSize;
+    if (__builtin_smul_overflow(elmSize, *size, &allocationSize)) return NO_MEMORY;
+
+    // High limit of 1MB since something this big could never be returned. Could
+    // probably scope this down, but might impact very specific usecases.
+    constexpr int32_t kMaxAllocationSize = 1 * 1000 * 1000;
+
+    if (allocationSize >= kMaxAllocationSize) {
+        return NO_MEMORY;
+    }
+
+    return OK;
+}
+
 template<class T>
 status_t Parcel::readAligned(T *pArg) const {
     static_assert(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
@@ -2196,7 +2257,7 @@
         i--;
         const flat_binder_object* flat
             = reinterpret_cast<flat_binder_object*>(data+objects[i]);
-        release_object(proc, *flat, this, &mOpenAshmemSize);
+        release_object(proc, *flat, this);
     }
 }
 
@@ -2213,7 +2274,7 @@
         i--;
         const flat_binder_object* flat
             = reinterpret_cast<flat_binder_object*>(data+objects[i]);
-        acquire_object(proc, *flat, this, &mOpenAshmemSize);
+        acquire_object(proc, *flat, this);
     }
 }
 
@@ -2418,7 +2479,7 @@
                     // will need to rescan because we may have lopped off the only FDs
                     mFdsKnown = false;
                 }
-                release_object(proc, *flat, this, &mOpenAshmemSize);
+                release_object(proc, *flat, this);
             }
 
             if (objectsSize == 0) {
@@ -2511,7 +2572,6 @@
     mAllowFds = true;
     mDeallocZero = false;
     mOwner = nullptr;
-    mOpenAshmemSize = 0;
     mWorkSourceRequestHeaderPosition = 0;
     mRequestHeaderPresent = false;
 
@@ -2528,18 +2588,9 @@
     }
 }
 
-void Parcel::scanForFds() const
-{
-    bool hasFds = false;
-    for (size_t i=0; i<mObjectsSize; i++) {
-        const flat_binder_object* flat
-            = reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
-        if (flat->hdr.type == BINDER_TYPE_FD) {
-            hasFds = true;
-            break;
-        }
-    }
-    mHasFds = hasFds;
+void Parcel::scanForFds() const {
+    status_t status = hasFileDescriptorsInRange(0, dataSize(), &mHasFds);
+    ALOGE_IF(status != NO_ERROR, "Error %d calling hasFileDescriptorsInRange()", status);
     mFdsKnown = true;
 }
 
@@ -2547,13 +2598,28 @@
 {
     // This used to return the size of all blobs that were written to ashmem, now we're returning
     // the ashmem currently referenced by this Parcel, which should be equivalent.
-    // TODO: Remove method once ABI can be changed.
-    return mOpenAshmemSize;
+    // TODO(b/202029388): Remove method once ABI can be changed.
+    return getOpenAshmemSize();
 }
 
 size_t Parcel::getOpenAshmemSize() const
 {
-    return mOpenAshmemSize;
+    size_t openAshmemSize = 0;
+    for (size_t i = 0; i < mObjectsSize; i++) {
+        const flat_binder_object* flat =
+                reinterpret_cast<const flat_binder_object*>(mData + mObjects[i]);
+
+        // cookie is compared against zero for historical reasons
+        // > obj.cookie = takeOwnership ? 1 : 0;
+        if (flat->hdr.type == BINDER_TYPE_FD && flat->cookie != 0 && ashmem_valid(flat->handle)) {
+            int size = ashmem_get_size_region(flat->handle);
+            if (__builtin_add_overflow(openAshmemSize, size, &openAshmemSize)) {
+                ALOGE("Overflow when computing ashmem size.");
+                return SIZE_MAX;
+            }
+        }
+    }
+    return openAshmemSize;
 }
 
 // --- Parcel::Blob ---
diff --git a/libs/binder/ParcelValTypes.h b/libs/binder/ParcelValTypes.h
index 666d22a..80736c8 100644
--- a/libs/binder/ParcelValTypes.h
+++ b/libs/binder/ParcelValTypes.h
@@ -27,18 +27,32 @@
     VAL_PARCELABLE = 4,
     VAL_SHORT = 5,
     VAL_LONG = 6,
+    VAL_FLOAT = 7,
     VAL_DOUBLE = 8,
     VAL_BOOLEAN = 9,
+    VAL_CHARSEQUENCE = 10,
+    VAL_LIST = 11,
+    VAL_SPARSEARRAY = 12,
     VAL_BYTEARRAY = 13,
     VAL_STRINGARRAY = 14,
     VAL_IBINDER = 15,
+    VAL_PARCELABLEARRAY = 16,
+    VAL_OBJECTARRAY = 17,
     VAL_INTARRAY = 18,
     VAL_LONGARRAY = 19,
     VAL_BYTE = 20,
     VAL_SERIALIZABLE = 21,
+    VAL_SPARSEBOOLEANARRAY = 22,
     VAL_BOOLEANARRAY = 23,
+    VAL_CHARSEQUENCEARRAY = 24,
     VAL_PERSISTABLEBUNDLE = 25,
+    VAL_SIZE = 26,
+    VAL_SIZEF = 27,
     VAL_DOUBLEARRAY = 28,
+    VAL_CHAR = 29,
+    VAL_SHORTARRAY = 30,
+    VAL_CHARARRAY = 31,
+    VAL_FLOATARRAY = 32,
 };
 
 } // namespace binder
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index bade918..4f21cda 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -18,6 +18,7 @@
 
 #include <binder/ProcessState.h>
 
+#include <android-base/result.h>
 #include <binder/BpBinder.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -88,13 +89,21 @@
     return init(nullptr, false /*requireDefault*/);
 }
 
+[[clang::no_destroy]] static sp<ProcessState> gProcess;
+[[clang::no_destroy]] static std::mutex gProcessMutex;
+
+static void verifyNotForked(bool forked) {
+    LOG_ALWAYS_FATAL_IF(forked, "libbinder ProcessState can not be used after fork");
+}
+
 sp<ProcessState> ProcessState::init(const char *driver, bool requireDefault)
 {
-    [[clang::no_destroy]] static sp<ProcessState> gProcess;
-    [[clang::no_destroy]] static std::mutex gProcessMutex;
 
     if (driver == nullptr) {
         std::lock_guard<std::mutex> l(gProcessMutex);
+        if (gProcess) {
+            verifyNotForked(gProcess->mForked);
+        }
         return gProcess;
     }
 
@@ -105,6 +114,14 @@
             driver = "/dev/binder";
         }
 
+        // we must install these before instantiating the gProcess object,
+        // otherwise this would race with creating it, and there could be the
+        // possibility of an invalid gProcess object forked by another thread
+        // before these are installed
+        int ret = pthread_atfork(ProcessState::onFork, ProcessState::parentPostFork,
+                                 ProcessState::childPostFork);
+        LOG_ALWAYS_FATAL_IF(ret != 0, "pthread_atfork error %s", strerror(ret));
+
         std::lock_guard<std::mutex> l(gProcessMutex);
         gProcess = sp<ProcessState>::make(driver);
     });
@@ -118,6 +135,7 @@
                             gProcess->getDriverName().c_str(), driver);
     }
 
+    verifyNotForked(gProcess->mForked);
     return gProcess;
 }
 
@@ -136,6 +154,24 @@
     return context;
 }
 
+void ProcessState::onFork() {
+    // make sure another thread isn't currently retrieving ProcessState
+    gProcessMutex.lock();
+}
+
+void ProcessState::parentPostFork() {
+    gProcessMutex.unlock();
+}
+
+void ProcessState::childPostFork() {
+    // another thread might call fork before gProcess is instantiated, but after
+    // the thread handler is installed
+    if (gProcess) {
+        gProcess->mForked = true;
+    }
+    gProcessMutex.unlock();
+}
+
 void ProcessState::startThreadPool()
 {
     AutoMutex _l(mLock);
@@ -211,7 +247,7 @@
     binder_node_info_for_ref info;
     memset(&info, 0, sizeof(binder_node_info_for_ref));
 
-    info.handle = binder->getPrivateAccessorForId().binderHandle();
+    info.handle = binder->getPrivateAccessor().binderHandle();
 
     status_t result = ioctl(mDriverFD, BINDER_GET_NODE_INFO_FOR_REF, &info);
 
@@ -300,7 +336,7 @@
                    return nullptr;
             }
 
-            sp<BpBinder> b = BpBinder::create(handle);
+            sp<BpBinder> b = BpBinder::PrivateAccessor::create(handle);
             e->binder = b.get();
             if (b) e->refs = b->getWeakRefs();
             result = b;
@@ -359,6 +395,14 @@
     return result;
 }
 
+size_t ProcessState::getThreadPoolMaxThreadCount() const {
+    // may actually be one more than this, if join is called
+    if (mThreadPoolStarted) return mMaxThreads;
+    // must not be initialized or maybe has poll thread setup, we
+    // currently don't track this in libbinder
+    return 0;
+}
+
 status_t ProcessState::enableOnewaySpamDetection(bool enable) {
     uint32_t enableDetection = enable ? 1 : 0;
     if (ioctl(mDriverFD, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enableDetection) == -1) {
@@ -376,68 +420,74 @@
     return mDriverName;
 }
 
-static int open_driver(const char *driver)
-{
+static base::Result<int> open_driver(const char* driver) {
     int fd = open(driver, O_RDWR | O_CLOEXEC);
-    if (fd >= 0) {
-        int vers = 0;
-        status_t result = ioctl(fd, BINDER_VERSION, &vers);
-        if (result == -1) {
-            ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
-            close(fd);
-            fd = -1;
-        }
-        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
-          ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
-                vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
-            close(fd);
-            fd = -1;
-        }
-        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
-        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
-        if (result == -1) {
-            ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
-        }
-        uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
-        result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
-        if (result == -1) {
-            ALOGD("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
-        }
-    } else {
-        ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
+    if (fd < 0) {
+        return base::ErrnoError() << "Opening '" << driver << "' failed";
+    }
+    int vers = 0;
+    status_t result = ioctl(fd, BINDER_VERSION, &vers);
+    if (result == -1) {
+        close(fd);
+        return base::ErrnoError() << "Binder ioctl to obtain version failed";
+    }
+    if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
+        close(fd);
+        return base::Error() << "Binder driver protocol(" << vers
+                             << ") does not match user space protocol("
+                             << BINDER_CURRENT_PROTOCOL_VERSION
+                             << ")! ioctl() return value: " << result;
+    }
+    size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
+    result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
+    if (result == -1) {
+        ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
+    }
+    uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
+    result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
+    if (result == -1) {
+        ALOGV("Binder ioctl to enable oneway spam detection failed: %s", strerror(errno));
     }
     return fd;
 }
 
-ProcessState::ProcessState(const char *driver)
-    : mDriverName(String8(driver))
-    , mDriverFD(open_driver(driver))
-    , mVMStart(MAP_FAILED)
-    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
-    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
-    , mExecutingThreadsCount(0)
-    , mWaitingForThreads(0)
-    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
-    , mStarvationStartTimeMs(0)
-    , mThreadPoolStarted(false)
-    , mThreadPoolSeq(1)
-    , mCallRestriction(CallRestriction::NONE)
-{
-    if (mDriverFD >= 0) {
+ProcessState::ProcessState(const char* driver)
+      : mDriverName(String8(driver)),
+        mDriverFD(-1),
+        mVMStart(MAP_FAILED),
+        mThreadCountLock(PTHREAD_MUTEX_INITIALIZER),
+        mThreadCountDecrement(PTHREAD_COND_INITIALIZER),
+        mExecutingThreadsCount(0),
+        mWaitingForThreads(0),
+        mMaxThreads(DEFAULT_MAX_BINDER_THREADS),
+        mStarvationStartTimeMs(0),
+        mForked(false),
+        mThreadPoolStarted(false),
+        mThreadPoolSeq(1),
+        mCallRestriction(CallRestriction::NONE) {
+    base::Result<int> opened = open_driver(driver);
+
+    if (opened.ok()) {
         // mmap the binder, providing a chunk of virtual address space to receive transactions.
-        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
+        mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE,
+                        opened.value(), 0);
         if (mVMStart == MAP_FAILED) {
+            close(opened.value());
             // *sigh*
-            ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
-            close(mDriverFD);
-            mDriverFD = -1;
+            opened = base::Error()
+                    << "Using " << driver << " failed: unable to mmap transaction memory.";
             mDriverName.clear();
         }
     }
 
 #ifdef __ANDROID__
-    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver '%s' could not be opened.  Terminating.", driver);
+    LOG_ALWAYS_FATAL_IF(!opened.ok(), "Binder driver '%s' could not be opened. Terminating: %s",
+                        driver, opened.error().message().c_str());
 #endif
+
+    if (opened.ok()) {
+        mDriverFD = opened.value();
+    }
 }
 
 ProcessState::~ProcessState()
diff --git a/libs/binder/RpcAddress.cpp b/libs/binder/RpcAddress.cpp
deleted file mode 100644
index 5c32320..0000000
--- a/libs/binder/RpcAddress.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <binder/RpcAddress.h>
-
-#include <binder/Parcel.h>
-
-#include "Debug.h"
-#include "RpcState.h"
-#include "RpcWireFormat.h"
-
-namespace android {
-
-RpcAddress RpcAddress::zero() {
-    return RpcAddress();
-}
-
-bool RpcAddress::isZero() const {
-    RpcWireAddress ZERO{0};
-    return memcmp(mRawAddr.get(), &ZERO, sizeof(RpcWireAddress)) == 0;
-}
-
-static void ReadRandomBytes(uint8_t* buf, size_t len) {
-    int fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW));
-    if (fd == -1) {
-        ALOGE("%s: cannot read /dev/urandom", __func__);
-        return;
-    }
-
-    size_t n;
-    while ((n = TEMP_FAILURE_RETRY(read(fd, buf, len))) > 0) {
-        len -= n;
-        buf += n;
-    }
-    if (len > 0) {
-        ALOGW("%s: there are %d bytes skipped", __func__, (int)len);
-    }
-    close(fd);
-}
-
-RpcAddress RpcAddress::unique() {
-    RpcAddress ret;
-    ReadRandomBytes((uint8_t*)ret.mRawAddr.get(), sizeof(RpcWireAddress));
-    LOG_RPC_DETAIL("Creating new address: %s", ret.toString().c_str());
-    return ret;
-}
-
-RpcAddress RpcAddress::fromRawEmbedded(const RpcWireAddress* raw) {
-    RpcAddress addr;
-    memcpy(addr.mRawAddr.get(), raw, sizeof(RpcWireAddress));
-    return addr;
-}
-
-const RpcWireAddress& RpcAddress::viewRawEmbedded() const {
-    return *mRawAddr.get();
-}
-
-bool RpcAddress::operator<(const RpcAddress& rhs) const {
-    return std::memcmp(mRawAddr.get(), rhs.mRawAddr.get(), sizeof(RpcWireAddress)) < 0;
-}
-
-std::string RpcAddress::toString() const {
-    return hexString(mRawAddr.get(), sizeof(RpcWireAddress));
-}
-
-status_t RpcAddress::writeToParcel(Parcel* parcel) const {
-    return parcel->write(mRawAddr.get(), sizeof(RpcWireAddress));
-}
-
-status_t RpcAddress::readFromParcel(const Parcel& parcel) {
-    return parcel.read(mRawAddr.get(), sizeof(RpcWireAddress));
-}
-
-RpcAddress::~RpcAddress() {}
-RpcAddress::RpcAddress() : mRawAddr(std::make_shared<RpcWireAddress>()) {}
-
-} // namespace android
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index 9cc6e7f..93ed50e 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -16,57 +16,67 @@
 
 #define LOG_TAG "RpcServer"
 
+#include <inttypes.h>
+#include <poll.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 
 #include <thread>
 #include <vector>
 
+#include <android-base/file.h>
+#include <android-base/hex.h>
 #include <android-base/scopeguard.h>
 #include <binder/Parcel.h>
 #include <binder/RpcServer.h>
+#include <binder/RpcTransportRaw.h>
 #include <log/log.h>
-#include "RpcState.h"
 
+#include "FdTrigger.h"
 #include "RpcSocketAddress.h"
+#include "RpcState.h"
 #include "RpcWireFormat.h"
 
 namespace android {
 
+constexpr size_t kSessionIdBytes = 32;
+
 using base::ScopeGuard;
 using base::unique_fd;
 
-RpcServer::RpcServer() {}
-RpcServer::~RpcServer() {}
-
-sp<RpcServer> RpcServer::make() {
-    return sp<RpcServer>::make();
+RpcServer::RpcServer(std::unique_ptr<RpcTransportCtx> ctx) : mCtx(std::move(ctx)) {}
+RpcServer::~RpcServer() {
+    (void)shutdown();
 }
 
-void RpcServer::iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction() {
-    mAgreedExperimental = true;
+sp<RpcServer> RpcServer::make(std::unique_ptr<RpcTransportCtxFactory> rpcTransportCtxFactory) {
+    // Default is without TLS.
+    if (rpcTransportCtxFactory == nullptr)
+        rpcTransportCtxFactory = RpcTransportCtxFactoryRaw::make();
+    auto ctx = rpcTransportCtxFactory->newServerCtx();
+    if (ctx == nullptr) return nullptr;
+    return sp<RpcServer>::make(std::move(ctx));
 }
 
-bool RpcServer::setupUnixDomainServer(const char* path) {
+status_t RpcServer::setupUnixDomainServer(const char* path) {
     return setupSocketServer(UnixSocketAddress(path));
 }
 
-bool RpcServer::setupVsockServer(unsigned int port) {
+status_t RpcServer::setupVsockServer(unsigned int port) {
     // realizing value w/ this type at compile time to avoid ubsan abort
     constexpr unsigned int kAnyCid = VMADDR_CID_ANY;
 
     return setupSocketServer(VsockSocketAddress(kAnyCid, port));
 }
 
-bool RpcServer::setupInetServer(unsigned int port, unsigned int* assignedPort) {
-    const char* kAddr = "127.0.0.1";
-
+status_t RpcServer::setupInetServer(const char* address, unsigned int port,
+                                    unsigned int* assignedPort) {
     if (assignedPort != nullptr) *assignedPort = 0;
-    auto aiStart = InetSocketAddress::getAddrInfo(kAddr, port);
-    if (aiStart == nullptr) return false;
+    auto aiStart = InetSocketAddress::getAddrInfo(address, port);
+    if (aiStart == nullptr) return UNKNOWN_ERROR;
     for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
-        InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, kAddr, port);
-        if (!setupSocketServer(socketAddress)) {
+        InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, address, port);
+        if (status_t status = setupSocketServer(socketAddress); status != OK) {
             continue;
         }
 
@@ -77,7 +87,7 @@
             int savedErrno = errno;
             ALOGE("Could not getsockname at %s: %s", socketAddress.toString().c_str(),
                   strerror(savedErrno));
-            return false;
+            return -savedErrno;
         }
         LOG_ALWAYS_FATAL_IF(len != sizeof(addr), "Wrong socket type: len %zu vs len %zu",
                             static_cast<size_t>(len), sizeof(addr));
@@ -90,16 +100,16 @@
             *assignedPort = realPort;
         }
 
-        return true;
+        return OK;
     }
-    ALOGE("None of the socket address resolved for %s:%u can be set up as inet server.", kAddr,
+    ALOGE("None of the socket address resolved for %s:%u can be set up as inet server.", address,
           port);
-    return false;
+    return UNKNOWN_ERROR;
 }
 
 void RpcServer::setMaxThreads(size_t threads) {
     LOG_ALWAYS_FATAL_IF(threads <= 0, "RpcServer is useless without threads");
-    LOG_ALWAYS_FATAL_IF(mStarted, "must be called before started");
+    LOG_ALWAYS_FATAL_IF(mJoinThreadRunning, "Cannot set max threads while running");
     mMaxThreads = threads;
 }
 
@@ -107,16 +117,29 @@
     return mMaxThreads;
 }
 
+void RpcServer::setProtocolVersion(uint32_t version) {
+    mProtocolVersion = version;
+}
+
 void RpcServer::setRootObject(const sp<IBinder>& binder) {
     std::lock_guard<std::mutex> _l(mLock);
+    mRootObjectFactory = nullptr;
     mRootObjectWeak = mRootObject = binder;
 }
 
 void RpcServer::setRootObjectWeak(const wp<IBinder>& binder) {
     std::lock_guard<std::mutex> _l(mLock);
     mRootObject.clear();
+    mRootObjectFactory = nullptr;
     mRootObjectWeak = binder;
 }
+void RpcServer::setPerSessionRootObject(
+        std::function<sp<IBinder>(const sockaddr*, socklen_t)>&& makeObject) {
+    std::lock_guard<std::mutex> _l(mLock);
+    mRootObject.clear();
+    mRootObjectWeak.clear();
+    mRootObjectFactory = std::move(makeObject);
+}
 
 sp<IBinder> RpcServer::getRootObject() {
     std::lock_guard<std::mutex> _l(mLock);
@@ -126,33 +149,105 @@
     return ret;
 }
 
-void RpcServer::join() {
-    while (true) {
-        (void)acceptOne();
-    }
+std::vector<uint8_t> RpcServer::getCertificate(RpcCertificateFormat format) {
+    std::lock_guard<std::mutex> _l(mLock);
+    return mCtx->getCertificate(format);
 }
 
-bool RpcServer::acceptOne() {
-    LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
-    LOG_ALWAYS_FATAL_IF(!hasServer(), "RpcServer must be setup to join.");
+static void joinRpcServer(sp<RpcServer>&& thiz) {
+    thiz->join();
+}
 
-    unique_fd clientFd(
-            TEMP_FAILURE_RETRY(accept4(mServer.get(), nullptr, nullptr /*length*/, SOCK_CLOEXEC)));
+void RpcServer::start() {
+    std::lock_guard<std::mutex> _l(mLock);
+    LOG_ALWAYS_FATAL_IF(mJoinThread.get(), "Already started!");
+    mJoinThread = std::make_unique<std::thread>(&joinRpcServer, sp<RpcServer>::fromExisting(this));
+}
 
-    if (clientFd < 0) {
-        ALOGE("Could not accept4 socket: %s", strerror(errno));
-        return false;
-    }
-    LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
+void RpcServer::join() {
 
     {
         std::lock_guard<std::mutex> _l(mLock);
-        std::thread thread =
-                std::thread(&RpcServer::establishConnection, this,
-                            std::move(sp<RpcServer>::fromExisting(this)), std::move(clientFd));
-        mConnectingThreads[thread.get_id()] = std::move(thread);
+        LOG_ALWAYS_FATAL_IF(!mServer.ok(), "RpcServer must be setup to join.");
+        LOG_ALWAYS_FATAL_IF(mShutdownTrigger != nullptr, "Already joined");
+        mJoinThreadRunning = true;
+        mShutdownTrigger = FdTrigger::make();
+        LOG_ALWAYS_FATAL_IF(mShutdownTrigger == nullptr, "Cannot create join signaler");
     }
 
+    status_t status;
+    while ((status = mShutdownTrigger->triggerablePoll(mServer, POLLIN)) == OK) {
+        sockaddr_storage addr;
+        socklen_t addrLen = sizeof(addr);
+
+        unique_fd clientFd(
+                TEMP_FAILURE_RETRY(accept4(mServer.get(), reinterpret_cast<sockaddr*>(&addr),
+                                           &addrLen, SOCK_CLOEXEC | SOCK_NONBLOCK)));
+
+        LOG_ALWAYS_FATAL_IF(addrLen > static_cast<socklen_t>(sizeof(addr)), "Truncated address");
+
+        if (clientFd < 0) {
+            ALOGE("Could not accept4 socket: %s", strerror(errno));
+            continue;
+        }
+        LOG_RPC_DETAIL("accept4 on fd %d yields fd %d", mServer.get(), clientFd.get());
+
+        {
+            std::lock_guard<std::mutex> _l(mLock);
+            std::thread thread =
+                    std::thread(&RpcServer::establishConnection, sp<RpcServer>::fromExisting(this),
+                                std::move(clientFd), addr, addrLen);
+            mConnectingThreads[thread.get_id()] = std::move(thread);
+        }
+    }
+    LOG_RPC_DETAIL("RpcServer::join exiting with %s", statusToString(status).c_str());
+
+    {
+        std::lock_guard<std::mutex> _l(mLock);
+        mJoinThreadRunning = false;
+    }
+    mShutdownCv.notify_all();
+}
+
+bool RpcServer::shutdown() {
+    std::unique_lock<std::mutex> _l(mLock);
+    if (mShutdownTrigger == nullptr) {
+        LOG_RPC_DETAIL("Cannot shutdown. No shutdown trigger installed (already shutdown?)");
+        return false;
+    }
+
+    mShutdownTrigger->trigger();
+
+    for (auto& [id, session] : mSessions) {
+        (void)id;
+        // server lock is a more general lock
+        std::lock_guard<std::mutex> _lSession(session->mMutex);
+        session->mShutdownTrigger->trigger();
+    }
+
+    while (mJoinThreadRunning || !mConnectingThreads.empty() || !mSessions.empty()) {
+        if (std::cv_status::timeout == mShutdownCv.wait_for(_l, std::chrono::seconds(1))) {
+            ALOGE("Waiting for RpcServer to shut down (1s w/o progress). Join thread running: %d, "
+                  "Connecting threads: "
+                  "%zu, Sessions: %zu. Is your server deadlocked?",
+                  mJoinThreadRunning, mConnectingThreads.size(), mSessions.size());
+        }
+    }
+
+    // At this point, we know join() is about to exit, but the thread that calls
+    // join() may not have exited yet.
+    // If RpcServer owns the join thread (aka start() is called), make sure the thread exits;
+    // otherwise ~thread() may call std::terminate(), which may crash the process.
+    // If RpcServer does not own the join thread (aka join() is called directly),
+    // then the owner of RpcServer is responsible for cleaning up that thread.
+    if (mJoinThread.get()) {
+        mJoinThread->join();
+        mJoinThread.reset();
+    }
+
+    LOG_RPC_DETAIL("Finished waiting on shutdown.");
+
+    mShutdownTrigger = nullptr;
     return true;
 }
 
@@ -171,127 +266,254 @@
     return mConnectingThreads.size();
 }
 
-void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clientFd) {
-    LOG_ALWAYS_FATAL_IF(this != server.get(), "Must pass same ownership object");
+void RpcServer::establishConnection(sp<RpcServer>&& server, base::unique_fd clientFd,
+                                    const sockaddr_storage addr, socklen_t addrLen) {
+    // mShutdownTrigger can only be cleared once connection threads have joined.
+    // It must be set before this thread is started
+    LOG_ALWAYS_FATAL_IF(server->mShutdownTrigger == nullptr);
+    LOG_ALWAYS_FATAL_IF(server->mCtx == nullptr);
 
-    // TODO(b/183988761): cannot trust this simple ID
-    LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
-    bool idValid = true;
-    int32_t id;
-    if (sizeof(id) != read(clientFd.get(), &id, sizeof(id))) {
-        ALOGE("Could not read ID from fd %d", clientFd.get());
-        idValid = false;
+    status_t status = OK;
+
+    int clientFdForLog = clientFd.get();
+    auto client = server->mCtx->newTransport(std::move(clientFd), server->mShutdownTrigger.get());
+    if (client == nullptr) {
+        ALOGE("Dropping accept4()-ed socket because sslAccept fails");
+        status = DEAD_OBJECT;
+        // still need to cleanup before we can return
+    } else {
+        LOG_RPC_DETAIL("Created RpcTransport %p for client fd %d", client.get(), clientFdForLog);
+    }
+
+    RpcConnectionHeader header;
+    if (status == OK) {
+        status = client->interruptableReadFully(server->mShutdownTrigger.get(), &header,
+                                                sizeof(header), {});
+        if (status != OK) {
+            ALOGE("Failed to read ID for client connecting to RPC server: %s",
+                  statusToString(status).c_str());
+            // still need to cleanup before we can return
+        }
+    }
+
+    std::vector<uint8_t> sessionId;
+    if (status == OK) {
+        if (header.sessionIdSize > 0) {
+            if (header.sessionIdSize == kSessionIdBytes) {
+                sessionId.resize(header.sessionIdSize);
+                status = client->interruptableReadFully(server->mShutdownTrigger.get(),
+                                                        sessionId.data(), sessionId.size(), {});
+                if (status != OK) {
+                    ALOGE("Failed to read session ID for client connecting to RPC server: %s",
+                          statusToString(status).c_str());
+                    // still need to cleanup before we can return
+                }
+            } else {
+                ALOGE("Malformed session ID. Expecting session ID of size %zu but got %" PRIu16,
+                      kSessionIdBytes, header.sessionIdSize);
+                status = BAD_VALUE;
+            }
+        }
+    }
+
+    bool incoming = false;
+    uint32_t protocolVersion = 0;
+    bool requestingNewSession = false;
+
+    if (status == OK) {
+        incoming = header.options & RPC_CONNECTION_OPTION_INCOMING;
+        protocolVersion = std::min(header.version,
+                                   server->mProtocolVersion.value_or(RPC_WIRE_PROTOCOL_VERSION));
+        requestingNewSession = sessionId.empty();
+
+        if (requestingNewSession) {
+            RpcNewSessionResponse response{
+                    .version = protocolVersion,
+            };
+
+            status = client->interruptableWriteFully(server->mShutdownTrigger.get(), &response,
+                                                     sizeof(response), {});
+            if (status != OK) {
+                ALOGE("Failed to send new session response: %s", statusToString(status).c_str());
+                // still need to cleanup before we can return
+            }
+        }
     }
 
     std::thread thisThread;
     sp<RpcSession> session;
     {
-        std::lock_guard<std::mutex> _l(mLock);
+        std::unique_lock<std::mutex> _l(server->mLock);
 
-        auto threadId = mConnectingThreads.find(std::this_thread::get_id());
-        LOG_ALWAYS_FATAL_IF(threadId == mConnectingThreads.end(),
+        auto threadId = server->mConnectingThreads.find(std::this_thread::get_id());
+        LOG_ALWAYS_FATAL_IF(threadId == server->mConnectingThreads.end(),
                             "Must establish connection on owned thread");
         thisThread = std::move(threadId->second);
-        ScopeGuard detachGuard = [&]() { thisThread.detach(); };
-        mConnectingThreads.erase(threadId);
+        ScopeGuard detachGuard = [&]() {
+            thisThread.detach();
+            _l.unlock();
+            server->mShutdownCv.notify_all();
+        };
+        server->mConnectingThreads.erase(threadId);
 
-        if (!idValid) {
+        if (status != OK || server->mShutdownTrigger->isTriggered()) {
             return;
         }
 
-        if (id == RPC_SESSION_ID_NEW) {
-            LOG_ALWAYS_FATAL_IF(mSessionIdCounter >= INT32_MAX, "Out of session IDs");
-            mSessionIdCounter++;
+        if (requestingNewSession) {
+            if (incoming) {
+                ALOGE("Cannot create a new session with an incoming connection, would leak");
+                return;
+            }
+
+            // Uniquely identify session at the application layer. Even if a
+            // client/server use the same certificates, if they create multiple
+            // sessions, we still want to distinguish between them.
+            sessionId.resize(kSessionIdBytes);
+            size_t tries = 0;
+            do {
+                // don't block if there is some entropy issue
+                if (tries++ > 5) {
+                    ALOGE("Cannot find new address: %s",
+                          base::HexString(sessionId.data(), sessionId.size()).c_str());
+                    return;
+                }
+
+                base::unique_fd fd(TEMP_FAILURE_RETRY(
+                        open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW)));
+                if (!base::ReadFully(fd, sessionId.data(), sessionId.size())) {
+                    ALOGE("Could not read from /dev/urandom to create session ID");
+                    return;
+                }
+            } while (server->mSessions.end() != server->mSessions.find(sessionId));
 
             session = RpcSession::make();
-            session->setForServer(wp<RpcServer>::fromExisting(this), mSessionIdCounter);
+            session->setMaxIncomingThreads(server->mMaxThreads);
+            if (!session->setProtocolVersion(protocolVersion)) return;
 
-            mSessions[mSessionIdCounter] = session;
+            // if null, falls back to server root
+            sp<IBinder> sessionSpecificRoot;
+            if (server->mRootObjectFactory != nullptr) {
+                sessionSpecificRoot =
+                        server->mRootObjectFactory(reinterpret_cast<const sockaddr*>(&addr),
+                                                   addrLen);
+                if (sessionSpecificRoot == nullptr) {
+                    ALOGE("Warning: server returned null from root object factory");
+                }
+            }
+
+            if (!session->setForServer(server,
+                                       sp<RpcServer::EventListener>::fromExisting(
+                                               static_cast<RpcServer::EventListener*>(
+                                                       server.get())),
+                                       sessionId, sessionSpecificRoot)) {
+                ALOGE("Failed to attach server to session");
+                return;
+            }
+
+            server->mSessions[sessionId] = session;
         } else {
-            auto it = mSessions.find(id);
-            if (it == mSessions.end()) {
-                ALOGE("Cannot add thread, no record of session with ID %d", id);
+            auto it = server->mSessions.find(sessionId);
+            if (it == server->mSessions.end()) {
+                ALOGE("Cannot add thread, no record of session with ID %s",
+                      base::HexString(sessionId.data(), sessionId.size()).c_str());
                 return;
             }
             session = it->second;
         }
 
+        if (incoming) {
+            LOG_ALWAYS_FATAL_IF(OK != session->addOutgoingConnection(std::move(client), true),
+                                "server state must already be initialized");
+            return;
+        }
+
         detachGuard.Disable();
-        session->preJoin(std::move(thisThread));
+        session->preJoinThreadOwnership(std::move(thisThread));
     }
 
+    auto setupResult = session->preJoinSetup(std::move(client));
+
     // avoid strong cycle
     server = nullptr;
-    //
-    //
-    // DO NOT ACCESS MEMBER VARIABLES BELOW
-    //
 
-    session->join(std::move(clientFd));
+    RpcSession::join(std::move(session), std::move(setupResult));
 }
 
-bool RpcServer::setupSocketServer(const RpcSocketAddress& addr) {
+status_t RpcServer::setupSocketServer(const RpcSocketAddress& addr) {
     LOG_RPC_DETAIL("Setting up socket server %s", addr.toString().c_str());
     LOG_ALWAYS_FATAL_IF(hasServer(), "Each RpcServer can only have one server.");
 
-    unique_fd serverFd(
-            TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
+    unique_fd serverFd(TEMP_FAILURE_RETRY(
+            socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)));
     if (serverFd == -1) {
-        ALOGE("Could not create socket: %s", strerror(errno));
-        return false;
+        int savedErrno = errno;
+        ALOGE("Could not create socket: %s", strerror(savedErrno));
+        return -savedErrno;
     }
 
     if (0 != TEMP_FAILURE_RETRY(bind(serverFd.get(), addr.addr(), addr.addrSize()))) {
         int savedErrno = errno;
         ALOGE("Could not bind socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
-        return false;
+        return -savedErrno;
     }
 
-    if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/))) {
+    // Right now, we create all threads at once, making accept4 slow. To avoid hanging the client,
+    // the backlog is increased to a large number.
+    // TODO(b/189955605): Once we create threads dynamically & lazily, the backlog can be reduced
+    //  to 1.
+    if (0 != TEMP_FAILURE_RETRY(listen(serverFd.get(), 50 /*backlog*/))) {
         int savedErrno = errno;
         ALOGE("Could not listen socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
-        return false;
+        return -savedErrno;
     }
 
     LOG_RPC_DETAIL("Successfully setup socket server %s", addr.toString().c_str());
 
-    mServer = std::move(serverFd);
-    return true;
+    if (status_t status = setupExternalServer(std::move(serverFd)); status != OK) {
+        ALOGE("Another thread has set up server while calling setupSocketServer. Race?");
+        return status;
+    }
+    return OK;
 }
 
-void RpcServer::onSessionTerminating(const sp<RpcSession>& session) {
-    auto id = session->mId;
-    LOG_ALWAYS_FATAL_IF(id == std::nullopt, "Server sessions must be initialized with ID");
-    LOG_RPC_DETAIL("Dropping session %d", *id);
+void RpcServer::onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) {
+    const std::vector<uint8_t>& id = session->mId;
+    LOG_ALWAYS_FATAL_IF(id.empty(), "Server sessions must be initialized with ID");
+    LOG_RPC_DETAIL("Dropping session with address %s",
+                   base::HexString(id.data(), id.size()).c_str());
 
     std::lock_guard<std::mutex> _l(mLock);
-    auto it = mSessions.find(*id);
-    LOG_ALWAYS_FATAL_IF(it == mSessions.end(), "Bad state, unknown session id %d", *id);
-    LOG_ALWAYS_FATAL_IF(it->second != session, "Bad state, session has id mismatch %d", *id);
+    auto it = mSessions.find(id);
+    LOG_ALWAYS_FATAL_IF(it == mSessions.end(), "Bad state, unknown session id %s",
+                        base::HexString(id.data(), id.size()).c_str());
+    LOG_ALWAYS_FATAL_IF(it->second != session, "Bad state, session has id mismatch %s",
+                        base::HexString(id.data(), id.size()).c_str());
     (void)mSessions.erase(it);
 }
 
+void RpcServer::onSessionIncomingThreadEnded() {
+    mShutdownCv.notify_all();
+}
+
 bool RpcServer::hasServer() {
-    LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
     std::lock_guard<std::mutex> _l(mLock);
     return mServer.ok();
 }
 
 unique_fd RpcServer::releaseServer() {
-    LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
     std::lock_guard<std::mutex> _l(mLock);
     return std::move(mServer);
 }
 
-bool RpcServer::setupExternalServer(base::unique_fd serverFd) {
-    LOG_ALWAYS_FATAL_IF(!mAgreedExperimental, "no!");
+status_t RpcServer::setupExternalServer(base::unique_fd serverFd) {
     std::lock_guard<std::mutex> _l(mLock);
     if (mServer.ok()) {
         ALOGE("Each RpcServer can only have one server.");
-        return false;
+        return INVALID_OPERATION;
     }
     mServer = std::move(serverFd);
-    return true;
+    return OK;
 }
 
 } // namespace android
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 05fa49e..a5a2bb1 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -18,99 +18,234 @@
 
 #include <binder/RpcSession.h>
 
+#include <dlfcn.h>
 #include <inttypes.h>
+#include <poll.h>
+#include <pthread.h>
 #include <unistd.h>
 
 #include <string_view>
 
+#include <android-base/hex.h>
+#include <android-base/macros.h>
+#include <android-base/scopeguard.h>
+#include <binder/BpBinder.h>
 #include <binder/Parcel.h>
 #include <binder/RpcServer.h>
+#include <binder/RpcTransportRaw.h>
 #include <binder/Stability.h>
 #include <utils/String8.h>
 
+#include "FdTrigger.h"
 #include "RpcSocketAddress.h"
 #include "RpcState.h"
 #include "RpcWireFormat.h"
+#include "Utils.h"
 
 #ifdef __GLIBC__
 extern "C" pid_t gettid();
 #endif
 
+#ifndef __ANDROID_RECOVERY__
+#include <android_runtime/vm.h>
+#include <jni.h>
+#endif
+
 namespace android {
 
 using base::unique_fd;
 
-RpcSession::RpcSession() {
+RpcSession::RpcSession(std::unique_ptr<RpcTransportCtx> ctx) : mCtx(std::move(ctx)) {
     LOG_RPC_DETAIL("RpcSession created %p", this);
 
-    mState = std::make_unique<RpcState>();
+    mRpcBinderState = std::make_unique<RpcState>();
 }
 RpcSession::~RpcSession() {
     LOG_RPC_DETAIL("RpcSession destroyed %p", this);
 
     std::lock_guard<std::mutex> _l(mMutex);
-    LOG_ALWAYS_FATAL_IF(mServerConnections.size() != 0,
+    LOG_ALWAYS_FATAL_IF(mConnections.mIncoming.size() != 0,
                         "Should not be able to destroy a session with servers in use.");
 }
 
 sp<RpcSession> RpcSession::make() {
-    return sp<RpcSession>::make();
+    // Default is without TLS.
+    return make(RpcTransportCtxFactoryRaw::make());
 }
 
-bool RpcSession::setupUnixDomainClient(const char* path) {
-    return setupSocketClient(UnixSocketAddress(path));
+sp<RpcSession> RpcSession::make(std::unique_ptr<RpcTransportCtxFactory> rpcTransportCtxFactory) {
+    auto ctx = rpcTransportCtxFactory->newClientCtx();
+    if (ctx == nullptr) return nullptr;
+    return sp<RpcSession>::make(std::move(ctx));
 }
 
-bool RpcSession::setupVsockClient(unsigned int cid, unsigned int port) {
-    return setupSocketClient(VsockSocketAddress(cid, port));
+void RpcSession::setMaxIncomingThreads(size_t threads) {
+    std::lock_guard<std::mutex> _l(mMutex);
+    LOG_ALWAYS_FATAL_IF(!mConnections.mOutgoing.empty() || !mConnections.mIncoming.empty(),
+                        "Must set max incoming threads before setting up connections, but has %zu "
+                        "client(s) and %zu server(s)",
+                        mConnections.mOutgoing.size(), mConnections.mIncoming.size());
+    mMaxIncomingThreads = threads;
 }
 
-bool RpcSession::setupInetClient(const char* addr, unsigned int port) {
-    auto aiStart = InetSocketAddress::getAddrInfo(addr, port);
-    if (aiStart == nullptr) return false;
-    for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
-        InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, addr, port);
-        if (setupSocketClient(socketAddress)) return true;
-    }
-    ALOGE("None of the socket address resolved for %s:%u can be added as inet client.", addr, port);
-    return false;
+size_t RpcSession::getMaxIncomingThreads() {
+    std::lock_guard<std::mutex> _l(mMutex);
+    return mMaxIncomingThreads;
 }
 
-bool RpcSession::addNullDebuggingClient() {
-    unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));
+void RpcSession::setMaxOutgoingThreads(size_t threads) {
+    std::lock_guard<std::mutex> _l(mMutex);
+    LOG_ALWAYS_FATAL_IF(!mConnections.mOutgoing.empty() || !mConnections.mIncoming.empty(),
+                        "Must set max outgoing threads before setting up connections, but has %zu "
+                        "client(s) and %zu server(s)",
+                        mConnections.mOutgoing.size(), mConnections.mIncoming.size());
+    mMaxOutgoingThreads = threads;
+}
 
-    if (serverFd == -1) {
-        ALOGE("Could not connect to /dev/null: %s", strerror(errno));
+size_t RpcSession::getMaxOutgoingThreads() {
+    std::lock_guard<std::mutex> _l(mMutex);
+    return mMaxOutgoingThreads;
+}
+
+bool RpcSession::setProtocolVersion(uint32_t version) {
+    if (version >= RPC_WIRE_PROTOCOL_VERSION_NEXT &&
+        version != RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL) {
+        ALOGE("Cannot start RPC session with version %u which is unknown (current protocol version "
+              "is %u).",
+              version, RPC_WIRE_PROTOCOL_VERSION);
         return false;
     }
 
-    addClientConnection(std::move(serverFd));
+    std::lock_guard<std::mutex> _l(mMutex);
+    if (mProtocolVersion && version > *mProtocolVersion) {
+        ALOGE("Cannot upgrade explicitly capped protocol version %u to newer version %u",
+              *mProtocolVersion, version);
+        return false;
+    }
+
+    mProtocolVersion = version;
     return true;
 }
 
+std::optional<uint32_t> RpcSession::getProtocolVersion() {
+    std::lock_guard<std::mutex> _l(mMutex);
+    return mProtocolVersion;
+}
+
+status_t RpcSession::setupUnixDomainClient(const char* path) {
+    return setupSocketClient(UnixSocketAddress(path));
+}
+
+status_t RpcSession::setupVsockClient(unsigned int cid, unsigned int port) {
+    return setupSocketClient(VsockSocketAddress(cid, port));
+}
+
+status_t RpcSession::setupInetClient(const char* addr, unsigned int port) {
+    auto aiStart = InetSocketAddress::getAddrInfo(addr, port);
+    if (aiStart == nullptr) return UNKNOWN_ERROR;
+    for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
+        InetSocketAddress socketAddress(ai->ai_addr, ai->ai_addrlen, addr, port);
+        if (status_t status = setupSocketClient(socketAddress); status == OK) return OK;
+    }
+    ALOGE("None of the socket address resolved for %s:%u can be added as inet client.", addr, port);
+    return NAME_NOT_FOUND;
+}
+
+status_t RpcSession::setupPreconnectedClient(unique_fd fd, std::function<unique_fd()>&& request) {
+    return setupClient([&](const std::vector<uint8_t>& sessionId, bool incoming) -> status_t {
+        // std::move'd from fd becomes -1 (!ok())
+        if (!fd.ok()) {
+            fd = request();
+            if (!fd.ok()) return BAD_VALUE;
+        }
+        if (auto res = setNonBlocking(fd); !res.ok()) {
+            ALOGE("setupPreconnectedClient: %s", res.error().message().c_str());
+            return res.error().code() == 0 ? UNKNOWN_ERROR : -res.error().code();
+        }
+        return initAndAddConnection(std::move(fd), sessionId, incoming);
+    });
+}
+
+status_t RpcSession::addNullDebuggingClient() {
+    // Note: only works on raw sockets.
+    if (auto status = initShutdownTrigger(); status != OK) return status;
+
+    unique_fd serverFd(TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY | O_CLOEXEC)));
+
+    if (serverFd == -1) {
+        int savedErrno = errno;
+        ALOGE("Could not connect to /dev/null: %s", strerror(savedErrno));
+        return -savedErrno;
+    }
+
+    auto server = mCtx->newTransport(std::move(serverFd), mShutdownTrigger.get());
+    if (server == nullptr) {
+        ALOGE("Unable to set up RpcTransport");
+        return UNKNOWN_ERROR;
+    }
+    return addOutgoingConnection(std::move(server), false);
+}
+
 sp<IBinder> RpcSession::getRootObject() {
-    ExclusiveConnection connection(sp<RpcSession>::fromExisting(this), ConnectionUse::CLIENT);
-    return state()->getRootObject(connection.fd(), sp<RpcSession>::fromExisting(this));
+    ExclusiveConnection connection;
+    status_t status = ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+                                                ConnectionUse::CLIENT, &connection);
+    if (status != OK) return nullptr;
+    return state()->getRootObject(connection.get(), sp<RpcSession>::fromExisting(this));
 }
 
 status_t RpcSession::getRemoteMaxThreads(size_t* maxThreads) {
-    ExclusiveConnection connection(sp<RpcSession>::fromExisting(this), ConnectionUse::CLIENT);
-    return state()->getMaxThreads(connection.fd(), sp<RpcSession>::fromExisting(this), maxThreads);
+    ExclusiveConnection connection;
+    status_t status = ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+                                                ConnectionUse::CLIENT, &connection);
+    if (status != OK) return status;
+    return state()->getMaxThreads(connection.get(), sp<RpcSession>::fromExisting(this), maxThreads);
 }
 
-status_t RpcSession::transact(const RpcAddress& address, uint32_t code, const Parcel& data,
+bool RpcSession::shutdownAndWait(bool wait) {
+    std::unique_lock<std::mutex> _l(mMutex);
+    LOG_ALWAYS_FATAL_IF(mShutdownTrigger == nullptr, "Shutdown trigger not installed");
+
+    mShutdownTrigger->trigger();
+
+    if (wait) {
+        LOG_ALWAYS_FATAL_IF(mShutdownListener == nullptr, "Shutdown listener not installed");
+        mShutdownListener->waitForShutdown(_l, sp<RpcSession>::fromExisting(this));
+
+        LOG_ALWAYS_FATAL_IF(!mConnections.mThreads.empty(), "Shutdown failed");
+    }
+
+    _l.unlock();
+    mRpcBinderState->clear();
+
+    return true;
+}
+
+status_t RpcSession::transact(const sp<IBinder>& binder, uint32_t code, const Parcel& data,
                               Parcel* reply, uint32_t flags) {
-    ExclusiveConnection connection(sp<RpcSession>::fromExisting(this),
-                                   (flags & IBinder::FLAG_ONEWAY) ? ConnectionUse::CLIENT_ASYNC
-                                                                  : ConnectionUse::CLIENT);
-    return state()->transact(connection.fd(), address, code, data,
+    ExclusiveConnection connection;
+    status_t status =
+            ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+                                      (flags & IBinder::FLAG_ONEWAY) ? ConnectionUse::CLIENT_ASYNC
+                                                                     : ConnectionUse::CLIENT,
+                                      &connection);
+    if (status != OK) return status;
+    return state()->transact(connection.get(), binder, code, data,
                              sp<RpcSession>::fromExisting(this), reply, flags);
 }
 
-status_t RpcSession::sendDecStrong(const RpcAddress& address) {
-    ExclusiveConnection connection(sp<RpcSession>::fromExisting(this),
-                                   ConnectionUse::CLIENT_REFCOUNT);
-    return state()->sendDecStrong(connection.fd(), address);
+status_t RpcSession::sendDecStrong(const BpBinder* binder) {
+    // target is 0 because this is used to free BpBinder objects
+    return sendDecStrongToTarget(binder->getPrivateAccessor().rpcAddress(), 0 /*target*/);
+}
+
+status_t RpcSession::sendDecStrongToTarget(uint64_t address, size_t target) {
+    ExclusiveConnection connection;
+    status_t status = ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+                                                ConnectionUse::CLIENT_REFCOUNT, &connection);
+    if (status != OK) return status;
+    return state()->sendDecStrongToTarget(connection.get(), sp<RpcSession>::fromExisting(this),
+                                          address, target);
 }
 
 status_t RpcSession::readId() {
@@ -119,204 +254,550 @@
         LOG_ALWAYS_FATAL_IF(mForServer != nullptr, "Can only update ID for client.");
     }
 
-    int32_t id;
-
-    ExclusiveConnection connection(sp<RpcSession>::fromExisting(this), ConnectionUse::CLIENT);
-    status_t status =
-            state()->getSessionId(connection.fd(), sp<RpcSession>::fromExisting(this), &id);
+    ExclusiveConnection connection;
+    status_t status = ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+                                                ConnectionUse::CLIENT, &connection);
     if (status != OK) return status;
 
-    LOG_RPC_DETAIL("RpcSession %p has id %d", this, id);
-    mId = id;
+    status = state()->getSessionId(connection.get(), sp<RpcSession>::fromExisting(this), &mId);
+    if (status != OK) return status;
+
+    LOG_RPC_DETAIL("RpcSession %p has id %s", this,
+                   base::HexString(mId.data(), mId.size()).c_str());
     return OK;
 }
 
-void RpcSession::preJoin(std::thread thread) {
+void RpcSession::WaitForShutdownListener::onSessionAllIncomingThreadsEnded(
+        const sp<RpcSession>& session) {
+    (void)session;
+}
+
+void RpcSession::WaitForShutdownListener::onSessionIncomingThreadEnded() {
+    mCv.notify_all();
+}
+
+void RpcSession::WaitForShutdownListener::waitForShutdown(std::unique_lock<std::mutex>& lock,
+                                                          const sp<RpcSession>& session) {
+    while (session->mConnections.mIncoming.size() > 0) {
+        if (std::cv_status::timeout == mCv.wait_for(lock, std::chrono::seconds(1))) {
+            ALOGE("Waiting for RpcSession to shut down (1s w/o progress): %zu incoming connections "
+                  "still.",
+                  session->mConnections.mIncoming.size());
+        }
+    }
+}
+
+void RpcSession::preJoinThreadOwnership(std::thread thread) {
     LOG_ALWAYS_FATAL_IF(thread.get_id() != std::this_thread::get_id(), "Must own this thread");
 
     {
         std::lock_guard<std::mutex> _l(mMutex);
-        mThreads[thread.get_id()] = std::move(thread);
+        mConnections.mThreads[thread.get_id()] = std::move(thread);
     }
 }
 
-void RpcSession::join(unique_fd client) {
+RpcSession::PreJoinSetupResult RpcSession::preJoinSetup(
+        std::unique_ptr<RpcTransport> rpcTransport) {
     // must be registered to allow arbitrary client code executing commands to
     // be able to do nested calls (we can't only read from it)
-    sp<RpcConnection> connection = assignServerToThisThread(std::move(client));
+    sp<RpcConnection> connection = assignIncomingConnectionToThisThread(std::move(rpcTransport));
 
-    while (true) {
-        status_t error =
-                state()->getAndExecuteCommand(connection->fd, sp<RpcSession>::fromExisting(this));
+    status_t status;
 
-        if (error != OK) {
-            ALOGI("Binder connection thread closing w/ status %s", statusToString(error).c_str());
-            break;
+    if (connection == nullptr) {
+        status = DEAD_OBJECT;
+    } else {
+        status =
+                mRpcBinderState->readConnectionInit(connection, sp<RpcSession>::fromExisting(this));
+    }
+
+    return PreJoinSetupResult{
+            .connection = std::move(connection),
+            .status = status,
+    };
+}
+
+namespace {
+#ifdef __ANDROID_RECOVERY__
+class JavaThreadAttacher {};
+#else
+// RAII object for attaching / detaching current thread to JVM if Android Runtime exists. If
+// Android Runtime doesn't exist, no-op.
+class JavaThreadAttacher {
+public:
+    JavaThreadAttacher() {
+        // Use dlsym to find androidJavaAttachThread because libandroid_runtime is loaded after
+        // libbinder.
+        auto vm = getJavaVM();
+        if (vm == nullptr) return;
+
+        char threadName[16];
+        if (0 != pthread_getname_np(pthread_self(), threadName, sizeof(threadName))) {
+            constexpr const char* defaultThreadName = "UnknownRpcSessionThread";
+            memcpy(threadName, defaultThreadName,
+                   std::min<size_t>(sizeof(threadName), strlen(defaultThreadName) + 1));
+        }
+        LOG_RPC_DETAIL("Attaching current thread %s to JVM", threadName);
+        JavaVMAttachArgs args;
+        args.version = JNI_VERSION_1_2;
+        args.name = threadName;
+        args.group = nullptr;
+        JNIEnv* env;
+
+        LOG_ALWAYS_FATAL_IF(vm->AttachCurrentThread(&env, &args) != JNI_OK,
+                            "Cannot attach thread %s to JVM", threadName);
+        mAttached = true;
+    }
+    ~JavaThreadAttacher() {
+        if (!mAttached) return;
+        auto vm = getJavaVM();
+        LOG_ALWAYS_FATAL_IF(vm == nullptr,
+                            "Unable to detach thread. No JavaVM, but it was present before!");
+
+        LOG_RPC_DETAIL("Detaching current thread from JVM");
+        if (vm->DetachCurrentThread() != JNI_OK) {
+            mAttached = false;
+        } else {
+            ALOGW("Unable to detach current thread from JVM");
         }
     }
 
-    LOG_ALWAYS_FATAL_IF(!removeServerConnection(connection),
-                        "bad state: connection object guaranteed to be in list");
+private:
+    DISALLOW_COPY_AND_ASSIGN(JavaThreadAttacher);
+    bool mAttached = false;
 
+    static JavaVM* getJavaVM() {
+        static auto fn = reinterpret_cast<decltype(&AndroidRuntimeGetJavaVM)>(
+                dlsym(RTLD_DEFAULT, "AndroidRuntimeGetJavaVM"));
+        if (fn == nullptr) return nullptr;
+        return fn();
+    }
+};
+#endif
+} // namespace
+
+void RpcSession::join(sp<RpcSession>&& session, PreJoinSetupResult&& setupResult) {
+    sp<RpcConnection>& connection = setupResult.connection;
+
+    if (setupResult.status == OK) {
+        LOG_ALWAYS_FATAL_IF(!connection, "must have connection if setup succeeded");
+        [[maybe_unused]] JavaThreadAttacher javaThreadAttacher;
+        while (true) {
+            status_t status = session->state()->getAndExecuteCommand(connection, session,
+                                                                     RpcState::CommandType::ANY);
+            if (status != OK) {
+                LOG_RPC_DETAIL("Binder connection thread closing w/ status %s",
+                               statusToString(status).c_str());
+                break;
+            }
+        }
+    } else {
+        ALOGE("Connection failed to init, closing with status %s",
+              statusToString(setupResult.status).c_str());
+    }
+
+    sp<RpcSession::EventListener> listener;
     {
-        std::lock_guard<std::mutex> _l(mMutex);
-        auto it = mThreads.find(std::this_thread::get_id());
-        LOG_ALWAYS_FATAL_IF(it == mThreads.end());
+        std::lock_guard<std::mutex> _l(session->mMutex);
+        auto it = session->mConnections.mThreads.find(std::this_thread::get_id());
+        LOG_ALWAYS_FATAL_IF(it == session->mConnections.mThreads.end());
         it->second.detach();
-        mThreads.erase(it);
+        session->mConnections.mThreads.erase(it);
+
+        listener = session->mEventListener.promote();
+    }
+
+    // done after all cleanup, since session shutdown progresses via callbacks here
+    if (connection != nullptr) {
+        LOG_ALWAYS_FATAL_IF(!session->removeIncomingConnection(connection),
+                            "bad state: connection object guaranteed to be in list");
+    }
+
+    session = nullptr;
+
+    if (listener != nullptr) {
+        listener->onSessionIncomingThreadEnded();
     }
 }
 
-void RpcSession::terminateLocked() {
-    // TODO(b/185167543):
-    // - kindly notify other side of the connection of termination (can't be
-    // locked)
-    // - prevent new client/servers from being added
-    // - stop all threads which are currently reading/writing
-    // - terminate RpcState?
-
-    if (mTerminated) return;
-
+sp<RpcServer> RpcSession::server() {
+    RpcServer* unsafeServer = mForServer.unsafe_get();
     sp<RpcServer> server = mForServer.promote();
-    if (server) {
-        server->onSessionTerminating(sp<RpcSession>::fromExisting(this));
-    }
+
+    LOG_ALWAYS_FATAL_IF((unsafeServer == nullptr) != (server == nullptr),
+                        "wp<> is to avoid strong cycle only");
+    return server;
 }
 
-wp<RpcServer> RpcSession::server() {
-    return mForServer;
-}
-
-bool RpcSession::setupSocketClient(const RpcSocketAddress& addr) {
+status_t RpcSession::setupClient(const std::function<status_t(const std::vector<uint8_t>& sessionId,
+                                                              bool incoming)>& connectAndInit) {
     {
         std::lock_guard<std::mutex> _l(mMutex);
-        LOG_ALWAYS_FATAL_IF(mClientConnections.size() != 0,
+        LOG_ALWAYS_FATAL_IF(mConnections.mOutgoing.size() != 0,
                             "Must only setup session once, but already has %zu clients",
-                            mClientConnections.size());
+                            mConnections.mOutgoing.size());
     }
 
-    if (!setupOneSocketClient(addr, RPC_SESSION_ID_NEW)) return false;
+    if (auto status = initShutdownTrigger(); status != OK) return status;
 
-    // TODO(b/185167543): we should add additional sessions dynamically
+    auto oldProtocolVersion = mProtocolVersion;
+    auto cleanup = base::ScopeGuard([&] {
+        // if any threads are started, shut them down
+        (void)shutdownAndWait(true);
+
+        mShutdownListener = nullptr;
+        mEventListener.clear();
+
+        mId.clear();
+
+        mShutdownTrigger = nullptr;
+        mRpcBinderState = std::make_unique<RpcState>();
+
+        // protocol version may have been downgraded - if we reuse this object
+        // to connect to another server, force that server to request a
+        // downgrade again
+        mProtocolVersion = oldProtocolVersion;
+
+        mConnections = {};
+    });
+
+    if (status_t status = connectAndInit({}, false /*incoming*/); status != OK) return status;
+
+    {
+        ExclusiveConnection connection;
+        if (status_t status = ExclusiveConnection::find(sp<RpcSession>::fromExisting(this),
+                                                        ConnectionUse::CLIENT, &connection);
+            status != OK)
+            return status;
+
+        uint32_t version;
+        if (status_t status =
+                    state()->readNewSessionResponse(connection.get(),
+                                                    sp<RpcSession>::fromExisting(this), &version);
+            status != OK)
+            return status;
+        if (!setProtocolVersion(version)) return BAD_VALUE;
+    }
+
+    // TODO(b/189955605): we should add additional sessions dynamically
     // instead of all at once.
-    // TODO(b/186470974): first risk of blocking
     size_t numThreadsAvailable;
     if (status_t status = getRemoteMaxThreads(&numThreadsAvailable); status != OK) {
-        ALOGE("Could not get max threads after initial session to %s: %s", addr.toString().c_str(),
+        ALOGE("Could not get max threads after initial session setup: %s",
               statusToString(status).c_str());
-        return false;
+        return status;
     }
 
     if (status_t status = readId(); status != OK) {
-        ALOGE("Could not get session id after initial session to %s; %s", addr.toString().c_str(),
+        ALOGE("Could not get session id after initial session setup: %s",
               statusToString(status).c_str());
-        return false;
+        return status;
     }
 
+    size_t outgoingThreads = std::min(numThreadsAvailable, mMaxOutgoingThreads);
+    ALOGI_IF(outgoingThreads != numThreadsAvailable,
+             "Server hints client to start %zu outgoing threads, but client will only start %zu "
+             "because it is preconfigured to start at most %zu outgoing threads.",
+             numThreadsAvailable, outgoingThreads, mMaxOutgoingThreads);
+
+    // TODO(b/189955605): we should add additional sessions dynamically
+    // instead of all at once - the other side should be responsible for setting
+    // up additional connections. We need to create at least one (unless 0 are
+    // requested to be set) in order to allow the other side to reliably make
+    // any requests at all.
+
     // we've already setup one client
-    for (size_t i = 0; i + 1 < numThreadsAvailable; i++) {
-        // TODO(b/185167543): shutdown existing connections?
-        if (!setupOneSocketClient(addr, mId.value())) return false;
+    LOG_RPC_DETAIL("RpcSession::setupClient() instantiating %zu outgoing (server max: %zu) and %zu "
+                   "incoming threads",
+                   outgoingThreads, numThreadsAvailable, mMaxIncomingThreads);
+    for (size_t i = 0; i + 1 < outgoingThreads; i++) {
+        if (status_t status = connectAndInit(mId, false /*incoming*/); status != OK) return status;
     }
 
-    return true;
+    for (size_t i = 0; i < mMaxIncomingThreads; i++) {
+        if (status_t status = connectAndInit(mId, true /*incoming*/); status != OK) return status;
+    }
+
+    cleanup.Disable();
+
+    return OK;
 }
 
-bool RpcSession::setupOneSocketClient(const RpcSocketAddress& addr, int32_t id) {
+status_t RpcSession::setupSocketClient(const RpcSocketAddress& addr) {
+    return setupClient([&](const std::vector<uint8_t>& sessionId, bool incoming) {
+        return setupOneSocketConnection(addr, sessionId, incoming);
+    });
+}
+
+status_t RpcSession::setupOneSocketConnection(const RpcSocketAddress& addr,
+                                              const std::vector<uint8_t>& sessionId,
+                                              bool incoming) {
     for (size_t tries = 0; tries < 5; tries++) {
         if (tries > 0) usleep(10000);
 
-        unique_fd serverFd(
-                TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
+        unique_fd serverFd(TEMP_FAILURE_RETRY(
+                socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)));
         if (serverFd == -1) {
             int savedErrno = errno;
             ALOGE("Could not create socket at %s: %s", addr.toString().c_str(),
                   strerror(savedErrno));
-            return false;
+            return -savedErrno;
         }
 
         if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
-            if (errno == ECONNRESET) {
+            int connErrno = errno;
+            if (connErrno == EAGAIN || connErrno == EINPROGRESS) {
+                // For non-blocking sockets, connect() may return EAGAIN (for unix domain socket) or
+                // EINPROGRESS (for others). Call poll() and getsockopt() to get the error.
+                status_t pollStatus = mShutdownTrigger->triggerablePoll(serverFd, POLLOUT);
+                if (pollStatus != OK) {
+                    ALOGE("Could not POLLOUT after connect() on non-blocking socket: %s",
+                          statusToString(pollStatus).c_str());
+                    return pollStatus;
+                }
+                // Set connErrno to the errno that connect() would have set if the fd were blocking.
+                socklen_t connErrnoLen = sizeof(connErrno);
+                int ret =
+                        getsockopt(serverFd.get(), SOL_SOCKET, SO_ERROR, &connErrno, &connErrnoLen);
+                if (ret == -1) {
+                    int savedErrno = errno;
+                    ALOGE("Could not getsockopt() after connect() on non-blocking socket: %s. "
+                          "(Original error from connect() is: %s)",
+                          strerror(savedErrno), strerror(connErrno));
+                    return -savedErrno;
+                }
+                // Retrieved the real connErrno as if connect() was called with a blocking socket
+                // fd. Continue checking connErrno.
+            }
+            if (connErrno == ECONNRESET) {
                 ALOGW("Connection reset on %s", addr.toString().c_str());
                 continue;
             }
-            int savedErrno = errno;
-            ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(),
-                  strerror(savedErrno));
-            return false;
+            // connErrno could be zero if getsockopt determines so. Hence zero-check again.
+            if (connErrno != 0) {
+                ALOGE("Could not connect socket at %s: %s", addr.toString().c_str(),
+                      strerror(connErrno));
+                return -connErrno;
+            }
         }
-
-        if (sizeof(id) != TEMP_FAILURE_RETRY(write(serverFd.get(), &id, sizeof(id)))) {
-            int savedErrno = errno;
-            ALOGE("Could not write id to socket at %s: %s", addr.toString().c_str(),
-                  strerror(savedErrno));
-            return false;
-        }
-
         LOG_RPC_DETAIL("Socket at %s client with fd %d", addr.toString().c_str(), serverFd.get());
 
-        addClientConnection(std::move(serverFd));
-        return true;
+        return initAndAddConnection(std::move(serverFd), sessionId, incoming);
     }
 
     ALOGE("Ran out of retries to connect to %s", addr.toString().c_str());
-    return false;
+    return UNKNOWN_ERROR;
 }
 
-void RpcSession::addClientConnection(unique_fd fd) {
-    std::lock_guard<std::mutex> _l(mMutex);
-    sp<RpcConnection> session = sp<RpcConnection>::make();
-    session->fd = std::move(fd);
-    mClientConnections.push_back(session);
+status_t RpcSession::initAndAddConnection(unique_fd fd, const std::vector<uint8_t>& sessionId,
+                                          bool incoming) {
+    LOG_ALWAYS_FATAL_IF(mShutdownTrigger == nullptr);
+    auto server = mCtx->newTransport(std::move(fd), mShutdownTrigger.get());
+    if (server == nullptr) {
+        ALOGE("%s: Unable to set up RpcTransport", __PRETTY_FUNCTION__);
+        return UNKNOWN_ERROR;
+    }
+
+    LOG_RPC_DETAIL("Socket at client with RpcTransport %p", server.get());
+
+    if (sessionId.size() > std::numeric_limits<uint16_t>::max()) {
+        ALOGE("Session ID too big %zu", sessionId.size());
+        return BAD_VALUE;
+    }
+
+    RpcConnectionHeader header{
+            .version = mProtocolVersion.value_or(RPC_WIRE_PROTOCOL_VERSION),
+            .options = 0,
+            .sessionIdSize = static_cast<uint16_t>(sessionId.size()),
+    };
+
+    if (incoming) {
+        header.options |= RPC_CONNECTION_OPTION_INCOMING;
+    }
+
+    auto sendHeaderStatus =
+            server->interruptableWriteFully(mShutdownTrigger.get(), &header, sizeof(header), {});
+    if (sendHeaderStatus != OK) {
+        ALOGE("Could not write connection header to socket: %s",
+              statusToString(sendHeaderStatus).c_str());
+        return sendHeaderStatus;
+    }
+
+    if (sessionId.size() > 0) {
+        auto sendSessionIdStatus =
+                server->interruptableWriteFully(mShutdownTrigger.get(), sessionId.data(),
+                                                sessionId.size(), {});
+        if (sendSessionIdStatus != OK) {
+            ALOGE("Could not write session ID ('%s') to socket: %s",
+                  base::HexString(sessionId.data(), sessionId.size()).c_str(),
+                  statusToString(sendSessionIdStatus).c_str());
+            return sendSessionIdStatus;
+        }
+    }
+
+    LOG_RPC_DETAIL("Socket at client: header sent");
+
+    if (incoming) {
+        return addIncomingConnection(std::move(server));
+    } else {
+        return addOutgoingConnection(std::move(server), true /*init*/);
+    }
 }
 
-void RpcSession::setForServer(const wp<RpcServer>& server, int32_t sessionId) {
+status_t RpcSession::addIncomingConnection(std::unique_ptr<RpcTransport> rpcTransport) {
+    std::mutex mutex;
+    std::condition_variable joinCv;
+    std::unique_lock<std::mutex> lock(mutex);
+    std::thread thread;
+    sp<RpcSession> thiz = sp<RpcSession>::fromExisting(this);
+    bool ownershipTransferred = false;
+    thread = std::thread([&]() {
+        std::unique_lock<std::mutex> threadLock(mutex);
+        std::unique_ptr<RpcTransport> movedRpcTransport = std::move(rpcTransport);
+        // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
+        sp<RpcSession> session = thiz;
+        session->preJoinThreadOwnership(std::move(thread));
+
+        // only continue once we have a response or the connection fails
+        auto setupResult = session->preJoinSetup(std::move(movedRpcTransport));
+
+        ownershipTransferred = true;
+        threadLock.unlock();
+        joinCv.notify_one();
+        // do not use & vars below
+
+        RpcSession::join(std::move(session), std::move(setupResult));
+    });
+    joinCv.wait(lock, [&] { return ownershipTransferred; });
+    LOG_ALWAYS_FATAL_IF(!ownershipTransferred);
+    return OK;
+}
+
+status_t RpcSession::initShutdownTrigger() {
+    // first client connection added, but setForServer not called, so
+    // initializaing for a client.
+    if (mShutdownTrigger == nullptr) {
+        mShutdownTrigger = FdTrigger::make();
+        mEventListener = mShutdownListener = sp<WaitForShutdownListener>::make();
+        if (mShutdownTrigger == nullptr) return INVALID_OPERATION;
+    }
+    return OK;
+}
+
+status_t RpcSession::addOutgoingConnection(std::unique_ptr<RpcTransport> rpcTransport, bool init) {
+    sp<RpcConnection> connection = sp<RpcConnection>::make();
+    {
+        std::lock_guard<std::mutex> _l(mMutex);
+        connection->rpcTransport = std::move(rpcTransport);
+        connection->exclusiveTid = gettid();
+        mConnections.mOutgoing.push_back(connection);
+    }
+
+    status_t status = OK;
+    if (init) {
+        status =
+                mRpcBinderState->sendConnectionInit(connection, sp<RpcSession>::fromExisting(this));
+    }
+
+    {
+        std::lock_guard<std::mutex> _l(mMutex);
+        connection->exclusiveTid = std::nullopt;
+    }
+
+    return status;
+}
+
+bool RpcSession::setForServer(const wp<RpcServer>& server, const wp<EventListener>& eventListener,
+                              const std::vector<uint8_t>& sessionId,
+                              const sp<IBinder>& sessionSpecificRoot) {
+    LOG_ALWAYS_FATAL_IF(mForServer != nullptr);
+    LOG_ALWAYS_FATAL_IF(server == nullptr);
+    LOG_ALWAYS_FATAL_IF(mEventListener != nullptr);
+    LOG_ALWAYS_FATAL_IF(eventListener == nullptr);
+    LOG_ALWAYS_FATAL_IF(mShutdownTrigger != nullptr);
+
+    mShutdownTrigger = FdTrigger::make();
+    if (mShutdownTrigger == nullptr) return false;
+
     mId = sessionId;
     mForServer = server;
+    mEventListener = eventListener;
+    mSessionSpecificRootObject = sessionSpecificRoot;
+    return true;
 }
 
-sp<RpcSession::RpcConnection> RpcSession::assignServerToThisThread(unique_fd fd) {
+sp<RpcSession::RpcConnection> RpcSession::assignIncomingConnectionToThisThread(
+        std::unique_ptr<RpcTransport> rpcTransport) {
     std::lock_guard<std::mutex> _l(mMutex);
+
+    if (mConnections.mIncoming.size() >= mMaxIncomingThreads) {
+        ALOGE("Cannot add thread to session with %zu threads (max is set to %zu)",
+              mConnections.mIncoming.size(), mMaxIncomingThreads);
+        return nullptr;
+    }
+
+    // Don't accept any more connections, some have shutdown. Usually this
+    // happens when new connections are still being established as part of a
+    // very short-lived session which shuts down after it already started
+    // accepting new connections.
+    if (mConnections.mIncoming.size() < mConnections.mMaxIncoming) {
+        return nullptr;
+    }
+
     sp<RpcConnection> session = sp<RpcConnection>::make();
-    session->fd = std::move(fd);
+    session->rpcTransport = std::move(rpcTransport);
     session->exclusiveTid = gettid();
-    mServerConnections.push_back(session);
+
+    mConnections.mIncoming.push_back(session);
+    mConnections.mMaxIncoming = mConnections.mIncoming.size();
 
     return session;
 }
 
-bool RpcSession::removeServerConnection(const sp<RpcConnection>& connection) {
-    std::lock_guard<std::mutex> _l(mMutex);
-    if (auto it = std::find(mServerConnections.begin(), mServerConnections.end(), connection);
-        it != mServerConnections.end()) {
-        mServerConnections.erase(it);
-        if (mServerConnections.size() == 0) {
-            terminateLocked();
+bool RpcSession::removeIncomingConnection(const sp<RpcConnection>& connection) {
+    std::unique_lock<std::mutex> _l(mMutex);
+    if (auto it =
+                std::find(mConnections.mIncoming.begin(), mConnections.mIncoming.end(), connection);
+        it != mConnections.mIncoming.end()) {
+        mConnections.mIncoming.erase(it);
+        if (mConnections.mIncoming.size() == 0) {
+            sp<EventListener> listener = mEventListener.promote();
+            if (listener) {
+                _l.unlock();
+                listener->onSessionAllIncomingThreadsEnded(sp<RpcSession>::fromExisting(this));
+            }
         }
         return true;
     }
     return false;
 }
 
-RpcSession::ExclusiveConnection::ExclusiveConnection(const sp<RpcSession>& session,
-                                                     ConnectionUse use)
-      : mSession(session) {
-    pid_t tid = gettid();
-    std::unique_lock<std::mutex> _l(mSession->mMutex);
+std::vector<uint8_t> RpcSession::getCertificate(RpcCertificateFormat format) {
+    return mCtx->getCertificate(format);
+}
 
-    mSession->mWaitingThreads++;
+status_t RpcSession::ExclusiveConnection::find(const sp<RpcSession>& session, ConnectionUse use,
+                                               ExclusiveConnection* connection) {
+    connection->mSession = session;
+    connection->mConnection = nullptr;
+    connection->mReentrant = false;
+
+    pid_t tid = gettid();
+    std::unique_lock<std::mutex> _l(session->mMutex);
+
+    session->mConnections.mWaitingThreads++;
     while (true) {
         sp<RpcConnection> exclusive;
         sp<RpcConnection> available;
 
         // CHECK FOR DEDICATED CLIENT SOCKET
         //
-        // A server/looper should always use a dedicated session if available
-        findConnection(tid, &exclusive, &available, mSession->mClientConnections,
-                       mSession->mClientConnectionsOffset);
+        // A server/looper should always use a dedicated connection if available
+        findConnection(tid, &exclusive, &available, session->mConnections.mOutgoing,
+                       session->mConnections.mOutgoingOffset);
 
         // WARNING: this assumes a server cannot request its client to send
-        // a transaction, as mServerConnections is excluded below.
+        // a transaction, as mIncoming is excluded below.
         //
         // Imagine we have more than one thread in play, and a single thread
         // sends a synchronous, then an asynchronous command. Imagine the
@@ -326,41 +807,60 @@
         // command. So, we move to considering the second available thread
         // for subsequent calls.
         if (use == ConnectionUse::CLIENT_ASYNC && (exclusive != nullptr || available != nullptr)) {
-            mSession->mClientConnectionsOffset =
-                    (mSession->mClientConnectionsOffset + 1) % mSession->mClientConnections.size();
+            session->mConnections.mOutgoingOffset = (session->mConnections.mOutgoingOffset + 1) %
+                    session->mConnections.mOutgoing.size();
         }
 
-        // USE SERVING SOCKET (for nested transaction)
-        //
-        // asynchronous calls cannot be nested
+        // USE SERVING SOCKET (e.g. nested transaction)
         if (use != ConnectionUse::CLIENT_ASYNC) {
+            sp<RpcConnection> exclusiveIncoming;
             // server connections are always assigned to a thread
-            findConnection(tid, &exclusive, nullptr /*available*/, mSession->mServerConnections,
-                           0 /* index hint */);
+            findConnection(tid, &exclusiveIncoming, nullptr /*available*/,
+                           session->mConnections.mIncoming, 0 /* index hint */);
+
+            // asynchronous calls cannot be nested, we currently allow ref count
+            // calls to be nested (so that you can use this without having extra
+            // threads). Note 'drainCommands' is used so that these ref counts can't
+            // build up.
+            if (exclusiveIncoming != nullptr) {
+                if (exclusiveIncoming->allowNested) {
+                    // guaranteed to be processed as nested command
+                    exclusive = exclusiveIncoming;
+                } else if (use == ConnectionUse::CLIENT_REFCOUNT && available == nullptr) {
+                    // prefer available socket, but if we don't have one, don't
+                    // wait for one
+                    exclusive = exclusiveIncoming;
+                }
+            }
         }
 
-        // if our thread is already using a session, prioritize using that
+        // if our thread is already using a connection, prioritize using that
         if (exclusive != nullptr) {
-            mConnection = exclusive;
-            mReentrant = true;
+            connection->mConnection = exclusive;
+            connection->mReentrant = true;
             break;
         } else if (available != nullptr) {
-            mConnection = available;
-            mConnection->exclusiveTid = tid;
+            connection->mConnection = available;
+            connection->mConnection->exclusiveTid = tid;
             break;
         }
 
-        // in regular binder, this would usually be a deadlock :)
-        LOG_ALWAYS_FATAL_IF(mSession->mClientConnections.size() == 0,
-                            "Not a client of any session. You must create a session to an "
-                            "RPC server to make any non-nested (e.g. oneway or on another thread) "
-                            "calls.");
+        if (session->mConnections.mOutgoing.size() == 0) {
+            ALOGE("Session has no client connections. This is required for an RPC server to make "
+                  "any non-nested (e.g. oneway or on another thread) calls. Use: %d. Server "
+                  "connections: %zu",
+                  static_cast<int>(use), session->mConnections.mIncoming.size());
+            return WOULD_BLOCK;
+        }
 
-        LOG_RPC_DETAIL("No available session (have %zu clients and %zu servers). Waiting...",
-                       mSession->mClientConnections.size(), mSession->mServerConnections.size());
-        mSession->mAvailableConnectionCv.wait(_l);
+        LOG_RPC_DETAIL("No available connections (have %zu clients and %zu servers). Waiting...",
+                       session->mConnections.mOutgoing.size(),
+                       session->mConnections.mIncoming.size());
+        session->mAvailableConnectionCv.wait(_l);
     }
-    mSession->mWaitingThreads--;
+    session->mConnections.mWaitingThreads--;
+
+    return OK;
 }
 
 void RpcSession::ExclusiveConnection::findConnection(pid_t tid, sp<RpcConnection>* exclusive,
@@ -375,13 +875,13 @@
     for (size_t i = 0; i < sockets.size(); i++) {
         sp<RpcConnection>& socket = sockets[(i + socketsIndexHint) % sockets.size()];
 
-        // take first available session (intuition = caching)
+        // take first available connection (intuition = caching)
         if (available && *available == nullptr && socket->exclusiveTid == std::nullopt) {
             *available = socket;
             continue;
         }
 
-        // though, prefer to take session which is already inuse by this thread
+        // though, prefer to take connection which is already inuse by this thread
         // (nested transactions)
         if (exclusive && socket->exclusiveTid == tid) {
             *exclusive = socket;
@@ -391,13 +891,13 @@
 }
 
 RpcSession::ExclusiveConnection::~ExclusiveConnection() {
-    // reentrant use of a session means something less deep in the call stack
+    // reentrant use of a connection means something less deep in the call stack
     // is using this fd, and it retains the right to it. So, we don't give up
     // exclusive ownership, and no thread is freed.
-    if (!mReentrant) {
+    if (!mReentrant && mConnection != nullptr) {
         std::unique_lock<std::mutex> _l(mSession->mMutex);
         mConnection->exclusiveTid = std::nullopt;
-        if (mSession->mWaitingThreads > 0) {
+        if (mSession->mConnections.mWaitingThreads > 0) {
             _l.unlock();
             mSession->mAvailableConnectionCv.notify_one();
         }
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index 2ba9fa2..09b3d68 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -18,25 +18,45 @@
 
 #include "RpcState.h"
 
+#include <android-base/hex.h>
+#include <android-base/scopeguard.h>
 #include <binder/BpBinder.h>
+#include <binder/IPCThreadState.h>
 #include <binder/RpcServer.h>
 
 #include "Debug.h"
 #include "RpcWireFormat.h"
 
+#include <random>
+
 #include <inttypes.h>
 
 namespace android {
 
+using base::ScopeGuard;
+
+#if RPC_FLAKE_PRONE
+void rpcMaybeWaitToFlake() {
+    [[clang::no_destroy]] static std::random_device r;
+    [[clang::no_destroy]] static std::mutex m;
+    unsigned num;
+    {
+        std::lock_guard<std::mutex> lock(m);
+        num = r();
+    }
+    if (num % 10 == 0) usleep(num % 1000);
+}
+#endif
+
 RpcState::RpcState() {}
 RpcState::~RpcState() {}
 
 status_t RpcState::onBinderLeaving(const sp<RpcSession>& session, const sp<IBinder>& binder,
-                                   RpcAddress* outAddress) {
+                                   uint64_t* outAddress) {
     bool isRemote = binder->remoteBinder();
     bool isRpc = isRemote && binder->remoteBinder()->isRpcBinder();
 
-    if (isRpc && binder->remoteBinder()->getPrivateAccessorForId().rpcSession() != session) {
+    if (isRpc && binder->remoteBinder()->getPrivateAccessor().rpcSession() != session) {
         // We need to be able to send instructions over the socket for how to
         // connect to a different server, and we also need to let the host
         // process know that this is happening.
@@ -57,18 +77,17 @@
     }
 
     std::lock_guard<std::mutex> _l(mNodeMutex);
+    if (mTerminated) return DEAD_OBJECT;
 
     // TODO(b/182939933): maybe move address out of BpBinder, and keep binder->address map
     // in RpcState
     for (auto& [addr, node] : mNodeForAddress) {
         if (binder == node.binder) {
             if (isRpc) {
-                const RpcAddress& actualAddr =
-                        binder->remoteBinder()->getPrivateAccessorForId().rpcAddress();
-                // TODO(b/182939933): this is only checking integrity of data structure
-                // a different data structure doesn't need this
-                LOG_ALWAYS_FATAL_IF(addr < actualAddr, "Address mismatch");
-                LOG_ALWAYS_FATAL_IF(actualAddr < addr, "Address mismatch");
+                // check integrity of data structure
+                uint64_t actualAddr = binder->remoteBinder()->getPrivateAccessor().rpcAddress();
+                LOG_ALWAYS_FATAL_IF(addr != actualAddr, "Address mismatch %" PRIu64 " vs %" PRIu64,
+                                    addr, actualAddr);
             }
             node.timesSent++;
             node.sentRef = binder; // might already be set
@@ -78,36 +97,78 @@
     }
     LOG_ALWAYS_FATAL_IF(isRpc, "RPC binder must have known address at this point");
 
-    auto&& [it, inserted] = mNodeForAddress.insert({RpcAddress::unique(),
-                                                    BinderNode{
-                                                            .binder = binder,
-                                                            .timesSent = 1,
-                                                            .sentRef = binder,
-                                                    }});
-    // TODO(b/182939933): better organization could avoid needing this log
-    LOG_ALWAYS_FATAL_IF(!inserted);
+    bool forServer = session->server() != nullptr;
 
-    *outAddress = it->first;
-    return OK;
+    // arbitrary limit for maximum number of nodes in a process (otherwise we
+    // might run out of addresses)
+    if (mNodeForAddress.size() > 100000) {
+        return NO_MEMORY;
+    }
+
+    while (true) {
+        RpcWireAddress address{
+                .options = RPC_WIRE_ADDRESS_OPTION_CREATED,
+                .address = mNextId,
+        };
+        if (forServer) {
+            address.options |= RPC_WIRE_ADDRESS_OPTION_FOR_SERVER;
+        }
+
+        // avoid ubsan abort
+        if (mNextId >= std::numeric_limits<uint32_t>::max()) {
+            mNextId = 0;
+        } else {
+            mNextId++;
+        }
+
+        auto&& [it, inserted] = mNodeForAddress.insert({RpcWireAddress::toRaw(address),
+                                                        BinderNode{
+                                                                .binder = binder,
+                                                                .timesSent = 1,
+                                                                .sentRef = binder,
+                                                        }});
+        if (inserted) {
+            *outAddress = it->first;
+            return OK;
+        }
+    }
 }
 
-sp<IBinder> RpcState::onBinderEntering(const sp<RpcSession>& session, const RpcAddress& address) {
-    std::unique_lock<std::mutex> _l(mNodeMutex);
+status_t RpcState::onBinderEntering(const sp<RpcSession>& session, uint64_t address,
+                                    sp<IBinder>* out) {
+    // ensure that: if we want to use addresses for something else in the future (for
+    //   instance, allowing transitive binder sends), that we don't accidentally
+    //   send those addresses to old server. Accidentally ignoring this in that
+    //   case and considering the binder to be recognized could cause this
+    //   process to accidentally proxy transactions for that binder. Of course,
+    //   if we communicate with a binder, it could always be proxying
+    //   information. However, we want to make sure that isn't done on accident
+    //   by a client.
+    RpcWireAddress addr = RpcWireAddress::fromRaw(address);
+    constexpr uint32_t kKnownOptions =
+            RPC_WIRE_ADDRESS_OPTION_CREATED | RPC_WIRE_ADDRESS_OPTION_FOR_SERVER;
+    if (addr.options & ~kKnownOptions) {
+        ALOGE("Address is of an unknown type, rejecting: %" PRIu64, address);
+        return BAD_VALUE;
+    }
+
+    std::lock_guard<std::mutex> _l(mNodeMutex);
+    if (mTerminated) return DEAD_OBJECT;
 
     if (auto it = mNodeForAddress.find(address); it != mNodeForAddress.end()) {
-        sp<IBinder> binder = it->second.binder.promote();
+        *out = it->second.binder.promote();
 
         // implicitly have strong RPC refcount, since we received this binder
         it->second.timesRecd++;
+        return OK;
+    }
 
-        _l.unlock();
-
-        // We have timesRecd RPC refcounts, but we only need to hold on to one
-        // when we keep the object. All additional dec strongs are sent
-        // immediately, we wait to send the last one in BpBinder::onLastDecStrong.
-        (void)session->sendDecStrong(address);
-
-        return binder;
+    // we don't know about this binder, so the other side of the connection
+    // should have created it.
+    if ((addr.options & RPC_WIRE_ADDRESS_OPTION_FOR_SERVER) == !!session->server()) {
+        ALOGE("Server received unrecognized address which we should own the creation of %" PRIu64,
+              address);
+        return BAD_VALUE;
     }
 
     auto&& [it, inserted] = mNodeForAddress.insert({address, BinderNode{}});
@@ -115,10 +176,42 @@
 
     // Currently, all binders are assumed to be part of the same session (no
     // device global binders in the RPC world).
-    sp<IBinder> binder = BpBinder::create(session, it->first);
-    it->second.binder = binder;
+    it->second.binder = *out = BpBinder::PrivateAccessor::create(session, it->first);
     it->second.timesRecd = 1;
-    return binder;
+    return OK;
+}
+
+status_t RpcState::flushExcessBinderRefs(const sp<RpcSession>& session, uint64_t address,
+                                         const sp<IBinder>& binder) {
+    // We can flush all references when the binder is destroyed. No need to send
+    // extra reference counting packets now.
+    if (binder->remoteBinder()) return OK;
+
+    std::unique_lock<std::mutex> _l(mNodeMutex);
+    if (mTerminated) return DEAD_OBJECT;
+
+    auto it = mNodeForAddress.find(address);
+
+    LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(), "Can't be deleted while we hold sp<>");
+    LOG_ALWAYS_FATAL_IF(it->second.binder != binder,
+                        "Caller of flushExcessBinderRefs using inconsistent arguments");
+
+    LOG_ALWAYS_FATAL_IF(it->second.timesSent <= 0, "Local binder must have been sent %p",
+                        binder.get());
+
+    // For a local binder, we only need to know that we sent it. Now that we
+    // have an sp<> for this call, we don't need anything more. If the other
+    // process is done with this binder, it needs to know we received the
+    // refcount associated with this call, so we can acknowledge that we
+    // received it. Once (or if) it has no other refcounts, it would reply with
+    // its own decStrong so that it could be removed from this session.
+    if (it->second.timesRecd != 0) {
+        _l.unlock();
+
+        return session->sendDecStrongToTarget(address, 0);
+    }
+
+    return OK;
 }
 
 size_t RpcState::countBinders() {
@@ -128,6 +221,45 @@
 
 void RpcState::dump() {
     std::lock_guard<std::mutex> _l(mNodeMutex);
+    dumpLocked();
+}
+
+void RpcState::clear() {
+    std::unique_lock<std::mutex> _l(mNodeMutex);
+
+    if (mTerminated) {
+        LOG_ALWAYS_FATAL_IF(!mNodeForAddress.empty(),
+                            "New state should be impossible after terminating!");
+        return;
+    }
+
+    if (SHOULD_LOG_RPC_DETAIL) {
+        ALOGE("RpcState::clear()");
+        dumpLocked();
+    }
+
+    // if the destructor of a binder object makes another RPC call, then calling
+    // decStrong could deadlock. So, we must hold onto these binders until
+    // mNodeMutex is no longer taken.
+    std::vector<sp<IBinder>> tempHoldBinder;
+
+    mTerminated = true;
+    for (auto& [address, node] : mNodeForAddress) {
+        sp<IBinder> binder = node.binder.promote();
+        LOG_ALWAYS_FATAL_IF(binder == nullptr, "Binder %p expected to be owned.", binder.get());
+
+        if (node.sentRef != nullptr) {
+            tempHoldBinder.push_back(node.sentRef);
+        }
+    }
+
+    mNodeForAddress.clear();
+
+    _l.unlock();
+    tempHoldBinder.clear(); // explicit
+}
+
+void RpcState::dumpLocked() {
     ALOGE("DUMP OF RpcState %p", this);
     ALOGE("DUMP OF RpcState (%zu nodes)", mNodeForAddress.size());
     for (const auto& [address, node] : mNodeForAddress) {
@@ -148,39 +280,12 @@
             desc = "(null)";
         }
 
-        ALOGE("- BINDER NODE: %p times sent:%zu times recd: %zu a:%s type:%s",
-              node.binder.unsafe_get(), node.timesSent, node.timesRecd, address.toString().c_str(),
-              desc);
+        ALOGE("- BINDER NODE: %p times sent:%zu times recd: %zu a: %" PRIu64 " type: %s",
+              node.binder.unsafe_get(), node.timesSent, node.timesRecd, address, desc);
     }
     ALOGE("END DUMP OF RpcState");
 }
 
-void RpcState::terminate() {
-    if (SHOULD_LOG_RPC_DETAIL) {
-        ALOGE("RpcState::terminate()");
-        dump();
-    }
-
-    // if the destructor of a binder object makes another RPC call, then calling
-    // decStrong could deadlock. So, we must hold onto these binders until
-    // mNodeMutex is no longer taken.
-    std::vector<sp<IBinder>> tempHoldBinder;
-
-    {
-        std::lock_guard<std::mutex> _l(mNodeMutex);
-        mTerminated = true;
-        for (auto& [address, node] : mNodeForAddress) {
-            sp<IBinder> binder = node.binder.promote();
-            LOG_ALWAYS_FATAL_IF(binder == nullptr, "Binder %p expected to be owned.", binder.get());
-
-            if (node.sentRef != nullptr) {
-                tempHoldBinder.push_back(node.sentRef);
-            }
-        }
-
-        mNodeForAddress.clear();
-    }
-}
 
 RpcState::CommandData::CommandData(size_t size) : mSize(size) {
     // The maximum size for regular binder is 1MB for all concurrent
@@ -203,62 +308,99 @@
     mData.reset(new (std::nothrow) uint8_t[size]);
 }
 
-bool RpcState::rpcSend(const base::unique_fd& fd, const char* what, const void* data, size_t size) {
-    LOG_RPC_DETAIL("Sending %s on fd %d: %s", what, fd.get(), hexString(data, size).c_str());
+status_t RpcState::rpcSend(const sp<RpcSession::RpcConnection>& connection,
+                           const sp<RpcSession>& session, const char* what, const void* data,
+                           size_t size, const std::function<status_t()>& altPoll) {
+    LOG_RPC_DETAIL("Sending %s on RpcTransport %p: %s", what, connection->rpcTransport.get(),
+                   android::base::HexString(data, size).c_str());
 
     if (size > std::numeric_limits<ssize_t>::max()) {
         ALOGE("Cannot send %s at size %zu (too big)", what, size);
-        terminate();
-        return false;
+        (void)session->shutdownAndWait(false);
+        return BAD_VALUE;
     }
 
-    ssize_t sent = TEMP_FAILURE_RETRY(send(fd.get(), data, size, MSG_NOSIGNAL));
-
-    if (sent < 0 || sent != static_cast<ssize_t>(size)) {
-        ALOGE("Failed to send %s (sent %zd of %zu bytes) on fd %d, error: %s", what, sent, size,
-              fd.get(), strerror(errno));
-
-        terminate();
-        return false;
+    if (status_t status =
+                connection->rpcTransport->interruptableWriteFully(session->mShutdownTrigger.get(),
+                                                                  data, size, altPoll);
+        status != OK) {
+        LOG_RPC_DETAIL("Failed to write %s (%zu bytes) on RpcTransport %p, error: %s", what, size,
+                       connection->rpcTransport.get(), statusToString(status).c_str());
+        (void)session->shutdownAndWait(false);
+        return status;
     }
 
-    return true;
+    return OK;
 }
 
-bool RpcState::rpcRec(const base::unique_fd& fd, const char* what, void* data, size_t size) {
+status_t RpcState::rpcRec(const sp<RpcSession::RpcConnection>& connection,
+                          const sp<RpcSession>& session, const char* what, void* data,
+                          size_t size) {
     if (size > std::numeric_limits<ssize_t>::max()) {
         ALOGE("Cannot rec %s at size %zu (too big)", what, size);
-        terminate();
-        return false;
+        (void)session->shutdownAndWait(false);
+        return BAD_VALUE;
     }
 
-    ssize_t recd = TEMP_FAILURE_RETRY(recv(fd.get(), data, size, MSG_WAITALL | MSG_NOSIGNAL));
-
-    if (recd < 0 || recd != static_cast<ssize_t>(size)) {
-        terminate();
-
-        if (recd == 0 && errno == 0) {
-            LOG_RPC_DETAIL("No more data when trying to read %s on fd %d", what, fd.get());
-            return false;
-        }
-
-        ALOGE("Failed to read %s (received %zd of %zu bytes) on fd %d, error: %s", what, recd, size,
-              fd.get(), strerror(errno));
-        return false;
-    } else {
-        LOG_RPC_DETAIL("Received %s on fd %d: %s", what, fd.get(), hexString(data, size).c_str());
+    if (status_t status =
+                connection->rpcTransport->interruptableReadFully(session->mShutdownTrigger.get(),
+                                                                 data, size, {});
+        status != OK) {
+        LOG_RPC_DETAIL("Failed to read %s (%zu bytes) on RpcTransport %p, error: %s", what, size,
+                       connection->rpcTransport.get(), statusToString(status).c_str());
+        (void)session->shutdownAndWait(false);
+        return status;
     }
 
-    return true;
+    LOG_RPC_DETAIL("Received %s on RpcTransport %p: %s", what, connection->rpcTransport.get(),
+                   android::base::HexString(data, size).c_str());
+    return OK;
 }
 
-sp<IBinder> RpcState::getRootObject(const base::unique_fd& fd, const sp<RpcSession>& session) {
+status_t RpcState::readNewSessionResponse(const sp<RpcSession::RpcConnection>& connection,
+                                          const sp<RpcSession>& session, uint32_t* version) {
+    RpcNewSessionResponse response;
+    if (status_t status =
+                rpcRec(connection, session, "new session response", &response, sizeof(response));
+        status != OK) {
+        return status;
+    }
+    *version = response.version;
+    return OK;
+}
+
+status_t RpcState::sendConnectionInit(const sp<RpcSession::RpcConnection>& connection,
+                                      const sp<RpcSession>& session) {
+    RpcOutgoingConnectionInit init{
+            .msg = RPC_CONNECTION_INIT_OKAY,
+    };
+    return rpcSend(connection, session, "connection init", &init, sizeof(init));
+}
+
+status_t RpcState::readConnectionInit(const sp<RpcSession::RpcConnection>& connection,
+                                      const sp<RpcSession>& session) {
+    RpcOutgoingConnectionInit init;
+    if (status_t status = rpcRec(connection, session, "connection init", &init, sizeof(init));
+        status != OK)
+        return status;
+
+    static_assert(sizeof(init.msg) == sizeof(RPC_CONNECTION_INIT_OKAY));
+    if (0 != strncmp(init.msg, RPC_CONNECTION_INIT_OKAY, sizeof(init.msg))) {
+        ALOGE("Connection init message unrecognized %.*s", static_cast<int>(sizeof(init.msg)),
+              init.msg);
+        return BAD_VALUE;
+    }
+    return OK;
+}
+
+sp<IBinder> RpcState::getRootObject(const sp<RpcSession::RpcConnection>& connection,
+                                    const sp<RpcSession>& session) {
     Parcel data;
     data.markForRpc(session);
     Parcel reply;
 
-    status_t status = transact(fd, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_ROOT, data, session,
-                               &reply, 0);
+    status_t status =
+            transactAddress(connection, 0, RPC_SPECIAL_TRANSACT_GET_ROOT, data, session, &reply, 0);
     if (status != OK) {
         ALOGE("Error getting root object: %s", statusToString(status).c_str());
         return nullptr;
@@ -267,14 +409,14 @@
     return reply.readStrongBinder();
 }
 
-status_t RpcState::getMaxThreads(const base::unique_fd& fd, const sp<RpcSession>& session,
-                                 size_t* maxThreadsOut) {
+status_t RpcState::getMaxThreads(const sp<RpcSession::RpcConnection>& connection,
+                                 const sp<RpcSession>& session, size_t* maxThreadsOut) {
     Parcel data;
     data.markForRpc(session);
     Parcel reply;
 
-    status_t status = transact(fd, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_MAX_THREADS, data,
-                               session, &reply, 0);
+    status_t status = transactAddress(connection, 0, RPC_SPECIAL_TRANSACT_GET_MAX_THREADS, data,
+                                      session, &reply, 0);
     if (status != OK) {
         ALOGE("Error getting max threads: %s", statusToString(status).c_str());
         return status;
@@ -292,93 +434,141 @@
     return OK;
 }
 
-status_t RpcState::getSessionId(const base::unique_fd& fd, const sp<RpcSession>& session,
-                                int32_t* sessionIdOut) {
+status_t RpcState::getSessionId(const sp<RpcSession::RpcConnection>& connection,
+                                const sp<RpcSession>& session, std::vector<uint8_t>* sessionIdOut) {
     Parcel data;
     data.markForRpc(session);
     Parcel reply;
 
-    status_t status = transact(fd, RpcAddress::zero(), RPC_SPECIAL_TRANSACT_GET_SESSION_ID, data,
-                               session, &reply, 0);
+    status_t status = transactAddress(connection, 0, RPC_SPECIAL_TRANSACT_GET_SESSION_ID, data,
+                                      session, &reply, 0);
     if (status != OK) {
         ALOGE("Error getting session ID: %s", statusToString(status).c_str());
         return status;
     }
 
-    int32_t sessionId;
-    status = reply.readInt32(&sessionId);
-    if (status != OK) return status;
-
-    *sessionIdOut = sessionId;
-    return OK;
+    return reply.readByteVector(sessionIdOut);
 }
 
-status_t RpcState::transact(const base::unique_fd& fd, const RpcAddress& address, uint32_t code,
-                            const Parcel& data, const sp<RpcSession>& session, Parcel* reply,
-                            uint32_t flags) {
-    uint64_t asyncNumber = 0;
-
-    if (!address.isZero()) {
-        std::lock_guard<std::mutex> _l(mNodeMutex);
-        if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races
-        auto it = mNodeForAddress.find(address);
-        LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(), "Sending transact on unknown address %s",
-                            address.toString().c_str());
-
-        if (flags & IBinder::FLAG_ONEWAY) {
-            asyncNumber = it->second.asyncNumber++;
-        }
-    }
-
+status_t RpcState::transact(const sp<RpcSession::RpcConnection>& connection,
+                            const sp<IBinder>& binder, uint32_t code, const Parcel& data,
+                            const sp<RpcSession>& session, Parcel* reply, uint32_t flags) {
     if (!data.isForRpc()) {
-        ALOGE("Refusing to send RPC with parcel not crafted for RPC");
+        ALOGE("Refusing to send RPC with parcel not crafted for RPC call on binder %p code "
+              "%" PRIu32,
+              binder.get(), code);
         return BAD_TYPE;
     }
 
     if (data.objectsCount() != 0) {
-        ALOGE("Parcel at %p has attached objects but is being used in an RPC call", &data);
+        ALOGE("Parcel at %p has attached objects but is being used in an RPC call on binder %p "
+              "code %" PRIu32,
+              &data, binder.get(), code);
         return BAD_TYPE;
     }
 
+    uint64_t address;
+    if (status_t status = onBinderLeaving(session, binder, &address); status != OK) return status;
+
+    return transactAddress(connection, address, code, data, session, reply, flags);
+}
+
+status_t RpcState::transactAddress(const sp<RpcSession::RpcConnection>& connection,
+                                   uint64_t address, uint32_t code, const Parcel& data,
+                                   const sp<RpcSession>& session, Parcel* reply, uint32_t flags) {
+    LOG_ALWAYS_FATAL_IF(!data.isForRpc());
+    LOG_ALWAYS_FATAL_IF(data.objectsCount() != 0);
+
+    uint64_t asyncNumber = 0;
+
+    if (address != 0) {
+        std::unique_lock<std::mutex> _l(mNodeMutex);
+        if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races
+        auto it = mNodeForAddress.find(address);
+        LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(),
+                            "Sending transact on unknown address %" PRIu64, address);
+
+        if (flags & IBinder::FLAG_ONEWAY) {
+            asyncNumber = it->second.asyncNumber;
+            if (!nodeProgressAsyncNumber(&it->second)) {
+                _l.unlock();
+                (void)session->shutdownAndWait(false);
+                return DEAD_OBJECT;
+            }
+        }
+    }
+
+    LOG_ALWAYS_FATAL_IF(std::numeric_limits<int32_t>::max() - sizeof(RpcWireHeader) -
+                                        sizeof(RpcWireTransaction) <
+                                data.dataSize(),
+                        "Too much data %zu", data.dataSize());
+
+    RpcWireHeader command{
+            .command = RPC_COMMAND_TRANSACT,
+            .bodySize = static_cast<uint32_t>(sizeof(RpcWireTransaction) + data.dataSize()),
+    };
+
     RpcWireTransaction transaction{
-            .address = address.viewRawEmbedded(),
+            .address = RpcWireAddress::fromRaw(address),
             .code = code,
             .flags = flags,
             .asyncNumber = asyncNumber,
     };
-
-    CommandData transactionData(sizeof(RpcWireTransaction) + data.dataSize());
+    CommandData transactionData(sizeof(RpcWireHeader) + sizeof(RpcWireTransaction) +
+                                data.dataSize());
     if (!transactionData.valid()) {
         return NO_MEMORY;
     }
 
-    memcpy(transactionData.data() + 0, &transaction, sizeof(RpcWireTransaction));
-    memcpy(transactionData.data() + sizeof(RpcWireTransaction), data.data(), data.dataSize());
+    memcpy(transactionData.data() + 0, &command, sizeof(RpcWireHeader));
+    memcpy(transactionData.data() + sizeof(RpcWireHeader), &transaction,
+           sizeof(RpcWireTransaction));
+    memcpy(transactionData.data() + sizeof(RpcWireHeader) + sizeof(RpcWireTransaction), data.data(),
+           data.dataSize());
 
-    if (transactionData.size() > std::numeric_limits<uint32_t>::max()) {
-        ALOGE("Transaction size too big %zu", transactionData.size());
-        return BAD_VALUE;
-    }
+    constexpr size_t kWaitMaxUs = 1000000;
+    constexpr size_t kWaitLogUs = 10000;
+    size_t waitUs = 0;
 
-    RpcWireHeader command{
-            .command = RPC_COMMAND_TRANSACT,
-            .bodySize = static_cast<uint32_t>(transactionData.size()),
+    // Oneway calls have no sync point, so if many are sent before, whether this
+    // is a twoway or oneway transaction, they may have filled up the socket.
+    // So, make sure we drain them before polling.
+    std::function<status_t()> drainRefs = [&] {
+        if (waitUs > kWaitLogUs) {
+            ALOGE("Cannot send command, trying to process pending refcounts. Waiting %zuus. Too "
+                  "many oneway calls?",
+                  waitUs);
+        }
+
+        if (waitUs > 0) {
+            usleep(waitUs);
+            waitUs = std::min(kWaitMaxUs, waitUs * 2);
+        } else {
+            waitUs = 1;
+        }
+
+        return drainCommands(connection, session, CommandType::CONTROL_ONLY);
     };
 
-    if (!rpcSend(fd, "transact header", &command, sizeof(command))) {
-        return DEAD_OBJECT;
-    }
-    if (!rpcSend(fd, "command body", transactionData.data(), transactionData.size())) {
-        return DEAD_OBJECT;
+    if (status_t status = rpcSend(connection, session, "transaction", transactionData.data(),
+                                  transactionData.size(), drainRefs);
+        status != OK) {
+        // TODO(b/167966510): need to undo onBinderLeaving - we know the
+        // refcount isn't successfully transferred.
+        return status;
     }
 
     if (flags & IBinder::FLAG_ONEWAY) {
-        return OK; // do not wait for result
+        LOG_RPC_DETAIL("Oneway command, so no longer waiting on RpcTransport %p",
+                       connection->rpcTransport.get());
+
+        // Do not wait on result.
+        return OK;
     }
 
     LOG_ALWAYS_FATAL_IF(reply == nullptr, "Reply parcel must be used for synchronous transaction.");
 
-    return waitForReply(fd, session, reply);
+    return waitForReply(connection, session, reply);
 }
 
 static void cleanup_reply_data(Parcel* p, const uint8_t* data, size_t dataSize,
@@ -387,36 +577,36 @@
     delete[] const_cast<uint8_t*>(data - offsetof(RpcWireReply, data));
     (void)dataSize;
     LOG_ALWAYS_FATAL_IF(objects != nullptr);
-    LOG_ALWAYS_FATAL_IF(objectsCount, 0);
+    LOG_ALWAYS_FATAL_IF(objectsCount != 0, "%zu objects remaining", objectsCount);
 }
 
-status_t RpcState::waitForReply(const base::unique_fd& fd, const sp<RpcSession>& session,
-                                Parcel* reply) {
+status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection,
+                                const sp<RpcSession>& session, Parcel* reply) {
     RpcWireHeader command;
     while (true) {
-        if (!rpcRec(fd, "command header", &command, sizeof(command))) {
-            return DEAD_OBJECT;
-        }
+        if (status_t status = rpcRec(connection, session, "command header (for reply)", &command,
+                                     sizeof(command));
+            status != OK)
+            return status;
 
         if (command.command == RPC_COMMAND_REPLY) break;
 
-        status_t status = processServerCommand(fd, session, command);
-        if (status != OK) return status;
+        if (status_t status = processCommand(connection, session, command, CommandType::ANY);
+            status != OK)
+            return status;
     }
 
     CommandData data(command.bodySize);
-    if (!data.valid()) {
-        return NO_MEMORY;
-    }
+    if (!data.valid()) return NO_MEMORY;
 
-    if (!rpcRec(fd, "reply body", data.data(), command.bodySize)) {
-        return DEAD_OBJECT;
-    }
+    if (status_t status = rpcRec(connection, session, "reply body", data.data(), command.bodySize);
+        status != OK)
+        return status;
 
     if (command.bodySize < sizeof(RpcWireReply)) {
         ALOGE("Expecting %zu but got %" PRId32 " bytes for RpcWireReply. Terminating!",
               sizeof(RpcWireReply), command.bodySize);
-        terminate();
+        (void)session->shutdownAndWait(false);
         return BAD_VALUE;
     }
     RpcWireReply* rpcReply = reinterpret_cast<RpcWireReply*>(data.data());
@@ -431,50 +621,92 @@
     return OK;
 }
 
-status_t RpcState::sendDecStrong(const base::unique_fd& fd, const RpcAddress& addr) {
+status_t RpcState::sendDecStrongToTarget(const sp<RpcSession::RpcConnection>& connection,
+                                         const sp<RpcSession>& session, uint64_t addr,
+                                         size_t target) {
+    RpcDecStrong body = {
+            .address = RpcWireAddress::fromRaw(addr),
+    };
+
     {
         std::lock_guard<std::mutex> _l(mNodeMutex);
         if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races
         auto it = mNodeForAddress.find(addr);
-        LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(), "Sending dec strong on unknown address %s",
-                            addr.toString().c_str());
-        LOG_ALWAYS_FATAL_IF(it->second.timesRecd <= 0, "Bad dec strong %s",
-                            addr.toString().c_str());
+        LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(),
+                            "Sending dec strong on unknown address %" PRIu64, addr);
 
-        it->second.timesRecd--;
-        if (it->second.timesRecd == 0 && it->second.timesSent == 0) {
-            mNodeForAddress.erase(it);
-        }
+        LOG_ALWAYS_FATAL_IF(it->second.timesRecd < target, "Can't dec count of %zu to %zu.",
+                            it->second.timesRecd, target);
+
+        // typically this happens when multiple threads send dec refs at the
+        // same time - the transactions will get combined automatically
+        if (it->second.timesRecd == target) return OK;
+
+        body.amount = it->second.timesRecd - target;
+        it->second.timesRecd = target;
+
+        LOG_ALWAYS_FATAL_IF(nullptr != tryEraseNode(it),
+                            "Bad state. RpcState shouldn't own received binder");
     }
 
     RpcWireHeader cmd = {
             .command = RPC_COMMAND_DEC_STRONG,
-            .bodySize = sizeof(RpcWireAddress),
+            .bodySize = sizeof(RpcDecStrong),
     };
-    if (!rpcSend(fd, "dec ref header", &cmd, sizeof(cmd))) return DEAD_OBJECT;
-    if (!rpcSend(fd, "dec ref body", &addr.viewRawEmbedded(), sizeof(RpcWireAddress)))
-        return DEAD_OBJECT;
+    if (status_t status = rpcSend(connection, session, "dec ref header", &cmd, sizeof(cmd));
+        status != OK)
+        return status;
+
+    return rpcSend(connection, session, "dec ref body", &body, sizeof(body));
+}
+
+status_t RpcState::getAndExecuteCommand(const sp<RpcSession::RpcConnection>& connection,
+                                        const sp<RpcSession>& session, CommandType type) {
+    LOG_RPC_DETAIL("getAndExecuteCommand on RpcTransport %p", connection->rpcTransport.get());
+
+    RpcWireHeader command;
+    if (status_t status = rpcRec(connection, session, "command header (for server)", &command,
+                                 sizeof(command));
+        status != OK)
+        return status;
+
+    return processCommand(connection, session, command, type);
+}
+
+status_t RpcState::drainCommands(const sp<RpcSession::RpcConnection>& connection,
+                                 const sp<RpcSession>& session, CommandType type) {
+    uint8_t buf;
+    while (connection->rpcTransport->peek(&buf, sizeof(buf)).value_or(0) > 0) {
+        status_t status = getAndExecuteCommand(connection, session, type);
+        if (status != OK) return status;
+    }
     return OK;
 }
 
-status_t RpcState::getAndExecuteCommand(const base::unique_fd& fd, const sp<RpcSession>& session) {
-    LOG_RPC_DETAIL("getAndExecuteCommand on fd %d", fd.get());
-
-    RpcWireHeader command;
-    if (!rpcRec(fd, "command header", &command, sizeof(command))) {
-        return DEAD_OBJECT;
+status_t RpcState::processCommand(const sp<RpcSession::RpcConnection>& connection,
+                                  const sp<RpcSession>& session, const RpcWireHeader& command,
+                                  CommandType type) {
+    IPCThreadState* kernelBinderState = IPCThreadState::selfOrNull();
+    IPCThreadState::SpGuard spGuard{
+            .address = __builtin_frame_address(0),
+            .context = "processing binder RPC command",
+    };
+    const IPCThreadState::SpGuard* origGuard;
+    if (kernelBinderState != nullptr) {
+        origGuard = kernelBinderState->pushGetCallingSpGuard(&spGuard);
     }
+    ScopeGuard guardUnguard = [&]() {
+        if (kernelBinderState != nullptr) {
+            kernelBinderState->restoreGetCallingSpGuard(origGuard);
+        }
+    };
 
-    return processServerCommand(fd, session, command);
-}
-
-status_t RpcState::processServerCommand(const base::unique_fd& fd, const sp<RpcSession>& session,
-                                        const RpcWireHeader& command) {
     switch (command.command) {
         case RPC_COMMAND_TRANSACT:
-            return processTransact(fd, session, command);
+            if (type != CommandType::ANY) return BAD_TYPE;
+            return processTransact(connection, session, command);
         case RPC_COMMAND_DEC_STRONG:
-            return processDecStrong(fd, command);
+            return processDecStrong(connection, session, command);
     }
 
     // We should always know the version of the opposing side, and since the
@@ -483,22 +715,23 @@
     // also can't consider it a fatal error because this would allow any client
     // to kill us, so ending the session for misbehaving client.
     ALOGE("Unknown RPC command %d - terminating session", command.command);
-    terminate();
+    (void)session->shutdownAndWait(false);
     return DEAD_OBJECT;
 }
-status_t RpcState::processTransact(const base::unique_fd& fd, const sp<RpcSession>& session,
-                                   const RpcWireHeader& command) {
+status_t RpcState::processTransact(const sp<RpcSession::RpcConnection>& connection,
+                                   const sp<RpcSession>& session, const RpcWireHeader& command) {
     LOG_ALWAYS_FATAL_IF(command.command != RPC_COMMAND_TRANSACT, "command: %d", command.command);
 
     CommandData transactionData(command.bodySize);
     if (!transactionData.valid()) {
         return NO_MEMORY;
     }
-    if (!rpcRec(fd, "transaction body", transactionData.data(), transactionData.size())) {
-        return DEAD_OBJECT;
-    }
+    if (status_t status = rpcRec(connection, session, "transaction body", transactionData.data(),
+                                 transactionData.size());
+        status != OK)
+        return status;
 
-    return processTransactInternal(fd, session, std::move(transactionData));
+    return processTransactInternal(connection, session, std::move(transactionData));
 }
 
 static void do_nothing_to_transact_data(Parcel* p, const uint8_t* data, size_t dataSize,
@@ -510,62 +743,88 @@
     (void)objectsCount;
 }
 
-status_t RpcState::processTransactInternal(const base::unique_fd& fd, const sp<RpcSession>& session,
+status_t RpcState::processTransactInternal(const sp<RpcSession::RpcConnection>& connection,
+                                           const sp<RpcSession>& session,
                                            CommandData transactionData) {
+    // for 'recursive' calls to this, we have already read and processed the
+    // binder from the transaction data and taken reference counts into account,
+    // so it is cached here.
+    sp<IBinder> target;
+processTransactInternalTailCall:
+
     if (transactionData.size() < sizeof(RpcWireTransaction)) {
         ALOGE("Expecting %zu but got %zu bytes for RpcWireTransaction. Terminating!",
               sizeof(RpcWireTransaction), transactionData.size());
-        terminate();
+        (void)session->shutdownAndWait(false);
         return BAD_VALUE;
     }
     RpcWireTransaction* transaction = reinterpret_cast<RpcWireTransaction*>(transactionData.data());
 
-    // TODO(b/182939933): heap allocation just for lookup in mNodeForAddress,
-    // maybe add an RpcAddress 'view' if the type remains 'heavy'
-    auto addr = RpcAddress::fromRawEmbedded(&transaction->address);
+    uint64_t addr = RpcWireAddress::toRaw(transaction->address);
+    bool oneway = transaction->flags & IBinder::FLAG_ONEWAY;
 
     status_t replyStatus = OK;
-    sp<IBinder> target;
-    if (!addr.isZero()) {
-        std::lock_guard<std::mutex> _l(mNodeMutex);
+    if (addr != 0) {
+        if (!target) {
+            replyStatus = onBinderEntering(session, addr, &target);
+        }
 
-        auto it = mNodeForAddress.find(addr);
-        if (it == mNodeForAddress.end()) {
-            ALOGE("Unknown binder address %s.", addr.toString().c_str());
+        if (replyStatus != OK) {
+            // do nothing
+        } else if (target == nullptr) {
+            // This can happen if the binder is remote in this process, and
+            // another thread has called the last decStrong on this binder.
+            // However, for local binders, it indicates a misbehaving client
+            // (any binder which is being transacted on should be holding a
+            // strong ref count), so in either case, terminating the
+            // session.
+            ALOGE("While transacting, binder has been deleted at address %" PRIu64 ". Terminating!",
+                  addr);
+            (void)session->shutdownAndWait(false);
             replyStatus = BAD_VALUE;
-        } else {
-            target = it->second.binder.promote();
-            if (target == nullptr) {
-                // This can happen if the binder is remote in this process, and
-                // another thread has called the last decStrong on this binder.
-                // However, for local binders, it indicates a misbehaving client
-                // (any binder which is being transacted on should be holding a
-                // strong ref count), so in either case, terminating the
-                // session.
-                ALOGE("While transacting, binder has been deleted at address %s. Terminating!",
-                      addr.toString().c_str());
-                terminate();
+        } else if (target->localBinder() == nullptr) {
+            ALOGE("Unknown binder address or non-local binder, not address %" PRIu64
+                  ". Terminating!",
+                  addr);
+            (void)session->shutdownAndWait(false);
+            replyStatus = BAD_VALUE;
+        } else if (oneway) {
+            std::unique_lock<std::mutex> _l(mNodeMutex);
+            auto it = mNodeForAddress.find(addr);
+            if (it->second.binder.promote() != target) {
+                ALOGE("Binder became invalid during transaction. Bad client? %" PRIu64, addr);
                 replyStatus = BAD_VALUE;
-            } else if (target->localBinder() == nullptr) {
-                ALOGE("Transactions can only go to local binders, not address %s. Terminating!",
-                      addr.toString().c_str());
-                terminate();
-                replyStatus = BAD_VALUE;
-            } else if (transaction->flags & IBinder::FLAG_ONEWAY) {
-                if (transaction->asyncNumber != it->second.asyncNumber) {
-                    // we need to process some other asynchronous transaction
-                    // first
-                    // TODO(b/183140903): limit enqueues/detect overfill for bad client
-                    // TODO(b/183140903): detect when an object is deleted when it still has
-                    //        pending async transactions
-                    it->second.asyncTodo.push(BinderNode::AsyncTodo{
-                            .data = std::move(transactionData),
-                            .asyncNumber = transaction->asyncNumber,
-                    });
-                    LOG_RPC_DETAIL("Enqueuing %" PRId64 " on %s", transaction->asyncNumber,
-                                   addr.toString().c_str());
-                    return OK;
+            } else if (transaction->asyncNumber != it->second.asyncNumber) {
+                // we need to process some other asynchronous transaction
+                // first
+                it->second.asyncTodo.push(BinderNode::AsyncTodo{
+                        .ref = target,
+                        .data = std::move(transactionData),
+                        .asyncNumber = transaction->asyncNumber,
+                });
+
+                size_t numPending = it->second.asyncTodo.size();
+                LOG_RPC_DETAIL("Enqueuing %" PRIu64 " on %" PRIu64 " (%zu pending)",
+                               transaction->asyncNumber, addr, numPending);
+
+                constexpr size_t kArbitraryOnewayCallTerminateLevel = 10000;
+                constexpr size_t kArbitraryOnewayCallWarnLevel = 1000;
+                constexpr size_t kArbitraryOnewayCallWarnPer = 1000;
+
+                if (numPending >= kArbitraryOnewayCallWarnLevel) {
+                    if (numPending >= kArbitraryOnewayCallTerminateLevel) {
+                        ALOGE("WARNING: %zu pending oneway transactions. Terminating!", numPending);
+                        _l.unlock();
+                        (void)session->shutdownAndWait(false);
+                        return FAILED_TRANSACTION;
+                    }
+
+                    if (numPending % kArbitraryOnewayCallWarnPer == 0) {
+                        ALOGW("Warning: many oneway transactions built up on %p (%zu)",
+                              target.get(), numPending);
+                    }
                 }
+                return OK;
             }
         }
     }
@@ -585,49 +844,56 @@
         data.markForRpc(session);
 
         if (target) {
+            bool origAllowNested = connection->allowNested;
+            connection->allowNested = !oneway;
+
             replyStatus = target->transact(transaction->code, data, &reply, transaction->flags);
+
+            connection->allowNested = origAllowNested;
         } else {
             LOG_RPC_DETAIL("Got special transaction %u", transaction->code);
 
-            sp<RpcServer> server = session->server().promote();
-            if (server) {
-                // special case for 'zero' address (special server commands)
-                switch (transaction->code) {
-                    case RPC_SPECIAL_TRANSACT_GET_ROOT: {
-                        replyStatus = reply.writeStrongBinder(server->getRootObject());
-                        break;
-                    }
-                    case RPC_SPECIAL_TRANSACT_GET_MAX_THREADS: {
-                        replyStatus = reply.writeInt32(server->getMaxThreads());
-                        break;
-                    }
-                    case RPC_SPECIAL_TRANSACT_GET_SESSION_ID: {
-                        // only sessions w/ services can be the source of a
-                        // session ID (so still guarded by non-null server)
-                        //
-                        // sessions associated with servers must have an ID
-                        // (hence abort)
-                        int32_t id = session->getPrivateAccessorForId().get().value();
-                        replyStatus = reply.writeInt32(id);
-                        break;
-                    }
-                    default: {
-                        replyStatus = UNKNOWN_TRANSACTION;
+            switch (transaction->code) {
+                case RPC_SPECIAL_TRANSACT_GET_MAX_THREADS: {
+                    replyStatus = reply.writeInt32(session->getMaxIncomingThreads());
+                    break;
+                }
+                case RPC_SPECIAL_TRANSACT_GET_SESSION_ID: {
+                    // for client connections, this should always report the value
+                    // originally returned from the server, so this is asserting
+                    // that it exists
+                    replyStatus = reply.writeByteVector(session->mId);
+                    break;
+                }
+                default: {
+                    sp<RpcServer> server = session->server();
+                    if (server) {
+                        switch (transaction->code) {
+                            case RPC_SPECIAL_TRANSACT_GET_ROOT: {
+                                sp<IBinder> root = session->mSessionSpecificRootObject
+                                        ?: server->getRootObject();
+                                replyStatus = reply.writeStrongBinder(root);
+                                break;
+                            }
+                            default: {
+                                replyStatus = UNKNOWN_TRANSACTION;
+                            }
+                        }
+                    } else {
+                        ALOGE("Special command sent, but no server object attached.");
                     }
                 }
-            } else {
-                ALOGE("Special command sent, but no server object attached.");
             }
         }
     }
 
-    if (transaction->flags & IBinder::FLAG_ONEWAY) {
+    if (oneway) {
         if (replyStatus != OK) {
             ALOGW("Oneway call failed with error: %d", replyStatus);
         }
 
-        LOG_RPC_DETAIL("Processed async transaction %" PRId64 " on %s", transaction->asyncNumber,
-                       addr.toString().c_str());
+        LOG_RPC_DETAIL("Processed async transaction %" PRIu64 " on %" PRIu64,
+                       transaction->asyncNumber, addr);
 
         // Check to see if there is another asynchronous transaction to process.
         // This behavior differs from binder behavior, since in the binder
@@ -645,123 +911,156 @@
             // last refcount dropped after this transaction happened
             if (it == mNodeForAddress.end()) return OK;
 
-            // note - only updated now, instead of later, so that other threads
-            // will queue any later transactions
-
-            // TODO(b/183140903): support > 2**64 async transactions
-            //     (we can do this by allowing asyncNumber to wrap, since we
-            //     don't expect more than 2**64 simultaneous transactions)
-            it->second.asyncNumber++;
+            if (!nodeProgressAsyncNumber(&it->second)) {
+                _l.unlock();
+                (void)session->shutdownAndWait(false);
+                return DEAD_OBJECT;
+            }
 
             if (it->second.asyncTodo.size() == 0) return OK;
             if (it->second.asyncTodo.top().asyncNumber == it->second.asyncNumber) {
-                LOG_RPC_DETAIL("Found next async transaction %" PRId64 " on %s",
-                               it->second.asyncNumber, addr.toString().c_str());
+                LOG_RPC_DETAIL("Found next async transaction %" PRIu64 " on %" PRIu64,
+                               it->second.asyncNumber, addr);
 
                 // justification for const_cast (consider avoiding priority_queue):
-                // - AsyncTodo operator< doesn't depend on 'data' object
+                // - AsyncTodo operator< doesn't depend on 'data' or 'ref' objects
                 // - gotta go fast
-                CommandData data = std::move(
-                        const_cast<BinderNode::AsyncTodo&>(it->second.asyncTodo.top()).data);
+                auto& todo = const_cast<BinderNode::AsyncTodo&>(it->second.asyncTodo.top());
+
+                // reset up arguments
+                transactionData = std::move(todo.data);
+                LOG_ALWAYS_FATAL_IF(target != todo.ref,
+                                    "async list should be associated with a binder");
+
                 it->second.asyncTodo.pop();
-                _l.unlock();
-                return processTransactInternal(fd, session, std::move(data));
+                goto processTransactInternalTailCall;
             }
         }
+
+        // done processing all the async commands on this binder that we can, so
+        // write decstrongs on the binder
+        if (addr != 0 && replyStatus == OK) {
+            return flushExcessBinderRefs(session, addr, target);
+        }
+
         return OK;
     }
 
+    // Binder refs are flushed for oneway calls only after all calls which are
+    // built up are executed. Otherwise, they fill up the binder buffer.
+    if (addr != 0 && replyStatus == OK) {
+        replyStatus = flushExcessBinderRefs(session, addr, target);
+    }
+
+    LOG_ALWAYS_FATAL_IF(std::numeric_limits<int32_t>::max() - sizeof(RpcWireHeader) -
+                                        sizeof(RpcWireReply) <
+                                reply.dataSize(),
+                        "Too much data for reply %zu", reply.dataSize());
+
+    RpcWireHeader cmdReply{
+            .command = RPC_COMMAND_REPLY,
+            .bodySize = static_cast<uint32_t>(sizeof(RpcWireReply) + reply.dataSize()),
+    };
     RpcWireReply rpcReply{
             .status = replyStatus,
     };
 
-    CommandData replyData(sizeof(RpcWireReply) + reply.dataSize());
+    CommandData replyData(sizeof(RpcWireHeader) + sizeof(RpcWireReply) + reply.dataSize());
     if (!replyData.valid()) {
         return NO_MEMORY;
     }
-    memcpy(replyData.data() + 0, &rpcReply, sizeof(RpcWireReply));
-    memcpy(replyData.data() + sizeof(RpcWireReply), reply.data(), reply.dataSize());
+    memcpy(replyData.data() + 0, &cmdReply, sizeof(RpcWireHeader));
+    memcpy(replyData.data() + sizeof(RpcWireHeader), &rpcReply, sizeof(RpcWireReply));
+    memcpy(replyData.data() + sizeof(RpcWireHeader) + sizeof(RpcWireReply), reply.data(),
+           reply.dataSize());
 
-    if (replyData.size() > std::numeric_limits<uint32_t>::max()) {
-        ALOGE("Reply size too big %zu", transactionData.size());
-        terminate();
-        return BAD_VALUE;
-    }
-
-    RpcWireHeader cmdReply{
-            .command = RPC_COMMAND_REPLY,
-            .bodySize = static_cast<uint32_t>(replyData.size()),
-    };
-
-    if (!rpcSend(fd, "reply header", &cmdReply, sizeof(RpcWireHeader))) {
-        return DEAD_OBJECT;
-    }
-    if (!rpcSend(fd, "reply body", replyData.data(), replyData.size())) {
-        return DEAD_OBJECT;
-    }
-    return OK;
+    return rpcSend(connection, session, "reply", replyData.data(), replyData.size());
 }
 
-status_t RpcState::processDecStrong(const base::unique_fd& fd, const RpcWireHeader& command) {
+status_t RpcState::processDecStrong(const sp<RpcSession::RpcConnection>& connection,
+                                    const sp<RpcSession>& session, const RpcWireHeader& command) {
     LOG_ALWAYS_FATAL_IF(command.command != RPC_COMMAND_DEC_STRONG, "command: %d", command.command);
 
     CommandData commandData(command.bodySize);
     if (!commandData.valid()) {
         return NO_MEMORY;
     }
-    if (!rpcRec(fd, "dec ref body", commandData.data(), commandData.size())) {
-        return DEAD_OBJECT;
-    }
+    if (status_t status =
+                rpcRec(connection, session, "dec ref body", commandData.data(), commandData.size());
+        status != OK)
+        return status;
 
-    if (command.bodySize < sizeof(RpcWireAddress)) {
-        ALOGE("Expecting %zu but got %" PRId32 " bytes for RpcWireAddress. Terminating!",
-              sizeof(RpcWireAddress), command.bodySize);
-        terminate();
+    if (command.bodySize != sizeof(RpcDecStrong)) {
+        ALOGE("Expecting %zu but got %" PRId32 " bytes for RpcDecStrong. Terminating!",
+              sizeof(RpcDecStrong), command.bodySize);
+        (void)session->shutdownAndWait(false);
         return BAD_VALUE;
     }
-    RpcWireAddress* address = reinterpret_cast<RpcWireAddress*>(commandData.data());
+    RpcDecStrong* body = reinterpret_cast<RpcDecStrong*>(commandData.data());
 
-    // TODO(b/182939933): heap allocation just for lookup
-    auto addr = RpcAddress::fromRawEmbedded(address);
+    uint64_t addr = RpcWireAddress::toRaw(body->address);
     std::unique_lock<std::mutex> _l(mNodeMutex);
     auto it = mNodeForAddress.find(addr);
     if (it == mNodeForAddress.end()) {
-        ALOGE("Unknown binder address %s for dec strong.", addr.toString().c_str());
+        ALOGE("Unknown binder address %" PRIu64 " for dec strong.", addr);
         return OK;
     }
 
     sp<IBinder> target = it->second.binder.promote();
     if (target == nullptr) {
-        ALOGE("While requesting dec strong, binder has been deleted at address %s. Terminating!",
-              addr.toString().c_str());
-        terminate();
+        ALOGE("While requesting dec strong, binder has been deleted at address %" PRIu64
+              ". Terminating!",
+              addr);
+        _l.unlock();
+        (void)session->shutdownAndWait(false);
         return BAD_VALUE;
     }
 
-    if (it->second.timesSent == 0) {
-        ALOGE("No record of sending binder, but requested decStrong: %s", addr.toString().c_str());
+    if (it->second.timesSent < body->amount) {
+        ALOGE("Record of sending binder %zu times, but requested decStrong for %" PRIu64 " of %u",
+              it->second.timesSent, addr, body->amount);
         return OK;
     }
 
-    LOG_ALWAYS_FATAL_IF(it->second.sentRef == nullptr, "Inconsistent state, lost ref for %s",
-                        addr.toString().c_str());
+    LOG_ALWAYS_FATAL_IF(it->second.sentRef == nullptr, "Inconsistent state, lost ref for %" PRIu64,
+                        addr);
 
-    sp<IBinder> tempHold;
+    LOG_RPC_DETAIL("Processing dec strong of %" PRIu64 " by %u from %zu", addr, body->amount,
+                   it->second.timesSent);
 
-    it->second.timesSent--;
-    if (it->second.timesSent == 0) {
-        tempHold = it->second.sentRef;
-        it->second.sentRef = nullptr;
-
-        if (it->second.timesRecd == 0) {
-            mNodeForAddress.erase(it);
-        }
-    }
-
+    it->second.timesSent -= body->amount;
+    sp<IBinder> tempHold = tryEraseNode(it);
     _l.unlock();
     tempHold = nullptr; // destructor may make binder calls on this session
 
     return OK;
 }
 
+sp<IBinder> RpcState::tryEraseNode(std::map<uint64_t, BinderNode>::iterator& it) {
+    sp<IBinder> ref;
+
+    if (it->second.timesSent == 0) {
+        ref = std::move(it->second.sentRef);
+
+        if (it->second.timesRecd == 0) {
+            LOG_ALWAYS_FATAL_IF(!it->second.asyncTodo.empty(),
+                                "Can't delete binder w/ pending async transactions");
+            mNodeForAddress.erase(it);
+        }
+    }
+
+    return ref;
+}
+
+bool RpcState::nodeProgressAsyncNumber(BinderNode* node) {
+    // 2**64 =~ 10**19 =~ 1000 transactions per second for 585 million years to
+    // a single binder
+    if (node->asyncNumber >= std::numeric_limits<decltype(node->asyncNumber)>::max()) {
+        ALOGE("Out of async transaction IDs. Terminating");
+        return false;
+    }
+    node->asyncNumber++;
+    return true;
+}
+
 } // namespace android
diff --git a/libs/binder/RpcState.h b/libs/binder/RpcState.h
index 31f8a22..dba0a43 100644
--- a/libs/binder/RpcState.h
+++ b/libs/binder/RpcState.h
@@ -42,6 +42,15 @@
 #define LOG_RPC_DETAIL(...) ALOGV(__VA_ARGS__) // for type checking
 #endif
 
+#define RPC_FLAKE_PRONE false
+
+#if RPC_FLAKE_PRONE
+void rpcMaybeWaitToFlake();
+#define MAYBE_WAIT_IN_FLAKE_MODE rpcMaybeWaitToFlake()
+#else
+#define MAYBE_WAIT_IN_FLAKE_MODE do {} while (false)
+#endif
+
 /**
  * Abstracts away management of ref counts and the wire format from
  * RpcSession
@@ -51,38 +60,87 @@
     RpcState();
     ~RpcState();
 
-    // TODO(b/182940634): combine some special transactions into one "getServerInfo" call?
-    sp<IBinder> getRootObject(const base::unique_fd& fd, const sp<RpcSession>& session);
-    status_t getMaxThreads(const base::unique_fd& fd, const sp<RpcSession>& session,
-                           size_t* maxThreadsOut);
-    status_t getSessionId(const base::unique_fd& fd, const sp<RpcSession>& session,
-                          int32_t* sessionIdOut);
+    [[nodiscard]] status_t readNewSessionResponse(const sp<RpcSession::RpcConnection>& connection,
+                                                  const sp<RpcSession>& session, uint32_t* version);
+    [[nodiscard]] status_t sendConnectionInit(const sp<RpcSession::RpcConnection>& connection,
+                                              const sp<RpcSession>& session);
+    [[nodiscard]] status_t readConnectionInit(const sp<RpcSession::RpcConnection>& connection,
+                                              const sp<RpcSession>& session);
 
-    [[nodiscard]] status_t transact(const base::unique_fd& fd, const RpcAddress& address,
-                                    uint32_t code, const Parcel& data,
+    // TODO(b/182940634): combine some special transactions into one "getServerInfo" call?
+    sp<IBinder> getRootObject(const sp<RpcSession::RpcConnection>& connection,
+                              const sp<RpcSession>& session);
+    [[nodiscard]] status_t getMaxThreads(const sp<RpcSession::RpcConnection>& connection,
+                                         const sp<RpcSession>& session, size_t* maxThreadsOut);
+    [[nodiscard]] status_t getSessionId(const sp<RpcSession::RpcConnection>& connection,
+                                        const sp<RpcSession>& session,
+                                        std::vector<uint8_t>* sessionIdOut);
+
+    [[nodiscard]] status_t transact(const sp<RpcSession::RpcConnection>& connection,
+                                    const sp<IBinder>& address, uint32_t code, const Parcel& data,
                                     const sp<RpcSession>& session, Parcel* reply, uint32_t flags);
-    [[nodiscard]] status_t sendDecStrong(const base::unique_fd& fd, const RpcAddress& address);
-    [[nodiscard]] status_t getAndExecuteCommand(const base::unique_fd& fd,
-                                                const sp<RpcSession>& session);
+    [[nodiscard]] status_t transactAddress(const sp<RpcSession::RpcConnection>& connection,
+                                           uint64_t address, uint32_t code, const Parcel& data,
+                                           const sp<RpcSession>& session, Parcel* reply,
+                                           uint32_t flags);
+
+    /**
+     * The ownership model here carries an implicit strong refcount whenever a
+     * binder is sent across processes. Since we have a local strong count in
+     * sp<> over these objects, we only ever need to keep one of these. So,
+     * typically we tell the remote process that we drop all the implicit dec
+     * strongs, and we hold onto the last one. 'target' here is the target
+     * timesRecd (the number of remaining reference counts) we wish to keep.
+     * Typically this should be '0' or '1'. The target is used instead of an
+     * explicit decrement count in order to allow multiple threads to lower the
+     * number of counts simultaneously. Since we only lower the count to 0 when
+     * a binder is deleted, targets of '1' should only be sent when the caller
+     * owns a local strong reference to the binder. Larger targets may be used
+     * for testing, and to make the function generic, but generally this should
+     * be avoided because it would be hard to guarantee another thread doesn't
+     * lower the number of held refcounts to '1'. Note also, these refcounts
+     * must be sent actively. If they are sent when binders are deleted, this
+     * can cause leaks, since even remote binders carry an implicit strong ref
+     * when they are sent to another process.
+     */
+    [[nodiscard]] status_t sendDecStrongToTarget(const sp<RpcSession::RpcConnection>& connection,
+                                                 const sp<RpcSession>& session, uint64_t address,
+                                                 size_t target);
+
+    enum class CommandType {
+        ANY,
+        CONTROL_ONLY,
+    };
+    [[nodiscard]] status_t getAndExecuteCommand(const sp<RpcSession::RpcConnection>& connection,
+                                                const sp<RpcSession>& session, CommandType type);
+    [[nodiscard]] status_t drainCommands(const sp<RpcSession::RpcConnection>& connection,
+                                         const sp<RpcSession>& session, CommandType type);
 
     /**
      * Called by Parcel for outgoing binders. This implies one refcount of
      * ownership to the outgoing binder.
      */
     [[nodiscard]] status_t onBinderLeaving(const sp<RpcSession>& session, const sp<IBinder>& binder,
-                                           RpcAddress* outAddress);
+                                           uint64_t* outAddress);
 
     /**
      * Called by Parcel for incoming binders. This either returns the refcount
      * to the process, if this process already has one, or it takes ownership of
      * that refcount
      */
-    sp<IBinder> onBinderEntering(const sp<RpcSession>& session, const RpcAddress& address);
+    [[nodiscard]] status_t onBinderEntering(const sp<RpcSession>& session, uint64_t address,
+                                            sp<IBinder>* out);
+    /**
+     * Called on incoming binders to update refcounting information. This should
+     * only be called when it is done as part of making progress on a
+     * transaction.
+     */
+    [[nodiscard]] status_t flushExcessBinderRefs(const sp<RpcSession>& session, uint64_t address,
+                                                 const sp<IBinder>& binder);
 
     size_t countBinders();
     void dump();
 
-private:
     /**
      * Called when reading or writing data to a session fails to clean up
      * data associated with the session in order to cleanup binders.
@@ -99,7 +157,10 @@
      * WARNING: RpcState is responsible for calling this when the session is
      * no longer recoverable.
      */
-    void terminate();
+    void clear();
+
+private:
+    void dumpLocked();
 
     // Alternative to std::vector<uint8_t> that doesn't abort on allocation failure and caps
     // large allocations to avoid being requested from allocating too much data.
@@ -115,21 +176,27 @@
         size_t mSize;
     };
 
-    [[nodiscard]] bool rpcSend(const base::unique_fd& fd, const char* what, const void* data,
-                               size_t size);
-    [[nodiscard]] bool rpcRec(const base::unique_fd& fd, const char* what, void* data, size_t size);
+    [[nodiscard]] status_t rpcSend(const sp<RpcSession::RpcConnection>& connection,
+                                   const sp<RpcSession>& session, const char* what,
+                                   const void* data, size_t size,
+                                   const std::function<status_t()>& altPoll = nullptr);
+    [[nodiscard]] status_t rpcRec(const sp<RpcSession::RpcConnection>& connection,
+                                  const sp<RpcSession>& session, const char* what, void* data,
+                                  size_t size);
 
-    [[nodiscard]] status_t waitForReply(const base::unique_fd& fd, const sp<RpcSession>& session,
-                                        Parcel* reply);
-    [[nodiscard]] status_t processServerCommand(const base::unique_fd& fd,
-                                                const sp<RpcSession>& session,
-                                                const RpcWireHeader& command);
-    [[nodiscard]] status_t processTransact(const base::unique_fd& fd, const sp<RpcSession>& session,
+    [[nodiscard]] status_t waitForReply(const sp<RpcSession::RpcConnection>& connection,
+                                        const sp<RpcSession>& session, Parcel* reply);
+    [[nodiscard]] status_t processCommand(const sp<RpcSession::RpcConnection>& connection,
+                                          const sp<RpcSession>& session,
+                                          const RpcWireHeader& command, CommandType type);
+    [[nodiscard]] status_t processTransact(const sp<RpcSession::RpcConnection>& connection,
+                                           const sp<RpcSession>& session,
                                            const RpcWireHeader& command);
-    [[nodiscard]] status_t processTransactInternal(const base::unique_fd& fd,
+    [[nodiscard]] status_t processTransactInternal(const sp<RpcSession::RpcConnection>& connection,
                                                    const sp<RpcSession>& session,
                                                    CommandData transactionData);
-    [[nodiscard]] status_t processDecStrong(const base::unique_fd& fd,
+    [[nodiscard]] status_t processDecStrong(const sp<RpcSession::RpcConnection>& connection,
+                                            const sp<RpcSession>& session,
                                             const RpcWireHeader& command);
 
     struct BinderNode {
@@ -163,6 +230,7 @@
 
         // async transaction queue, _only_ for local binder
         struct AsyncTodo {
+            sp<IBinder> ref;
             CommandData data;
             uint64_t asyncNumber = 0;
 
@@ -179,10 +247,20 @@
         // (no additional data specific to remote binders)
     };
 
+    // checks if there is any reference left to a node and erases it. If erase
+    // happens, and there is a strong reference to the binder kept by
+    // binderNode, this returns that strong reference, so that it can be
+    // dropped after any locks are removed.
+    sp<IBinder> tryEraseNode(std::map<uint64_t, BinderNode>::iterator& it);
+    // true - success
+    // false - session shutdown, halt
+    [[nodiscard]] bool nodeProgressAsyncNumber(BinderNode* node);
+
     std::mutex mNodeMutex;
     bool mTerminated = false;
+    uint32_t mNextId = 0;
     // binders known by both sides of a session
-    std::map<RpcAddress, BinderNode> mNodeForAddress;
+    std::map<uint64_t, BinderNode> mNodeForAddress;
 };
 
 } // namespace android
diff --git a/libs/binder/RpcTlsUtils.cpp b/libs/binder/RpcTlsUtils.cpp
new file mode 100644
index 0000000..f3ca02a
--- /dev/null
+++ b/libs/binder/RpcTlsUtils.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "RpcTlsUtils"
+#include <log/log.h>
+
+#include <binder/RpcTlsUtils.h>
+
+#include "Utils.h"
+
+namespace android {
+
+namespace {
+
+static_assert(sizeof(unsigned char) == sizeof(uint8_t));
+
+template <typename PemReadBioFn,
+          typename T = std::remove_pointer_t<std::invoke_result_t<
+                  PemReadBioFn, BIO*, std::nullptr_t, std::nullptr_t, std::nullptr_t>>>
+bssl::UniquePtr<T> fromPem(const std::vector<uint8_t>& data, PemReadBioFn fn) {
+    if (data.size() > std::numeric_limits<int>::max()) return nullptr;
+    bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(data.data(), static_cast<int>(data.size())));
+    return bssl::UniquePtr<T>(fn(bio.get(), nullptr, nullptr, nullptr));
+}
+
+template <typename D2iFn,
+          typename T = std::remove_pointer_t<
+                  std::invoke_result_t<D2iFn, std::nullptr_t, const unsigned char**, long>>>
+bssl::UniquePtr<T> fromDer(const std::vector<uint8_t>& data, D2iFn fn) {
+    if (data.size() > std::numeric_limits<long>::max()) return nullptr;
+    const unsigned char* dataPtr = data.data();
+    auto expectedEnd = dataPtr + data.size();
+    bssl::UniquePtr<T> ret(fn(nullptr, &dataPtr, static_cast<long>(data.size())));
+    if (dataPtr != expectedEnd) {
+        ALOGE("%s: %td bytes remaining!", __PRETTY_FUNCTION__, expectedEnd - dataPtr);
+        return nullptr;
+    }
+    return ret;
+}
+
+template <typename T, typename WriteBioFn = int (*)(BIO*, T*)>
+std::vector<uint8_t> serialize(T* object, WriteBioFn writeBio) {
+    bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
+    TEST_AND_RETURN({}, writeBio(bio.get(), object));
+    const uint8_t* data;
+    size_t len;
+    TEST_AND_RETURN({}, BIO_mem_contents(bio.get(), &data, &len));
+    return std::vector<uint8_t>(data, data + len);
+}
+
+} // namespace
+
+bssl::UniquePtr<X509> deserializeCertificate(const std::vector<uint8_t>& data,
+                                             RpcCertificateFormat format) {
+    switch (format) {
+        case RpcCertificateFormat::PEM:
+            return fromPem(data, PEM_read_bio_X509);
+        case RpcCertificateFormat::DER:
+            return fromDer(data, d2i_X509);
+    }
+    LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
+}
+
+std::vector<uint8_t> serializeCertificate(X509* x509, RpcCertificateFormat format) {
+    switch (format) {
+        case RpcCertificateFormat::PEM:
+            return serialize(x509, PEM_write_bio_X509);
+        case RpcCertificateFormat::DER:
+            return serialize(x509, i2d_X509_bio);
+    }
+    LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
+}
+
+bssl::UniquePtr<EVP_PKEY> deserializeUnencryptedPrivatekey(const std::vector<uint8_t>& data,
+                                                           RpcKeyFormat format) {
+    switch (format) {
+        case RpcKeyFormat::PEM:
+            return fromPem(data, PEM_read_bio_PrivateKey);
+        case RpcKeyFormat::DER:
+            return fromDer(data, d2i_AutoPrivateKey);
+    }
+    LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
+}
+
+std::vector<uint8_t> serializeUnencryptedPrivatekey(EVP_PKEY* pkey, RpcKeyFormat format) {
+    switch (format) {
+        case RpcKeyFormat::PEM:
+            return serialize(pkey, [](BIO* bio, EVP_PKEY* pkey) {
+                return PEM_write_bio_PrivateKey(bio, pkey, nullptr /* enc */, nullptr /* kstr */,
+                                                0 /* klen */, nullptr, nullptr);
+            });
+        case RpcKeyFormat::DER:
+            return serialize(pkey, i2d_PrivateKey_bio);
+    }
+    LOG_ALWAYS_FATAL("Unsupported format %d", static_cast<int>(format));
+}
+
+} // namespace android
diff --git a/libs/binder/RpcTransportRaw.cpp b/libs/binder/RpcTransportRaw.cpp
new file mode 100644
index 0000000..7669518
--- /dev/null
+++ b/libs/binder/RpcTransportRaw.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "RpcRawTransport"
+#include <log/log.h>
+
+#include <poll.h>
+
+#include <binder/RpcTransportRaw.h>
+
+#include "FdTrigger.h"
+#include "RpcState.h"
+
+using android::base::ErrnoError;
+using android::base::Result;
+
+namespace android {
+
+namespace {
+
+// RpcTransport with TLS disabled.
+class RpcTransportRaw : public RpcTransport {
+public:
+    explicit RpcTransportRaw(android::base::unique_fd socket) : mSocket(std::move(socket)) {}
+    Result<size_t> peek(void *buf, size_t size) override {
+        ssize_t ret = TEMP_FAILURE_RETRY(::recv(mSocket.get(), buf, size, MSG_PEEK));
+        if (ret < 0) {
+            return ErrnoError() << "recv(MSG_PEEK)";
+        }
+        return ret;
+    }
+
+    template <typename Buffer, typename SendOrReceive>
+    status_t interruptableReadOrWrite(FdTrigger* fdTrigger, Buffer buffer, size_t size,
+                                      SendOrReceive sendOrReceiveFun, const char* funName,
+                                      int16_t event, const std::function<status_t()>& altPoll) {
+        const Buffer end = buffer + size;
+
+        MAYBE_WAIT_IN_FLAKE_MODE;
+
+        // Since we didn't poll, we need to manually check to see if it was triggered. Otherwise, we
+        // may never know we should be shutting down.
+        if (fdTrigger->isTriggered()) {
+            return DEAD_OBJECT;
+        }
+
+        bool havePolled = false;
+        while (true) {
+            ssize_t processSize = TEMP_FAILURE_RETRY(
+                    sendOrReceiveFun(mSocket.get(), buffer, end - buffer, MSG_NOSIGNAL));
+
+            if (processSize < 0) {
+                int savedErrno = errno;
+
+                // Still return the error on later passes, since it would expose
+                // a problem with polling
+                if (havePolled ||
+                    (!havePolled && savedErrno != EAGAIN && savedErrno != EWOULDBLOCK)) {
+                    LOG_RPC_DETAIL("RpcTransport %s(): %s", funName, strerror(savedErrno));
+                    return -savedErrno;
+                }
+            } else if (processSize == 0) {
+                return DEAD_OBJECT;
+            } else {
+                buffer += processSize;
+                if (buffer == end) {
+                    return OK;
+                }
+            }
+
+            if (altPoll) {
+                if (status_t status = altPoll(); status != OK) return status;
+                if (fdTrigger->isTriggered()) {
+                    return DEAD_OBJECT;
+                }
+            } else {
+                if (status_t status = fdTrigger->triggerablePoll(mSocket.get(), event);
+                    status != OK)
+                    return status;
+                if (!havePolled) havePolled = true;
+            }
+        }
+    }
+
+    status_t interruptableWriteFully(FdTrigger* fdTrigger, const void* data, size_t size,
+                                     const std::function<status_t()>& altPoll) override {
+        return interruptableReadOrWrite(fdTrigger, reinterpret_cast<const uint8_t*>(data), size,
+                                        send, "send", POLLOUT, altPoll);
+    }
+
+    status_t interruptableReadFully(FdTrigger* fdTrigger, void* data, size_t size,
+                                    const std::function<status_t()>& altPoll) override {
+        return interruptableReadOrWrite(fdTrigger, reinterpret_cast<uint8_t*>(data), size, recv,
+                                        "recv", POLLIN, altPoll);
+    }
+
+private:
+    base::unique_fd mSocket;
+};
+
+// RpcTransportCtx with TLS disabled.
+class RpcTransportCtxRaw : public RpcTransportCtx {
+public:
+    std::unique_ptr<RpcTransport> newTransport(android::base::unique_fd fd, FdTrigger*) const {
+        return std::make_unique<RpcTransportRaw>(std::move(fd));
+    }
+    std::vector<uint8_t> getCertificate(RpcCertificateFormat) const override { return {}; }
+};
+
+} // namespace
+
+std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryRaw::newServerCtx() const {
+    return std::make_unique<RpcTransportCtxRaw>();
+}
+
+std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryRaw::newClientCtx() const {
+    return std::make_unique<RpcTransportCtxRaw>();
+}
+
+const char *RpcTransportCtxFactoryRaw::toCString() const {
+    return "raw";
+}
+
+std::unique_ptr<RpcTransportCtxFactory> RpcTransportCtxFactoryRaw::make() {
+    return std::unique_ptr<RpcTransportCtxFactoryRaw>(new RpcTransportCtxFactoryRaw());
+}
+
+} // namespace android
diff --git a/libs/binder/RpcTransportTls.cpp b/libs/binder/RpcTransportTls.cpp
new file mode 100644
index 0000000..7f810b1
--- /dev/null
+++ b/libs/binder/RpcTransportTls.cpp
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "RpcTransportTls"
+#include <log/log.h>
+
+#include <poll.h>
+
+#include <openssl/bn.h>
+#include <openssl/ssl.h>
+
+#include <binder/RpcTlsUtils.h>
+#include <binder/RpcTransportTls.h>
+
+#include "FdTrigger.h"
+#include "RpcState.h"
+#include "Utils.h"
+
+#define SHOULD_LOG_TLS_DETAIL false
+
+#if SHOULD_LOG_TLS_DETAIL
+#define LOG_TLS_DETAIL(...) ALOGI(__VA_ARGS__)
+#else
+#define LOG_TLS_DETAIL(...) ALOGV(__VA_ARGS__) // for type checking
+#endif
+
+using android::base::ErrnoError;
+using android::base::Error;
+using android::base::Result;
+
+namespace android {
+namespace {
+
+// Implement BIO for socket that ignores SIGPIPE.
+int socketNew(BIO* bio) {
+    BIO_set_data(bio, reinterpret_cast<void*>(-1));
+    BIO_set_init(bio, 0);
+    return 1;
+}
+int socketFree(BIO* bio) {
+    LOG_ALWAYS_FATAL_IF(bio == nullptr);
+    return 1;
+}
+int socketRead(BIO* bio, char* buf, int size) {
+    android::base::borrowed_fd fd(static_cast<int>(reinterpret_cast<intptr_t>(BIO_get_data(bio))));
+    int ret = TEMP_FAILURE_RETRY(::recv(fd.get(), buf, size, MSG_NOSIGNAL));
+    BIO_clear_retry_flags(bio);
+    if (errno == EAGAIN || errno == EWOULDBLOCK) {
+        BIO_set_retry_read(bio);
+    }
+    return ret;
+}
+
+int socketWrite(BIO* bio, const char* buf, int size) {
+    android::base::borrowed_fd fd(static_cast<int>(reinterpret_cast<intptr_t>(BIO_get_data(bio))));
+    int ret = TEMP_FAILURE_RETRY(::send(fd.get(), buf, size, MSG_NOSIGNAL));
+    BIO_clear_retry_flags(bio);
+    if (errno == EAGAIN || errno == EWOULDBLOCK) {
+        BIO_set_retry_write(bio);
+    }
+    return ret;
+}
+
+long socketCtrl(BIO* bio, int cmd, long num, void*) { // NOLINT
+    android::base::borrowed_fd fd(static_cast<int>(reinterpret_cast<intptr_t>(BIO_get_data(bio))));
+    if (cmd == BIO_CTRL_FLUSH) return 1;
+    LOG_ALWAYS_FATAL("sockCtrl(fd=%d, %d, %ld)", fd.get(), cmd, num);
+    return 0;
+}
+
+bssl::UniquePtr<BIO> newSocketBio(android::base::borrowed_fd fd) {
+    static const BIO_METHOD* gMethods = ([] {
+        auto methods = BIO_meth_new(BIO_get_new_index(), "socket_no_signal");
+        LOG_ALWAYS_FATAL_IF(0 == BIO_meth_set_write(methods, socketWrite), "BIO_meth_set_write");
+        LOG_ALWAYS_FATAL_IF(0 == BIO_meth_set_read(methods, socketRead), "BIO_meth_set_read");
+        LOG_ALWAYS_FATAL_IF(0 == BIO_meth_set_ctrl(methods, socketCtrl), "BIO_meth_set_ctrl");
+        LOG_ALWAYS_FATAL_IF(0 == BIO_meth_set_create(methods, socketNew), "BIO_meth_set_create");
+        LOG_ALWAYS_FATAL_IF(0 == BIO_meth_set_destroy(methods, socketFree), "BIO_meth_set_destroy");
+        return methods;
+    })();
+    bssl::UniquePtr<BIO> ret(BIO_new(gMethods));
+    if (ret == nullptr) return nullptr;
+    BIO_set_data(ret.get(), reinterpret_cast<void*>(fd.get()));
+    BIO_set_init(ret.get(), 1);
+    return ret;
+}
+
+[[maybe_unused]] void sslDebugLog(const SSL* ssl, int type, int value) {
+    switch (type) {
+        case SSL_CB_HANDSHAKE_START:
+            LOG_TLS_DETAIL("Handshake started.");
+            break;
+        case SSL_CB_HANDSHAKE_DONE:
+            LOG_TLS_DETAIL("Handshake done.");
+            break;
+        case SSL_CB_ACCEPT_LOOP:
+            LOG_TLS_DETAIL("Handshake progress: %s", SSL_state_string_long(ssl));
+            break;
+        default:
+            LOG_TLS_DETAIL("SSL Debug Log: type = %d, value = %d", type, value);
+            break;
+    }
+}
+
+// Helper class to ErrorQueue::toString
+class ErrorQueueString {
+public:
+    static std::string toString() {
+        ErrorQueueString thiz;
+        ERR_print_errors_cb(staticCallback, &thiz);
+        return thiz.mSs.str();
+    }
+
+private:
+    static int staticCallback(const char* str, size_t len, void* ctx) {
+        return reinterpret_cast<ErrorQueueString*>(ctx)->callback(str, len);
+    }
+    int callback(const char* str, size_t len) {
+        if (len == 0) return 1; // continue
+        // ERR_print_errors_cb place a new line at the end, but it doesn't say so in the API.
+        if (str[len - 1] == '\n') len -= 1;
+        if (!mIsFirst) {
+            mSs << '\n';
+        }
+        mSs << std::string_view(str, len);
+        mIsFirst = false;
+        return 1; // continue
+    }
+    std::stringstream mSs;
+    bool mIsFirst = true;
+};
+
+// Handles libssl's error queue.
+//
+// Call into any of its member functions to ensure the error queue is properly handled or cleared.
+// If the error queue is not handled or cleared, the destructor will abort.
+class ErrorQueue {
+public:
+    ~ErrorQueue() { LOG_ALWAYS_FATAL_IF(!mHandled); }
+
+    // Clear the error queue.
+    void clear() {
+        ERR_clear_error();
+        mHandled = true;
+    }
+
+    // Stores the error queue in |ssl| into a string, then clears the error queue.
+    std::string toString() {
+        auto ret = ErrorQueueString::toString();
+        // Though ERR_print_errors_cb should have cleared it, it is okay to clear again.
+        clear();
+        return ret;
+    }
+
+    // |sslError| should be from Ssl::getError().
+    // If |sslError| is WANT_READ / WANT_WRITE, poll for POLLIN / POLLOUT respectively. Otherwise
+    // return error. Also return error if |fdTrigger| is triggered before or during poll().
+    status_t pollForSslError(android::base::borrowed_fd fd, int sslError, FdTrigger* fdTrigger,
+                             const char* fnString, int additionalEvent,
+                             const std::function<status_t()>& altPoll) {
+        switch (sslError) {
+            case SSL_ERROR_WANT_READ:
+                return handlePoll(POLLIN | additionalEvent, fd, fdTrigger, fnString, altPoll);
+            case SSL_ERROR_WANT_WRITE:
+                return handlePoll(POLLOUT | additionalEvent, fd, fdTrigger, fnString, altPoll);
+            case SSL_ERROR_SYSCALL: {
+                auto queue = toString();
+                LOG_TLS_DETAIL("%s(): %s. Treating as DEAD_OBJECT. Error queue: %s", fnString,
+                               SSL_error_description(sslError), queue.c_str());
+                return DEAD_OBJECT;
+            }
+            default: {
+                auto queue = toString();
+                ALOGE("%s(): %s. Error queue: %s", fnString, SSL_error_description(sslError),
+                      queue.c_str());
+                return UNKNOWN_ERROR;
+            }
+        }
+    }
+
+private:
+    bool mHandled = false;
+
+    status_t handlePoll(int event, android::base::borrowed_fd fd, FdTrigger* fdTrigger,
+                        const char* fnString, const std::function<status_t()>& altPoll) {
+        status_t ret;
+        if (altPoll) {
+            ret = altPoll();
+            if (fdTrigger->isTriggered()) ret = DEAD_OBJECT;
+        } else {
+            ret = fdTrigger->triggerablePoll(fd, event);
+        }
+
+        if (ret != OK && ret != DEAD_OBJECT) {
+            ALOGE("poll error while after %s(): %s", fnString, statusToString(ret).c_str());
+        }
+        clear();
+        return ret;
+    }
+};
+
+// Helper to call a function, with its return value instantiable.
+template <typename Fn, typename... Args>
+struct FuncCaller {
+    struct Monostate {};
+    static constexpr bool sIsVoid = std::is_void_v<std::invoke_result_t<Fn, Args...>>;
+    using Result = std::conditional_t<sIsVoid, Monostate, std::invoke_result_t<Fn, Args...>>;
+    static inline Result call(Fn fn, Args&&... args) {
+        if constexpr (std::is_void_v<std::invoke_result_t<Fn, Args...>>) {
+            std::invoke(fn, std::forward<Args>(args)...);
+            return {};
+        } else {
+            return std::invoke(fn, std::forward<Args>(args)...);
+        }
+    }
+};
+
+// Helper to Ssl::call(). Returns the result to the SSL_* function as well as an ErrorQueue object.
+template <typename Fn, typename... Args>
+struct SslCaller {
+    using RawCaller = FuncCaller<Fn, SSL*, Args...>;
+    struct ResultAndErrorQueue {
+        typename RawCaller::Result result;
+        ErrorQueue errorQueue;
+    };
+    static inline ResultAndErrorQueue call(Fn fn, SSL* ssl, Args&&... args) {
+        LOG_ALWAYS_FATAL_IF(ssl == nullptr);
+        auto result = RawCaller::call(fn, std::forward<SSL*>(ssl), std::forward<Args>(args)...);
+        return ResultAndErrorQueue{std::move(result), ErrorQueue()};
+    }
+};
+
+// A wrapper over bssl::UniquePtr<SSL>. This class ensures that all SSL_* functions are called
+// through call(), which returns an ErrorQueue object that requires the caller to either handle
+// or clear it.
+// Example:
+//   auto [ret, errorQueue] = ssl.call(SSL_read, buf, size);
+//   if (ret >= 0) errorQueue.clear();
+//   else ALOGE("%s", errorQueue.toString().c_str());
+class Ssl {
+public:
+    explicit Ssl(bssl::UniquePtr<SSL> ssl) : mSsl(std::move(ssl)) {
+        LOG_ALWAYS_FATAL_IF(mSsl == nullptr);
+    }
+
+    template <typename Fn, typename... Args>
+    inline typename SslCaller<Fn, Args...>::ResultAndErrorQueue call(Fn fn, Args&&... args) {
+        return SslCaller<Fn, Args...>::call(fn, mSsl.get(), std::forward<Args>(args)...);
+    }
+
+    int getError(int ret) {
+        LOG_ALWAYS_FATAL_IF(mSsl == nullptr);
+        return SSL_get_error(mSsl.get(), ret);
+    }
+
+private:
+    bssl::UniquePtr<SSL> mSsl;
+};
+
+class RpcTransportTls : public RpcTransport {
+public:
+    RpcTransportTls(android::base::unique_fd socket, Ssl ssl)
+          : mSocket(std::move(socket)), mSsl(std::move(ssl)) {}
+    Result<size_t> peek(void* buf, size_t size) override;
+    status_t interruptableWriteFully(FdTrigger* fdTrigger, const void* data, size_t size,
+                                     const std::function<status_t()>& altPoll) override;
+    status_t interruptableReadFully(FdTrigger* fdTrigger, void* data, size_t size,
+                                    const std::function<status_t()>& altPoll) override;
+
+private:
+    android::base::unique_fd mSocket;
+    Ssl mSsl;
+};
+
+// Error code is errno.
+Result<size_t> RpcTransportTls::peek(void* buf, size_t size) {
+    size_t todo = std::min<size_t>(size, std::numeric_limits<int>::max());
+    auto [ret, errorQueue] = mSsl.call(SSL_peek, buf, static_cast<int>(todo));
+    if (ret < 0) {
+        int err = mSsl.getError(ret);
+        if (err == SSL_ERROR_WANT_WRITE || err == SSL_ERROR_WANT_READ) {
+            // Seen EAGAIN / EWOULDBLOCK on recv(2) / send(2).
+            // Like RpcTransportRaw::peek(), don't handle it here.
+            return Error(EWOULDBLOCK) << "SSL_peek(): " << errorQueue.toString();
+        }
+        return Error() << "SSL_peek(): " << errorQueue.toString();
+    }
+    errorQueue.clear();
+    LOG_TLS_DETAIL("TLS: Peeked %d bytes!", ret);
+    return ret;
+}
+
+status_t RpcTransportTls::interruptableWriteFully(FdTrigger* fdTrigger, const void* data,
+                                                  size_t size,
+                                                  const std::function<status_t()>& altPoll) {
+    auto buffer = reinterpret_cast<const uint8_t*>(data);
+    const uint8_t* end = buffer + size;
+
+    MAYBE_WAIT_IN_FLAKE_MODE;
+
+    // Before doing any I/O, check trigger once. This ensures the trigger is checked at least
+    // once. The trigger is also checked via triggerablePoll() after every SSL_write().
+    if (fdTrigger->isTriggered()) return DEAD_OBJECT;
+
+    while (buffer < end) {
+        size_t todo = std::min<size_t>(end - buffer, std::numeric_limits<int>::max());
+        auto [writeSize, errorQueue] = mSsl.call(SSL_write, buffer, todo);
+        if (writeSize > 0) {
+            buffer += writeSize;
+            errorQueue.clear();
+            continue;
+        }
+        // SSL_write() should never return 0 unless BIO_write were to return 0.
+        int sslError = mSsl.getError(writeSize);
+        // TODO(b/195788248): BIO should contain the FdTrigger, and send(2) / recv(2) should be
+        //   triggerablePoll()-ed. Then additionalEvent is no longer necessary.
+        status_t pollStatus = errorQueue.pollForSslError(mSocket.get(), sslError, fdTrigger,
+                                                         "SSL_write", POLLIN, altPoll);
+        if (pollStatus != OK) return pollStatus;
+        // Do not advance buffer. Try SSL_write() again.
+    }
+    LOG_TLS_DETAIL("TLS: Sent %zu bytes!", size);
+    return OK;
+}
+
+status_t RpcTransportTls::interruptableReadFully(FdTrigger* fdTrigger, void* data, size_t size,
+                                                 const std::function<status_t()>& altPoll) {
+    auto buffer = reinterpret_cast<uint8_t*>(data);
+    uint8_t* end = buffer + size;
+
+    MAYBE_WAIT_IN_FLAKE_MODE;
+
+    // Before doing any I/O, check trigger once. This ensures the trigger is checked at least
+    // once. The trigger is also checked via triggerablePoll() after every SSL_write().
+    if (fdTrigger->isTriggered()) return DEAD_OBJECT;
+
+    while (buffer < end) {
+        size_t todo = std::min<size_t>(end - buffer, std::numeric_limits<int>::max());
+        auto [readSize, errorQueue] = mSsl.call(SSL_read, buffer, todo);
+        if (readSize > 0) {
+            buffer += readSize;
+            errorQueue.clear();
+            continue;
+        }
+        if (readSize == 0) {
+            // SSL_read() only returns 0 on EOF.
+            errorQueue.clear();
+            return DEAD_OBJECT;
+        }
+        int sslError = mSsl.getError(readSize);
+        status_t pollStatus = errorQueue.pollForSslError(mSocket.get(), sslError, fdTrigger,
+                                                         "SSL_read", 0, altPoll);
+        if (pollStatus != OK) return pollStatus;
+        // Do not advance buffer. Try SSL_read() again.
+    }
+    LOG_TLS_DETAIL("TLS: Received %zu bytes!", size);
+    return OK;
+}
+
+// For |ssl|, set internal FD to |fd|, and do handshake. Handshake is triggerable by |fdTrigger|.
+bool setFdAndDoHandshake(Ssl* ssl, android::base::borrowed_fd fd, FdTrigger* fdTrigger) {
+    bssl::UniquePtr<BIO> bio = newSocketBio(fd);
+    TEST_AND_RETURN(false, bio != nullptr);
+    auto [_, errorQueue] = ssl->call(SSL_set_bio, bio.get(), bio.get());
+    (void)bio.release(); // SSL_set_bio takes ownership.
+    errorQueue.clear();
+
+    MAYBE_WAIT_IN_FLAKE_MODE;
+
+    while (true) {
+        auto [ret, errorQueue] = ssl->call(SSL_do_handshake);
+        if (ret > 0) {
+            errorQueue.clear();
+            return true;
+        }
+        if (ret == 0) {
+            // SSL_do_handshake() only returns 0 on EOF.
+            ALOGE("SSL_do_handshake(): EOF: %s", errorQueue.toString().c_str());
+            return false;
+        }
+        int sslError = ssl->getError(ret);
+        status_t pollStatus =
+                errorQueue.pollForSslError(fd, sslError, fdTrigger, "SSL_do_handshake", 0, {});
+        if (pollStatus != OK) return false;
+    }
+}
+
+class RpcTransportCtxTls : public RpcTransportCtx {
+public:
+    template <typename Impl,
+              typename = std::enable_if_t<std::is_base_of_v<RpcTransportCtxTls, Impl>>>
+    static std::unique_ptr<RpcTransportCtxTls> create(
+            std::shared_ptr<RpcCertificateVerifier> verifier, RpcAuth* auth);
+    std::unique_ptr<RpcTransport> newTransport(android::base::unique_fd fd,
+                                               FdTrigger* fdTrigger) const override;
+    std::vector<uint8_t> getCertificate(RpcCertificateFormat) const override;
+
+protected:
+    static ssl_verify_result_t sslCustomVerify(SSL* ssl, uint8_t* outAlert);
+    virtual void preHandshake(Ssl* ssl) const = 0;
+    bssl::UniquePtr<SSL_CTX> mCtx;
+    std::shared_ptr<RpcCertificateVerifier> mCertVerifier;
+};
+
+std::vector<uint8_t> RpcTransportCtxTls::getCertificate(RpcCertificateFormat format) const {
+    X509* x509 = SSL_CTX_get0_certificate(mCtx.get()); // does not own
+    return serializeCertificate(x509, format);
+}
+
+// Verify by comparing the leaf of peer certificate with every certificate in
+// mTrustedPeerCertificates. Does not support certificate chains.
+ssl_verify_result_t RpcTransportCtxTls::sslCustomVerify(SSL* ssl, uint8_t* outAlert) {
+    LOG_ALWAYS_FATAL_IF(outAlert == nullptr);
+    const char* logPrefix = SSL_is_server(ssl) ? "Server" : "Client";
+
+    auto ctx = SSL_get_SSL_CTX(ssl); // Does not set error queue
+    LOG_ALWAYS_FATAL_IF(ctx == nullptr);
+    // void* -> RpcTransportCtxTls*
+    auto rpcTransportCtxTls = reinterpret_cast<RpcTransportCtxTls*>(SSL_CTX_get_app_data(ctx));
+    LOG_ALWAYS_FATAL_IF(rpcTransportCtxTls == nullptr);
+
+    status_t verifyStatus = rpcTransportCtxTls->mCertVerifier->verify(ssl, outAlert);
+    if (verifyStatus == OK) {
+        return ssl_verify_ok;
+    }
+    LOG_TLS_DETAIL("%s: Failed to verify client: status = %s, alert = %s", logPrefix,
+                   statusToString(verifyStatus).c_str(), SSL_alert_desc_string_long(*outAlert));
+    return ssl_verify_invalid;
+}
+
+// Common implementation for creating server and client contexts. The child class, |Impl|, is
+// provided as a template argument so that this function can initialize an |Impl| object.
+template <typename Impl, typename>
+std::unique_ptr<RpcTransportCtxTls> RpcTransportCtxTls::create(
+        std::shared_ptr<RpcCertificateVerifier> verifier, RpcAuth* auth) {
+    bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
+    TEST_AND_RETURN(nullptr, ctx != nullptr);
+
+    if (status_t authStatus = auth->configure(ctx.get()); authStatus != OK) {
+        ALOGE("%s: Failed to configure auth info: %s", __PRETTY_FUNCTION__,
+              statusToString(authStatus).c_str());
+        return nullptr;
+    };
+
+    // Enable two-way authentication by setting SSL_VERIFY_FAIL_IF_NO_PEER_CERT on server.
+    // Client ignores SSL_VERIFY_FAIL_IF_NO_PEER_CERT flag.
+    SSL_CTX_set_custom_verify(ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+                              sslCustomVerify);
+
+    // Require at least TLS 1.3
+    TEST_AND_RETURN(nullptr, SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
+
+    if constexpr (SHOULD_LOG_TLS_DETAIL) { // NOLINT
+        SSL_CTX_set_info_callback(ctx.get(), sslDebugLog);
+    }
+
+    auto ret = std::make_unique<Impl>();
+    // RpcTransportCtxTls* -> void*
+    TEST_AND_RETURN(nullptr, SSL_CTX_set_app_data(ctx.get(), reinterpret_cast<void*>(ret.get())));
+    ret->mCtx = std::move(ctx);
+    ret->mCertVerifier = std::move(verifier);
+    return ret;
+}
+
+std::unique_ptr<RpcTransport> RpcTransportCtxTls::newTransport(android::base::unique_fd fd,
+                                                               FdTrigger* fdTrigger) const {
+    bssl::UniquePtr<SSL> ssl(SSL_new(mCtx.get()));
+    TEST_AND_RETURN(nullptr, ssl != nullptr);
+    Ssl wrapped(std::move(ssl));
+
+    preHandshake(&wrapped);
+    TEST_AND_RETURN(nullptr, setFdAndDoHandshake(&wrapped, fd, fdTrigger));
+    return std::make_unique<RpcTransportTls>(std::move(fd), std::move(wrapped));
+}
+
+class RpcTransportCtxTlsServer : public RpcTransportCtxTls {
+protected:
+    void preHandshake(Ssl* ssl) const override {
+        ssl->call(SSL_set_accept_state).errorQueue.clear();
+    }
+};
+
+class RpcTransportCtxTlsClient : public RpcTransportCtxTls {
+protected:
+    void preHandshake(Ssl* ssl) const override {
+        ssl->call(SSL_set_connect_state).errorQueue.clear();
+    }
+};
+
+} // namespace
+
+std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryTls::newServerCtx() const {
+    return android::RpcTransportCtxTls::create<RpcTransportCtxTlsServer>(mCertVerifier,
+                                                                         mAuth.get());
+}
+
+std::unique_ptr<RpcTransportCtx> RpcTransportCtxFactoryTls::newClientCtx() const {
+    return android::RpcTransportCtxTls::create<RpcTransportCtxTlsClient>(mCertVerifier,
+                                                                         mAuth.get());
+}
+
+const char* RpcTransportCtxFactoryTls::toCString() const {
+    return "tls";
+}
+
+std::unique_ptr<RpcTransportCtxFactory> RpcTransportCtxFactoryTls::make(
+        std::shared_ptr<RpcCertificateVerifier> verifier, std::unique_ptr<RpcAuth> auth) {
+    if (verifier == nullptr) {
+        ALOGE("%s: Must provide a certificate verifier", __PRETTY_FUNCTION__);
+        return nullptr;
+    }
+    if (auth == nullptr) {
+        ALOGE("%s: Must provide an auth provider", __PRETTY_FUNCTION__);
+        return nullptr;
+    }
+    return std::unique_ptr<RpcTransportCtxFactoryTls>(
+            new RpcTransportCtxFactoryTls(std::move(verifier), std::move(auth)));
+}
+
+} // namespace android
diff --git a/libs/binder/RpcWireFormat.h b/libs/binder/RpcWireFormat.h
index c5fa008..171550e 100644
--- a/libs/binder/RpcWireFormat.h
+++ b/libs/binder/RpcWireFormat.h
@@ -20,6 +20,61 @@
 #pragma clang diagnostic push
 #pragma clang diagnostic error "-Wpadded"
 
+constexpr uint8_t RPC_CONNECTION_OPTION_INCOMING = 0x1; // default is outgoing
+
+constexpr uint32_t RPC_WIRE_ADDRESS_OPTION_CREATED = 1 << 0; // distinguish from '0' address
+constexpr uint32_t RPC_WIRE_ADDRESS_OPTION_FOR_SERVER = 1 << 1;
+
+struct RpcWireAddress {
+    uint32_t options;
+    uint32_t address;
+
+    static inline RpcWireAddress fromRaw(uint64_t raw) {
+        return *reinterpret_cast<RpcWireAddress*>(&raw);
+    }
+    static inline uint64_t toRaw(RpcWireAddress addr) {
+        return *reinterpret_cast<uint64_t*>(&addr);
+    }
+};
+static_assert(sizeof(RpcWireAddress) == sizeof(uint64_t));
+
+/**
+ * This is sent to an RpcServer in order to request a new connection is created,
+ * either as part of a new session or an existing session
+ */
+struct RpcConnectionHeader {
+    uint32_t version; // maximum supported by caller
+    uint8_t options;
+    uint8_t reservered[9];
+    // Follows is sessionIdSize bytes.
+    // if size is 0, this is requesting a new session.
+    uint16_t sessionIdSize;
+};
+static_assert(sizeof(RpcConnectionHeader) == 16);
+
+/**
+ * In response to an RpcConnectionHeader which corresponds to a new session,
+ * this returns information to the server.
+ */
+struct RpcNewSessionResponse {
+    uint32_t version; // maximum supported by callee <= maximum supported by caller
+    uint8_t reserved[4];
+};
+static_assert(sizeof(RpcNewSessionResponse) == 8);
+
+#define RPC_CONNECTION_INIT_OKAY "cci"
+
+/**
+ * Whenever a client connection is setup, this is sent as the initial
+ * transaction. The main use of this is in order to control the timing for when
+ * an incoming connection is setup.
+ */
+struct RpcOutgoingConnectionInit {
+    char msg[4];
+    uint8_t reserved[4];
+};
+static_assert(sizeof(RpcOutgoingConnectionInit) == 8);
+
 enum : uint32_t {
     /**
      * follows is RpcWireTransaction, if flags != oneway, reply w/ RPC_COMMAND_REPLY expected
@@ -30,7 +85,7 @@
      */
     RPC_COMMAND_REPLY,
     /**
-     * follows is RpcWireAddress
+     * follows is RpcDecStrong
      *
      * note - this in the protocol directly instead of as a 'special
      * transaction' in order to keep it as lightweight as possible (we don't
@@ -51,8 +106,6 @@
     RPC_SPECIAL_TRANSACT_GET_SESSION_ID = 2,
 };
 
-constexpr int32_t RPC_SESSION_ID_NEW = -1;
-
 // serialization is like:
 // |RpcWireHeader|struct desginated by 'command'| (over and over again)
 
@@ -62,10 +115,14 @@
 
     uint32_t reserved[2];
 };
+static_assert(sizeof(RpcWireHeader) == 16);
 
-struct RpcWireAddress {
-    uint8_t address[32];
+struct RpcDecStrong {
+    RpcWireAddress address;
+    uint32_t amount;
+    uint32_t reserved;
 };
+static_assert(sizeof(RpcDecStrong) == 16);
 
 struct RpcWireTransaction {
     RpcWireAddress address;
@@ -76,13 +133,15 @@
 
     uint32_t reserved[4];
 
-    uint8_t data[0];
+    uint8_t data[];
 };
+static_assert(sizeof(RpcWireTransaction) == 40);
 
 struct RpcWireReply {
     int32_t status; // transact return
-    uint8_t data[0];
+    uint8_t data[];
 };
+static_assert(sizeof(RpcWireReply) == 4);
 
 #pragma clang diagnostic pop
 
diff --git a/libs/binder/ServiceManagerHost.cpp b/libs/binder/ServiceManagerHost.cpp
new file mode 100644
index 0000000..194254a
--- /dev/null
+++ b/libs/binder/ServiceManagerHost.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ServiceManagerHost.h"
+
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+#include <binder/IServiceManager.h>
+#include <binder/RpcSession.h>
+
+#include "UtilsHost.h"
+
+namespace android {
+
+namespace {
+
+const void* kDeviceServiceExtraId = "DeviceServiceExtra";
+
+// Parse stdout of program execution to string. If any error, return 0.
+unsigned int parsePortNumber(const std::string& out, const std::string& what) {
+    auto trimmed = android::base::Trim(out);
+    unsigned int port = 0;
+    if (!android::base::ParseUint(trimmed, &port)) {
+        int savedErrno = errno;
+        ALOGE("%s is not a valid %s: %s", trimmed.c_str(), what.c_str(), strerror(savedErrno));
+        return 0;
+    }
+    if (port == 0) {
+        ALOGE("0 is not a valid %s", what.c_str());
+        return 0; // explicitly
+    }
+    return port;
+}
+
+// RAII object for adb forwarding
+class AdbForwarder {
+public:
+    AdbForwarder() = default;
+    static std::optional<AdbForwarder> forward(unsigned int devicePort);
+    AdbForwarder(AdbForwarder&& other) noexcept { (*this) = std::move(other); }
+    AdbForwarder& operator=(AdbForwarder&&) noexcept;
+    ~AdbForwarder();
+    [[nodiscard]] const std::optional<unsigned int>& hostPort() const { return mPort; }
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(AdbForwarder);
+    explicit AdbForwarder(unsigned int port) : mPort(port) {}
+    std::optional<unsigned int> mPort;
+};
+std::optional<AdbForwarder> AdbForwarder::forward(unsigned int devicePort) {
+    auto result =
+            execute({"adb", "forward", "tcp:0", "tcp:" + std::to_string(devicePort)}, nullptr);
+    if (!result.ok()) {
+        ALOGE("Unable to run `adb forward tcp:0 tcp:%d`: %s", devicePort,
+              result.error().message().c_str());
+        return std::nullopt;
+    }
+    // Must end with exit code 0 (`has_value() && value() == 0`)
+    if (result->exitCode.value_or(1) != 0) {
+        ALOGE("Unable to run `adb forward tcp:0 tcp:%d`, command exits with %s", devicePort,
+              result->toString().c_str());
+        return std::nullopt;
+    }
+    if (!result->stderrStr.empty()) {
+        LOG_HOST("`adb forward tcp:0 tcp:%d` writes to stderr: %s", devicePort,
+                 result->stderrStr.c_str());
+    }
+
+    unsigned int hostPort = parsePortNumber(result->stdoutStr, "host port");
+    if (hostPort == 0) return std::nullopt;
+
+    return AdbForwarder(hostPort);
+}
+
+AdbForwarder& AdbForwarder::operator=(AdbForwarder&& other) noexcept {
+    std::swap(mPort, other.mPort);
+    return *this;
+}
+
+AdbForwarder::~AdbForwarder() {
+    if (!mPort.has_value()) return;
+
+    auto result = execute({"adb", "forward", "--remove", "tcp:" + std::to_string(*mPort)}, nullptr);
+    if (!result.ok()) {
+        ALOGE("Unable to run `adb forward --remove tcp:%d`: %s", *mPort,
+              result.error().message().c_str());
+        return;
+    }
+    // Must end with exit code 0 (`has_value() && value() == 0`)
+    if (result->exitCode.value_or(1) != 0) {
+        ALOGE("Unable to run `adb forward --remove tcp:%d`, command exits with %s", *mPort,
+              result->toString().c_str());
+        return;
+    }
+    if (!result->stderrStr.empty()) {
+        LOG_HOST("`adb forward --remove tcp:%d` writes to stderr: %s", *mPort,
+                 result->stderrStr.c_str());
+    }
+
+    LOG_HOST("Successfully run `adb forward --remove tcp:%d`", *mPort);
+}
+
+void cleanupCommandResult(const void* id, void* obj, void* /* cookie */) {
+    LOG_ALWAYS_FATAL_IF(id != kDeviceServiceExtraId,
+                        "cleanupCommandResult invoked with mismatched ID %p, "
+                        "expected %p",
+                        id, kDeviceServiceExtraId);
+    auto ptr = static_cast<CommandResult*>(obj);
+    delete ptr;
+}
+
+} // namespace
+
+sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs,
+                             const RpcDelegateServiceManagerOptions& options) {
+    std::vector<std::string> prefix{"adb", "shell", "servicedispatcher"};
+    serviceDispatcherArgs.insert(serviceDispatcherArgs.begin(), prefix.begin(), prefix.end());
+
+    auto result = execute(std::move(serviceDispatcherArgs), &CommandResult::stdoutEndsWithNewLine);
+    if (!result.ok()) {
+        ALOGE("%s", result.error().message().c_str());
+        return nullptr;
+    }
+
+    // `servicedispatcher` process must be alive to keep the port open.
+    if (result->exitCode.has_value()) {
+        ALOGE("Command exits with: %s", result->toString().c_str());
+        return nullptr;
+    }
+    if (!result->stderrStr.empty()) {
+        LOG_HOST("servicedispatcher writes to stderr: %s", result->stderrStr.c_str());
+    }
+
+    if (!result->stdoutEndsWithNewLine()) {
+        ALOGE("Unexpected command result: %s", result->toString().c_str());
+        return nullptr;
+    }
+
+    unsigned int devicePort = parsePortNumber(result->stdoutStr, "device port");
+    if (devicePort == 0) return nullptr;
+
+    auto forwardResult = AdbForwarder::forward(devicePort);
+    if (!forwardResult.has_value()) {
+        return nullptr;
+    }
+    LOG_ALWAYS_FATAL_IF(!forwardResult->hostPort().has_value());
+
+    auto rpcSession = RpcSession::make();
+    if (options.maxOutgoingThreads.has_value()) {
+        rpcSession->setMaxOutgoingThreads(*options.maxOutgoingThreads);
+    }
+
+    if (status_t status = rpcSession->setupInetClient("127.0.0.1", *forwardResult->hostPort());
+        status != OK) {
+        ALOGE("Unable to set up inet client on host port %u: %s", *forwardResult->hostPort(),
+              statusToString(status).c_str());
+        return nullptr;
+    }
+    auto binder = rpcSession->getRootObject();
+    if (binder == nullptr) {
+        ALOGE("RpcSession::getRootObject returns nullptr");
+        return nullptr;
+    }
+
+    LOG_ALWAYS_FATAL_IF(
+            nullptr !=
+            binder->attachObject(kDeviceServiceExtraId,
+                                 static_cast<void*>(new CommandResult(std::move(*result))), nullptr,
+                                 &cleanupCommandResult));
+    return binder;
+}
+
+} // namespace android
diff --git a/libs/binder/ServiceManagerHost.h b/libs/binder/ServiceManagerHost.h
new file mode 100644
index 0000000..c5310da
--- /dev/null
+++ b/libs/binder/ServiceManagerHost.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android-base/macros.h>
+#include <android/os/IServiceManager.h>
+
+namespace android {
+
+struct RpcDelegateServiceManagerOptions;
+
+// Get a service on device by running servicedispatcher with the given args, e.g.
+//     getDeviceService({"foo"});
+// Return nullptr on any error.
+// When the returned binder object is destroyed, remove adb forwarding and kills
+// the long-running servicedispatcher process.
+sp<IBinder> getDeviceService(std::vector<std::string>&& serviceDispatcherArgs,
+                             const RpcDelegateServiceManagerOptions& options);
+
+} // namespace android
diff --git a/libs/binder/Stability.cpp b/libs/binder/Stability.cpp
index f12ef4e..2d05fb2 100644
--- a/libs/binder/Stability.cpp
+++ b/libs/binder/Stability.cpp
@@ -23,21 +23,6 @@
 namespace android {
 namespace internal {
 
-// the libbinder parcel format is currently unstable
-
-// oldest version which is supported
-constexpr uint8_t kBinderWireFormatOldest = 1;
-// current version
-constexpr uint8_t kBinderWireFormatVersion = 1;
-
-Stability::Category Stability::Category::currentFromLevel(Level level) {
-    return {
-        .version = kBinderWireFormatVersion,
-        .reserved = {0},
-        .level = level,
-    };
-}
-
 void Stability::forceDowngradeToStability(const sp<IBinder>& binder, Level level) {
     // Downgrading a remote binder would require also copying the version from
     // the binder sent here. In practice though, we don't need to downgrade the
@@ -45,8 +30,7 @@
     // what we can do to it.
     LOG_ALWAYS_FATAL_IF(!binder || !binder->localBinder(), "Can only downgrade local binder");
 
-    auto stability = Category::currentFromLevel(level);
-    status_t result = setRepr(binder.get(), stability.repr(), REPR_LOG | REPR_ALLOW_DOWNGRADE);
+    status_t result = setRepr(binder.get(), level, REPR_LOG | REPR_ALLOW_DOWNGRADE);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
@@ -62,41 +46,31 @@
     forceDowngradeToStability(binder, Level::VENDOR);
 }
 
-std::string Stability::Category::debugString() {
-    return levelString(level) + " wire protocol version "
-        + std::to_string(version);
-}
-
 void Stability::markCompilationUnit(IBinder* binder) {
-    auto stability = Category::currentFromLevel(getLocalLevel());
-    status_t result = setRepr(binder, stability.repr(), REPR_LOG);
+    status_t result = setRepr(binder, getLocalLevel(), REPR_LOG);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
 void Stability::markVintf(IBinder* binder) {
-    auto stability = Category::currentFromLevel(Level::VINTF);
-    status_t result = setRepr(binder, stability.repr(), REPR_LOG);
+    status_t result = setRepr(binder, Level::VINTF, REPR_LOG);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
-void Stability::debugLogStability(const std::string& tag, const sp<IBinder>& binder) {
-    auto stability = getCategory(binder.get());
-    ALOGE("%s: stability is %s", tag.c_str(), stability.debugString().c_str());
+std::string Stability::debugToString(const sp<IBinder>& binder) {
+    return levelString(getRepr(binder.get()));
 }
 
 void Stability::markVndk(IBinder* binder) {
-    auto stability = Category::currentFromLevel(Level::VENDOR);
-    status_t result = setRepr(binder, stability.repr(), REPR_LOG);
+    status_t result = setRepr(binder, Level::VENDOR, REPR_LOG);
     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
 }
 
 bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) {
-    return check(getCategory(binder.get()), Level::VINTF);
+    return check(getRepr(binder.get()), Level::VINTF);
 }
 
 void Stability::tryMarkCompilationUnit(IBinder* binder) {
-    auto stability = Category::currentFromLevel(getLocalLevel());
-    (void) setRepr(binder, stability.repr(), REPR_NONE);
+    (void)setRepr(binder, getLocalLevel(), REPR_NONE);
 }
 
 Stability::Level Stability::getLocalLevel() {
@@ -112,92 +86,77 @@
 #endif
 }
 
-status_t Stability::setRepr(IBinder* binder, int32_t representation, uint32_t flags) {
+status_t Stability::setRepr(IBinder* binder, int32_t setting, uint32_t flags) {
     bool log = flags & REPR_LOG;
     bool allowDowngrade = flags & REPR_ALLOW_DOWNGRADE;
 
-    auto current = getCategory(binder);
-    auto setting = Category::fromRepr(representation);
-
-    // If we have ahold of a binder with a newer declared version, then it
-    // should support older versions, and we will simply write our parcels with
-    // the current wire parcel format.
-    if (setting.version < kBinderWireFormatOldest) {
-        // always log, because this shouldn't happen
-        ALOGE("Cannot accept binder with older binder wire protocol version "
-              "%u. Versions less than %u are unsupported.", setting.version,
-               kBinderWireFormatOldest);
-        return BAD_TYPE;
-    }
+    int16_t current = getRepr(binder);
 
     // null binder is always written w/ 'UNDECLARED' stability
     if (binder == nullptr) {
-        if (setting.level == UNDECLARED) {
+        if (setting == UNDECLARED) {
             return OK;
         } else {
             if (log) {
-                ALOGE("Null binder written with stability %s.",
-                    levelString(setting.level).c_str());
+                ALOGE("Null binder written with stability %s.", levelString(setting).c_str());
             }
             return BAD_TYPE;
         }
     }
 
-    if (!isDeclaredLevel(setting.level)) {
+    if (!isDeclaredLevel(setting)) {
         if (log) {
-            ALOGE("Can only set known stability, not %u.", setting.level);
+            ALOGE("Can only set known stability, not %d.", setting);
         }
         return BAD_TYPE;
     }
+    Level levelSetting = static_cast<Level>(setting);
 
     if (current == setting) return OK;
 
-    bool hasAlreadyBeenSet = current.repr() != 0;
-    bool isAllowedDowngrade = allowDowngrade && check(current, setting.level);
+    bool hasAlreadyBeenSet = current != Level::UNDECLARED;
+    bool isAllowedDowngrade = allowDowngrade && check(current, levelSetting);
     if (hasAlreadyBeenSet && !isAllowedDowngrade) {
         if (log) {
             ALOGE("Interface being set with %s but it is already marked as %s",
-                  setting.debugString().c_str(),
-                  current.debugString().c_str());
+                  levelString(setting).c_str(), levelString(current).c_str());
         }
         return BAD_TYPE;
     }
 
     if (isAllowedDowngrade) {
-        ALOGI("Interface set with %s downgraded to %s stability",
-              current.debugString().c_str(),
-              setting.debugString().c_str());
+        ALOGI("Interface set with %s downgraded to %s stability", levelString(current).c_str(),
+              levelString(setting).c_str());
     }
 
     BBinder* local = binder->localBinder();
     if (local != nullptr) {
-        local->mStability = setting.repr();
+        local->mStability = setting;
     } else {
-        binder->remoteBinder()->mStability = setting.repr();
+        binder->remoteBinder()->mStability = setting;
     }
 
     return OK;
 }
 
-Stability::Category Stability::getCategory(IBinder* binder) {
+int16_t Stability::getRepr(IBinder* binder) {
     if (binder == nullptr) {
-        return Category::currentFromLevel(Level::UNDECLARED);
+        return Level::UNDECLARED;
     }
 
     BBinder* local = binder->localBinder();
     if (local != nullptr) {
-        return Category::fromRepr(local->mStability);
+        return local->mStability;
     }
 
-    return Category::fromRepr(binder->remoteBinder()->mStability);
+    return binder->remoteBinder()->mStability;
 }
 
-bool Stability::check(Category provided, Level required) {
-    bool stable = (provided.level & required) == required;
+bool Stability::check(int16_t provided, Level required) {
+    bool stable = (provided & required) == required;
 
-    if (provided.level != UNDECLARED && !isDeclaredLevel(provided.level)) {
-        ALOGE("Unknown stability when checking interface stability %d.",
-              provided.level);
+    if (provided != UNDECLARED && !isDeclaredLevel(provided)) {
+        ALOGE("Unknown stability when checking interface stability %d.", provided);
 
         stable = false;
     }
@@ -205,11 +164,11 @@
     return stable;
 }
 
-bool Stability::isDeclaredLevel(Level stability) {
+bool Stability::isDeclaredLevel(int32_t stability) {
     return stability == VENDOR || stability == SYSTEM || stability == VINTF;
 }
 
-std::string Stability::levelString(Level level) {
+std::string Stability::levelString(int32_t level) {
     switch (level) {
         case Level::UNDECLARED: return "undeclared stability";
         case Level::VENDOR: return "vendor stability";
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index b5a078c..a44c578 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -130,13 +130,13 @@
     }
 
     // The remote threw an exception.  Get the message back.
-    String16 message;
+    std::optional<String16> message;
     status = parcel.readString16(&message);
     if (status != OK) {
         setFromStatusT(status);
         return status;
     }
-    mMessage = String8(message);
+    mMessage = String8(message.value_or(String16()));
 
     // Skip over the remote stack trace data
     int32_t remote_stack_trace_header_size;
diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING
index b9f4502..ebb0d27 100644
--- a/libs/binder/TEST_MAPPING
+++ b/libs/binder/TEST_MAPPING
@@ -16,18 +16,30 @@
       "name": "binderDriverInterfaceTest"
     },
     {
+      "name": "binderHostDeviceTest"
+    },
+    {
       "name": "binderTextOutputTest"
     },
     {
-      "name": "binderParcelTest"
+      "name": "binderUnitTest"
     },
     {
       "name": "binderLibTest"
     },
     {
+      "name": "binderRpcTest"
+    },
+    {
       "name": "binderStabilityTest"
     },
     {
+      "name": "binderRpcWireProtocolTest"
+    },
+    {
+      "name": "binderUtilsHostTest"
+    },
+    {
       "name": "libbinder_ndk_unit_test"
     },
     {
diff --git a/libs/binder/Utils.cpp b/libs/binder/Utils.cpp
index 90a4502..d2a5be1 100644
--- a/libs/binder/Utils.cpp
+++ b/libs/binder/Utils.cpp
@@ -18,10 +18,24 @@
 
 #include <string.h>
 
+using android::base::ErrnoError;
+using android::base::Result;
+
 namespace android {
 
 void zeroMemory(uint8_t* data, size_t size) {
     memset(data, 0, size);
 }
 
-}   // namespace android
+Result<void> setNonBlocking(android::base::borrowed_fd fd) {
+    int flags = TEMP_FAILURE_RETRY(fcntl(fd.get(), F_GETFL));
+    if (flags == -1) {
+        return ErrnoError() << "Could not get flags for fd";
+    }
+    if (int ret = TEMP_FAILURE_RETRY(fcntl(fd.get(), F_SETFL, flags | O_NONBLOCK)); ret == -1) {
+        return ErrnoError() << "Could not set non-blocking flag for fd";
+    }
+    return {};
+}
+
+} // namespace android
diff --git a/libs/binder/Utils.h b/libs/binder/Utils.h
index f94b158..ff2fad8 100644
--- a/libs/binder/Utils.h
+++ b/libs/binder/Utils.h
@@ -17,9 +17,23 @@
 #include <cstdint>
 #include <stddef.h>
 
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+#include <log/log.h>
+
+#define TEST_AND_RETURN(value, expr)            \
+    do {                                        \
+        if (!(expr)) {                          \
+            ALOGE("Failed to call: %s", #expr); \
+            return value;                       \
+        }                                       \
+    } while (0)
+
 namespace android {
 
 // avoid optimizations
 void zeroMemory(uint8_t* data, size_t size);
 
+android::base::Result<void> setNonBlocking(android::base::borrowed_fd fd);
+
 }   // namespace android
diff --git a/libs/binder/UtilsHost.cpp b/libs/binder/UtilsHost.cpp
new file mode 100644
index 0000000..52b8f69
--- /dev/null
+++ b/libs/binder/UtilsHost.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "UtilsHost.h"
+
+#include <poll.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <sstream>
+
+#include <log/log.h>
+
+namespace android {
+
+CommandResult::~CommandResult() {
+    if (!pid.has_value()) return;
+    if (*pid == 0) {
+        ALOGW("%s: PID is unexpectedly 0, won't kill it", __PRETTY_FUNCTION__);
+        return;
+    }
+
+    ALOGE_IF(kill(*pid, SIGKILL) != 0, "kill(%d): %s", *pid, strerror(errno));
+
+    while (pid.has_value()) {
+        int status;
+        LOG_HOST("%s: Waiting for PID %d to exit.", __PRETTY_FUNCTION__, *pid);
+        int waitres = waitpid(*pid, &status, 0);
+        if (waitres == -1) {
+            ALOGE("%s: waitpid(%d): %s", __PRETTY_FUNCTION__, *pid, strerror(errno));
+            break;
+        }
+        if (WIFEXITED(status)) {
+            LOG_HOST("%s: PID %d exited.", __PRETTY_FUNCTION__, *pid);
+            pid.reset();
+        } else if (WIFSIGNALED(status)) {
+            LOG_HOST("%s: PID %d terminated by signal %d.", __PRETTY_FUNCTION__, *pid,
+                     WTERMSIG(status));
+            pid.reset();
+        } else if (WIFSTOPPED(status)) {
+            ALOGW("%s: pid %d stopped", __PRETTY_FUNCTION__, *pid);
+        } else if (WIFCONTINUED(status)) {
+            ALOGW("%s: pid %d continued", __PRETTY_FUNCTION__, *pid);
+        }
+    }
+}
+
+std::ostream& operator<<(std::ostream& os, const CommandResult& res) {
+    if (res.exitCode) os << "code=" << *res.exitCode;
+    if (res.signal) os << "signal=" << *res.signal;
+    if (res.pid) os << ", pid=" << *res.pid;
+    return os << ", stdout=" << res.stdoutStr << ", stderr=" << res.stderrStr;
+}
+
+std::string CommandResult::toString() const {
+    std::stringstream ss;
+    ss << (*this);
+    return ss.str();
+}
+
+android::base::Result<CommandResult> execute(std::vector<std::string> argStringVec,
+                                             const std::function<bool(const CommandResult&)>& end) {
+    // turn vector<string> into null-terminated char* vector.
+    std::vector<char*> argv;
+    argv.reserve(argStringVec.size() + 1);
+    for (auto& arg : argStringVec) argv.push_back(arg.data());
+    argv.push_back(nullptr);
+
+    CommandResult ret;
+    android::base::unique_fd outWrite;
+    if (!android::base::Pipe(&ret.outPipe, &outWrite))
+        return android::base::ErrnoError() << "pipe() for outPipe";
+    android::base::unique_fd errWrite;
+    if (!android::base::Pipe(&ret.errPipe, &errWrite))
+        return android::base::ErrnoError() << "pipe() for errPipe";
+
+    int pid = fork();
+    if (pid == -1) return android::base::ErrnoError() << "fork()";
+    if (pid == 0) {
+        // child
+        ret.outPipe.reset();
+        ret.errPipe.reset();
+
+        int res = TEMP_FAILURE_RETRY(dup2(outWrite.get(), STDOUT_FILENO));
+        LOG_ALWAYS_FATAL_IF(-1 == res, "dup2(outPipe): %s", strerror(errno));
+        outWrite.reset();
+
+        res = TEMP_FAILURE_RETRY(dup2(errWrite.get(), STDERR_FILENO));
+        LOG_ALWAYS_FATAL_IF(-1 == res, "dup2(errPipe): %s", strerror(errno));
+        errWrite.reset();
+
+        execvp(argv[0], argv.data());
+        LOG_ALWAYS_FATAL("execvp() returns");
+    }
+    // parent
+    outWrite.reset();
+    errWrite.reset();
+    ret.pid = pid;
+
+    auto handlePoll = [](android::base::unique_fd* fd, const pollfd* pfd, std::string* s) {
+        if (!fd->ok()) return true;
+        if (pfd->revents & POLLIN) {
+            char buf[1024];
+            ssize_t n = TEMP_FAILURE_RETRY(read(fd->get(), buf, sizeof(buf)));
+            if (n < 0) return false;
+            if (n > 0) *s += std::string_view(buf, n);
+        }
+        if (pfd->revents & POLLHUP) {
+            fd->reset();
+        }
+        return true;
+    };
+
+    // Drain both stdout and stderr. Check end() regularly until both are closed.
+    while (ret.outPipe.ok() || ret.errPipe.ok()) {
+        pollfd fds[2];
+        pollfd *outPollFd = nullptr, *errPollFd = nullptr;
+        memset(fds, 0, sizeof(fds));
+        nfds_t nfds = 0;
+        if (ret.outPipe.ok()) {
+            outPollFd = &fds[nfds++];
+            *outPollFd = {.fd = ret.outPipe.get(), .events = POLLIN};
+        }
+        if (ret.errPipe.ok()) {
+            errPollFd = &fds[nfds++];
+            *errPollFd = {.fd = ret.errPipe.get(), .events = POLLIN};
+        }
+        int pollRet = poll(fds, nfds, 1000 /* ms timeout */);
+        if (pollRet == -1) return android::base::ErrnoError() << "poll()";
+
+        if (!handlePoll(&ret.outPipe, outPollFd, &ret.stdoutStr))
+            return android::base::ErrnoError() << "read(stdout)";
+        if (!handlePoll(&ret.errPipe, errPollFd, &ret.stderrStr))
+            return android::base::ErrnoError() << "read(stderr)";
+
+        if (end && end(ret)) return ret;
+    }
+
+    // If both stdout and stderr are closed by the subprocess, it may or may not be terminated.
+    while (ret.pid.has_value()) {
+        int status;
+        auto exitPid = waitpid(pid, &status, 0);
+        if (exitPid == -1) return android::base::ErrnoError() << "waitpid(" << pid << ")";
+        if (exitPid == pid) {
+            if (WIFEXITED(status)) {
+                ret.pid = std::nullopt;
+                ret.exitCode = WEXITSTATUS(status);
+            } else if (WIFSIGNALED(status)) {
+                ret.pid = std::nullopt;
+                ret.signal = WTERMSIG(status);
+            } else if (WIFSTOPPED(status)) {
+                ALOGW("%s: pid %d stopped", __PRETTY_FUNCTION__, *ret.pid);
+            } else if (WIFCONTINUED(status)) {
+                ALOGW("%s: pid %d continued", __PRETTY_FUNCTION__, *ret.pid);
+            }
+        }
+        // ret is not changed unless the process is terminated (where pid == nullopt). Hence there
+        // is no need to check the predicate `end(ret)`.
+    }
+
+    return ret;
+}
+} // namespace android
diff --git a/libs/binder/UtilsHost.h b/libs/binder/UtilsHost.h
new file mode 100644
index 0000000..98ac4e0
--- /dev/null
+++ b/libs/binder/UtilsHost.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <optional>
+#include <ostream>
+#include <string>
+#include <variant>
+#include <vector>
+
+#include <android-base/macros.h>
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+
+/**
+ * Log a lot more information about host-device binder communication, when debugging issues.
+ */
+#define SHOULD_LOG_HOST false
+
+#if SHOULD_LOG_HOST
+#define LOG_HOST(...) ALOGI(__VA_ARGS__)
+#else
+#define LOG_HOST(...) ALOGV(__VA_ARGS__) // for type checking
+#endif
+
+namespace android {
+
+struct CommandResult {
+    std::optional<int32_t> exitCode;
+    std::optional<int32_t> signal;
+    std::optional<pid_t> pid;
+    std::string stdoutStr;
+    std::string stderrStr;
+
+    android::base::unique_fd outPipe;
+    android::base::unique_fd errPipe;
+
+    CommandResult() = default;
+    CommandResult(CommandResult&& other) noexcept { (*this) = std::move(other); }
+    CommandResult& operator=(CommandResult&& other) noexcept {
+        std::swap(exitCode, other.exitCode);
+        std::swap(signal, other.signal);
+        std::swap(pid, other.pid);
+        std::swap(stdoutStr, other.stdoutStr);
+        std::swap(stderrStr, other.stderrStr);
+        return *this;
+    }
+    ~CommandResult();
+    [[nodiscard]] std::string toString() const;
+
+    [[nodiscard]] bool stdoutEndsWithNewLine() const {
+        return !stdoutStr.empty() && stdoutStr.back() == '\n';
+    }
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(CommandResult);
+};
+
+std::ostream& operator<<(std::ostream& os, const CommandResult& res);
+
+// Execute a command using tokens specified in @a argStringVec.
+//
+// @a end is a predicate checked periodically when the command emits any output to stdout or
+// stderr. When it is evaluated to true, the function returns immediately even though
+// the child process has not been terminated. The function also assumes that, after @a end
+// is evaluated to true, the child process does not emit any other messages.
+// If this is not the case, caller to execute() must handle these I/O in the pipes in the returned
+// CommandResult object. Otherwise the child program may hang on I/O.
+//
+// If @a end is nullptr, it is equivalent to a predicate that always returns false. In this
+// case, execute() returns after the child process is terminated.
+//
+// If @a end is evaluated to true, and execute() returns with the child process running,
+// the returned CommandResult has pid, outPipe, and errPipe set. In this case, the caller is
+// responsible for holding the returned CommandResult. When the CommandResult object is destroyed,
+// the child process is killed.
+//
+// On the other hand, execute() returns with the child process terminated, either exitCode or signal
+// is set.
+//
+// If the parent process has encountered any errors for system calls, return ExecuteError with
+// the proper errno set.
+android::base::Result<CommandResult> execute(std::vector<std::string> argStringVec,
+                                             const std::function<bool(const CommandResult&)>& end);
+} // namespace android
diff --git a/libs/binder/aidl/android/content/pm/ApexStagedEvent.aidl b/libs/binder/aidl/android/content/pm/ApexStagedEvent.aidl
new file mode 100644
index 0000000..75f8753
--- /dev/null
+++ b/libs/binder/aidl/android/content/pm/ApexStagedEvent.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.content.pm;
+
+/**
+ * This event is designed for notification to native code listener about
+ * any changes to set of apex packages staged for installation on next boot.
+ *
+ * @hide
+ */
+parcelable ApexStagedEvent {
+  @utf8InCpp String[] stagedApexModuleNames;
+}
diff --git a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
index c20d9f6..7c99f76 100644
--- a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
+++ b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
@@ -18,6 +18,8 @@
 package android.content.pm;
 
 import android.content.pm.IPackageChangeObserver;
+import android.content.pm.IStagedApexObserver;
+import android.content.pm.StagedApexInfo;
 
 /**
  * Parallel implementation of certain {@link PackageManager} APIs that need to
@@ -123,4 +125,24 @@
      * requested version.
      */
     boolean hasSystemFeature(in String featureName, in int version);
+
+    /** Register a observer for change in set of staged APEX ready for installation */
+    void registerStagedApexObserver(in IStagedApexObserver observer);
+
+    /**
+     * Unregister an existing staged apex observer.
+     * This does nothing if this observer was not already registered.
+     */
+    void unregisterStagedApexObserver(in IStagedApexObserver observer);
+
+    /**
+     * Get APEX module names of all APEX that are staged ready for installation
+     */
+    @utf8InCpp String[] getStagedApexModuleNames();
+
+    /**
+     * Get information of APEX which is staged ready for installation.
+     * Returns null if no such APEX is found.
+     */
+    @nullable StagedApexInfo getStagedApexInfo(in @utf8InCpp String moduleName);
 }
diff --git a/libs/binder/aidl/android/content/pm/IStagedApexObserver.aidl b/libs/binder/aidl/android/content/pm/IStagedApexObserver.aidl
new file mode 100644
index 0000000..9906436
--- /dev/null
+++ b/libs/binder/aidl/android/content/pm/IStagedApexObserver.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.content.pm;
+
+import android.content.pm.ApexStagedEvent;
+
+/**
+ * This is a non-blocking notification when set of staged apex has changed
+ *
+ * @hide
+ */
+oneway interface IStagedApexObserver {
+  void onApexStaged(in ApexStagedEvent event);
+}
diff --git a/libs/binder/aidl/android/content/pm/StagedApexInfo.aidl b/libs/binder/aidl/android/content/pm/StagedApexInfo.aidl
new file mode 100644
index 0000000..bffab5e
--- /dev/null
+++ b/libs/binder/aidl/android/content/pm/StagedApexInfo.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.content.pm;
+
+/**
+ * This object is designed for returning information regarding
+ * staged APEX that are ready to be installed on next reboot.
+ *
+ * @hide
+ */
+parcelable StagedApexInfo {
+  @utf8InCpp String moduleName;
+  @utf8InCpp String diskImagePath;
+  long versionCode;
+  @utf8InCpp String versionName;
+  boolean hasBootClassPathJars;
+  boolean hasDex2OatBootClassPathJars;
+  boolean hasSystemServerClassPathJars;
+}
diff --git a/libs/binder/aidl/android/os/ConnectionInfo.aidl b/libs/binder/aidl/android/os/ConnectionInfo.aidl
new file mode 100644
index 0000000..160c9ea
--- /dev/null
+++ b/libs/binder/aidl/android/os/ConnectionInfo.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.os;
+
+/**
+ * Remote connection info associated with a declared service
+ * @hide
+ */
+parcelable ConnectionInfo {
+    /**
+     * IP address that the service is listening on.
+     */
+    @utf8InCpp String ipAddress;
+    /**
+     * Port number that the service is listening on. Actual value is an unsigned integer.
+     */
+    int port;
+}
+
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 75c4092..5880c0a 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -19,6 +19,7 @@
 import android.os.IClientCallback;
 import android.os.IServiceCallback;
 import android.os.ServiceDebugInfo;
+import android.os.ConnectionInfo;
 
 /**
  * Basic interface for finding and publishing system services.
@@ -113,6 +114,11 @@
     @nullable @utf8InCpp String updatableViaApex(@utf8InCpp String name);
 
     /**
+     * If connection info is available for the given instance, returns the ConnectionInfo
+     */
+    @nullable ConnectionInfo getConnectionInfo(@utf8InCpp String name);
+
+    /**
      * Request a callback when the number of clients of the service changes.
      * Used by LazyServiceRegistrar to dynamically stop services that have no clients.
      */
diff --git a/libs/binder/include/binder/Binder.h b/libs/binder/include/binder/Binder.h
index 7e9be41..46223bb 100644
--- a/libs/binder/include/binder/Binder.h
+++ b/libs/binder/include/binder/Binder.h
@@ -54,12 +54,11 @@
                                         uint32_t flags = 0,
                                         wp<DeathRecipient>* outRecipient = nullptr);
 
-    virtual void        attachObject(   const void* objectID,
-                                        void* object,
-                                        void* cleanupCookie,
-                                        object_cleanup_func func) final;
+    virtual void* attachObject(const void* objectID, void* object, void* cleanupCookie,
+                               object_cleanup_func func) final;
     virtual void*       findObject(const void* objectID) const final;
-    virtual void        detachObject(const void* objectID) final;
+    virtual void* detachObject(const void* objectID) final;
+    void withLock(const std::function<void()>& doWithLock);
 
     virtual BBinder*    localBinder();
 
@@ -94,6 +93,16 @@
 
     pid_t               getDebugPid();
 
+    // Whether this binder has been sent to another process.
+    bool wasParceled();
+    // Consider this binder as parceled (setup/init-related calls should no
+    // longer by called. This is automatically set by when this binder is sent
+    // to another process.
+    void setParceled();
+
+    [[nodiscard]] status_t setRpcClientDebug(android::base::unique_fd clientFd,
+                                             const sp<IBinder>& keepAliveBinder);
+
 protected:
     virtual             ~BBinder();
 
@@ -107,17 +116,24 @@
                         BBinder(const BBinder& o);
             BBinder&    operator=(const BBinder& o);
 
+    class RpcServerLink;
     class Extras;
 
     Extras*             getOrCreateExtras();
 
+    [[nodiscard]] status_t setRpcClientDebug(const Parcel& data);
+    void removeRpcServerLink(const sp<RpcServerLink>& link);
+
     std::atomic<Extras*> mExtras;
 
     friend ::android::internal::Stability;
-    union {
-        int32_t mStability;
-        void* mReserved0;
-    };
+    int16_t mStability;
+    bool mParceled;
+    uint8_t mReserved0;
+
+#ifdef __LP64__
+    int32_t mReserved1;
+#endif
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/BinderService.h b/libs/binder/include/binder/BinderService.h
index 5776f3c..e58d489 100644
--- a/libs/binder/include/binder/BinderService.h
+++ b/libs/binder/include/binder/BinderService.h
@@ -26,6 +26,24 @@
 #include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
 
+// WARNING: deprecated - DO NOT USE - prefer to setup service directly.
+//
+// This class embellishes a class with a few static methods which can be used in
+// limited circumstances (when one service needs to be registered and
+// published). However, this is an anti-pattern:
+// - these methods are aliases of existing methods, and as such, represent an
+//   incremental amount of information required to understand the system but
+//   which does not actually save in terms of lines of code. For instance, users
+//   of this class should be surprised to know that this will start up to 16
+//   threads in the binder threadpool.
+// - the template instantiation costs need to be paid, even though everything
+//   done here is generic.
+// - the getServiceName API here is undocumented and non-local (for instance,
+//   this unnecessarily assumes a single service type will only be instantiated
+//   once with no arguments).
+//
+// So, DO NOT USE.
+
 // ---------------------------------------------------------------------------
 namespace android {
 
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 61bf018..c0454b6 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -17,7 +17,6 @@
 #pragma once
 
 #include <binder/IBinder.h>
-#include <binder/RpcAddress.h>
 #include <utils/KeyedVector.h>
 #include <utils/Mutex.h>
 #include <utils/threads.h>
@@ -40,9 +39,6 @@
 class BpBinder : public IBinder
 {
 public:
-    static sp<BpBinder> create(int32_t handle);
-    static sp<BpBinder> create(const sp<RpcSession>& session, const RpcAddress& address);
-
     /**
      * Return value:
      * true - this is associated with a socket RpcSession
@@ -72,12 +68,11 @@
                                         uint32_t flags = 0,
                                         wp<DeathRecipient>* outRecipient = nullptr);
 
-    virtual void        attachObject(   const void* objectID,
-                                        void* object,
-                                        void* cleanupCookie,
-                                        object_cleanup_func func) final;
+    virtual void* attachObject(const void* objectID, void* object, void* cleanupCookie,
+                               object_cleanup_func func) final;
     virtual void*       findObject(const void* objectID) const final;
-    virtual void        detachObject(const void* objectID) final;
+    virtual void* detachObject(const void* objectID) final;
+    void withLock(const std::function<void()>& doWithLock);
 
     virtual BpBinder*   remoteBinder();
 
@@ -91,27 +86,25 @@
     static void         setLimitCallback(binder_proxy_limit_callback cb);
     static void         setBinderProxyCountWatermarks(int high, int low);
 
-    class ObjectManager
-    {
+    std::optional<int32_t> getDebugBinderHandle() const;
+
+    class ObjectManager {
     public:
-                    ObjectManager();
-                    ~ObjectManager();
+        ObjectManager();
+        ~ObjectManager();
 
-        void        attach( const void* objectID,
-                            void* object,
-                            void* cleanupCookie,
-                            IBinder::object_cleanup_func func);
-        void*       find(const void* objectID) const;
-        void        detach(const void* objectID);
+        void* attach(const void* objectID, void* object, void* cleanupCookie,
+                     IBinder::object_cleanup_func func);
+        void* find(const void* objectID) const;
+        void* detach(const void* objectID);
 
-        void        kill();
+        void kill();
 
     private:
-                    ObjectManager(const ObjectManager&);
+        ObjectManager(const ObjectManager&);
         ObjectManager& operator=(const ObjectManager&);
 
-        struct entry_t
-        {
+        struct entry_t {
             void* object;
             void* cleanupCookie;
             IBinder::object_cleanup_func func;
@@ -120,42 +113,49 @@
         KeyedVector<const void*, entry_t> mObjects;
     };
 
-    class PrivateAccessorForId {
+    class PrivateAccessor {
     private:
         friend class BpBinder;
         friend class ::android::Parcel;
         friend class ::android::ProcessState;
+        friend class ::android::RpcSession;
         friend class ::android::RpcState;
-        explicit PrivateAccessorForId(const BpBinder* binder) : mBinder(binder) {}
+        explicit PrivateAccessor(const BpBinder* binder) : mBinder(binder) {}
+
+        static sp<BpBinder> create(int32_t handle) { return BpBinder::create(handle); }
+        static sp<BpBinder> create(const sp<RpcSession>& session, uint64_t address) {
+            return BpBinder::create(session, address);
+        }
 
         // valid if !isRpcBinder
         int32_t binderHandle() const { return mBinder->binderHandle(); }
 
         // valid if isRpcBinder
-        const RpcAddress& rpcAddress() const { return mBinder->rpcAddress(); }
+        uint64_t rpcAddress() const { return mBinder->rpcAddress(); }
         const sp<RpcSession>& rpcSession() const { return mBinder->rpcSession(); }
 
         const BpBinder* mBinder;
     };
-    const PrivateAccessorForId getPrivateAccessorForId() const {
-        return PrivateAccessorForId(this);
-    }
+    const PrivateAccessor getPrivateAccessor() const { return PrivateAccessor(this); }
 
 private:
-    friend PrivateAccessorForId;
+    friend PrivateAccessor;
     friend class sp<BpBinder>;
 
+    static sp<BpBinder> create(int32_t handle);
+    static sp<BpBinder> create(const sp<RpcSession>& session, uint64_t address);
+
     struct BinderHandle {
         int32_t handle;
     };
     struct RpcHandle {
         sp<RpcSession> session;
-        RpcAddress address;
+        uint64_t address;
     };
     using Handle = std::variant<BinderHandle, RpcHandle>;
 
     int32_t binderHandle() const;
-    const RpcAddress& rpcAddress() const;
+    uint64_t rpcAddress() const;
     const sp<RpcSession>& rpcSession() const;
 
     explicit BpBinder(Handle&& handle);
@@ -197,6 +197,7 @@
     static uint32_t                             sBinderProxyCountHighWatermark;
     static uint32_t                             sBinderProxyCountLowWatermark;
     static bool                                 sBinderProxyThrottleCreate;
+    static std::unordered_map<int32_t,uint32_t> sLastLimitCallbackMap;
 };
 
 } // namespace android
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index 97c826c..43fc5ff 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -22,6 +22,8 @@
 #include <utils/String16.h>
 #include <utils/Vector.h>
 
+#include <functional>
+
 // linux/binder.h defines this, but we don't want to include it here in order to
 // avoid exporting the kernel headers
 #ifndef B_PACK_CHARS
@@ -60,6 +62,7 @@
         SYSPROPS_TRANSACTION = B_PACK_CHARS('_', 'S', 'P', 'R'),
         EXTENSION_TRANSACTION = B_PACK_CHARS('_', 'E', 'X', 'T'),
         DEBUG_PID_TRANSACTION = B_PACK_CHARS('_', 'P', 'I', 'D'),
+        SET_RPC_CLIENT_TRANSACTION = B_PACK_CHARS('_', 'R', 'P', 'C'),
 
         // See android.os.IBinder.TWEET_TRANSACTION
         // Most importantly, messages can be anything not exceeding 130 UTF-8
@@ -152,6 +155,27 @@
      */
     status_t                getDebugPid(pid_t* outPid);
 
+    /**
+     * Set the RPC client fd to this binder service, for debugging. This is only available on
+     * debuggable builds.
+     *
+     * When this is called on a binder service, the service:
+     * 1. sets up RPC server
+     * 2. spawns 1 new thread that calls RpcServer::join()
+     *    - join() spawns some number of threads that accept() connections; see RpcServer
+     *
+     * setRpcClientDebug() may be called multiple times. Each call will add a new RpcServer
+     * and opens up a TCP port.
+     *
+     * Note: A thread is spawned for each accept()'ed fd, which may call into functions of the
+     * interface freely. See RpcServer::join(). To avoid such race conditions, implement the service
+     * functions with multithreading support.
+     *
+     * On death of @a keepAliveBinder, the RpcServer shuts down.
+     */
+    [[nodiscard]] status_t setRpcClientDebug(android::base::unique_fd socketFd,
+                                             const sp<IBinder>& keepAliveBinder);
+
     // NOLINTNEXTLINE(google-default-arguments)
     virtual status_t        transact(   uint32_t code,
                                         const Parcel& data,
@@ -233,26 +257,30 @@
      * objects are invoked with their respective objectID, object, and
      * cleanupCookie. Access to these APIs can be made from multiple threads,
      * but calls from different threads are allowed to be interleaved.
+     *
+     * This returns the object which is already attached. If this returns a
+     * non-null value, it means that attachObject failed (a given objectID can
+     * only be used once).
      */
-    virtual void            attachObject(   const void* objectID,
-                                            void* object,
-                                            void* cleanupCookie,
-                                            object_cleanup_func func) = 0;
+    [[nodiscard]] virtual void* attachObject(const void* objectID, void* object,
+                                             void* cleanupCookie, object_cleanup_func func) = 0;
     /**
      * Returns object attached with attachObject.
      */
-    virtual void*           findObject(const void* objectID) const = 0;
+    [[nodiscard]] virtual void* findObject(const void* objectID) const = 0;
     /**
-     * WARNING: this API does not call the cleanup function for legacy reasons.
-     * It also does not return void* for legacy reasons. If you need to detach
-     * an object and destroy it, there are two options:
-     * - if you can, don't call detachObject and instead wait for the destructor
-     *   to clean it up.
-     * - manually retrieve and destruct the object (if multiple of your threads
-     *   are accessing these APIs, you must guarantee that attachObject isn't
-     *   called after findObject and before detachObject is called).
+     * Returns object attached with attachObject, and detaches it. This does not
+     * delete the object.
      */
-    virtual void            detachObject(const void* objectID) = 0;
+    [[nodiscard]] virtual void* detachObject(const void* objectID) = 0;
+
+    /**
+     * Use the lock that this binder contains internally. For instance, this can
+     * be used to modify an attached object without needing to add an additional
+     * lock (though, that attached object must be retrieved before calling this
+     * method). Calling (most) IBinder methods inside this will deadlock.
+     */
+    void withLock(const std::function<void()>& doWithLock);
 
     virtual BBinder*        localBinder();
     virtual BpBinder*       remoteBinder();
diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h
index ff90b30..7d14315 100644
--- a/libs/binder/include/binder/IInterface.h
+++ b/libs/binder/include/binder/IInterface.h
@@ -129,48 +129,50 @@
 
 #endif
 
-#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME)\
-    const ::android::StaticString16                                     \
-        I##INTERFACE##_descriptor_static_str16(__IINTF_CONCAT(u, NAME));\
-    const ::android::String16 I##INTERFACE::descriptor(                 \
-        I##INTERFACE##_descriptor_static_str16);                        \
-    const ::android::String16&                                          \
-            I##INTERFACE::getInterfaceDescriptor() const {              \
-        return I##INTERFACE::descriptor;                                \
-    }                                                                   \
-    ::android::sp<I##INTERFACE> I##INTERFACE::asInterface(              \
-            const ::android::sp<::android::IBinder>& obj)               \
-    {                                                                   \
-        ::android::sp<I##INTERFACE> intr;                               \
-        if (obj != nullptr) {                                           \
-            intr = ::android::sp<I##INTERFACE>::cast(                   \
-                obj->queryLocalInterface(I##INTERFACE::descriptor));    \
-            if (intr == nullptr) {                                      \
-                intr = ::android::sp<Bp##INTERFACE>::make(obj);         \
-            }                                                           \
-        }                                                               \
-        return intr;                                                    \
-    }                                                                   \
-    std::unique_ptr<I##INTERFACE> I##INTERFACE::default_impl;           \
-    bool I##INTERFACE::setDefaultImpl(std::unique_ptr<I##INTERFACE> impl)\
-    {                                                                   \
-        /* Only one user of this interface can use this function     */ \
-        /* at a time. This is a heuristic to detect if two different */ \
-        /* users in the same process use this function.              */ \
-        assert(!I##INTERFACE::default_impl);                            \
-        if (impl) {                                                     \
-            I##INTERFACE::default_impl = std::move(impl);               \
-            return true;                                                \
-        }                                                               \
-        return false;                                                   \
-    }                                                                   \
-    const std::unique_ptr<I##INTERFACE>& I##INTERFACE::getDefaultImpl() \
-    {                                                                   \
-        return I##INTERFACE::default_impl;                              \
-    }                                                                   \
-    I##INTERFACE::I##INTERFACE() { }                                    \
-    I##INTERFACE::~I##INTERFACE() { }                                   \
+// Macro to be used by both IMPLEMENT_META_INTERFACE and IMPLEMENT_META_NESTED_INTERFACE
+#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(ITYPE, INAME, BPTYPE)                     \
+    const ::android::String16& ITYPE::getInterfaceDescriptor() const { return ITYPE::descriptor; } \
+    ::android::sp<ITYPE> ITYPE::asInterface(const ::android::sp<::android::IBinder>& obj) {        \
+        ::android::sp<ITYPE> intr;                                                                 \
+        if (obj != nullptr) {                                                                      \
+            intr = ::android::sp<ITYPE>::cast(obj->queryLocalInterface(ITYPE::descriptor));        \
+            if (intr == nullptr) {                                                                 \
+                intr = ::android::sp<BPTYPE>::make(obj);                                           \
+            }                                                                                      \
+        }                                                                                          \
+        return intr;                                                                               \
+    }                                                                                              \
+    std::unique_ptr<ITYPE> ITYPE::default_impl;                                                    \
+    bool ITYPE::setDefaultImpl(std::unique_ptr<ITYPE> impl) {                                      \
+        /* Only one user of this interface can use this function     */                            \
+        /* at a time. This is a heuristic to detect if two different */                            \
+        /* users in the same process use this function.              */                            \
+        assert(!ITYPE::default_impl);                                                              \
+        if (impl) {                                                                                \
+            ITYPE::default_impl = std::move(impl);                                                 \
+            return true;                                                                           \
+        }                                                                                          \
+        return false;                                                                              \
+    }                                                                                              \
+    const std::unique_ptr<ITYPE>& ITYPE::getDefaultImpl() { return ITYPE::default_impl; }          \
+    ITYPE::INAME() {}                                                                              \
+    ITYPE::~INAME() {}
 
+// Macro for an interface type.
+#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                        \
+    const ::android::StaticString16 I##INTERFACE##_descriptor_static_str16(                     \
+            __IINTF_CONCAT(u, NAME));                                                           \
+    const ::android::String16 I##INTERFACE::descriptor(I##INTERFACE##_descriptor_static_str16); \
+    DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(I##INTERFACE, I##INTERFACE, Bp##INTERFACE)
+
+// Macro for "nested" interface type.
+// For example,
+//   class Parent .. { class INested .. { }; };
+// DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_NESTED_INTERFACE(Parent, Nested, "Parent.INested")
+#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_NESTED_INTERFACE(PARENT, INTERFACE, NAME)  \
+    const ::android::String16 PARENT::I##INTERFACE::descriptor(NAME);                    \
+    DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(PARENT::I##INTERFACE, I##INTERFACE, \
+                                                     PARENT::Bp##INTERFACE)
 
 #define CHECK_INTERFACE(interface, data, reply)                         \
     do {                                                                \
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index b401ea9..82bebc9 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -51,17 +51,11 @@
     static  status_t            freeze(pid_t pid, bool enabled, uint32_t timeout_ms);
 
     // Provide information about the state of a frozen process
-    static  status_t            getProcessFreezeInfo(pid_t pid, bool *sync_received,
-                                                    bool *async_received);
-
-    // TODO: Remove the above legacy duplicated function in next version
-#ifndef __ANDROID_VNDK__
     static  status_t            getProcessFreezeInfo(pid_t pid, uint32_t *sync_received,
                                                     uint32_t *async_received);
-#endif
 
             sp<ProcessState>    process();
-            
+
             status_t            clearLastError();
 
             /**
@@ -69,7 +63,7 @@
              * call. If not in a binder call, this will return getpid. If the
              * call is oneway, this will return 0.
              */
-            pid_t               getCallingPid() const;
+            [[nodiscard]] pid_t getCallingPid() const;
 
             /**
              * Returns the SELinux security identifier of the process which has
@@ -80,13 +74,43 @@
              * This can't be restored once it's cleared, and it does not return the
              * context of the current process when not in a binder call.
              */
-            const char*         getCallingSid() const;
+            [[nodiscard]] const char* getCallingSid() const;
 
             /**
              * Returns the UID of the process which has made the current binder
              * call. If not in a binder call, this will return 0.
              */
-            uid_t               getCallingUid() const;
+            [[nodiscard]] uid_t getCallingUid() const;
+
+            /**
+             * Make it an abort to rely on getCalling* for a section of
+             * execution.
+             *
+             * Usage:
+             *     IPCThreadState::SpGuard guard {
+             *        .address = __builtin_frame_address(0),
+             *        .context = "...",
+             *     };
+             *     const auto* orig = pushGetCallingSpGuard(&guard);
+             *     {
+             *         // will abort if you call getCalling*, unless you are
+             *         // serving a nested binder transaction
+             *     }
+             *     restoreCallingSpGuard(orig);
+             */
+            struct SpGuard {
+                const void* address;
+                const char* context;
+            };
+            const SpGuard* pushGetCallingSpGuard(const SpGuard* guard);
+            void restoreGetCallingSpGuard(const SpGuard* guard);
+            /**
+             * Used internally by getCalling*. Can also be used to assert that
+             * you are in a binder context (getCalling* is valid). This is
+             * intentionally not exposed as a boolean API since code should be
+             * written to know its environment.
+             */
+            void checkContextIsBinderForUse(const char* use) const;
 
             void                setStrictModePolicy(int32_t policy);
             int32_t             getStrictModePolicy() const;
@@ -204,6 +228,7 @@
             Parcel              mOut;
             status_t            mLastError;
             const void*         mServingStackPointer;
+            const SpGuard* mServingStackPointerGuard;
             pid_t               mCallingPid;
             const char*         mCallingSid;
             uid_t               mCallingUid;
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 3dbe2c4..240e3c2 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -15,11 +15,9 @@
  */
 
 #pragma once
-
 #include <binder/IInterface.h>
 #include <utils/Vector.h>
 #include <utils/String16.h>
-
 #include <optional>
 
 namespace android {
@@ -107,6 +105,16 @@
      * this can be updated.
      */
     virtual std::optional<String16> updatableViaApex(const String16& name) = 0;
+
+    /**
+     * If this instance has declared remote connection information, returns
+     * the ConnectionInfo.
+     */
+    struct ConnectionInfo {
+        std::string ipAddress;
+        unsigned int port;
+    };
+    virtual std::optional<ConnectionInfo> getConnectionInfo(const String16& name) = 0;
 };
 
 sp<IServiceManager> defaultServiceManager();
@@ -167,6 +175,29 @@
 bool checkCallingPermission(const String16& permission);
 bool checkCallingPermission(const String16& permission,
                             int32_t* outPid, int32_t* outUid);
-bool checkPermission(const String16& permission, pid_t pid, uid_t uid);
+bool checkPermission(const String16& permission, pid_t pid, uid_t uid,
+                     bool logPermissionFailure = true);
+
+#ifndef __ANDROID__
+// Create an IServiceManager that delegates the service manager on the device via adb.
+// This is can be set as the default service manager at program start, so that
+// defaultServiceManager() returns it:
+//    int main() {
+//        setDefaultServiceManager(createRpcDelegateServiceManager());
+//        auto sm = defaultServiceManager();
+//        // ...
+//    }
+// Resources are cleaned up when the object is destroyed.
+//
+// For each returned binder object, at most |maxOutgoingThreads| outgoing threads are instantiated.
+// Hence, only |maxOutgoingThreads| calls can be made simultaneously. Additional calls are blocked
+// if there are |maxOutgoingThreads| ongoing calls. See RpcSession::setMaxOutgoingThreads.
+// If |maxOutgoingThreads| is not set, default is |RpcSession::kDefaultMaxOutgoingThreads|.
+struct RpcDelegateServiceManagerOptions {
+    std::optional<size_t> maxOutgoingThreads;
+};
+sp<IServiceManager> createRpcDelegateServiceManager(
+        const RpcDelegateServiceManagerOptions& options);
+#endif
 
 } // namespace android
diff --git a/libs/binder/include/binder/MemoryDealer.h b/libs/binder/include/binder/MemoryDealer.h
index e727772..3f7dd11 100644
--- a/libs/binder/include/binder/MemoryDealer.h
+++ b/libs/binder/include/binder/MemoryDealer.h
@@ -36,7 +36,6 @@
             uint32_t flags = 0 /* or bits such as MemoryHeapBase::READ_ONLY */ );
 
     virtual sp<IMemory> allocate(size_t size);
-    virtual void        deallocate(size_t offset);
     virtual void        dump(const char* what) const;
 
     // allocations are aligned to some value. return that value so clients can account for it.
@@ -48,6 +47,8 @@
     virtual ~MemoryDealer();
 
 private:
+    friend class Allocation;
+    virtual void                deallocate(size_t offset);
     const sp<IMemoryHeap>&      heap() const;
     SimpleBestFitAllocator*     allocator() const;
 
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 5aaaa0c..9670d7b 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -81,12 +81,15 @@
                                    size_t start, size_t len);
 
     int                 compareData(const Parcel& other);
+    status_t compareDataInRange(size_t thisOffset, const Parcel& other, size_t otherOffset,
+                                size_t length, int* result) const;
 
     bool                allowFds() const;
     bool                pushAllowFds(bool allowFds);
     void                restoreAllowFds(bool lastValue);
 
     bool                hasFileDescriptors() const;
+    status_t hasFileDescriptorsInRange(size_t offset, size_t length, bool* result) const;
 
     // Zeros data when reallocating. Other mitigations may be added
     // in the future.
@@ -204,6 +207,23 @@
     status_t            writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IBinder>>>& val) __attribute__((deprecated("use std::optional version instead")));
     status_t            writeStrongBinderVector(const std::vector<sp<IBinder>>& val);
 
+    // Write an IInterface or a vector of IInterface's
+    template <typename T,
+              std::enable_if_t<std::is_base_of_v<::android::IInterface, T>, bool> = true>
+    status_t writeStrongBinder(const sp<T>& val) {
+        return writeStrongBinder(T::asBinder(val));
+    }
+    template <typename T,
+              std::enable_if_t<std::is_base_of_v<::android::IInterface, T>, bool> = true>
+    status_t writeStrongBinderVector(const std::vector<sp<T>>& val) {
+        return writeData(val);
+    }
+    template <typename T,
+              std::enable_if_t<std::is_base_of_v<::android::IInterface, T>, bool> = true>
+    status_t writeStrongBinderVector(const std::optional<std::vector<sp<T>>>& val) {
+        return writeData(val);
+    }
+
     // Write an Enum vector with underlying type int8_t.
     // Does not use padding; each byte is contiguous.
     template<typename T, std::enable_if_t<std::is_enum_v<T> && std::is_same_v<typename std::underlying_type_t<T>,int8_t>, bool> = 0>
@@ -245,9 +265,10 @@
     template<typename T>
     status_t            writeNullableParcelable(const std::optional<T>& parcelable)
             { return writeData(parcelable); }
-    template<typename T>
-    status_t            writeNullableParcelable(const std::unique_ptr<T>& parcelable) __attribute__((deprecated("use std::optional version instead")))
-            { return writeData(parcelable); }
+    template <typename T>
+    status_t writeNullableParcelable(const std::unique_ptr<T>& parcelable) {
+        return writeData(parcelable);
+    }
 
     status_t            writeParcelable(const Parcelable& parcelable);
 
@@ -401,9 +422,10 @@
     template<typename T>
     status_t            readParcelable(std::optional<T>* parcelable) const
             { return readData(parcelable); }
-    template<typename T>
-    status_t            readParcelable(std::unique_ptr<T>* parcelable) const __attribute__((deprecated("use std::optional version instead")))
-            { return readData(parcelable); }
+    template <typename T>
+    status_t readParcelable(std::unique_ptr<T>* parcelable) const {
+        return readData(parcelable);
+    }
 
     // If strong binder would be nullptr, readStrongBinder() returns an error.
     // TODO: T must be derived from IInterface, fix for clarity.
@@ -416,6 +438,16 @@
     status_t            readStrongBinderVector(std::optional<std::vector<sp<IBinder>>>* val) const;
     status_t            readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const __attribute__((deprecated("use std::optional version instead")));
     status_t            readStrongBinderVector(std::vector<sp<IBinder>>* val) const;
+    template <typename T,
+              std::enable_if_t<std::is_base_of_v<::android::IInterface, T>, bool> = true>
+    status_t readStrongBinderVector(std::vector<sp<T>>* val) const {
+        return readData(val);
+    }
+    template <typename T,
+              std::enable_if_t<std::is_base_of_v<::android::IInterface, T>, bool> = true>
+    status_t readStrongBinderVector(std::optional<std::vector<sp<T>>>* val) const {
+        return readData(val);
+    }
 
     status_t            readByteVector(std::optional<std::vector<int8_t>>* val) const;
     status_t            readByteVector(std::unique_ptr<std::vector<int8_t>>* val) const __attribute__((deprecated("use std::optional version instead")));
@@ -561,6 +593,8 @@
     status_t            flattenBinder(const sp<IBinder>& binder);
     status_t            unflattenBinder(sp<IBinder>* out) const;
 
+    status_t readOutVectorSizeWithCheck(size_t elmSize, int32_t* size) const;
+
     template<class T>
     status_t            readAligned(T *pArg) const;
 
@@ -1137,6 +1171,7 @@
     release_func        mOwner;
 
     sp<RpcSession> mSession;
+    size_t mReserved;
 
     class Blob {
     public:
@@ -1221,13 +1256,19 @@
         inline void* data() { return mData; }
     };
 
-private:
-    size_t mOpenAshmemSize;
-
-public:
-    // TODO: Remove once ABI can be changed.
-    size_t getBlobAshmemSize() const;
+    /**
+     * Returns the total amount of ashmem memory owned by this object.
+     *
+     * Note: for historical reasons, this does not include ashmem memory which
+     * is referenced by this Parcel, but which this parcel doesn't own (e.g.
+     * writeFileDescriptor is called without 'takeOwnership' true).
+     */
     size_t getOpenAshmemSize() const;
+
+private:
+    // TODO(b/202029388): Remove 'getBlobAshmemSize' once no prebuilts reference
+    // this
+    size_t getBlobAshmemSize() const;
 };
 
 // ---------------------------------------------------------------------------
@@ -1315,7 +1356,7 @@
 template<typename T>
 status_t Parcel::resizeOutVector(std::vector<T>* val) const {
     int32_t size;
-    status_t err = readInt32(&size);
+    status_t err = readOutVectorSizeWithCheck(sizeof(T), &size);
     if (err != NO_ERROR) {
         return err;
     }
@@ -1330,7 +1371,7 @@
 template<typename T>
 status_t Parcel::resizeOutVector(std::optional<std::vector<T>>* val) const {
     int32_t size;
-    status_t err = readInt32(&size);
+    status_t err = readOutVectorSizeWithCheck(sizeof(T), &size);
     if (err != NO_ERROR) {
         return err;
     }
@@ -1346,7 +1387,7 @@
 template<typename T>
 status_t Parcel::resizeOutVector(std::unique_ptr<std::vector<T>>* val) const {
     int32_t size;
-    status_t err = readInt32(&size);
+    status_t err = readOutVectorSizeWithCheck(sizeof(T), &size);
     if (err != NO_ERROR) {
         return err;
     }
diff --git a/libs/binder/include/binder/ParcelableHolder.h b/libs/binder/include/binder/ParcelableHolder.h
index 9e4475c..42c85f9 100644
--- a/libs/binder/include/binder/ParcelableHolder.h
+++ b/libs/binder/include/binder/ParcelableHolder.h
@@ -42,6 +42,7 @@
         }
         mStability = other.mStability;
     }
+    ParcelableHolder(ParcelableHolder&& other) = default;
 
     status_t writeToParcel(Parcel* parcel) const override;
     status_t readFromParcel(const Parcel* parcel) override;
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index b9db5d7..cf8d8e4 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -18,8 +18,8 @@
 
 #include <binder/IBinder.h>
 #include <utils/KeyedVector.h>
-#include <utils/String8.h>
 #include <utils/String16.h>
+#include <utils/String8.h>
 
 #include <utils/threads.h>
 
@@ -30,11 +30,10 @@
 
 class IPCThreadState;
 
-class ProcessState : public virtual RefBase
-{
+class ProcessState : public virtual RefBase {
 public:
-    static  sp<ProcessState>    self();
-    static  sp<ProcessState>    selfOrNull();
+    static sp<ProcessState> self();
+    static sp<ProcessState> selfOrNull();
 
     /* initWithDriver() can be used to configure libbinder to use
      * a different binder driver dev node. It must be called *before*
@@ -44,94 +43,106 @@
      *
      * If this is called with nullptr, the behavior is the same as selfOrNull.
      */
-    static  sp<ProcessState>    initWithDriver(const char *driver);
+    static sp<ProcessState> initWithDriver(const char* driver);
 
-            sp<IBinder>         getContextObject(const sp<IBinder>& caller);
+    sp<IBinder> getContextObject(const sp<IBinder>& caller);
 
-            void                startThreadPool();
+    void startThreadPool();
 
-            bool                becomeContextManager();
+    bool becomeContextManager();
 
-            sp<IBinder>         getStrongProxyForHandle(int32_t handle);
-            void                expungeHandle(int32_t handle, IBinder* binder);
+    sp<IBinder> getStrongProxyForHandle(int32_t handle);
+    void expungeHandle(int32_t handle, IBinder* binder);
 
-            void                spawnPooledThread(bool isMain);
-            
-            status_t            setThreadPoolMaxThreadCount(size_t maxThreads);
-            status_t            enableOnewaySpamDetection(bool enable);
-            void                giveThreadPoolName();
+    void spawnPooledThread(bool isMain);
 
-            String8             getDriverName();
+    status_t setThreadPoolMaxThreadCount(size_t maxThreads);
+    status_t enableOnewaySpamDetection(bool enable);
+    void giveThreadPoolName();
 
-            ssize_t             getKernelReferences(size_t count, uintptr_t* buf);
+    String8 getDriverName();
 
-                                // Only usable by the context manager.
-                                // This refcount includes:
-                                // 1. Strong references to the node by this and other processes
-                                // 2. Temporary strong references held by the kernel during a
-                                //    transaction on the node.
-                                // It does NOT include local strong references to the node
-            ssize_t             getStrongRefCountForNode(const sp<BpBinder>& binder);
+    ssize_t getKernelReferences(size_t count, uintptr_t* buf);
 
-            enum class CallRestriction {
-                // all calls okay
-                NONE,
-                // log when calls are blocking
-                ERROR_IF_NOT_ONEWAY,
-                // abort process on blocking calls
-                FATAL_IF_NOT_ONEWAY,
-            };
-            // Sets calling restrictions for all transactions in this process. This must be called
-            // before any threads are spawned.
-            void setCallRestriction(CallRestriction restriction);
+    // Only usable by the context manager.
+    // This refcount includes:
+    // 1. Strong references to the node by this and other processes
+    // 2. Temporary strong references held by the kernel during a
+    //    transaction on the node.
+    // It does NOT include local strong references to the node
+    ssize_t getStrongRefCountForNode(const sp<BpBinder>& binder);
+
+    enum class CallRestriction {
+        // all calls okay
+        NONE,
+        // log when calls are blocking
+        ERROR_IF_NOT_ONEWAY,
+        // abort process on blocking calls
+        FATAL_IF_NOT_ONEWAY,
+    };
+    // Sets calling restrictions for all transactions in this process. This must be called
+    // before any threads are spawned.
+    void setCallRestriction(CallRestriction restriction);
+
+    /**
+     * Get the max number of threads that the kernel can start.
+     *
+     * Note: this is the lower bound. Additional threads may be started.
+     */
+    size_t getThreadPoolMaxThreadCount() const;
 
 private:
-    static  sp<ProcessState>    init(const char *defaultDriver, bool requireDefault);
+    static sp<ProcessState> init(const char* defaultDriver, bool requireDefault);
+
+    static void onFork();
+    static void parentPostFork();
+    static void childPostFork();
 
     friend class IPCThreadState;
     friend class sp<ProcessState>;
 
-            explicit            ProcessState(const char* driver);
-                                ~ProcessState();
+    explicit ProcessState(const char* driver);
+    ~ProcessState();
 
-                                ProcessState(const ProcessState& o);
-            ProcessState&       operator=(const ProcessState& o);
-            String8             makeBinderThreadName();
+    ProcessState(const ProcessState& o);
+    ProcessState& operator=(const ProcessState& o);
+    String8 makeBinderThreadName();
 
-            struct handle_entry {
-                IBinder* binder;
-                RefBase::weakref_type* refs;
-            };
+    struct handle_entry {
+        IBinder* binder;
+        RefBase::weakref_type* refs;
+    };
 
-            handle_entry*       lookupHandleLocked(int32_t handle);
+    handle_entry* lookupHandleLocked(int32_t handle);
 
-            String8             mDriverName;
-            int                 mDriverFD;
-            void*               mVMStart;
+    String8 mDriverName;
+    int mDriverFD;
+    void* mVMStart;
 
-            // Protects thread count and wait variables below.
-            pthread_mutex_t     mThreadCountLock;
-            // Broadcast whenever mWaitingForThreads > 0
-            pthread_cond_t      mThreadCountDecrement;
-            // Number of binder threads current executing a command.
-            size_t              mExecutingThreadsCount;
-            // Number of threads calling IPCThreadState::blockUntilThreadAvailable()
-            size_t              mWaitingForThreads;
-            // Maximum number for binder threads allowed for this process.
-            size_t              mMaxThreads;
-            // Time when thread pool was emptied
-            int64_t             mStarvationStartTimeMs;
+    // Protects thread count and wait variables below.
+    pthread_mutex_t mThreadCountLock;
+    // Broadcast whenever mWaitingForThreads > 0
+    pthread_cond_t mThreadCountDecrement;
+    // Number of binder threads current executing a command.
+    size_t mExecutingThreadsCount;
+    // Number of threads calling IPCThreadState::blockUntilThreadAvailable()
+    size_t mWaitingForThreads;
+    // Maximum number for binder threads allowed for this process.
+    size_t mMaxThreads;
+    // Time when thread pool was emptied
+    int64_t mStarvationStartTimeMs;
 
-    mutable Mutex               mLock;  // protects everything below.
+    mutable Mutex mLock; // protects everything below.
 
-            Vector<handle_entry>mHandleToObject;
+    Vector<handle_entry> mHandleToObject;
 
-            bool                mThreadPoolStarted;
-    volatile int32_t            mThreadPoolSeq;
+    bool mForked;
+    bool mThreadPoolStarted;
+    volatile int32_t mThreadPoolSeq;
 
-            CallRestriction     mCallRestriction;
+    CallRestriction mCallRestriction;
 };
-    
+
 } // namespace android
 
 // ---------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/RpcAddress.h b/libs/binder/include/binder/RpcAddress.h
deleted file mode 100644
index 5a3f3a6..0000000
--- a/libs/binder/include/binder/RpcAddress.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <memory>
-
-#include <utils/Errors.h>
-
-// WARNING: This is a feature which is still in development, and it is subject
-// to radical change. Any production use of this may subject your code to any
-// number of problems.
-
-namespace android {
-
-class Parcel;
-struct RpcWireAddress;
-
-/**
- * This class represents an identifier of a binder object.
- *
- * The purpose of this class it to hide the ABI of an RpcWireAddress, and
- * potentially allow us to change the size of it in the future (RpcWireAddress
- * is PIMPL, essentially - although the type that is used here is not exposed).
- */
-class RpcAddress {
-public:
-    /**
-     * The zero address is used for special RPC transactions, but it might also
-     * be used in conjunction with readFromParcel.
-     */
-    static RpcAddress zero();
-
-    bool isZero() const;
-
-    /**
-     * Create a new address which is unique
-     */
-    static RpcAddress unique();
-
-    /**
-     * Creates a new address as a copy of an embedded object.
-     */
-    static RpcAddress fromRawEmbedded(const RpcWireAddress* raw);
-    const RpcWireAddress& viewRawEmbedded() const;
-
-    bool operator<(const RpcAddress& rhs) const;
-    std::string toString() const;
-
-    status_t writeToParcel(Parcel* parcel) const;
-    status_t readFromParcel(const Parcel& parcel);
-
-    ~RpcAddress();
-
-private:
-    RpcAddress();
-
-    std::shared_ptr<RpcWireAddress> mRawAddr;
-};
-
-} // namespace android
diff --git a/libs/binder/include/binder/RpcCertificateFormat.h b/libs/binder/include/binder/RpcCertificateFormat.h
new file mode 100644
index 0000000..bc9d814
--- /dev/null
+++ b/libs/binder/include/binder/RpcCertificateFormat.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+// Formats for serializing TLS certificate.
+
+#pragma once
+
+#include <string>
+
+namespace android {
+
+enum class RpcCertificateFormat {
+    PEM,
+    DER,
+};
+
+static inline std::string PrintToString(RpcCertificateFormat format) {
+    switch (format) {
+        case RpcCertificateFormat::PEM:
+            return "PEM";
+        case RpcCertificateFormat::DER:
+            return "DER";
+        default:
+            return "<unknown>";
+    }
+}
+
+} // namespace android
diff --git a/libs/binder/include/binder/RpcKeyFormat.h b/libs/binder/include/binder/RpcKeyFormat.h
new file mode 100644
index 0000000..5099c2e
--- /dev/null
+++ b/libs/binder/include/binder/RpcKeyFormat.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+// Formats for serializing TLS private keys.
+
+#pragma once
+
+#include <string>
+
+namespace android {
+
+enum class RpcKeyFormat {
+    PEM,
+    DER,
+};
+
+static inline std::string PrintToString(RpcKeyFormat format) {
+    switch (format) {
+        case RpcKeyFormat::PEM:
+            return "PEM";
+        case RpcKeyFormat::DER:
+            return "DER";
+        default:
+            return "<unknown>";
+    }
+}
+
+} // namespace android
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index 8f0c6fd..aaa812b 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -18,18 +18,16 @@
 #include <android-base/unique_fd.h>
 #include <binder/IBinder.h>
 #include <binder/RpcSession.h>
+#include <binder/RpcTransport.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 
 #include <mutex>
 #include <thread>
 
-// WARNING: This is a feature which is still in development, and it is subject
-// to radical change. Any production use of this may subject your code to any
-// number of problems.
-
 namespace android {
 
+class FdTrigger;
 class RpcSocketAddress;
 
 /**
@@ -44,9 +42,10 @@
  *     }
  *     server->join();
  */
-class RpcServer final : public virtual RefBase {
+class RpcServer final : public virtual RefBase, private RpcSession::EventListener {
 public:
-    static sp<RpcServer> make();
+    static sp<RpcServer> make(
+            std::unique_ptr<RpcTransportCtxFactory> rpcTransportCtxFactory = nullptr);
 
     /**
      * This represents a session for responses, e.g.:
@@ -56,12 +55,12 @@
      *     process B makes binder b and sends it to A
      *     A uses this 'back session' to send things back to B
      */
-    [[nodiscard]] bool setupUnixDomainServer(const char* path);
+    [[nodiscard]] status_t setupUnixDomainServer(const char* path);
 
     /**
      * Creates an RPC server at the current port.
      */
-    [[nodiscard]] bool setupVsockServer(unsigned int port);
+    [[nodiscard]] status_t setupVsockServer(unsigned int port);
 
     /**
      * Creates an RPC server at the current port using IPv4.
@@ -71,8 +70,14 @@
      * Set |port| to 0 to pick an ephemeral port; see discussion of
      * /proc/sys/net/ipv4/ip_local_port_range in ip(7). In this case, |assignedPort|
      * will be set to the picked port number, if it is not null.
+     *
+     * Set the IPv4 address for the socket to be listening on.
+     * "127.0.0.1" allows for local connections from the same device.
+     * "0.0.0.0" allows for connections on any IP address that the device may
+     * have
      */
-    [[nodiscard]] bool setupInetServer(unsigned int port, unsigned int* assignedPort);
+    [[nodiscard]] status_t setupInetServer(const char* address, unsigned int port,
+                                           unsigned int* assignedPort);
 
     /**
      * If setup*Server has been successful, return true. Otherwise return false.
@@ -88,22 +93,27 @@
      * Set up server using an external FD previously set up by releaseServer().
      * Return false if there's already a server.
      */
-    bool setupExternalServer(base::unique_fd serverFd);
-
-    void iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+    [[nodiscard]] status_t setupExternalServer(base::unique_fd serverFd);
 
     /**
      * This must be called before adding a client session.
      *
      * If this is not specified, this will be a single-threaded server.
      *
-     * TODO(b/185167543): these are currently created per client, but these
+     * TODO(b/167966510): these are currently created per client, but these
      * should be shared.
      */
     void setMaxThreads(size_t threads);
     size_t getMaxThreads();
 
     /**
+     * By default, the latest protocol version which is supported by a client is
+     * used. However, this can be used in order to prevent newer protocol
+     * versions from ever being used. This is expected to be useful for testing.
+     */
+    void setProtocolVersion(uint32_t version);
+
+    /**
      * The root object can be retrieved by any client, without any
      * authentication. TODO(b/183988761)
      *
@@ -114,20 +124,43 @@
      * Holds a weak reference to the root object.
      */
     void setRootObjectWeak(const wp<IBinder>& binder);
+    /**
+     * Allows a root object to be created for each session
+     */
+    void setPerSessionRootObject(std::function<sp<IBinder>(const sockaddr*, socklen_t)>&& object);
     sp<IBinder> getRootObject();
 
     /**
+     * See RpcTransportCtx::getCertificate
+     */
+    std::vector<uint8_t> getCertificate(RpcCertificateFormat);
+
+    /**
+     * Runs join() in a background thread. Immediately returns.
+     */
+    void start();
+
+    /**
      * You must have at least one client session before calling this.
      *
-     * TODO(b/185167543): way to shut down?
+     * If a client needs to actively terminate join, call shutdown() in a separate thread.
+     *
+     * At any given point, there can only be one thread calling join().
+     *
+     * Warning: if shutdown is called, this will return while the shutdown is
+     * still occurring. To ensure that the service is fully shutdown, you might
+     * want to call shutdown after 'join' returns.
      */
     void join();
 
     /**
-     * Accept one connection on this server. You must have at least one client
-     * session before calling this.
+     * Shut down any existing join(). Return true if successfully shut down, false otherwise
+     * (e.g. no join() is running). Will wait for the server to be fully
+     * shutdown.
+     *
+     * Warning: this will hang if it is called from its own thread.
      */
-    [[nodiscard]] bool acceptOne();
+    [[nodiscard]] bool shutdown();
 
     /**
      * For debugging!
@@ -137,28 +170,32 @@
 
     ~RpcServer();
 
-    // internal use only
-
-    void onSessionTerminating(const sp<RpcSession>& session);
-
 private:
     friend sp<RpcServer>;
-    RpcServer();
+    explicit RpcServer(std::unique_ptr<RpcTransportCtx> ctx);
 
-    void establishConnection(sp<RpcServer>&& session, base::unique_fd clientFd);
-    bool setupSocketServer(const RpcSocketAddress& address);
+    void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) override;
+    void onSessionIncomingThreadEnded() override;
 
-    bool mAgreedExperimental = false;
-    bool mStarted = false; // TODO(b/185167543): support dynamically added clients
+    static void establishConnection(sp<RpcServer>&& server, base::unique_fd clientFd,
+                                    const sockaddr_storage addr, socklen_t addrLen);
+    [[nodiscard]] status_t setupSocketServer(const RpcSocketAddress& address);
+
+    const std::unique_ptr<RpcTransportCtx> mCtx;
     size_t mMaxThreads = 1;
+    std::optional<uint32_t> mProtocolVersion;
     base::unique_fd mServer; // socket we are accepting sessions on
 
     std::mutex mLock; // for below
+    std::unique_ptr<std::thread> mJoinThread;
+    bool mJoinThreadRunning = false;
     std::map<std::thread::id, std::thread> mConnectingThreads;
     sp<IBinder> mRootObject;
     wp<IBinder> mRootObjectWeak;
-    std::map<int32_t, sp<RpcSession>> mSessions;
-    int32_t mSessionIdCounter = 0;
+    std::function<sp<IBinder>(const sockaddr*, socklen_t)> mRootObjectFactory;
+    std::map<std::vector<uint8_t>, sp<RpcSession>> mSessions;
+    std::unique_ptr<FdTrigger> mShutdownTrigger;
+    std::condition_variable mShutdownCv;
 };
 
 } // namespace android
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index bcc213c..1bc8464 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -17,7 +17,7 @@
 
 #include <android-base/unique_fd.h>
 #include <binder/IBinder.h>
-#include <binder/RpcAddress.h>
+#include <binder/RpcTransport.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 
@@ -26,16 +26,18 @@
 #include <thread>
 #include <vector>
 
-// WARNING: This is a feature which is still in development, and it is subject
-// to radical change. Any production use of this may subject your code to any
-// number of problems.
-
 namespace android {
 
 class Parcel;
 class RpcServer;
 class RpcSocketAddress;
 class RpcState;
+class RpcTransport;
+class FdTrigger;
+
+constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_NEXT = 0;
+constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL = 0xF0000000;
+constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION = RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL;
 
 /**
  * This represents a session (group of connections) between a client
@@ -44,23 +46,76 @@
  */
 class RpcSession final : public virtual RefBase {
 public:
+    static constexpr size_t kDefaultMaxOutgoingThreads = 10;
+
+    // Create an RpcSession with default configuration (raw sockets).
     static sp<RpcSession> make();
 
+    // Create an RpcSession with the given configuration. |serverRpcCertificateFormat| and
+    // |serverCertificate| must have values or be nullopt simultaneously. If they have values, set
+    // server certificate.
+    static sp<RpcSession> make(std::unique_ptr<RpcTransportCtxFactory> rpcTransportCtxFactory);
+
+    /**
+     * Set the maximum number of incoming threads allowed to be made (for things like callbacks).
+     * By default, this is 0. This must be called before setting up this connection as a client.
+     * Server sessions will inherits this value from RpcServer.
+     *
+     * If this is called, 'shutdown' on this session must also be called.
+     * Otherwise, a threadpool will leak.
+     *
+     * TODO(b/189955605): start these dynamically
+     */
+    void setMaxIncomingThreads(size_t threads);
+    size_t getMaxIncomingThreads();
+
+    /**
+     * Set the maximum number of outgoing threads allowed to be made.
+     * By default, this is |kDefaultMaxOutgoingThreads|. This must be called before setting up this
+     * connection as a client.
+     *
+     * This limits the number of outgoing threads on top of the remote peer setting. This RpcSession
+     * will only instantiate |min(maxOutgoingThreads, remoteMaxThreads)| outgoing threads, where
+     * |remoteMaxThreads| can be retrieved from the remote peer via |getRemoteMaxThreads()|.
+     */
+    void setMaxOutgoingThreads(size_t threads);
+    size_t getMaxOutgoingThreads();
+
+    /**
+     * By default, the minimum of the supported versions of the client and the
+     * server will be used. Usually, this API should only be used for debugging.
+     */
+    [[nodiscard]] bool setProtocolVersion(uint32_t version);
+    std::optional<uint32_t> getProtocolVersion();
+
     /**
      * This should be called once per thread, matching 'join' in the remote
      * process.
      */
-    [[nodiscard]] bool setupUnixDomainClient(const char* path);
+    [[nodiscard]] status_t setupUnixDomainClient(const char* path);
 
     /**
      * Connects to an RPC server at the CVD & port.
      */
-    [[nodiscard]] bool setupVsockClient(unsigned int cvd, unsigned int port);
+    [[nodiscard]] status_t setupVsockClient(unsigned int cvd, unsigned int port);
 
     /**
      * Connects to an RPC server at the given address and port.
      */
-    [[nodiscard]] bool setupInetClient(const char* addr, unsigned int port);
+    [[nodiscard]] status_t setupInetClient(const char* addr, unsigned int port);
+
+    /**
+     * Starts talking to an RPC server which has already been connected to. This
+     * is expected to be used when another process has permission to connect to
+     * a binder RPC service, but this process only has permission to talk to
+     * that service.
+     *
+     * For convenience, if 'fd' is -1, 'request' will be called.
+     *
+     * For future compatibility, 'request' should not reference any stack data.
+     */
+    [[nodiscard]] status_t setupPreconnectedClient(base::unique_fd fd,
+                                                   std::function<base::unique_fd()>&& request);
 
     /**
      * For debugging!
@@ -69,7 +124,7 @@
      * response will never be satisfied. All data sent here will be
      * unceremoniously cast down the bottomless pit, /dev/null.
      */
-    [[nodiscard]] bool addNullDebuggingClient();
+    [[nodiscard]] status_t addNullDebuggingClient();
 
     /**
      * Query the other side of the session for the root object hosted by that
@@ -81,59 +136,129 @@
      * Query the other side of the session for the maximum number of threads
      * it supports (maximum number of concurrent non-nested synchronous transactions)
      */
-    status_t getRemoteMaxThreads(size_t* maxThreads);
+    [[nodiscard]] status_t getRemoteMaxThreads(size_t* maxThreads);
 
-    [[nodiscard]] status_t transact(const RpcAddress& address, uint32_t code, const Parcel& data,
+    /**
+     * See RpcTransportCtx::getCertificate
+     */
+    std::vector<uint8_t> getCertificate(RpcCertificateFormat);
+
+    /**
+     * Shuts down the service.
+     *
+     * For client sessions, wait can be true or false. For server sessions,
+     * waiting is not currently supported (will abort).
+     *
+     * Warning: this is currently not active/nice (the server isn't told we're
+     * shutting down). Being nicer to the server could potentially make it
+     * reclaim resources faster.
+     *
+     * If this is called w/ 'wait' true, then this will wait for shutdown to
+     * complete before returning. This will hang if it is called from the
+     * session threadpool (when processing received calls).
+     */
+    [[nodiscard]] bool shutdownAndWait(bool wait);
+
+    [[nodiscard]] status_t transact(const sp<IBinder>& binder, uint32_t code, const Parcel& data,
                                     Parcel* reply, uint32_t flags);
-    [[nodiscard]] status_t sendDecStrong(const RpcAddress& address);
+
+    /**
+     * Generally, you should not call this, unless you are testing error
+     * conditions, as this is called automatically by BpBinders when they are
+     * deleted (this is also why a raw pointer is used here)
+     */
+    [[nodiscard]] status_t sendDecStrong(const BpBinder* binder);
 
     ~RpcSession();
 
-    wp<RpcServer> server();
+    /**
+     * Server if this session is created as part of a server (symmetrical to
+     * client servers). Otherwise, nullptr.
+     */
+    sp<RpcServer> server();
 
     // internal only
-    const std::unique_ptr<RpcState>& state() { return mState; }
-
-    class PrivateAccessorForId {
-    private:
-        friend class RpcSession;
-        friend class RpcState;
-        explicit PrivateAccessorForId(const RpcSession* session) : mSession(session) {}
-
-        const std::optional<int32_t> get() { return mSession->mId; }
-
-        const RpcSession* mSession;
-    };
-    PrivateAccessorForId getPrivateAccessorForId() const { return PrivateAccessorForId(this); }
+    const std::unique_ptr<RpcState>& state() { return mRpcBinderState; }
 
 private:
-    friend PrivateAccessorForId;
     friend sp<RpcSession>;
     friend RpcServer;
-    RpcSession();
+    friend RpcState;
+    explicit RpcSession(std::unique_ptr<RpcTransportCtx> ctx);
 
-    status_t readId();
+    // for 'target', see RpcState::sendDecStrongToTarget
+    [[nodiscard]] status_t sendDecStrongToTarget(uint64_t address, size_t target);
 
-    // transfer ownership of thread
-    void preJoin(std::thread thread);
-    // join on thread passed to preJoin
-    void join(base::unique_fd client);
-    void terminateLocked();
+    class EventListener : public virtual RefBase {
+    public:
+        virtual void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) = 0;
+        virtual void onSessionIncomingThreadEnded() = 0;
+    };
+
+    class WaitForShutdownListener : public EventListener {
+    public:
+        void onSessionAllIncomingThreadsEnded(const sp<RpcSession>& session) override;
+        void onSessionIncomingThreadEnded() override;
+        void waitForShutdown(std::unique_lock<std::mutex>& lock, const sp<RpcSession>& session);
+
+    private:
+        std::condition_variable mCv;
+    };
+    friend WaitForShutdownListener;
 
     struct RpcConnection : public RefBase {
-        base::unique_fd fd;
+        std::unique_ptr<RpcTransport> rpcTransport;
 
         // whether this or another thread is currently using this fd to make
         // or receive transactions.
         std::optional<pid_t> exclusiveTid;
+
+        bool allowNested = false;
     };
 
-    bool setupSocketClient(const RpcSocketAddress& address);
-    bool setupOneSocketClient(const RpcSocketAddress& address, int32_t sessionId);
-    void addClientConnection(base::unique_fd fd);
-    void setForServer(const wp<RpcServer>& server, int32_t sessionId);
-    sp<RpcConnection> assignServerToThisThread(base::unique_fd fd);
-    bool removeServerConnection(const sp<RpcConnection>& connection);
+    [[nodiscard]] status_t readId();
+
+    // A thread joining a server must always call these functions in order, and
+    // cleanup is only programmed once into join. These are in separate
+    // functions in order to allow for different locks to be taken during
+    // different parts of setup.
+    //
+    // transfer ownership of thread (usually done while a lock is taken on the
+    // structure which originally owns the thread)
+    void preJoinThreadOwnership(std::thread thread);
+    // pass FD to thread and read initial connection information
+    struct PreJoinSetupResult {
+        // Server connection object associated with this
+        sp<RpcConnection> connection;
+        // Status of setup
+        status_t status;
+    };
+    PreJoinSetupResult preJoinSetup(std::unique_ptr<RpcTransport> rpcTransport);
+    // join on thread passed to preJoinThreadOwnership
+    static void join(sp<RpcSession>&& session, PreJoinSetupResult&& result);
+
+    [[nodiscard]] status_t setupClient(
+            const std::function<status_t(const std::vector<uint8_t>& sessionId, bool incoming)>&
+                    connectAndInit);
+    [[nodiscard]] status_t setupSocketClient(const RpcSocketAddress& address);
+    [[nodiscard]] status_t setupOneSocketConnection(const RpcSocketAddress& address,
+                                                    const std::vector<uint8_t>& sessionId,
+                                                    bool incoming);
+    [[nodiscard]] status_t initAndAddConnection(base::unique_fd fd,
+                                                const std::vector<uint8_t>& sessionId,
+                                                bool incoming);
+    [[nodiscard]] status_t addIncomingConnection(std::unique_ptr<RpcTransport> rpcTransport);
+    [[nodiscard]] status_t addOutgoingConnection(std::unique_ptr<RpcTransport> rpcTransport,
+                                                 bool init);
+    [[nodiscard]] bool setForServer(const wp<RpcServer>& server,
+                                    const wp<RpcSession::EventListener>& eventListener,
+                                    const std::vector<uint8_t>& sessionId,
+                                    const sp<IBinder>& sessionSpecificRoot);
+    sp<RpcConnection> assignIncomingConnectionToThisThread(
+            std::unique_ptr<RpcTransport> rpcTransport);
+    [[nodiscard]] bool removeIncomingConnection(const sp<RpcConnection>& connection);
+
+    [[nodiscard]] status_t initShutdownTrigger();
 
     enum class ConnectionUse {
         CLIENT,
@@ -141,12 +266,14 @@
         CLIENT_REFCOUNT,
     };
 
-    // RAII object for session connection
+    // Object representing exclusive access to a connection.
     class ExclusiveConnection {
     public:
-        explicit ExclusiveConnection(const sp<RpcSession>& session, ConnectionUse use);
+        [[nodiscard]] static status_t find(const sp<RpcSession>& session, ConnectionUse use,
+                                           ExclusiveConnection* connection);
+
         ~ExclusiveConnection();
-        const base::unique_fd& fd() { return mConnection->fd; }
+        const sp<RpcConnection>& get() { return mConnection; }
 
     private:
         static void findConnection(pid_t tid, sp<RpcConnection>* exclusive,
@@ -163,13 +290,15 @@
         bool mReentrant = false;
     };
 
-    // On the other side of a session, for each of mClientConnections here, there should
-    // be one of mServerConnections on the other side (and vice versa).
+    const std::unique_ptr<RpcTransportCtx> mCtx;
+
+    // On the other side of a session, for each of mOutgoing here, there should
+    // be one of mIncoming on the other side (and vice versa).
     //
     // For the simplest session, a single server with one client, you would
     // have:
-    //  - the server has a single 'mServerConnections' and a thread listening on this
-    //  - the client has a single 'mClientConnections' and makes calls to this
+    //  - the server has a single 'mIncoming' and a thread listening on this
+    //  - the client has a single 'mOutgoing' and makes calls to this
     //  - here, when the client makes a call, the server can call back into it
     //    (nested calls), but outside of this, the client will only ever read
     //    calls from the server when it makes a call itself.
@@ -178,27 +307,36 @@
     // serve calls to the server at all times (e.g. if it hosts a callback)
 
     wp<RpcServer> mForServer; // maybe null, for client sessions
+    sp<WaitForShutdownListener> mShutdownListener; // used for client sessions
+    wp<EventListener> mEventListener; // mForServer if server, mShutdownListener if client
 
-    // TODO(b/183988761): this shouldn't be guessable
-    std::optional<int32_t> mId;
+    // session-specific root object (if a different root is used for each
+    // session)
+    sp<IBinder> mSessionSpecificRootObject;
 
-    std::unique_ptr<RpcState> mState;
+    std::vector<uint8_t> mId;
+
+    std::unique_ptr<FdTrigger> mShutdownTrigger;
+
+    std::unique_ptr<RpcState> mRpcBinderState;
 
     std::mutex mMutex; // for all below
 
-    std::condition_variable mAvailableConnectionCv; // for mWaitingThreads
-    size_t mWaitingThreads = 0;
-    // hint index into clients, ++ when sending an async transaction
-    size_t mClientConnectionsOffset = 0;
-    std::vector<sp<RpcConnection>> mClientConnections;
-    std::vector<sp<RpcConnection>> mServerConnections;
+    size_t mMaxIncomingThreads = 0;
+    size_t mMaxOutgoingThreads = kDefaultMaxOutgoingThreads;
+    std::optional<uint32_t> mProtocolVersion;
 
-    // TODO(b/185167543): use for reverse sessions (allow client to also
-    // serve calls on a session).
-    // TODO(b/185167543): allow sharing between different sessions in a
-    // process? (or combine with mServerConnections)
-    std::map<std::thread::id, std::thread> mThreads;
-    bool mTerminated = false;
+    std::condition_variable mAvailableConnectionCv; // for mWaitingThreads
+
+    struct ThreadState {
+        size_t mWaitingThreads = 0;
+        // hint index into clients, ++ when sending an async transaction
+        size_t mOutgoingOffset = 0;
+        std::vector<sp<RpcConnection>> mOutgoing;
+        size_t mMaxIncoming = 0;
+        std::vector<sp<RpcConnection>> mIncoming;
+        std::map<std::thread::id, std::thread> mThreads;
+    } mConnections;
 };
 
 } // namespace android
diff --git a/libs/binder/include/binder/RpcTransport.h b/libs/binder/include/binder/RpcTransport.h
new file mode 100644
index 0000000..db8b5e9
--- /dev/null
+++ b/libs/binder/include/binder/RpcTransport.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+// Wraps the transport layer of RPC. Implementation may use plain sockets or TLS.
+
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <string>
+
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+#include <utils/Errors.h>
+
+#include <binder/RpcCertificateFormat.h>
+
+namespace android {
+
+class FdTrigger;
+
+// Represents a socket connection.
+// No thread-safety is guaranteed for these APIs.
+class RpcTransport {
+public:
+    virtual ~RpcTransport() = default;
+
+    // replacement of ::recv(MSG_PEEK). Error code may not be set if TLS is enabled.
+    [[nodiscard]] virtual android::base::Result<size_t> peek(void *buf, size_t size) = 0;
+
+    /**
+     * Read (or write), but allow to be interrupted by a trigger.
+     *
+     * altPoll - function to be called instead of polling, when needing to wait
+     * to read/write data. If this returns an error, that error is returned from
+     * this function.
+     *
+     * Return:
+     *   OK - succeeded in completely processing 'size'
+     *   error - interrupted (failure or trigger)
+     */
+    [[nodiscard]] virtual status_t interruptableWriteFully(
+            FdTrigger *fdTrigger, const void *buf, size_t size,
+            const std::function<status_t()> &altPoll) = 0;
+    [[nodiscard]] virtual status_t interruptableReadFully(
+            FdTrigger *fdTrigger, void *buf, size_t size,
+            const std::function<status_t()> &altPoll) = 0;
+
+protected:
+    RpcTransport() = default;
+};
+
+// Represents the context that generates the socket connection.
+// All APIs are thread-safe. See RpcTransportCtxRaw and RpcTransportCtxTls for details.
+class RpcTransportCtx {
+public:
+    virtual ~RpcTransportCtx() = default;
+
+    // Create a new RpcTransport object.
+    //
+    // Implementation details: for TLS, this function may incur I/O. |fdTrigger| may be used
+    // to interrupt I/O. This function blocks until handshake is finished.
+    [[nodiscard]] virtual std::unique_ptr<RpcTransport> newTransport(
+            android::base::unique_fd fd, FdTrigger *fdTrigger) const = 0;
+
+    // Return the preconfigured certificate of this context.
+    //
+    // Implementation details:
+    // - For raw sockets, this always returns empty string.
+    // - For TLS, this returns the certificate. See RpcTransportTls for details.
+    [[nodiscard]] virtual std::vector<uint8_t> getCertificate(
+            RpcCertificateFormat format) const = 0;
+
+protected:
+    RpcTransportCtx() = default;
+};
+
+// A factory class that generates RpcTransportCtx.
+// All APIs are thread-safe.
+class RpcTransportCtxFactory {
+public:
+    virtual ~RpcTransportCtxFactory() = default;
+    // Creates server context.
+    [[nodiscard]] virtual std::unique_ptr<RpcTransportCtx> newServerCtx() const = 0;
+
+    // Creates client context.
+    [[nodiscard]] virtual std::unique_ptr<RpcTransportCtx> newClientCtx() const = 0;
+
+    // Return a short description of this transport (e.g. "raw"). For logging / debugging / testing
+    // only.
+    [[nodiscard]] virtual const char *toCString() const = 0;
+
+protected:
+    RpcTransportCtxFactory() = default;
+};
+
+} // namespace android
diff --git a/libs/binder/include/binder/RpcTransportRaw.h b/libs/binder/include/binder/RpcTransportRaw.h
new file mode 100644
index 0000000..6fb1f92
--- /dev/null
+++ b/libs/binder/include/binder/RpcTransportRaw.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+// Wraps the transport layer of RPC. Implementation uses plain sockets.
+// Note: don't use directly. You probably want newServerRpcTransportCtx / newClientRpcTransportCtx.
+
+#pragma once
+
+#include <memory>
+
+#include <binder/RpcTransport.h>
+
+namespace android {
+
+// RpcTransportCtxFactory with TLS disabled.
+class RpcTransportCtxFactoryRaw : public RpcTransportCtxFactory {
+public:
+    static std::unique_ptr<RpcTransportCtxFactory> make();
+
+    std::unique_ptr<RpcTransportCtx> newServerCtx() const override;
+    std::unique_ptr<RpcTransportCtx> newClientCtx() const override;
+    const char* toCString() const override;
+
+private:
+    RpcTransportCtxFactoryRaw() = default;
+};
+
+} // namespace android
diff --git a/libs/binder/include/binder/Stability.h b/libs/binder/include/binder/Stability.h
index f4bfac8..ce4362f 100644
--- a/libs/binder/include/binder/Stability.h
+++ b/libs/binder/include/binder/Stability.h
@@ -44,10 +44,9 @@
 //   to old servers, and new servers know how to interpret the 8-byte result,
 //   they can still communicate.
 //
-// Every binder object has a stability level associated with it, and when
-// communicating with a binder, we make sure that the command we sent is one
-// that it knows how to process. The summary of stability of a binder is
-// represented by a Stability::Category object.
+// This class is specifically about (1). (2) is not currently tracked by
+// libbinder for regular binder calls, and everything on the system uses the
+// same copy of libbinder.
 
 class Stability final {
 public:
@@ -100,7 +99,7 @@
     static void markVintf(IBinder* binder);
 
     // WARNING: for debugging only
-    static void debugLogStability(const std::string& tag, const sp<IBinder>& binder);
+    static std::string debugToString(const sp<IBinder>& binder);
 
     // WARNING: This is only ever expected to be called by auto-generated code or tests.
     // You likely want to change or modify the stability of the interface you are using.
@@ -128,7 +127,10 @@
 
     static void tryMarkCompilationUnit(IBinder* binder);
 
-    enum Level : uint8_t {
+    // Currently, we use int16_t for Level so that it can fit in BBinder.
+    // However, on the wire, we have 4 bytes reserved for stability, so whenever
+    // we ingest a Level, we always accept an int32_t.
+    enum Level : int16_t {
         UNDECLARED = 0,
 
         VENDOR = 0b000011,
@@ -136,38 +138,6 @@
         VINTF = 0b111111,
     };
 
-    // This is the format of stability passed on the wire.
-    struct Category {
-        static inline Category fromRepr(int32_t representation) {
-            return *reinterpret_cast<Category*>(&representation);
-        }
-        int32_t repr() const {
-            return *reinterpret_cast<const int32_t*>(this);
-        }
-        static inline Category currentFromLevel(Level level);
-
-        bool operator== (const Category& o) const {
-            return repr() == o.repr();
-        }
-        bool operator!= (const Category& o) const {
-            return !(*this == o);
-        }
-
-        std::string debugString();
-
-        // This is the version of the wire protocol associated with the host
-        // process of a particular binder. As the wire protocol changes, if
-        // sending a transaction to a binder with an old version, the Parcel
-        // class must write parcels according to the version documented here.
-        uint8_t version;
-
-        uint8_t reserved[2];
-
-        // bitmask of Stability::Level
-        Level level;
-    };
-    static_assert(sizeof(Category) == sizeof(int32_t));
-
     // returns the stability according to how this was built
     static Level getLocalLevel();
 
@@ -180,18 +150,18 @@
       REPR_ALLOW_DOWNGRADE = 2,
     };
     // applies stability to binder if stability level is known
-    __attribute__((warn_unused_result))
-    static status_t setRepr(IBinder* binder, int32_t representation, uint32_t flags);
+    __attribute__((warn_unused_result)) static status_t setRepr(IBinder* binder, int32_t setting,
+                                                                uint32_t flags);
 
     // get stability information as encoded on the wire
-    static Category getCategory(IBinder* binder);
+    static int16_t getRepr(IBinder* binder);
 
     // whether a transaction on binder is allowed, if the transaction
     // is done from a context with a specific stability level
-    static bool check(Category provided, Level required);
+    static bool check(int16_t provided, Level required);
 
-    static bool isDeclaredLevel(Level level);
-    static std::string levelString(Level level);
+    static bool isDeclaredLevel(int32_t level);
+    static std::string levelString(int32_t level);
 
     Stability();
 };
diff --git a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
new file mode 100644
index 0000000..5baa4d7
--- /dev/null
+++ b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <sys/socket.h>
+
+extern "C" {
+
+struct AIBinder;
+
+// Starts an RPC server on a given port and a given root IBinder object.
+// This function sets up the server and joins before returning.
+bool RunRpcServer(AIBinder* service, unsigned int port);
+
+// Starts an RPC server on a given port and a given root IBinder object.
+// This function sets up the server, calls readyCallback with a given param, and
+// then joins before returning.
+bool RunRpcServerCallback(AIBinder* service, unsigned int port, void (*readyCallback)(void* param),
+                          void* param);
+
+// Starts an RPC server on a given port and a given root IBinder factory.
+// RunRpcServerWithFactory acts like RunRpcServerCallback, but instead of
+// assigning single root IBinder object to all connections, factory is called
+// whenever a client connects, making it possible to assign unique IBinder
+// object to each client.
+bool RunRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
+                          void* factoryContext, unsigned int port);
+
+AIBinder* RpcClient(unsigned int cid, unsigned int port);
+
+// Connect to an RPC server with preconnected file descriptors.
+//
+// requestFd should connect to the server and return a valid file descriptor, or
+// -1 if connection fails.
+//
+// param will be passed to requestFd. Callers can use param to pass contexts to
+// the requestFd function.
+AIBinder* RpcPreconnectedClient(int (*requestFd)(void* param), void* param);
+
+}
diff --git a/libs/binder/include_tls/binder/RpcAuth.h b/libs/binder/include_tls/binder/RpcAuth.h
new file mode 100644
index 0000000..ab64828
--- /dev/null
+++ b/libs/binder/include_tls/binder/RpcAuth.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <openssl/ssl.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+// An interface with a function that configures the SSL_CTX object with authentication information,
+// including certificates and private keys.
+class RpcAuth {
+public:
+    virtual ~RpcAuth() = default;
+
+    // The keys and certificates to provide is up to the implementation. Multiple calls to
+    // |configure()| may configure |ctx| with the same keys / certificates, or generate a
+    // different key / certificate every time |configure()| is called.
+    //
+    // It is guaranteed that, when a context object (RpcTransportCtx) is created,
+    // libbinder_tls calls |configure()| on server RpcAuth exactly once.
+    //
+    // The implementation may use the following function to set the private
+    // keys and certificates:
+    // - SSL_CTX_use_PrivateKey
+    // - SSL_CTX_use_certificate
+    // - SSL_CTX_set*_chain
+    // - SSL_CTX_add0_chain_cert
+    [[nodiscard]] virtual status_t configure(SSL_CTX* ctx) = 0;
+};
+
+} // namespace android
diff --git a/libs/binder/include_tls/binder/RpcCertificateVerifier.h b/libs/binder/include_tls/binder/RpcCertificateVerifier.h
new file mode 100644
index 0000000..800e375
--- /dev/null
+++ b/libs/binder/include_tls/binder/RpcCertificateVerifier.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <openssl/ssl.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+// An interface with a function that verifies a peer certificate. It is a wrapper over the custom
+// verify function (see SSL_CTX_set_custom_verify).
+class RpcCertificateVerifier {
+public:
+    virtual ~RpcCertificateVerifier() = default;
+
+    // The implementation may use the following function to get
+    // the peer certificate and chain:
+    // - SSL_get_peer_certificate
+    // - SSL_get_peer_cert_chain
+    // - SSL_get_peer_full_cert_chain
+    //
+    // The implementation should return OK on success or error codes on error. For example:
+    // - PERMISSION_DENIED for rejected certificates
+    // - NO_INIT for not presenting a certificate when requested
+    // - UNKNOWN_ERROR for other errors
+    virtual status_t verify(const SSL* ssl, uint8_t* outAlert) = 0;
+};
+
+} // namespace android
diff --git a/libs/binder/include_tls/binder/RpcTlsUtils.h b/libs/binder/include_tls/binder/RpcTlsUtils.h
new file mode 100644
index 0000000..591926b
--- /dev/null
+++ b/libs/binder/include_tls/binder/RpcTlsUtils.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+// Utilities for serializing and deserializing X509 certificates.
+
+#pragma once
+
+#include <vector>
+
+#include <openssl/ssl.h>
+
+#include <binder/RpcCertificateFormat.h>
+#include <binder/RpcKeyFormat.h>
+
+namespace android {
+
+bssl::UniquePtr<X509> deserializeCertificate(const std::vector<uint8_t>& data,
+                                             RpcCertificateFormat format);
+
+std::vector<uint8_t> serializeCertificate(X509* x509, RpcCertificateFormat format);
+
+// Deserialize an un-encrypted private key.
+bssl::UniquePtr<EVP_PKEY> deserializeUnencryptedPrivatekey(const std::vector<uint8_t>& data,
+                                                           RpcKeyFormat format);
+
+// Serialize a private key in un-encrypted form.
+std::vector<uint8_t> serializeUnencryptedPrivatekey(EVP_PKEY* pkey, RpcKeyFormat format);
+
+} // namespace android
diff --git a/libs/binder/include_tls/binder/RpcTransportTls.h b/libs/binder/include_tls/binder/RpcTransportTls.h
new file mode 100644
index 0000000..8a11125
--- /dev/null
+++ b/libs/binder/include_tls/binder/RpcTransportTls.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+// Wraps the transport layer of RPC. Implementation uses TLS.
+
+#pragma once
+
+#include <binder/RpcAuth.h>
+#include <binder/RpcCertificateVerifier.h>
+#include <binder/RpcTransport.h>
+
+namespace android {
+
+// RpcTransportCtxFactory with TLS enabled with self-signed certificate.
+class RpcTransportCtxFactoryTls : public RpcTransportCtxFactory {
+public:
+    static std::unique_ptr<RpcTransportCtxFactory> make(std::shared_ptr<RpcCertificateVerifier>,
+                                                        std::unique_ptr<RpcAuth>);
+
+    std::unique_ptr<RpcTransportCtx> newServerCtx() const override;
+    std::unique_ptr<RpcTransportCtx> newClientCtx() const override;
+    const char* toCString() const override;
+
+private:
+    RpcTransportCtxFactoryTls(std::shared_ptr<RpcCertificateVerifier> verifier,
+                              std::unique_ptr<RpcAuth> auth)
+          : mCertVerifier(std::move(verifier)), mAuth(std::move(auth)){};
+
+    std::shared_ptr<RpcCertificateVerifier> mCertVerifier;
+    std::unique_ptr<RpcAuth> mAuth;
+};
+
+} // namespace android
diff --git a/libs/binder/libbinder.arm32.map b/libs/binder/libbinder.arm32.map
deleted file mode 100644
index 9f10b67..0000000
--- a/libs/binder/libbinder.arm32.map
+++ /dev/null
@@ -1,1394 +0,0 @@
-LIBBINDER {
-  global:
-    getBinderKernelReferences;
-    kDefaultDriver;
-    _ZN7android10AllocationC1ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEEij;
-    _ZN7android10AllocationC2ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEEij;
-    _ZN7android10AllocationD0Ev;
-    _ZN7android10AllocationD1Ev;
-    _ZN7android10AllocationD2Ev;
-    _ZN7android10IInterface8asBinderEPKS0_;
-    _ZN7android10IInterface8asBinderERKNS_2spIS0_EE;
-    _ZN7android10IInterfaceC2Ev;
-    _ZN7android10IInterfaceD0Ev;
-    _ZN7android10IInterfaceD1Ev;
-    _ZN7android10IInterfaceD2Ev;
-    _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEEij;
-    _ZN7android10MemoryBaseC2ERKNS_2spINS_11IMemoryHeapEEEij;
-    _ZN7android10MemoryBaseD0Ev;
-    _ZN7android10MemoryBaseD1Ev;
-    _ZN7android10MemoryBaseD2Ev;
-    _ZN7android10RpcAddress14readFromParcelERKNS_6ParcelE;
-    _ZN7android10RpcAddress15fromRawEmbeddedEPKNS_14RpcWireAddressE;
-    _ZN7android10RpcAddress4zeroEv;
-    _ZN7android10RpcAddress6uniqueEv;
-    _ZN7android10RpcAddressC1Ev;
-    _ZN7android10RpcAddressC2Ev;
-    _ZN7android10RpcAddressD1Ev;
-    _ZN7android10RpcAddressD2Ev;
-    _ZN7android10RpcSession12setForServerERKNS_2wpINS_9RpcServerEEEi;
-    _ZN7android10RpcSession13getRootObjectEv;
-    _ZN7android10RpcSession13sendDecStrongERKNS_10RpcAddressE;
-    _ZN7android10RpcSession15setupInetClientEPKcj;
-    _ZN7android10RpcSession15terminateLockedEv;
-    _ZN7android10RpcSession16setupVsockClientEjj;
-    _ZN7android10RpcSession17setupSocketClientERKNS_16RpcSocketAddressE;
-    _ZN7android10RpcSession19addClientConnectionENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession19ExclusiveConnection14findConnectionEiPNS_2spINS0_13RpcConnectionEEES5_RNSt3__16vectorIS4_NS6_9allocatorIS4_EEEEj;
-    _ZN7android10RpcSession19ExclusiveConnectionC1ERKNS_2spIS0_EENS0_13ConnectionUseE;
-    _ZN7android10RpcSession19ExclusiveConnectionC2ERKNS_2spIS0_EENS0_13ConnectionUseE;
-    _ZN7android10RpcSession19ExclusiveConnectionD1Ev;
-    _ZN7android10RpcSession19ExclusiveConnectionD2Ev;
-    _ZN7android10RpcSession19getRemoteMaxThreadsEPj;
-    _ZN7android10RpcSession20setupOneSocketClientERKNS_16RpcSocketAddressEi;
-    _ZN7android10RpcSession21setupUnixDomainClientEPKc;
-    _ZN7android10RpcSession22addNullDebuggingClientEv;
-    _ZN7android10RpcSession22removeServerConnectionERKNS_2spINS0_13RpcConnectionEEE;
-    _ZN7android10RpcSession24assignServerToThisThreadENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession4joinENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession4makeEv;
-    _ZN7android10RpcSession6readIdEv;
-    _ZN7android10RpcSession6serverEv;
-    _ZN7android10RpcSession7preJoinENSt3__16threadE;
-    _ZN7android10RpcSession8transactERKNS_10RpcAddressEjRKNS_6ParcelEPS4_j;
-    _ZN7android10RpcSessionC1Ev;
-    _ZN7android10RpcSessionC2Ev;
-    _ZN7android10RpcSessionD0Ev;
-    _ZN7android10RpcSessionD1Ev;
-    _ZN7android10RpcSessionD2Ev;
-    _ZN7android10TextOutputC2Ev;
-    _ZN7android10TextOutputD0Ev;
-    _ZN7android10TextOutputD1Ev;
-    _ZN7android10TextOutputD2Ev;
-    _ZN7android10zeroMemoryEPhj;
-    _ZN7android11BnInterfaceINS_11IMemoryHeapEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_14IShellCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_15IResultReceiverEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_21IPermissionControllerEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os15IClientCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os15IServiceManagerEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os16IServiceCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7content2pm21IPackageManagerNativeEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7content2pm22IPackageChangeObserverEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7IMemoryEE10onAsBinderEv;
-    _ZN7android11IMemoryHeap10descriptorE;
-    _ZN7android11IMemoryHeap11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android11IMemoryHeap12default_implE;
-    _ZN7android11IMemoryHeap14getDefaultImplEv;
-    _ZN7android11IMemoryHeap14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android11IMemoryHeapC2Ev;
-    _ZN7android11IMemoryHeapD0Ev;
-    _ZN7android11IMemoryHeapD1Ev;
-    _ZN7android11IMemoryHeapD2Ev;
-    _ZN7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android12BnMemoryHeapC2Ev;
-    _ZN7android12BnMemoryHeapD0Ev;
-    _ZN7android12BnMemoryHeapD1Ev;
-    _ZN7android12BnMemoryHeapD2Ev;
-    _ZN7android12BpMemoryHeapC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android12BpMemoryHeapC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android12BpMemoryHeapD0Ev;
-    _ZN7android12BpMemoryHeapD1Ev;
-    _ZN7android12BpMemoryHeapD2Ev;
-    _ZN7android12gTextBuffersE;
-    _ZN7android12MemoryDealer10deallocateEj;
-    _ZN7android12MemoryDealer22getAllocationAlignmentEv;
-    _ZN7android12MemoryDealer8allocateEj;
-    _ZN7android12MemoryDealerC1EjPKcj;
-    _ZN7android12MemoryDealerC2EjPKcj;
-    _ZN7android12MemoryDealerD0Ev;
-    _ZN7android12MemoryDealerD1Ev;
-    _ZN7android12MemoryDealerD2Ev;
-    _ZN7android12printHexDataEiPKvjjijbPFvPvPKcES2_;
-    _ZN7android12ProcessState10selfOrNullEv;
-    _ZN7android12ProcessState13expungeHandleEiPNS_7IBinderE;
-    _ZN7android12ProcessState13getDriverNameEv;
-    _ZN7android12ProcessState14initWithDriverEPKc;
-    _ZN7android12ProcessState15startThreadPoolEv;
-    _ZN7android12ProcessState16getContextObjectERKNS_2spINS_7IBinderEEE;
-    _ZN7android12ProcessState17spawnPooledThreadEb;
-    _ZN7android12ProcessState18giveThreadPoolNameEv;
-    _ZN7android12ProcessState18lookupHandleLockedEi;
-    _ZN7android12ProcessState18setCallRestrictionENS0_15CallRestrictionE;
-    _ZN7android12ProcessState19getKernelReferencesEjPj;
-    _ZN7android12ProcessState20becomeContextManagerEv;
-    _ZN7android12ProcessState20makeBinderThreadNameEv;
-    _ZN7android12ProcessState23getStrongProxyForHandleEi;
-    _ZN7android12ProcessState24getStrongRefCountForNodeERKNS_2spINS_8BpBinderEEE;
-    _ZN7android12ProcessState25enableOnewaySpamDetectionEb;
-    _ZN7android12ProcessState27setThreadPoolMaxThreadCountEj;
-    _ZN7android12ProcessState4initEPKcb;
-    _ZN7android12ProcessState4selfEv;
-    _ZN7android12ProcessStateC1EPKc;
-    _ZN7android12ProcessStateC2EPKc;
-    _ZN7android12ProcessStateD0Ev;
-    _ZN7android12ProcessStateD1Ev;
-    _ZN7android12ProcessStateD2Ev;
-    _ZN7android13printTypeCodeEjPFvPvPKcES0_;
-    _ZN7android14IPCThreadState10freeBufferEPNS_6ParcelEPKhjPKyj;
-    _ZN7android14IPCThreadState10selfOrNullEv;
-    _ZN7android14IPCThreadState11clearCallerEv;
-    _ZN7android14IPCThreadState11stopProcessEb;
-    _ZN7android14IPCThreadState12setupPollingEPi;
-    _ZN7android14IPCThreadState13decWeakHandleEi;
-    _ZN7android14IPCThreadState13expungeHandleEiPNS_7IBinderE;
-    _ZN7android14IPCThreadState13flushCommandsEv;
-    _ZN7android14IPCThreadState13flushIfNeededEv;
-    _ZN7android14IPCThreadState13incWeakHandleEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState14clearLastErrorEv;
-    _ZN7android14IPCThreadState14executeCommandEi;
-    _ZN7android14IPCThreadState14joinThreadPoolEb;
-    _ZN7android14IPCThreadState14talkWithDriverEb;
-    _ZN7android14IPCThreadState15decStrongHandleEi;
-    _ZN7android14IPCThreadState15incStrongHandleEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState15waitForResponseEPNS_6ParcelEPi;
-    _ZN7android14IPCThreadState16threadDestructorEPv;
-    _ZN7android14IPCThreadState18setCallRestrictionENS_12ProcessState15CallRestrictionE;
-    _ZN7android14IPCThreadState19setStrictModePolicyEi;
-    _ZN7android14IPCThreadState19setTheContextObjectERKNS_2spINS_7BBinderEEE;
-    _ZN7android14IPCThreadState20clearCallingIdentityEv;
-    _ZN7android14IPCThreadState20getAndExecuteCommandEv;
-    _ZN7android14IPCThreadState20getProcessFreezeInfoEiPbS1_;
-    _ZN7android14IPCThreadState20getProcessFreezeInfoEiPjS1_;
-    _ZN7android14IPCThreadState20handlePolledCommandsEv;
-    _ZN7android14IPCThreadState20processPendingDerefsEv;
-    _ZN7android14IPCThreadState20writeTransactionDataEijijRKNS_6ParcelEPi;
-    _ZN7android14IPCThreadState22attemptIncStrongHandleEi;
-    _ZN7android14IPCThreadState22clearCallingWorkSourceEv;
-    _ZN7android14IPCThreadState22clearDeathNotificationEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState22processPostWriteDerefsEv;
-    _ZN7android14IPCThreadState22restoreCallingIdentityEx;
-    _ZN7android14IPCThreadState23setCallingWorkSourceUidEj;
-    _ZN7android14IPCThreadState24clearPropagateWorkSourceEv;
-    _ZN7android14IPCThreadState24requestDeathNotificationEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState24restoreCallingWorkSourceEx;
-    _ZN7android14IPCThreadState25blockUntilThreadAvailableEv;
-    _ZN7android14IPCThreadState27disableBackgroundSchedulingEb;
-    _ZN7android14IPCThreadState28backgroundSchedulingDisabledEv;
-    _ZN7android14IPCThreadState29setLastTransactionBinderFlagsEi;
-    _ZN7android14IPCThreadState41setCallingWorkSourceUidWithoutPropagationEj;
-    _ZN7android14IPCThreadState4selfEv;
-    _ZN7android14IPCThreadState6freezeEibj;
-    _ZN7android14IPCThreadState7processEv;
-    _ZN7android14IPCThreadState8shutdownEv;
-    _ZN7android14IPCThreadState8transactEijRKNS_6ParcelEPS1_j;
-    _ZN7android14IPCThreadState9sendReplyERKNS_6ParcelEj;
-    _ZN7android14IPCThreadStateC1Ev;
-    _ZN7android14IPCThreadStateC2Ev;
-    _ZN7android14IPCThreadStateD1Ev;
-    _ZN7android14IPCThreadStateD2Ev;
-    _ZN7android14IShellCallback10descriptorE;
-    _ZN7android14IShellCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android14IShellCallback12default_implE;
-    _ZN7android14IShellCallback14getDefaultImplEv;
-    _ZN7android14IShellCallback14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android14IShellCallbackC2Ev;
-    _ZN7android14IShellCallbackD0Ev;
-    _ZN7android14IShellCallbackD1Ev;
-    _ZN7android14IShellCallbackD2Ev;
-    _ZN7android14MemoryHeapBase4initEiPvjiPKc;
-    _ZN7android14MemoryHeapBase5mapfdEibjl;
-    _ZN7android14MemoryHeapBase7disposeEv;
-    _ZN7android14MemoryHeapBaseC1Eijjl;
-    _ZN7android14MemoryHeapBaseC1EjjPKc;
-    _ZN7android14MemoryHeapBaseC1EPKcjj;
-    _ZN7android14MemoryHeapBaseC1Ev;
-    _ZN7android14MemoryHeapBaseC2Eijjl;
-    _ZN7android14MemoryHeapBaseC2EjjPKc;
-    _ZN7android14MemoryHeapBaseC2EPKcjj;
-    _ZN7android14MemoryHeapBaseC2Ev;
-    _ZN7android14MemoryHeapBaseD0Ev;
-    _ZN7android14MemoryHeapBaseD1Ev;
-    _ZN7android14MemoryHeapBaseD2Ev;
-    _ZN7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android15checkPermissionERKNS_8String16Eij;
-    _ZN7android15IResultReceiver10descriptorE;
-    _ZN7android15IResultReceiver11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android15IResultReceiver12default_implE;
-    _ZN7android15IResultReceiver14getDefaultImplEv;
-    _ZN7android15IResultReceiver14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android15IResultReceiverC2Ev;
-    _ZN7android15IResultReceiverD0Ev;
-    _ZN7android15IResultReceiverD1Ev;
-    _ZN7android15IResultReceiverD2Ev;
-    _ZN7android15IServiceManagerC2Ev;
-    _ZN7android15IServiceManagerD0Ev;
-    _ZN7android15IServiceManagerD1Ev;
-    _ZN7android15IServiceManagerD2Ev;
-    _ZN7android15PermissionCache10purgeCacheEv;
-    _ZN7android15PermissionCache15checkPermissionERKNS_8String16Eij;
-    _ZN7android15PermissionCache22checkCallingPermissionERKNS_8String16E;
-    _ZN7android15PermissionCache22checkCallingPermissionERKNS_8String16EPiS4_;
-    _ZN7android15PermissionCache5cacheERKNS_8String16Ejb;
-    _ZN7android15PermissionCache5purgeEv;
-    _ZN7android15PermissionCacheC1Ev;
-    _ZN7android15PermissionCacheC2Ev;
-    _ZN7android15stringForIndentEi;
-    _ZN7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android18BufferedTextOutput10moveIndentEi;
-    _ZN7android18BufferedTextOutput10pushBundleEv;
-    _ZN7android18BufferedTextOutput5printEPKcj;
-    _ZN7android18BufferedTextOutput9popBundleEv;
-    _ZN7android18BufferedTextOutputC2Ej;
-    _ZN7android18BufferedTextOutputD0Ev;
-    _ZN7android18BufferedTextOutputD1Ev;
-    _ZN7android18BufferedTextOutputD2Ev;
-    _ZN7android18ServiceManagerShim10addServiceERKNS_8String16ERKNS_2spINS_7IBinderEEEbi;
-    _ZN7android18ServiceManagerShim10isDeclaredERKNS_8String16E;
-    _ZN7android18ServiceManagerShim12listServicesEi;
-    _ZN7android18ServiceManagerShim14waitForServiceERKNS_8String16E;
-    _ZN7android18ServiceManagerShim16updatableViaApexERKNS_8String16E;
-    _ZN7android18ServiceManagerShim20getDeclaredInstancesERKNS_8String16E;
-    _ZN7android18ServiceManagerShimC1ERKNS_2spINS_2os15IServiceManagerEEE;
-    _ZN7android18ServiceManagerShimC2ERKNS_2spINS_2os15IServiceManagerEEE;
-    _ZN7android18the_context_objectE;
-    _ZN7android20PermissionController10getServiceEv;
-    _ZN7android20PermissionController13getPackageUidERKNS_8String16Ei;
-    _ZN7android20PermissionController15checkPermissionERKNS_8String16Eii;
-    _ZN7android20PermissionController17getPackagesForUidEjRNS_6VectorINS_8String16EEE;
-    _ZN7android20PermissionController19isRuntimePermissionERKNS_8String16E;
-    _ZN7android20PermissionController6noteOpERKNS_8String16EiS3_;
-    _ZN7android20PermissionControllerC1Ev;
-    _ZN7android20PermissionControllerC2Ev;
-    _ZN7android21defaultServiceManagerEv;
-    _ZN7android21IPermissionController10descriptorE;
-    _ZN7android21IPermissionController11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android21IPermissionController12default_implE;
-    _ZN7android21IPermissionController14getDefaultImplEv;
-    _ZN7android21IPermissionController14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android21IPermissionControllerC2Ev;
-    _ZN7android21IPermissionControllerD0Ev;
-    _ZN7android21IPermissionControllerD1Ev;
-    _ZN7android21IPermissionControllerD2Ev;
-    _ZN7android22BnPermissionController10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android22checkCallingPermissionERKNS_8String16E;
-    _ZN7android22checkCallingPermissionERKNS_8String16EPiS3_;
-    _ZN7android22SimpleBestFitAllocator10deallocateEj;
-    _ZN7android22SimpleBestFitAllocator12kMemoryAlignE;
-    _ZN7android22SimpleBestFitAllocator5allocEjj;
-    _ZN7android22SimpleBestFitAllocator7deallocEj;
-    _ZN7android22SimpleBestFitAllocator8allocateEjj;
-    _ZN7android22SimpleBestFitAllocatorC1Ej;
-    _ZN7android22SimpleBestFitAllocatorC2Ej;
-    _ZN7android22SimpleBestFitAllocatorD1Ev;
-    _ZN7android22SimpleBestFitAllocatorD2Ev;
-    _ZN7android24setDefaultServiceManagerERKNS_2spINS_15IServiceManagerEEE;
-    _ZN7android2os15IClientCallback10descriptorE;
-    _ZN7android2os15IClientCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os15IClientCallback12default_implE;
-    _ZN7android2os15IClientCallback14getDefaultImplEv;
-    _ZN7android2os15IClientCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os15IClientCallbackC2Ev;
-    _ZN7android2os15IClientCallbackD0Ev;
-    _ZN7android2os15IClientCallbackD1Ev;
-    _ZN7android2os15IClientCallbackD2Ev;
-    _ZN7android2os15IServiceManager10descriptorE;
-    _ZN7android2os15IServiceManager11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os15IServiceManager12default_implE;
-    _ZN7android2os15IServiceManager14getDefaultImplEv;
-    _ZN7android2os15IServiceManager14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os15IServiceManagerC2Ev;
-    _ZN7android2os15IServiceManagerD0Ev;
-    _ZN7android2os15IServiceManagerD1Ev;
-    _ZN7android2os15IServiceManagerD2Ev;
-    _ZN7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os16BnClientCallbackC2Ev;
-    _ZN7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os16BnServiceManagerC2Ev;
-    _ZN7android2os16BpClientCallback9onClientsERKNS_2spINS_7IBinderEEEb;
-    _ZN7android2os16BpClientCallbackC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpClientCallbackC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager10addServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEEbi;
-    _ZN7android2os16BpServiceManager10getServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager10isDeclaredERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPb;
-    _ZN7android2os16BpServiceManager12checkServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager12listServicesEiPNSt3__16vectorINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS7_IS9_EEEE;
-    _ZN7android2os16BpServiceManager16updatableViaApexERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_8optionalIS8_EE;
-    _ZN7android2os16BpServiceManager19getServiceDebugInfoEPNSt3__16vectorINS0_16ServiceDebugInfoENS2_9allocatorIS4_EEEE;
-    _ZN7android2os16BpServiceManager20getDeclaredInstancesERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_6vectorIS8_NS6_IS8_EEEE;
-    _ZN7android2os16BpServiceManager20tryUnregisterServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager22registerClientCallbackERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEERKNSB_INS0_15IClientCallbackEEE;
-    _ZN7android2os16BpServiceManager24registerForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
-    _ZN7android2os16BpServiceManager26unregisterForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
-    _ZN7android2os16BpServiceManagerC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManagerC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16IServiceCallback10descriptorE;
-    _ZN7android2os16IServiceCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16IServiceCallback12default_implE;
-    _ZN7android2os16IServiceCallback14getDefaultImplEv;
-    _ZN7android2os16IServiceCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os16IServiceCallbackC2Ev;
-    _ZN7android2os16IServiceCallbackD0Ev;
-    _ZN7android2os16IServiceCallbackD1Ev;
-    _ZN7android2os16IServiceCallbackD2Ev;
-    _ZN7android2os16ParcelableHolder14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os16ServiceDebugInfo14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os17BnServiceCallbackC2Ev;
-    _ZN7android2os17BpServiceCallback14onRegistrationERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17BpServiceCallbackC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17BpServiceCallbackC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17PersistableBundle10putBooleanERKNS_8String16Eb;
-    _ZN7android2os17PersistableBundle12putIntVectorERKNS_8String16ERKNSt3__16vectorIiNS5_9allocatorIiEEEE;
-    _ZN7android2os17PersistableBundle13putLongVectorERKNS_8String16ERKNSt3__16vectorIxNS5_9allocatorIxEEEE;
-    _ZN7android2os17PersistableBundle14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os17PersistableBundle15putDoubleVectorERKNS_8String16ERKNSt3__16vectorIdNS5_9allocatorIdEEEE;
-    _ZN7android2os17PersistableBundle15putStringVectorERKNS_8String16ERKNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
-    _ZN7android2os17PersistableBundle16putBooleanVectorERKNS_8String16ERKNSt3__16vectorIbNS5_9allocatorIbEEEE;
-    _ZN7android2os17PersistableBundle19readFromParcelInnerEPKNS_6ParcelEj;
-    _ZN7android2os17PersistableBundle20putPersistableBundleERKNS_8String16ERKS1_;
-    _ZN7android2os17PersistableBundle5eraseERKNS_8String16E;
-    _ZN7android2os17PersistableBundle6putIntERKNS_8String16Ei;
-    _ZN7android2os17PersistableBundle7putLongERKNS_8String16Ex;
-    _ZN7android2os17PersistableBundle9putDoubleERKNS_8String16Ed;
-    _ZN7android2os17PersistableBundle9putStringERKNS_8String16ES4_;
-    _ZN7android2os20ParcelFileDescriptor14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os20ParcelFileDescriptorC1ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
-    _ZN7android2os20ParcelFileDescriptorC1Ev;
-    _ZN7android2os20ParcelFileDescriptorC2ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
-    _ZN7android2os20ParcelFileDescriptorC2Ev;
-    _ZN7android2os20ParcelFileDescriptorD0Ev;
-    _ZN7android2os20ParcelFileDescriptorD1Ev;
-    _ZN7android2os20ParcelFileDescriptorD2Ev;
-    _ZN7android4aerrE;
-    _ZN7android4alogE;
-    _ZN7android4aoutE;
-    _ZN7android6binder20LazyServiceRegistrar10reRegisterEv;
-    _ZN7android6binder20LazyServiceRegistrar11getInstanceEv;
-    _ZN7android6binder20LazyServiceRegistrar12forcePersistEb;
-    _ZN7android6binder20LazyServiceRegistrar13tryUnregisterEv;
-    _ZN7android6binder20LazyServiceRegistrar15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEbi;
-    _ZN7android6binder20LazyServiceRegistrar25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
-    _ZN7android6binder20LazyServiceRegistrarC1Ev;
-    _ZN7android6binder20LazyServiceRegistrarC2Ev;
-    _ZN7android6binder6Status11fromStatusTEi;
-    _ZN7android6binder6Status12setExceptionEiRKNS_7String8E;
-    _ZN7android6binder6Status14readFromParcelERKNS_6ParcelE;
-    _ZN7android6binder6Status14setFromStatusTEi;
-    _ZN7android6binder6Status17exceptionToStringEi;
-    _ZN7android6binder6Status17fromExceptionCodeEi;
-    _ZN7android6binder6Status17fromExceptionCodeEiPKc;
-    _ZN7android6binder6Status17fromExceptionCodeEiRKNS_7String8E;
-    _ZN7android6binder6Status23setServiceSpecificErrorEiRKNS_7String8E;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEi;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEiPKc;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEiRKNS_7String8E;
-    _ZN7android6binder6Status2okEv;
-    _ZN7android6binder6StatusC1Eii;
-    _ZN7android6binder6StatusC1EiiRKNS_7String8E;
-    _ZN7android6binder6StatusC2Eii;
-    _ZN7android6binder6StatusC2EiiRKNS_7String8E;
-    _ZN7android6binder8internal21ClientCounterCallback10reRegisterEv;
-    _ZN7android6binder8internal21ClientCounterCallback12forcePersistEb;
-    _ZN7android6binder8internal21ClientCounterCallback13tryUnregisterEv;
-    _ZN7android6binder8internal21ClientCounterCallback15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEbi;
-    _ZN7android6binder8internal21ClientCounterCallback25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
-    _ZN7android6binder8internal21ClientCounterCallbackC1Ev;
-    _ZN7android6binder8internal21ClientCounterCallbackC2Ev;
-    _ZN7android6Parcel10appendFromEPKS0_jj;
-    _ZN7android6Parcel10markForRpcERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android6Parcel10writeFloatEf;
-    _ZN7android6Parcel10writeInt32Ei;
-    _ZN7android6Parcel10writeInt64Ex;
-    _ZN7android6Parcel11compareDataERKS0_;
-    _ZN7android6Parcel11finishWriteEj;
-    _ZN7android6Parcel11setDataSizeEj;
-    _ZN7android6Parcel11writeDoubleEd;
-    _ZN7android6Parcel11writeObjectERK18flat_binder_objectb;
-    _ZN7android6Parcel11writeUint32Ej;
-    _ZN7android6Parcel11writeUint64Ey;
-    _ZN7android6Parcel12pushAllowFdsEb;
-    _ZN7android6Parcel12restartWriteEj;
-    _ZN7android6Parcel12writeCStringEPKc;
-    _ZN7android6Parcel12writeInplaceEj;
-    _ZN7android6Parcel12writePointerEj;
-    _ZN7android6Parcel12writeString8EPKcj;
-    _ZN7android6Parcel12writeString8ERKNS_7String8E;
-    _ZN7android6Parcel13continueWriteEj;
-    _ZN7android6Parcel13flattenBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel13markForBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel13writeString16EPKDsj;
-    _ZN7android6Parcel13writeString16ERKNS_8String16E;
-    _ZN7android6Parcel13writeString16ERKNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
-    _ZN7android6Parcel13writeString16ERKNSt3__18optionalINS_8String16EEE;
-    _ZN7android6Parcel13writeUnpaddedEPKvj;
-    _ZN7android6Parcel14acquireObjectsEv;
-    _ZN7android6Parcel14freeDataNoInitEv;
-    _ZN7android6Parcel14releaseObjectsEv;
-    _ZN7android6Parcel14writeByteArrayEjPKh;
-    _ZN7android6Parcel15restoreAllowFdsEb;
-    _ZN7android6Parcel15setDataCapacityEj;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__16vectorIbNS1_9allocatorIbEEEE;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIaNS1_9allocatorIaEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIhNS1_9allocatorIhEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
-    _ZN7android6Parcel15writeInt32ArrayEjPKi;
-    _ZN7android6Parcel15writeParcelableERKNS_10ParcelableE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__16vectorIfNS1_9allocatorIfEEEE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__16vectorIiNS1_9allocatorIiEEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__110unique_ptrINS1_6vectorIxNS1_9allocatorIxEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__16vectorIxNS1_9allocatorIxEEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__18optionalINS1_6vectorIxNS1_9allocatorIxEEEEEE;
-    _ZN7android6Parcel16writeNoExceptionEv;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__16vectorIdNS1_9allocatorIdEEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
-    _ZN7android6Parcel17writeNativeHandleEPK13native_handle;
-    _ZN7android6Parcel17writeStrongBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__110unique_ptrINS1_6vectorIyNS1_9allocatorIyEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__16vectorIyNS1_9allocatorIyEEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__18optionalINS1_6vectorIyNS1_9allocatorIyEEEEEE;
-    _ZN7android6Parcel18getGlobalAllocSizeEv;
-    _ZN7android6Parcel19finishFlattenBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel19getGlobalAllocCountEv;
-    _ZN7android6Parcel19ipcSetDataReferenceEPKhjPKyjPFvPS0_S2_jS4_jE;
-    _ZN7android6Parcel19writeFileDescriptorEib;
-    _ZN7android6Parcel19writeInterfaceTokenEPKDsj;
-    _ZN7android6Parcel19writeInterfaceTokenERKNS_8String16E;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
-    _ZN7android6Parcel20closeFileDescriptorsEv;
-    _ZN7android6Parcel22writeDupFileDescriptorEi;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
-    _ZN7android6Parcel25writeParcelFileDescriptorEib;
-    _ZN7android6Parcel25writeUniqueFileDescriptorERKNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android6Parcel26writeRawNullableParcelableEPKNS_10ParcelableE;
-    _ZN7android6Parcel27replaceCallingWorkSourceUidEj;
-    _ZN7android6Parcel28writeDupParcelFileDescriptorEi;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
-    _ZN7android6Parcel35writeDupImmutableBlobFileDescriptorEi;
-    _ZN7android6Parcel4Blob4initEiPvjb;
-    _ZN7android6Parcel4Blob5clearEv;
-    _ZN7android6Parcel4Blob7releaseEv;
-    _ZN7android6Parcel4BlobC1Ev;
-    _ZN7android6Parcel4BlobC2Ev;
-    _ZN7android6Parcel4BlobD1Ev;
-    _ZN7android6Parcel4BlobD2Ev;
-    _ZN7android6Parcel5writeEPKvj;
-    _ZN7android6Parcel5writeERKNS0_26FlattenableHelperInterfaceE;
-    _ZN7android6Parcel7setDataEPKhj;
-    _ZN7android6Parcel8freeDataEv;
-    _ZN7android6Parcel8growDataEj;
-    _ZN7android6Parcel8setErrorEi;
-    _ZN7android6Parcel9initStateEv;
-    _ZN7android6Parcel9writeBlobEjbPNS0_12WritableBlobE;
-    _ZN7android6Parcel9writeBoolEb;
-    _ZN7android6Parcel9writeByteEa;
-    _ZN7android6Parcel9writeCharEDs;
-    _ZN7android6ParcelC1Ev;
-    _ZN7android6ParcelC2Ev;
-    _ZN7android6ParcelD1Ev;
-    _ZN7android6ParcelD2Ev;
-    _ZN7android7BBinder10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android7BBinder10pingBinderEv;
-    _ZN7android7BBinder11getDebugPidEv;
-    _ZN7android7BBinder11isInheritRtEv;
-    _ZN7android7BBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
-    _ZN7android7BBinder11localBinderEv;
-    _ZN7android7BBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
-    _ZN7android7BBinder12detachObjectEPKv;
-    _ZN7android7BBinder12getExtensionEv;
-    _ZN7android7BBinder12setExtensionERKNS_2spINS_7IBinderEEE;
-    _ZN7android7BBinder12setInheritRtEb;
-    _ZN7android7BBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
-    _ZN7android7BBinder15isRequestingSidEv;
-    _ZN7android7BBinder16setRequestingSidEb;
-    _ZN7android7BBinder17getOrCreateExtrasEv;
-    _ZN7android7BBinder21getMinSchedulerPolicyEv;
-    _ZN7android7BBinder21setMinSchedulerPolicyEii;
-    _ZN7android7BBinder23getMinSchedulerPriorityEv;
-    _ZN7android7BBinder4dumpEiRKNS_6VectorINS_8String16EEE;
-    _ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j;
-    _ZN7android7BBinderC1Ev;
-    _ZN7android7BBinderC2Ev;
-    _ZN7android7BBinderD0Ev;
-    _ZN7android7BBinderD1Ev;
-    _ZN7android7BBinderD2Ev;
-    _ZN7android7content2pm18PackageChangeEvent14readFromParcelEPKNS_6ParcelE;
-    _ZN7android7content2pm21IPackageManagerNative10descriptorE;
-    _ZN7android7content2pm21IPackageManagerNative11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm21IPackageManagerNative12default_implE;
-    _ZN7android7content2pm21IPackageManagerNative14getDefaultImplEv;
-    _ZN7android7content2pm21IPackageManagerNative14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
-    _ZN7android7content2pm21IPackageManagerNativeC2Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD0Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD1Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD2Ev;
-    _ZN7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZN7android7content2pm22BnPackageManagerNativeC2Ev;
-    _ZN7android7content2pm22BpPackageManagerNative14getAllPackagesEPNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEE;
-    _ZN7android7content2pm22BpPackageManagerNative15getNamesForUidsERKNSt3__16vectorIiNS3_9allocatorIiEEEEPNS4_INS3_12basic_stringIcNS3_11char_traitsIcEENS5_IcEEEENS5_ISE_EEEE;
-    _ZN7android7content2pm22BpPackageManagerNative16getLocationFlagsERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPi;
-    _ZN7android7content2pm22BpPackageManagerNative16hasSystemFeatureERKNS_8String16EiPb;
-    _ZN7android7content2pm22BpPackageManagerNative19isPackageDebuggableERKNS_8String16EPb;
-    _ZN7android7content2pm22BpPackageManagerNative22getInstallerForPackageERKNS_8String16EPNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative24getVersionCodeForPackageERKNS_8String16EPx;
-    _ZN7android7content2pm22BpPackageManagerNative27hasSha256SigningCertificateERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKNS3_6vectorIhNS7_IhEEEEPb;
-    _ZN7android7content2pm22BpPackageManagerNative28getModuleMetadataPackageNameEPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative29getTargetSdkVersionForPackageERKNS_8String16EPi;
-    _ZN7android7content2pm22BpPackageManagerNative29isAudioPlaybackCaptureAllowedERKNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEEPNS4_IbNS8_IbEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative29registerPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
-    _ZN7android7content2pm22BpPackageManagerNative31unregisterPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
-    _ZN7android7content2pm22BpPackageManagerNativeC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22BpPackageManagerNativeC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22IPackageChangeObserver10descriptorE;
-    _ZN7android7content2pm22IPackageChangeObserver11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22IPackageChangeObserver12default_implE;
-    _ZN7android7content2pm22IPackageChangeObserver14getDefaultImplEv;
-    _ZN7android7content2pm22IPackageChangeObserver14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
-    _ZN7android7content2pm22IPackageChangeObserverC2Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD0Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD1Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD2Ev;
-    _ZN7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZN7android7content2pm23BnPackageChangeObserverC2Ev;
-    _ZN7android7content2pm23BpPackageChangeObserver16onPackageChangedERKNS1_18PackageChangeEventE;
-    _ZN7android7content2pm23BpPackageChangeObserverC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm23BpPackageChangeObserverC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7HexDumpC1EPKvjj;
-    _ZN7android7HexDumpC2EPKvjj;
-    _ZN7android7IBinder11getDebugPidEPi;
-    _ZN7android7IBinder11localBinderEv;
-    _ZN7android7IBinder12getExtensionEPNS_2spIS0_EE;
-    _ZN7android7IBinder12remoteBinderEv;
-    _ZN7android7IBinder12shellCommandERKNS_2spIS0_EEiiiRNS_6VectorINS_8String16EEERKNS1_INS_14IShellCallbackEEERKNS1_INS_15IResultReceiverEEE;
-    _ZN7android7IBinder19queryLocalInterfaceERKNS_8String16E;
-    _ZN7android7IBinderC2Ev;
-    _ZN7android7IBinderD0Ev;
-    _ZN7android7IBinderD1Ev;
-    _ZN7android7IBinderD2Ev;
-    _ZN7android7IMemory10descriptorE;
-    _ZN7android7IMemory11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7IMemory12default_implE;
-    _ZN7android7IMemory14getDefaultImplEv;
-    _ZN7android7IMemory14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android7IMemoryC2Ev;
-    _ZN7android7IMemoryD0Ev;
-    _ZN7android7IMemoryD1Ev;
-    _ZN7android7IMemoryD2Ev;
-    _ZN7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android8BnMemoryC2Ev;
-    _ZN7android8BnMemoryD0Ev;
-    _ZN7android8BnMemoryD1Ev;
-    _ZN7android8BnMemoryD2Ev;
-    _ZN7android8BpBinder10onFirstRefEv;
-    _ZN7android8BpBinder10pingBinderEv;
-    _ZN7android8BpBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
-    _ZN7android8BpBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
-    _ZN7android8BpBinder12detachObjectEPKv;
-    _ZN7android8BpBinder12remoteBinderEv;
-    _ZN7android8BpBinder12sendObituaryEv;
-    _ZN7android8BpBinder12sTrackingMapE;
-    _ZN7android8BpBinder13getCountByUidERNS_6VectorIjEES3_;
-    _ZN7android8BpBinder13ObjectManager4killEv;
-    _ZN7android8BpBinder13ObjectManager6attachEPKvPvS4_PFvS3_S4_S4_E;
-    _ZN7android8BpBinder13ObjectManager6detachEPKv;
-    _ZN7android8BpBinder13ObjectManagerC1Ev;
-    _ZN7android8BpBinder13ObjectManagerC2Ev;
-    _ZN7android8BpBinder13ObjectManagerD1Ev;
-    _ZN7android8BpBinder13ObjectManagerD2Ev;
-    _ZN7android8BpBinder13sTrackingLockE;
-    _ZN7android8BpBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
-    _ZN7android8BpBinder14reportOneDeathERKNS0_8ObituaryE;
-    _ZN7android8BpBinder14sLimitCallbackE;
-    _ZN7android8BpBinder15onLastStrongRefEPKv;
-    _ZN7android8BpBinder15sNumTrackedUidsE;
-    _ZN7android8BpBinder16enableCountByUidEv;
-    _ZN7android8BpBinder16setLimitCallbackEPFviE;
-    _ZN7android8BpBinder17disableCountByUidEv;
-    _ZN7android8BpBinder18sCountByUidEnabledE;
-    _ZN7android8BpBinder19getBinderProxyCountEj;
-    _ZN7android8BpBinder20onIncStrongAttemptedEjPKv;
-    _ZN7android8BpBinder20setCountByUidEnabledEb;
-    _ZN7android8BpBinder26sBinderProxyThrottleCreateE;
-    _ZN7android8BpBinder29sBinderProxyCountLowWatermarkE;
-    _ZN7android8BpBinder29setBinderProxyCountWatermarksEii;
-    _ZN7android8BpBinder30sBinderProxyCountHighWatermarkE;
-    _ZN7android8BpBinder4dumpEiRKNS_6VectorINS_8String16EEE;
-    _ZN7android8BpBinder6createEi;
-    _ZN7android8BpBinder6createERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
-    _ZN7android8BpBinder8transactEjRKNS_6ParcelEPS1_j;
-    _ZN7android8BpBinderC1EONS0_12BinderHandleEi;
-    _ZN7android8BpBinderC1EONS0_9RpcHandleE;
-    _ZN7android8BpBinderC1EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
-    _ZN7android8BpBinderC2EONS0_12BinderHandleEi;
-    _ZN7android8BpBinderC2EONS0_9RpcHandleE;
-    _ZN7android8BpBinderC2EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
-    _ZN7android8BpBinderD0Ev;
-    _ZN7android8BpBinderD1Ev;
-    _ZN7android8BpBinderD2Ev;
-    _ZN7android8BpMemoryC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android8BpMemoryC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android8BpMemoryD0Ev;
-    _ZN7android8BpMemoryD1Ev;
-    _ZN7android8BpMemoryD2Ev;
-    _ZN7android8internal9Stability11getCategoryEPNS_7IBinderE;
-    _ZN7android8internal9Stability11levelStringENS1_5LevelE;
-    _ZN7android8internal9Stability13getLocalLevelEv;
-    _ZN7android8internal9Stability15isDeclaredLevelENS1_5LevelE;
-    _ZN7android8internal9Stability17debugLogStabilityERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability19markCompilationUnitEPNS_7IBinderE;
-    _ZN7android8internal9Stability22tryMarkCompilationUnitEPNS_7IBinderE;
-    _ZN7android8internal9Stability24requiresVintfDeclarationERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability25forceDowngradeToStabilityERKNS_2spINS_7IBinderEEENS1_5LevelE;
-    _ZN7android8internal9Stability30forceDowngradeToLocalStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability31forceDowngradeToSystemStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability31forceDowngradeToVendorStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability5checkENS1_8CategoryENS1_5LevelE;
-    _ZN7android8internal9Stability7setReprEPNS_7IBinderEij;
-    _ZN7android8internal9Stability8Category11debugStringEv;
-    _ZN7android8internal9Stability8markVndkEPNS_7IBinderE;
-    _ZN7android8internal9Stability9markVintfEPNS_7IBinderE;
-    _ZN7android8RpcState11CommandDataC1Ej;
-    _ZN7android8RpcState11CommandDataC2Ej;
-    _ZN7android8RpcState12countBindersEv;
-    _ZN7android8RpcState12getSessionIdERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPi;
-    _ZN7android8RpcState12waitForReplyERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPNS_6ParcelE;
-    _ZN7android8RpcState13getMaxThreadsERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPj;
-    _ZN7android8RpcState13getRootObjectERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android8RpcState13sendDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressE;
-    _ZN7android8RpcState15onBinderLeavingERKNS_2spINS_10RpcSessionEEERKNS1_INS_7IBinderEEEPNS_10RpcAddressE;
-    _ZN7android8RpcState15processTransactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState16onBinderEnteringERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
-    _ZN7android8RpcState16processDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState20getAndExecuteCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android8RpcState20processServerCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState23processTransactInternalERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEENS0_11CommandDataE;
-    _ZN7android8RpcState4dumpEv;
-    _ZN7android8RpcState6rpcRecERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPvj;
-    _ZN7android8RpcState7rpcSendERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPKvj;
-    _ZN7android8RpcState8transactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressEjRKNS_6ParcelERKNS_2spINS_10RpcSessionEEEPSA_j;
-    _ZN7android8RpcState9terminateEv;
-    _ZN7android8RpcStateC1Ev;
-    _ZN7android8RpcStateC2Ev;
-    _ZN7android8RpcStateD1Ev;
-    _ZN7android8RpcStateD2Ev;
-    _ZN7android9BpRefBase10onFirstRefEv;
-    _ZN7android9BpRefBase15onLastStrongRefEPKv;
-    _ZN7android9BpRefBase20onIncStrongAttemptedEjPKv;
-    _ZN7android9BpRefBaseC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android9BpRefBaseC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android9BpRefBaseD0Ev;
-    _ZN7android9BpRefBaseD1Ev;
-    _ZN7android9BpRefBaseD2Ev;
-    _ZN7android9HeapCache10binderDiedERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9HeapCache10dump_heapsEv;
-    _ZN7android9HeapCache8get_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9find_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9free_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9free_heapERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9HeapCacheC1Ev;
-    _ZN7android9HeapCacheC2Ev;
-    _ZN7android9HeapCacheD0Ev;
-    _ZN7android9HeapCacheD1Ev;
-    _ZN7android9HeapCacheD2Ev;
-    _ZN7android9hexStringEPKvj;
-    _ZN7android9RpcServer12listSessionsEv;
-    _ZN7android9RpcServer13getMaxThreadsEv;
-    _ZN7android9RpcServer13getRootObjectEv;
-    _ZN7android9RpcServer13releaseServerEv;
-    _ZN7android9RpcServer13setMaxThreadsEj;
-    _ZN7android9RpcServer13setRootObjectERKNS_2spINS_7IBinderEEE;
-    _ZN7android9RpcServer15setupInetServerEjPj;
-    _ZN7android9RpcServer16setupVsockServerEj;
-    _ZN7android9RpcServer17setRootObjectWeakERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9RpcServer17setupSocketServerERKNS_16RpcSocketAddressE;
-    _ZN7android9RpcServer19establishConnectionEONS_2spIS0_EENS_4base14unique_fd_implINS4_13DefaultCloserEEE;
-    _ZN7android9RpcServer19setupExternalServerENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android9RpcServer20onSessionTerminatingERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android9RpcServer21setupUnixDomainServerEPKc;
-    _ZN7android9RpcServer24numUninitializedSessionsEv;
-    _ZN7android9RpcServer4joinEv;
-    _ZN7android9RpcServer4makeEv;
-    _ZN7android9RpcServer61iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProductionEv;
-    _ZN7android9RpcServer9acceptOneEv;
-    _ZN7android9RpcServer9hasServerEv;
-    _ZN7android9RpcServerC1Ev;
-    _ZN7android9RpcServerC2Ev;
-    _ZN7android9RpcServerD0Ev;
-    _ZN7android9RpcServerD1Ev;
-    _ZN7android9RpcServerD2Ev;
-    _ZN7android9SingletonINS_15PermissionCacheEE11getInstanceEv;
-    _ZN7android9SingletonINS_15PermissionCacheEE11hasInstanceEv;
-    _ZN7android9SingletonINS_15PermissionCacheEE5sLockE;
-    _ZN7android9SingletonINS_15PermissionCacheEE9sInstanceE;
-    _ZN7android9SingletonINS_15PermissionCacheEEC1Ev;
-    _ZN7android9SingletonINS_15PermissionCacheEEC2Ev;
-    _ZN7android9SingletonINS_15PermissionCacheEED1Ev;
-    _ZN7android9SingletonINS_15PermissionCacheEED2Ev;
-    _ZN7androidlsERNS_10TextOutputERKNS_7HexDumpE;
-    _ZN7androidlsERNS_10TextOutputERKNS_8TypeCodeE;
-    _ZN7androidlsIA15_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA24_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA2_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA34_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA3_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA43_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA4_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA5_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA8_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA9_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIjEERNS_10TextOutputES2_RKT_;
-    _ZN7androidlsINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEERNS_10TextOutputES9_RKT_;
-    _ZN7androidlsIPcEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIPvEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIyEERNS_10TextOutputES2_RKT_;
-    _ZNK7android10MemoryBase9getMemoryEPiPj;
-    _ZNK7android10RpcAddress13writeToParcelEPNS_6ParcelE;
-    _ZNK7android10RpcAddress15viewRawEmbeddedEv;
-    _ZNK7android10RpcAddress6isZeroEv;
-    _ZNK7android10RpcAddress8toStringEv;
-    _ZNK7android10RpcAddressltERKS0_;
-    _ZNK7android11IMemoryHeap22getInterfaceDescriptorEv;
-    _ZNK7android12BpMemoryHeap12assertMappedEv;
-    _ZNK7android12BpMemoryHeap18assertReallyMappedEv;
-    _ZNK7android12BpMemoryHeap7getBaseEv;
-    _ZNK7android12BpMemoryHeap7getSizeEv;
-    _ZNK7android12BpMemoryHeap8getFlagsEv;
-    _ZNK7android12BpMemoryHeap9getHeapIDEv;
-    _ZNK7android12BpMemoryHeap9getOffsetEv;
-    _ZNK7android12MemoryDealer4dumpEPKc;
-    _ZNK7android12MemoryDealer4heapEv;
-    _ZNK7android12MemoryDealer9allocatorEv;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE10do_compareEPKvS5_;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE10do_destroyEPvj;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE12do_constructEPvj;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE15do_move_forwardEPvPKvj;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE16do_move_backwardEPvPKvj;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE7do_copyEPvPKvj;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE8do_splatEPvPKvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_compareEPKvSA_;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_destroyEPvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE12do_constructEPvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE15do_move_forwardEPvPKvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE16do_move_backwardEPvPKvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE7do_copyEPvPKvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE8do_splatEPvPKvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_compareES3_S3_;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_destroyEPvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE12do_constructEPvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE15do_move_forwardEPvS3_j;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE16do_move_backwardEPvS3_j;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE7do_copyEPvS3_j;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE8do_splatEPvS3_j;
-    _ZNK7android12SortedVectorINS_8String16EE10do_compareEPKvS4_;
-    _ZNK7android12SortedVectorINS_8String16EE10do_destroyEPvj;
-    _ZNK7android12SortedVectorINS_8String16EE12do_constructEPvj;
-    _ZNK7android12SortedVectorINS_8String16EE15do_move_forwardEPvPKvj;
-    _ZNK7android12SortedVectorINS_8String16EE16do_move_backwardEPvPKvj;
-    _ZNK7android12SortedVectorINS_8String16EE7do_copyEPvPKvj;
-    _ZNK7android12SortedVectorINS_8String16EE8do_splatEPvPKvj;
-    _ZNK7android14IPCThreadState13getCallingPidEv;
-    _ZNK7android14IPCThreadState13getCallingSidEv;
-    _ZNK7android14IPCThreadState13getCallingUidEv;
-    _ZNK7android14IPCThreadState18getCallRestrictionEv;
-    _ZNK7android14IPCThreadState19getStrictModePolicyEv;
-    _ZNK7android14IPCThreadState22getServingStackPointerEv;
-    _ZNK7android14IPCThreadState23getCallingWorkSourceUidEv;
-    _ZNK7android14IPCThreadState25shouldPropagateWorkSourceEv;
-    _ZNK7android14IPCThreadState29getLastTransactionBinderFlagsEv;
-    _ZNK7android14IShellCallback22getInterfaceDescriptorEv;
-    _ZNK7android14MemoryHeapBase7getBaseEv;
-    _ZNK7android14MemoryHeapBase7getSizeEv;
-    _ZNK7android14MemoryHeapBase8getFlagsEv;
-    _ZNK7android14MemoryHeapBase9getDeviceEv;
-    _ZNK7android14MemoryHeapBase9getHeapIDEv;
-    _ZNK7android14MemoryHeapBase9getOffsetEv;
-    _ZNK7android15IResultReceiver22getInterfaceDescriptorEv;
-    _ZNK7android15IServiceManager22getInterfaceDescriptorEv;
-    _ZNK7android15PermissionCache5checkEPbRKNS_8String16Ej;
-    _ZNK7android18BufferedTextOutput9getBufferEv;
-    _ZNK7android18ServiceManagerShim10getServiceERKNS_8String16E;
-    _ZNK7android18ServiceManagerShim12checkServiceERKNS_8String16E;
-    _ZNK7android21IPermissionController22getInterfaceDescriptorEv;
-    _ZNK7android22SimpleBestFitAllocator4dumpEPKc;
-    _ZNK7android22SimpleBestFitAllocator4dumpERNS_7String8EPKc;
-    _ZNK7android22SimpleBestFitAllocator4sizeEv;
-    _ZNK7android22SimpleBestFitAllocator6dump_lEPKc;
-    _ZNK7android22SimpleBestFitAllocator6dump_lERNS_7String8EPKc;
-    _ZNK7android2os15IClientCallback22getInterfaceDescriptorEv;
-    _ZNK7android2os15IServiceManager22getInterfaceDescriptorEv;
-    _ZNK7android2os16IServiceCallback22getInterfaceDescriptorEv;
-    _ZNK7android2os16ParcelableHolder13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os16ServiceDebugInfo13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle10getBooleanERKNS_8String16EPb;
-    _ZNK7android2os17PersistableBundle10getIntKeysEv;
-    _ZNK7android2os17PersistableBundle11getLongKeysEv;
-    _ZNK7android2os17PersistableBundle12getIntVectorERKNS_8String16EPNSt3__16vectorIiNS5_9allocatorIiEEEE;
-    _ZNK7android2os17PersistableBundle13getDoubleKeysEv;
-    _ZNK7android2os17PersistableBundle13getLongVectorERKNS_8String16EPNSt3__16vectorIxNS5_9allocatorIxEEEE;
-    _ZNK7android2os17PersistableBundle13getStringKeysEv;
-    _ZNK7android2os17PersistableBundle13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle14getBooleanKeysEv;
-    _ZNK7android2os17PersistableBundle15getDoubleVectorERKNS_8String16EPNSt3__16vectorIdNS5_9allocatorIdEEEE;
-    _ZNK7android2os17PersistableBundle15getStringVectorERKNS_8String16EPNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
-    _ZNK7android2os17PersistableBundle16getBooleanVectorERKNS_8String16EPNSt3__16vectorIbNS5_9allocatorIbEEEE;
-    _ZNK7android2os17PersistableBundle16getIntVectorKeysEv;
-    _ZNK7android2os17PersistableBundle17getLongVectorKeysEv;
-    _ZNK7android2os17PersistableBundle18writeToParcelInnerEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle19getDoubleVectorKeysEv;
-    _ZNK7android2os17PersistableBundle19getStringVectorKeysEv;
-    _ZNK7android2os17PersistableBundle20getBooleanVectorKeysEv;
-    _ZNK7android2os17PersistableBundle20getPersistableBundleERKNS_8String16EPS1_;
-    _ZNK7android2os17PersistableBundle24getPersistableBundleKeysEv;
-    _ZNK7android2os17PersistableBundle4sizeEv;
-    _ZNK7android2os17PersistableBundle5emptyEv;
-    _ZNK7android2os17PersistableBundle6getIntERKNS_8String16EPi;
-    _ZNK7android2os17PersistableBundle7getLongERKNS_8String16EPx;
-    _ZNK7android2os17PersistableBundle9getDoubleERKNS_8String16EPd;
-    _ZNK7android2os17PersistableBundle9getStringERKNS_8String16EPS2_;
-    _ZNK7android2os20ParcelFileDescriptor13writeToParcelEPNS_6ParcelE;
-    _ZNK7android6binder6Status13writeToParcelEPNS_6ParcelE;
-    _ZNK7android6binder6Status9toString8Ev;
-    _ZNK7android6Parcel10errorCheckEv;
-    _ZNK7android6Parcel10ipcObjectsEv;
-    _ZNK7android6Parcel10readDoubleEPd;
-    _ZNK7android6Parcel10readDoubleEv;
-    _ZNK7android6Parcel10readObjectEb;
-    _ZNK7android6Parcel10readUint32EPj;
-    _ZNK7android6Parcel10readUint32Ev;
-    _ZNK7android6Parcel10readUint64EPy;
-    _ZNK7android6Parcel10readUint64Ev;
-    _ZNK7android6Parcel10scanForFdsEv;
-    _ZNK7android6Parcel11ipcDataSizeEv;
-    _ZNK7android6Parcel11readCStringEv;
-    _ZNK7android6Parcel11readInplaceEj;
-    _ZNK7android6Parcel11readPointerEPj;
-    _ZNK7android6Parcel11readPointerEv;
-    _ZNK7android6Parcel11readString8EPNS_7String8E;
-    _ZNK7android6Parcel11readString8Ev;
-    _ZNK7android6Parcel12dataCapacityEv;
-    _ZNK7android6Parcel12dataPositionEv;
-    _ZNK7android6Parcel12objectsCountEv;
-    _ZNK7android6Parcel12readString16EPNS_8String16E;
-    _ZNK7android6Parcel12readString16EPNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
-    _ZNK7android6Parcel12readString16EPNSt3__18optionalINS_8String16EEE;
-    _ZNK7android6Parcel12readString16Ev;
-    _ZNK7android6Parcel13markSensitiveEv;
-    _ZNK7android6Parcel14checkInterfaceEPNS_7IBinderE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__16vectorIbNS1_9allocatorIbEEEE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIaNS1_9allocatorIaEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIhNS1_9allocatorIhEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
-    _ZNK7android6Parcel14readParcelableEPNS_10ParcelableE;
-    _ZNK7android6Parcel15ipcObjectsCountEv;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__16vectorIfNS1_9allocatorIfEEEE;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__16vectorIiNS1_9allocatorIiEEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__110unique_ptrINS1_6vectorIxNS1_9allocatorIxEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__16vectorIxNS1_9allocatorIxEEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__18optionalINS1_6vectorIxNS1_9allocatorIxEEEEEE;
-    _ZNK7android6Parcel15setDataPositionEj;
-    _ZNK7android6Parcel15unflattenBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel16enforceInterfaceEPKDsjPNS_14IPCThreadStateE;
-    _ZNK7android6Parcel16enforceInterfaceERKNS_8String16EPNS_14IPCThreadStateE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__16vectorIdNS1_9allocatorIdEEEE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
-    _ZNK7android6Parcel16readNativeHandleEv;
-    _ZNK7android6Parcel16readStrongBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel16readStrongBinderEv;
-    _ZNK7android6Parcel16readStrongBinderINS_2os15IClientCallbackEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readStrongBinderINS_2os16IServiceCallbackEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readStrongBinderINS_7content2pm22IPackageChangeObserverEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__110unique_ptrINS1_6vectorIyNS1_9allocatorIyEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__16vectorIyNS1_9allocatorIyEEEE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__18optionalINS1_6vectorIyNS1_9allocatorIyEEEEEE;
-    _ZNK7android6Parcel16validateReadDataEj;
-    _ZNK7android6Parcel17getBlobAshmemSizeEv;
-    _ZNK7android6Parcel17getOpenAshmemSizeEv;
-    _ZNK7android6Parcel17readExceptionCodeEv;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
-    _ZNK7android6Parcel18hasFileDescriptorsEv;
-    _ZNK7android6Parcel18readFileDescriptorEv;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
-    _ZNK7android6Parcel18readString8InplaceEPj;
-    _ZNK7android6Parcel19readString16InplaceEPj;
-    _ZNK7android6Parcel21finishUnflattenBinderERKNS_2spINS_7IBinderEEEPS3_;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
-    _ZNK7android6Parcel24readCallingWorkSourceUidEv;
-    _ZNK7android6Parcel24readNullableStrongBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel24readParcelFileDescriptorEv;
-    _ZNK7android6Parcel24readUniqueFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
-    _ZNK7android6Parcel30readUniqueParcelFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZNK7android6Parcel37updateWorkSourceRequestHeaderPositionEv;
-    _ZNK7android6Parcel4dataEv;
-    _ZNK7android6Parcel4readEPvj;
-    _ZNK7android6Parcel4readERNS0_26FlattenableHelperInterfaceE;
-    _ZNK7android6Parcel5printERNS_10TextOutputEj;
-    _ZNK7android6Parcel7ipcDataEv;
-    _ZNK7android6Parcel8allowFdsEv;
-    _ZNK7android6Parcel8dataSizeEv;
-    _ZNK7android6Parcel8isForRpcEv;
-    _ZNK7android6Parcel8readBlobEjPNS0_12ReadableBlobE;
-    _ZNK7android6Parcel8readBoolEPb;
-    _ZNK7android6Parcel8readBoolEv;
-    _ZNK7android6Parcel8readByteEPa;
-    _ZNK7android6Parcel8readByteEv;
-    _ZNK7android6Parcel8readCharEPDs;
-    _ZNK7android6Parcel8readCharEv;
-    _ZNK7android6Parcel9dataAvailEv;
-    _ZNK7android6Parcel9readFloatEPf;
-    _ZNK7android6Parcel9readFloatEv;
-    _ZNK7android6Parcel9readInt32EPi;
-    _ZNK7android6Parcel9readInt32Ev;
-    _ZNK7android6Parcel9readInt64EPx;
-    _ZNK7android6Parcel9readInt64Ev;
-    _ZNK7android6VectorIiE10do_destroyEPvj;
-    _ZNK7android6VectorIiE12do_constructEPvj;
-    _ZNK7android6VectorIiE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorIiE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorIiE7do_copyEPvPKvj;
-    _ZNK7android6VectorIiE8do_splatEPvPKvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE10do_destroyEPvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE12do_constructEPvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE7do_copyEPvPKvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE8do_splatEPvPKvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE10do_destroyEPvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE12do_constructEPvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE7do_copyEPvPKvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE8do_splatEPvPKvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE10do_destroyEPvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE12do_constructEPvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE7do_copyEPvPKvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE8do_splatEPvPKvj;
-    _ZNK7android6VectorINS_8String16EE10do_destroyEPvj;
-    _ZNK7android6VectorINS_8String16EE12do_constructEPvj;
-    _ZNK7android6VectorINS_8String16EE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorINS_8String16EE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorINS_8String16EE7do_copyEPvPKvj;
-    _ZNK7android6VectorINS_8String16EE8do_splatEPvPKvj;
-    _ZNK7android6VectorIPNS_7BBinderEE10do_destroyEPvj;
-    _ZNK7android6VectorIPNS_7BBinderEE12do_constructEPvj;
-    _ZNK7android6VectorIPNS_7BBinderEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7BBinderEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7BBinderEE7do_copyEPvPKvj;
-    _ZNK7android6VectorIPNS_7BBinderEE8do_splatEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE10do_destroyEPvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE12do_constructEPvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE7do_copyEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE8do_splatEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE10do_destroyEPvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE12do_constructEPvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE7do_copyEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE8do_splatEPvPKvj;
-    _ZNK7android7BBinder10findObjectEPKv;
-    _ZNK7android7BBinder13isBinderAliveEv;
-    _ZNK7android7BBinder22getInterfaceDescriptorEv;
-    _ZNK7android7content2pm18PackageChangeEvent13writeToParcelEPNS_6ParcelE;
-    _ZNK7android7content2pm21IPackageManagerNative22getInterfaceDescriptorEv;
-    _ZNK7android7content2pm22IPackageChangeObserver22getInterfaceDescriptorEv;
-    _ZNK7android7IBinder13checkSubclassEPKv;
-    _ZNK7android7IMemory11fastPointerERKNS_2spINS_7IBinderEEEi;
-    _ZNK7android7IMemory15unsecurePointerEv;
-    _ZNK7android7IMemory22getInterfaceDescriptorEv;
-    _ZNK7android7IMemory4sizeEv;
-    _ZNK7android7IMemory6offsetEv;
-    _ZNK7android7IMemory7pointerEv;
-    _ZNK7android8BpBinder10findObjectEPKv;
-    _ZNK7android8BpBinder10rpcAddressEv;
-    _ZNK7android8BpBinder10rpcSessionEv;
-    _ZNK7android8BpBinder11isRpcBinderEv;
-    _ZNK7android8BpBinder12binderHandleEv;
-    _ZNK7android8BpBinder13isBinderAliveEv;
-    _ZNK7android8BpBinder13ObjectManager4findEPKv;
-    _ZNK7android8BpBinder18isDescriptorCachedEv;
-    _ZNK7android8BpBinder22getInterfaceDescriptorEv;
-    _ZNK7android8BpMemory9getMemoryEPiPj;
-    _ZTCN7android10AllocationE0_NS_10IInterfaceE;
-    _ZTCN7android10AllocationE0_NS_10MemoryBaseE;
-    _ZTCN7android10AllocationE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android10AllocationE0_NS_7IMemoryE;
-    _ZTCN7android10AllocationE0_NS_8BnMemoryE;
-    _ZTCN7android10AllocationE4_NS_7BBinderE;
-    _ZTCN7android10AllocationE4_NS_7IBinderE;
-    _ZTCN7android10MemoryBaseE0_NS_10IInterfaceE;
-    _ZTCN7android10MemoryBaseE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android10MemoryBaseE0_NS_7IMemoryE;
-    _ZTCN7android10MemoryBaseE0_NS_8BnMemoryE;
-    _ZTCN7android10MemoryBaseE4_NS_7BBinderE;
-    _ZTCN7android10MemoryBaseE4_NS_7IBinderE;
-    _ZTCN7android10PoolThreadE0_NS_6ThreadE;
-    _ZTCN7android11IMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BnMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BnMemoryHeapE0_NS_11BnInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android12BnMemoryHeapE0_NS_11IMemoryHeapE;
-    _ZTCN7android12BnMemoryHeapE4_NS_7BBinderE;
-    _ZTCN7android12BnMemoryHeapE4_NS_7IBinderE;
-    _ZTCN7android12BpMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BpMemoryHeapE0_NS_11BpInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android12BpMemoryHeapE0_NS_11IMemoryHeapE;
-    _ZTCN7android12BpMemoryHeapE4_NS_9BpRefBaseE;
-    _ZTCN7android14IShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android14MemoryHeapBaseE32_NS_10IInterfaceE;
-    _ZTCN7android14MemoryHeapBaseE32_NS_11BnInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android14MemoryHeapBaseE32_NS_11IMemoryHeapE;
-    _ZTCN7android14MemoryHeapBaseE32_NS_12BnMemoryHeapE;
-    _ZTCN7android14MemoryHeapBaseE36_NS_7BBinderE;
-    _ZTCN7android14MemoryHeapBaseE36_NS_7IBinderE;
-    _ZTCN7android15BnShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android15BnShellCallbackE0_NS_11BnInterfaceINS_14IShellCallbackEEE;
-    _ZTCN7android15BnShellCallbackE0_NS_14IShellCallbackE;
-    _ZTCN7android15BnShellCallbackE4_NS_7BBinderE;
-    _ZTCN7android15BnShellCallbackE4_NS_7IBinderE;
-    _ZTCN7android15BpShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android15BpShellCallbackE0_NS_11BpInterfaceINS_14IShellCallbackEEE;
-    _ZTCN7android15BpShellCallbackE0_NS_14IShellCallbackE;
-    _ZTCN7android15BpShellCallbackE4_NS_9BpRefBaseE;
-    _ZTCN7android15IResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android15IServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android16BnResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android16BnResultReceiverE0_NS_11BnInterfaceINS_15IResultReceiverEEE;
-    _ZTCN7android16BnResultReceiverE0_NS_15IResultReceiverE;
-    _ZTCN7android16BnResultReceiverE4_NS_7BBinderE;
-    _ZTCN7android16BnResultReceiverE4_NS_7IBinderE;
-    _ZTCN7android16BpResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android16BpResultReceiverE0_NS_11BpInterfaceINS_15IResultReceiverEEE;
-    _ZTCN7android16BpResultReceiverE0_NS_15IResultReceiverE;
-    _ZTCN7android16BpResultReceiverE4_NS_9BpRefBaseE;
-    _ZTCN7android18ServiceManagerShimE0_NS_10IInterfaceE;
-    _ZTCN7android18ServiceManagerShimE0_NS_15IServiceManagerE;
-    _ZTCN7android21IPermissionControllerE0_NS_10IInterfaceE;
-    _ZTCN7android22BnPermissionControllerE0_NS_10IInterfaceE;
-    _ZTCN7android22BnPermissionControllerE0_NS_11BnInterfaceINS_21IPermissionControllerEEE;
-    _ZTCN7android22BnPermissionControllerE0_NS_21IPermissionControllerE;
-    _ZTCN7android22BnPermissionControllerE4_NS_7BBinderE;
-    _ZTCN7android22BnPermissionControllerE4_NS_7IBinderE;
-    _ZTCN7android22BpPermissionControllerE0_NS_10IInterfaceE;
-    _ZTCN7android22BpPermissionControllerE0_NS_11BpInterfaceINS_21IPermissionControllerEEE;
-    _ZTCN7android22BpPermissionControllerE0_NS_21IPermissionControllerE;
-    _ZTCN7android22BpPermissionControllerE4_NS_9BpRefBaseE;
-    _ZTCN7android2os15IClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os15IServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnClientCallbackE0_NS0_15IClientCallbackE;
-    _ZTCN7android2os16BnClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnClientCallbackE0_NS_11BnInterfaceINS0_15IClientCallbackEEE;
-    _ZTCN7android2os16BnClientCallbackE4_NS_7BBinderE;
-    _ZTCN7android2os16BnClientCallbackE4_NS_7IBinderE;
-    _ZTCN7android2os16BnServiceManagerE0_NS0_15IServiceManagerE;
-    _ZTCN7android2os16BnServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnServiceManagerE0_NS_11BnInterfaceINS0_15IServiceManagerEEE;
-    _ZTCN7android2os16BnServiceManagerE4_NS_7BBinderE;
-    _ZTCN7android2os16BnServiceManagerE4_NS_7IBinderE;
-    _ZTCN7android2os16BpClientCallbackE0_NS0_15IClientCallbackE;
-    _ZTCN7android2os16BpClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BpClientCallbackE0_NS_11BpInterfaceINS0_15IClientCallbackEEE;
-    _ZTCN7android2os16BpClientCallbackE4_NS_9BpRefBaseE;
-    _ZTCN7android2os16BpServiceManagerE0_NS0_15IServiceManagerE;
-    _ZTCN7android2os16BpServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BpServiceManagerE0_NS_11BpInterfaceINS0_15IServiceManagerEEE;
-    _ZTCN7android2os16BpServiceManagerE4_NS_9BpRefBaseE;
-    _ZTCN7android2os16IServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS0_16IServiceCallbackE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS_11BnInterfaceINS0_16IServiceCallbackEEE;
-    _ZTCN7android2os17BnServiceCallbackE4_NS_7BBinderE;
-    _ZTCN7android2os17BnServiceCallbackE4_NS_7IBinderE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS0_16IServiceCallbackE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS_11BpInterfaceINS0_16IServiceCallbackEEE;
-    _ZTCN7android2os17BpServiceCallbackE4_NS_9BpRefBaseE;
-    _ZTCN7android7BBinderE0_NS_7IBinderE;
-    _ZTCN7android7content2pm21IPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_11BnInterfaceINS1_21IPackageManagerNativeEEE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE4_NS_7BBinderE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE4_NS_7IBinderE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_11BpInterfaceINS1_21IPackageManagerNativeEEE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE4_NS_9BpRefBaseE;
-    _ZTCN7android7content2pm22IPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_11BnInterfaceINS1_22IPackageChangeObserverEEE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE4_NS_7BBinderE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE4_NS_7IBinderE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_11BpInterfaceINS1_22IPackageChangeObserverEEE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE4_NS_9BpRefBaseE;
-    _ZTCN7android7IMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BnMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BnMemoryE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android8BnMemoryE0_NS_7IMemoryE;
-    _ZTCN7android8BnMemoryE4_NS_7BBinderE;
-    _ZTCN7android8BnMemoryE4_NS_7IBinderE;
-    _ZTCN7android8BpBinderE0_NS_7IBinderE;
-    _ZTCN7android8BpMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BpMemoryE0_NS_11BpInterfaceINS_7IMemoryEEE;
-    _ZTCN7android8BpMemoryE0_NS_7IMemoryE;
-    _ZTCN7android8BpMemoryE4_NS_9BpRefBaseE;
-    _ZTCN7android9HeapCacheE0_NS_7IBinder14DeathRecipientE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_13basic_istreamIcS2_EE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_14basic_iostreamIcS2_EE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE8_NS_13basic_ostreamIcS2_EE;
-    _ZThn4_N7android10AllocationD0Ev;
-    _ZThn4_N7android10AllocationD1Ev;
-    _ZThn4_N7android10MemoryBaseD0Ev;
-    _ZThn4_N7android10MemoryBaseD1Ev;
-    _ZThn4_N7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn4_N7android12BnMemoryHeapD0Ev;
-    _ZThn4_N7android12BnMemoryHeapD1Ev;
-    _ZThn4_N7android12BpMemoryHeapD0Ev;
-    _ZThn4_N7android12BpMemoryHeapD1Ev;
-    _ZThn4_N7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn4_N7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn4_N7android22BnPermissionController10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn4_N7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn4_N7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn4_N7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn4_N7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZThn4_N7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZThn4_N7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn4_N7android8BnMemoryD0Ev;
-    _ZThn4_N7android8BnMemoryD1Ev;
-    _ZThn4_N7android8BpMemoryD0Ev;
-    _ZThn4_N7android8BpMemoryD1Ev;
-    _ZTTN7android10AllocationE;
-    _ZTTN7android10IInterfaceE;
-    _ZTTN7android10MemoryBaseE;
-    _ZTTN7android10PoolThreadE;
-    _ZTTN7android10RpcSessionE;
-    _ZTTN7android11IMemoryHeapE;
-    _ZTTN7android12BnMemoryHeapE;
-    _ZTTN7android12BpMemoryHeapE;
-    _ZTTN7android12ProcessStateE;
-    _ZTTN7android14IShellCallbackE;
-    _ZTTN7android14MemoryHeapBaseE;
-    _ZTTN7android15BnShellCallbackE;
-    _ZTTN7android15BpShellCallbackE;
-    _ZTTN7android15IResultReceiverE;
-    _ZTTN7android15IServiceManagerE;
-    _ZTTN7android16BnResultReceiverE;
-    _ZTTN7android16BpResultReceiverE;
-    _ZTTN7android18ServiceManagerShimE;
-    _ZTTN7android21IPermissionControllerE;
-    _ZTTN7android22BnPermissionControllerE;
-    _ZTTN7android22BpPermissionControllerE;
-    _ZTTN7android2os15IClientCallbackE;
-    _ZTTN7android2os15IServiceManagerE;
-    _ZTTN7android2os16BnClientCallbackE;
-    _ZTTN7android2os16BnServiceManagerE;
-    _ZTTN7android2os16BpClientCallbackE;
-    _ZTTN7android2os16BpServiceManagerE;
-    _ZTTN7android2os16IServiceCallbackE;
-    _ZTTN7android2os17BnServiceCallbackE;
-    _ZTTN7android2os17BpServiceCallbackE;
-    _ZTTN7android7BBinderE;
-    _ZTTN7android7content2pm21IPackageManagerNativeE;
-    _ZTTN7android7content2pm22BnPackageManagerNativeE;
-    _ZTTN7android7content2pm22BpPackageManagerNativeE;
-    _ZTTN7android7content2pm22IPackageChangeObserverE;
-    _ZTTN7android7content2pm23BnPackageChangeObserverE;
-    _ZTTN7android7content2pm23BpPackageChangeObserverE;
-    _ZTTN7android7IBinderE;
-    _ZTTN7android7IMemoryE;
-    _ZTTN7android8BnMemoryE;
-    _ZTTN7android8BpBinderE;
-    _ZTTN7android8BpMemoryE;
-    _ZTTN7android9BpRefBaseE;
-    _ZTTN7android9HeapCacheE;
-    _ZTTN7android9RpcServerE;
-    _ZTTNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE;
-    _ZTv0_n12_N7android10AllocationD0Ev;
-    _ZTv0_n12_N7android10AllocationD1Ev;
-    _ZTv0_n12_N7android10IInterfaceD0Ev;
-    _ZTv0_n12_N7android10IInterfaceD1Ev;
-    _ZTv0_n12_N7android10MemoryBaseD0Ev;
-    _ZTv0_n12_N7android10MemoryBaseD1Ev;
-    _ZTv0_n12_N7android10RpcSessionD0Ev;
-    _ZTv0_n12_N7android10RpcSessionD1Ev;
-    _ZTv0_n12_N7android11IMemoryHeapD0Ev;
-    _ZTv0_n12_N7android11IMemoryHeapD1Ev;
-    _ZTv0_n12_N7android12BnMemoryHeapD0Ev;
-    _ZTv0_n12_N7android12BnMemoryHeapD1Ev;
-    _ZTv0_n12_N7android12BpMemoryHeapD0Ev;
-    _ZTv0_n12_N7android12BpMemoryHeapD1Ev;
-    _ZTv0_n12_N7android12ProcessStateD0Ev;
-    _ZTv0_n12_N7android12ProcessStateD1Ev;
-    _ZTv0_n12_N7android14IShellCallbackD0Ev;
-    _ZTv0_n12_N7android14IShellCallbackD1Ev;
-    _ZTv0_n12_N7android14MemoryHeapBaseD0Ev;
-    _ZTv0_n12_N7android14MemoryHeapBaseD1Ev;
-    _ZTv0_n12_N7android15IResultReceiverD0Ev;
-    _ZTv0_n12_N7android15IResultReceiverD1Ev;
-    _ZTv0_n12_N7android15IServiceManagerD0Ev;
-    _ZTv0_n12_N7android15IServiceManagerD1Ev;
-    _ZTv0_n12_N7android21IPermissionControllerD0Ev;
-    _ZTv0_n12_N7android21IPermissionControllerD1Ev;
-    _ZTv0_n12_N7android2os15IClientCallbackD0Ev;
-    _ZTv0_n12_N7android2os15IClientCallbackD1Ev;
-    _ZTv0_n12_N7android2os15IServiceManagerD0Ev;
-    _ZTv0_n12_N7android2os15IServiceManagerD1Ev;
-    _ZTv0_n12_N7android2os16IServiceCallbackD0Ev;
-    _ZTv0_n12_N7android2os16IServiceCallbackD1Ev;
-    _ZTv0_n12_N7android7BBinderD0Ev;
-    _ZTv0_n12_N7android7BBinderD1Ev;
-    _ZTv0_n12_N7android7content2pm21IPackageManagerNativeD0Ev;
-    _ZTv0_n12_N7android7content2pm21IPackageManagerNativeD1Ev;
-    _ZTv0_n12_N7android7content2pm22IPackageChangeObserverD0Ev;
-    _ZTv0_n12_N7android7content2pm22IPackageChangeObserverD1Ev;
-    _ZTv0_n12_N7android7IBinderD0Ev;
-    _ZTv0_n12_N7android7IBinderD1Ev;
-    _ZTv0_n12_N7android7IMemoryD0Ev;
-    _ZTv0_n12_N7android7IMemoryD1Ev;
-    _ZTv0_n12_N7android8BnMemoryD0Ev;
-    _ZTv0_n12_N7android8BnMemoryD1Ev;
-    _ZTv0_n12_N7android8BpBinderD0Ev;
-    _ZTv0_n12_N7android8BpBinderD1Ev;
-    _ZTv0_n12_N7android8BpMemoryD0Ev;
-    _ZTv0_n12_N7android8BpMemoryD1Ev;
-    _ZTv0_n12_N7android9BpRefBaseD0Ev;
-    _ZTv0_n12_N7android9BpRefBaseD1Ev;
-    _ZTv0_n12_N7android9HeapCacheD0Ev;
-    _ZTv0_n12_N7android9HeapCacheD1Ev;
-    _ZTv0_n12_N7android9RpcServerD0Ev;
-    _ZTv0_n12_N7android9RpcServerD1Ev;
-    _ZTv0_n16_N7android14MemoryHeapBaseD0Ev;
-    _ZTv0_n16_N7android14MemoryHeapBaseD1Ev;
-    _ZTv0_n16_N7android8BpBinder10onFirstRefEv;
-    _ZTv0_n16_N7android9BpRefBase10onFirstRefEv;
-    _ZTv0_n20_N7android8BpBinder15onLastStrongRefEPKv;
-    _ZTv0_n20_N7android9BpRefBase15onLastStrongRefEPKv;
-    _ZTv0_n24_N7android8BpBinder20onIncStrongAttemptedEjPKv;
-    _ZTv0_n24_N7android9BpRefBase20onIncStrongAttemptedEjPKv;
-    _ZTv0_n28_NK7android14MemoryHeapBase9getHeapIDEv;
-    _ZTv0_n32_NK7android14MemoryHeapBase7getBaseEv;
-    _ZTv0_n36_NK7android14MemoryHeapBase7getSizeEv;
-    _ZTv0_n40_NK7android14MemoryHeapBase8getFlagsEv;
-    _ZTv0_n44_NK7android14MemoryHeapBase9getOffsetEv;
-    _ZTvn4_n16_N7android14MemoryHeapBaseD0Ev;
-    _ZTvn4_n16_N7android14MemoryHeapBaseD1Ev;
-    _ZTVN7android10AllocationE;
-    _ZTVN7android10IInterfaceE;
-    _ZTVN7android10MemoryBaseE;
-    _ZTVN7android10PoolThreadE;
-    _ZTVN7android10RpcSession13RpcConnectionE;
-    _ZTVN7android10RpcSessionE;
-    _ZTVN7android10TextOutputE;
-    _ZTVN7android11IMemoryHeapE;
-    _ZTVN7android12BnMemoryHeapE;
-    _ZTVN7android12BpMemoryHeapE;
-    _ZTVN7android12FdTextOutputE;
-    _ZTVN7android12MemoryDealerE;
-    _ZTVN7android12ProcessStateE;
-    _ZTVN7android12SortedVectorINS_15PermissionCache5EntryEEE;
-    _ZTVN7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEEE;
-    _ZTVN7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEEE;
-    _ZTVN7android12SortedVectorINS_8String16EEE;
-    _ZTVN7android13LogTextOutputE;
-    _ZTVN7android14IShellCallbackE;
-    _ZTVN7android14MemoryHeapBaseE;
-    _ZTVN7android15BnShellCallbackE;
-    _ZTVN7android15BpShellCallbackE;
-    _ZTVN7android15IResultReceiverE;
-    _ZTVN7android15IServiceManagerE;
-    _ZTVN7android16BnResultReceiverE;
-    _ZTVN7android16BpResultReceiverE;
-    _ZTVN7android17InetSocketAddressE;
-    _ZTVN7android17UnixSocketAddressE;
-    _ZTVN7android18BufferedTextOutput11BufferStateE;
-    _ZTVN7android18BufferedTextOutputE;
-    _ZTVN7android18ServiceManagerShimE;
-    _ZTVN7android18VsockSocketAddressE;
-    _ZTVN7android21IPermissionControllerE;
-    _ZTVN7android22BnPermissionControllerE;
-    _ZTVN7android22BpPermissionControllerE;
-    _ZTVN7android2os15IClientCallbackE;
-    _ZTVN7android2os15IServiceManagerE;
-    _ZTVN7android2os16BnClientCallbackE;
-    _ZTVN7android2os16BnServiceManagerE;
-    _ZTVN7android2os16BpClientCallbackE;
-    _ZTVN7android2os16BpServiceManagerE;
-    _ZTVN7android2os16IServiceCallbackE;
-    _ZTVN7android2os16ParcelableHolderE;
-    _ZTVN7android2os16ServiceDebugInfoE;
-    _ZTVN7android2os17BnServiceCallbackE;
-    _ZTVN7android2os17BpServiceCallbackE;
-    _ZTVN7android2os17PersistableBundleE;
-    _ZTVN7android2os20ParcelFileDescriptorE;
-    _ZTVN7android6VectorIiEE;
-    _ZTVN7android6VectorINS_12ProcessState12handle_entryEEE;
-    _ZTVN7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEEE;
-    _ZTVN7android6VectorINS_8BpBinder8ObituaryEEE;
-    _ZTVN7android6VectorINS_8String16EEE;
-    _ZTVN7android6VectorIPNS_7BBinderEEE;
-    _ZTVN7android6VectorIPNS_7RefBase12weakref_typeEEE;
-    _ZTVN7android6VectorIPNS_7RefBaseEEE;
-    _ZTVN7android7BBinderE;
-    _ZTVN7android7content2pm18PackageChangeEventE;
-    _ZTVN7android7content2pm21IPackageManagerNativeE;
-    _ZTVN7android7content2pm22BnPackageManagerNativeE;
-    _ZTVN7android7content2pm22BpPackageManagerNativeE;
-    _ZTVN7android7content2pm22IPackageChangeObserverE;
-    _ZTVN7android7content2pm23BnPackageChangeObserverE;
-    _ZTVN7android7content2pm23BpPackageChangeObserverE;
-    _ZTVN7android7IBinderE;
-    _ZTVN7android7IMemoryE;
-    _ZTVN7android8BnMemoryE;
-    _ZTVN7android8BpBinderE;
-    _ZTVN7android8BpMemoryE;
-    _ZTVN7android9BpRefBaseE;
-    _ZTVN7android9HeapCacheE;
-    _ZTVN7android9RpcServerE;
-  local:
-    *;
-};
diff --git a/libs/binder/libbinder.arm32.vendor.map b/libs/binder/libbinder.arm32.vendor.map
deleted file mode 100644
index 5042414..0000000
--- a/libs/binder/libbinder.arm32.vendor.map
+++ /dev/null
@@ -1,1319 +0,0 @@
-# b/190148312: Populate with correct list of ABI symbols
-LIBBINDER {
-  global:
-    getBinderKernelReferences;
-    kDefaultDriver;
-    _ZN7android10AllocationC1ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEEij;
-    _ZN7android10AllocationC2ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEEij;
-    _ZN7android10AllocationD0Ev;
-    _ZN7android10AllocationD1Ev;
-    _ZN7android10AllocationD2Ev;
-    _ZN7android10IInterface8asBinderEPKS0_;
-    _ZN7android10IInterface8asBinderERKNS_2spIS0_EE;
-    _ZN7android10IInterfaceC2Ev;
-    _ZN7android10IInterfaceD0Ev;
-    _ZN7android10IInterfaceD1Ev;
-    _ZN7android10IInterfaceD2Ev;
-    _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEEij;
-    _ZN7android10MemoryBaseC2ERKNS_2spINS_11IMemoryHeapEEEij;
-    _ZN7android10MemoryBaseD0Ev;
-    _ZN7android10MemoryBaseD1Ev;
-    _ZN7android10MemoryBaseD2Ev;
-    _ZN7android10RpcAddress14readFromParcelERKNS_6ParcelE;
-    _ZN7android10RpcAddress15fromRawEmbeddedEPKNS_14RpcWireAddressE;
-    _ZN7android10RpcAddress4zeroEv;
-    _ZN7android10RpcAddress6uniqueEv;
-    _ZN7android10RpcAddressC1Ev;
-    _ZN7android10RpcAddressC2Ev;
-    _ZN7android10RpcAddressD1Ev;
-    _ZN7android10RpcAddressD2Ev;
-    _ZN7android10RpcSession12setForServerERKNS_2wpINS_9RpcServerEEEi;
-    _ZN7android10RpcSession13getRootObjectEv;
-    _ZN7android10RpcSession13sendDecStrongERKNS_10RpcAddressE;
-    _ZN7android10RpcSession15setupInetClientEPKcj;
-    _ZN7android10RpcSession15terminateLockedEv;
-    _ZN7android10RpcSession16setupVsockClientEjj;
-    _ZN7android10RpcSession17setupSocketClientERKNS_16RpcSocketAddressE;
-    _ZN7android10RpcSession19addClientConnectionENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession19ExclusiveConnection14findConnectionEiPNS_2spINS0_13RpcConnectionEEES5_RNSt3__16vectorIS4_NS6_9allocatorIS4_EEEEj;
-    _ZN7android10RpcSession19ExclusiveConnectionC1ERKNS_2spIS0_EENS0_13ConnectionUseE;
-    _ZN7android10RpcSession19ExclusiveConnectionC2ERKNS_2spIS0_EENS0_13ConnectionUseE;
-    _ZN7android10RpcSession19ExclusiveConnectionD1Ev;
-    _ZN7android10RpcSession19ExclusiveConnectionD2Ev;
-    _ZN7android10RpcSession19getRemoteMaxThreadsEPj;
-    _ZN7android10RpcSession20setupOneSocketClientERKNS_16RpcSocketAddressEi;
-    _ZN7android10RpcSession21setupUnixDomainClientEPKc;
-    _ZN7android10RpcSession22addNullDebuggingClientEv;
-    _ZN7android10RpcSession22removeServerConnectionERKNS_2spINS0_13RpcConnectionEEE;
-    _ZN7android10RpcSession24assignServerToThisThreadENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession4joinENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession4makeEv;
-    _ZN7android10RpcSession6readIdEv;
-    _ZN7android10RpcSession6serverEv;
-    _ZN7android10RpcSession7preJoinENSt3__16threadE;
-    _ZN7android10RpcSession8transactERKNS_10RpcAddressEjRKNS_6ParcelEPS4_j;
-    _ZN7android10RpcSessionC1Ev;
-    _ZN7android10RpcSessionC2Ev;
-    _ZN7android10RpcSessionD0Ev;
-    _ZN7android10RpcSessionD1Ev;
-    _ZN7android10RpcSessionD2Ev;
-    _ZN7android10TextOutputC2Ev;
-    _ZN7android10TextOutputD0Ev;
-    _ZN7android10TextOutputD1Ev;
-    _ZN7android10TextOutputD2Ev;
-    _ZN7android10zeroMemoryEPhj;
-    _ZN7android11BnInterfaceINS_11IMemoryHeapEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_14IShellCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_15IResultReceiverEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os15IClientCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os15IServiceManagerEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os16IServiceCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7content2pm21IPackageManagerNativeEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7content2pm22IPackageChangeObserverEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7IMemoryEE10onAsBinderEv;
-    _ZN7android11IMemoryHeap10descriptorE;
-    _ZN7android11IMemoryHeap11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android11IMemoryHeap12default_implE;
-    _ZN7android11IMemoryHeap14getDefaultImplEv;
-    _ZN7android11IMemoryHeap14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android11IMemoryHeapC2Ev;
-    _ZN7android11IMemoryHeapD0Ev;
-    _ZN7android11IMemoryHeapD1Ev;
-    _ZN7android11IMemoryHeapD2Ev;
-    _ZN7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android12BnMemoryHeapC2Ev;
-    _ZN7android12BnMemoryHeapD0Ev;
-    _ZN7android12BnMemoryHeapD1Ev;
-    _ZN7android12BnMemoryHeapD2Ev;
-    _ZN7android12BpMemoryHeapC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android12BpMemoryHeapC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android12BpMemoryHeapD0Ev;
-    _ZN7android12BpMemoryHeapD1Ev;
-    _ZN7android12BpMemoryHeapD2Ev;
-    _ZN7android12gTextBuffersE;
-    _ZN7android12MemoryDealer10deallocateEj;
-    _ZN7android12MemoryDealer22getAllocationAlignmentEv;
-    _ZN7android12MemoryDealer8allocateEj;
-    _ZN7android12MemoryDealerC1EjPKcj;
-    _ZN7android12MemoryDealerC2EjPKcj;
-    _ZN7android12MemoryDealerD0Ev;
-    _ZN7android12MemoryDealerD1Ev;
-    _ZN7android12MemoryDealerD2Ev;
-    _ZN7android12printHexDataEiPKvjjijbPFvPvPKcES2_;
-    _ZN7android12ProcessState10selfOrNullEv;
-    _ZN7android12ProcessState13expungeHandleEiPNS_7IBinderE;
-    _ZN7android12ProcessState13getDriverNameEv;
-    _ZN7android12ProcessState14initWithDriverEPKc;
-    _ZN7android12ProcessState15startThreadPoolEv;
-    _ZN7android12ProcessState16getContextObjectERKNS_2spINS_7IBinderEEE;
-    _ZN7android12ProcessState17spawnPooledThreadEb;
-    _ZN7android12ProcessState18giveThreadPoolNameEv;
-    _ZN7android12ProcessState18lookupHandleLockedEi;
-    _ZN7android12ProcessState18setCallRestrictionENS0_15CallRestrictionE;
-    _ZN7android12ProcessState19getKernelReferencesEjPj;
-    _ZN7android12ProcessState20becomeContextManagerEv;
-    _ZN7android12ProcessState20makeBinderThreadNameEv;
-    _ZN7android12ProcessState23getStrongProxyForHandleEi;
-    _ZN7android12ProcessState24getStrongRefCountForNodeERKNS_2spINS_8BpBinderEEE;
-    _ZN7android12ProcessState25enableOnewaySpamDetectionEb;
-    _ZN7android12ProcessState27setThreadPoolMaxThreadCountEj;
-    _ZN7android12ProcessState4initEPKcb;
-    _ZN7android12ProcessState4selfEv;
-    _ZN7android12ProcessStateC1EPKc;
-    _ZN7android12ProcessStateC2EPKc;
-    _ZN7android12ProcessStateD0Ev;
-    _ZN7android12ProcessStateD1Ev;
-    _ZN7android12ProcessStateD2Ev;
-    _ZN7android13printTypeCodeEjPFvPvPKcES0_;
-    _ZN7android14IPCThreadState10freeBufferEPNS_6ParcelEPKhjPKyj;
-    _ZN7android14IPCThreadState10selfOrNullEv;
-    _ZN7android14IPCThreadState11clearCallerEv;
-    _ZN7android14IPCThreadState11stopProcessEb;
-    _ZN7android14IPCThreadState12setupPollingEPi;
-    _ZN7android14IPCThreadState13decWeakHandleEi;
-    _ZN7android14IPCThreadState13expungeHandleEiPNS_7IBinderE;
-    _ZN7android14IPCThreadState13flushCommandsEv;
-    _ZN7android14IPCThreadState13flushIfNeededEv;
-    _ZN7android14IPCThreadState13incWeakHandleEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState14clearLastErrorEv;
-    _ZN7android14IPCThreadState14executeCommandEi;
-    _ZN7android14IPCThreadState14joinThreadPoolEb;
-    _ZN7android14IPCThreadState14talkWithDriverEb;
-    _ZN7android14IPCThreadState15decStrongHandleEi;
-    _ZN7android14IPCThreadState15incStrongHandleEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState15waitForResponseEPNS_6ParcelEPi;
-    _ZN7android14IPCThreadState16threadDestructorEPv;
-    _ZN7android14IPCThreadState18setCallRestrictionENS_12ProcessState15CallRestrictionE;
-    _ZN7android14IPCThreadState19setStrictModePolicyEi;
-    _ZN7android14IPCThreadState19setTheContextObjectERKNS_2spINS_7BBinderEEE;
-    _ZN7android14IPCThreadState20clearCallingIdentityEv;
-    _ZN7android14IPCThreadState20getAndExecuteCommandEv;
-    _ZN7android14IPCThreadState20getProcessFreezeInfoEiPbS1_;
-    _ZN7android14IPCThreadState20handlePolledCommandsEv;
-    _ZN7android14IPCThreadState20processPendingDerefsEv;
-    _ZN7android14IPCThreadState20writeTransactionDataEijijRKNS_6ParcelEPi;
-    _ZN7android14IPCThreadState22attemptIncStrongHandleEi;
-    _ZN7android14IPCThreadState22clearCallingWorkSourceEv;
-    _ZN7android14IPCThreadState22clearDeathNotificationEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState22processPostWriteDerefsEv;
-    _ZN7android14IPCThreadState22restoreCallingIdentityEx;
-    _ZN7android14IPCThreadState23setCallingWorkSourceUidEj;
-    _ZN7android14IPCThreadState24clearPropagateWorkSourceEv;
-    _ZN7android14IPCThreadState24requestDeathNotificationEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState24restoreCallingWorkSourceEx;
-    _ZN7android14IPCThreadState25blockUntilThreadAvailableEv;
-    _ZN7android14IPCThreadState27disableBackgroundSchedulingEb;
-    _ZN7android14IPCThreadState28backgroundSchedulingDisabledEv;
-    _ZN7android14IPCThreadState29setLastTransactionBinderFlagsEi;
-    _ZN7android14IPCThreadState41setCallingWorkSourceUidWithoutPropagationEj;
-    _ZN7android14IPCThreadState4selfEv;
-    _ZN7android14IPCThreadState6freezeEibj;
-    _ZN7android14IPCThreadState7processEv;
-    _ZN7android14IPCThreadState8shutdownEv;
-    _ZN7android14IPCThreadState8transactEijRKNS_6ParcelEPS1_j;
-    _ZN7android14IPCThreadState9sendReplyERKNS_6ParcelEj;
-    _ZN7android14IPCThreadStateC1Ev;
-    _ZN7android14IPCThreadStateC2Ev;
-    _ZN7android14IPCThreadStateD1Ev;
-    _ZN7android14IPCThreadStateD2Ev;
-    _ZN7android14IShellCallback10descriptorE;
-    _ZN7android14IShellCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android14IShellCallback12default_implE;
-    _ZN7android14IShellCallback14getDefaultImplEv;
-    _ZN7android14IShellCallback14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android14IShellCallbackC2Ev;
-    _ZN7android14IShellCallbackD0Ev;
-    _ZN7android14IShellCallbackD1Ev;
-    _ZN7android14IShellCallbackD2Ev;
-    _ZN7android14MemoryHeapBase4initEiPvjiPKc;
-    _ZN7android14MemoryHeapBase5mapfdEibjl;
-    _ZN7android14MemoryHeapBase7disposeEv;
-    _ZN7android14MemoryHeapBaseC1Eijjl;
-    _ZN7android14MemoryHeapBaseC1EjjPKc;
-    _ZN7android14MemoryHeapBaseC1EPKcjj;
-    _ZN7android14MemoryHeapBaseC1Ev;
-    _ZN7android14MemoryHeapBaseC2Eijjl;
-    _ZN7android14MemoryHeapBaseC2EjjPKc;
-    _ZN7android14MemoryHeapBaseC2EPKcjj;
-    _ZN7android14MemoryHeapBaseC2Ev;
-    _ZN7android14MemoryHeapBaseD0Ev;
-    _ZN7android14MemoryHeapBaseD1Ev;
-    _ZN7android14MemoryHeapBaseD2Ev;
-    _ZN7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android15IResultReceiver10descriptorE;
-    _ZN7android15IResultReceiver11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android15IResultReceiver12default_implE;
-    _ZN7android15IResultReceiver14getDefaultImplEv;
-    _ZN7android15IResultReceiver14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android15IResultReceiverC2Ev;
-    _ZN7android15IResultReceiverD0Ev;
-    _ZN7android15IResultReceiverD1Ev;
-    _ZN7android15IResultReceiverD2Ev;
-    _ZN7android15IServiceManagerC2Ev;
-    _ZN7android15IServiceManagerD0Ev;
-    _ZN7android15IServiceManagerD1Ev;
-    _ZN7android15IServiceManagerD2Ev;
-    _ZN7android15stringForIndentEi;
-    _ZN7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android18BufferedTextOutput10moveIndentEi;
-    _ZN7android18BufferedTextOutput10pushBundleEv;
-    _ZN7android18BufferedTextOutput5printEPKcj;
-    _ZN7android18BufferedTextOutput9popBundleEv;
-    _ZN7android18BufferedTextOutputC2Ej;
-    _ZN7android18BufferedTextOutputD0Ev;
-    _ZN7android18BufferedTextOutputD1Ev;
-    _ZN7android18BufferedTextOutputD2Ev;
-    _ZN7android18ServiceManagerShim10addServiceERKNS_8String16ERKNS_2spINS_7IBinderEEEbi;
-    _ZN7android18ServiceManagerShim10isDeclaredERKNS_8String16E;
-    _ZN7android18ServiceManagerShim12listServicesEi;
-    _ZN7android18ServiceManagerShim14waitForServiceERKNS_8String16E;
-    _ZN7android18ServiceManagerShim16updatableViaApexERKNS_8String16E;
-    _ZN7android18ServiceManagerShim20getDeclaredInstancesERKNS_8String16E;
-    _ZN7android18ServiceManagerShimC1ERKNS_2spINS_2os15IServiceManagerEEE;
-    _ZN7android18ServiceManagerShimC2ERKNS_2spINS_2os15IServiceManagerEEE;
-    _ZN7android18the_context_objectE;
-    _ZN7android21defaultServiceManagerEv;
-    _ZN7android22SimpleBestFitAllocator10deallocateEj;
-    _ZN7android22SimpleBestFitAllocator12kMemoryAlignE;
-    _ZN7android22SimpleBestFitAllocator5allocEjj;
-    _ZN7android22SimpleBestFitAllocator7deallocEj;
-    _ZN7android22SimpleBestFitAllocator8allocateEjj;
-    _ZN7android22SimpleBestFitAllocatorC1Ej;
-    _ZN7android22SimpleBestFitAllocatorC2Ej;
-    _ZN7android22SimpleBestFitAllocatorD1Ev;
-    _ZN7android22SimpleBestFitAllocatorD2Ev;
-    _ZN7android24setDefaultServiceManagerERKNS_2spINS_15IServiceManagerEEE;
-    _ZN7android2os15IClientCallback10descriptorE;
-    _ZN7android2os15IClientCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os15IClientCallback12default_implE;
-    _ZN7android2os15IClientCallback14getDefaultImplEv;
-    _ZN7android2os15IClientCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os15IClientCallbackC2Ev;
-    _ZN7android2os15IClientCallbackD0Ev;
-    _ZN7android2os15IClientCallbackD1Ev;
-    _ZN7android2os15IClientCallbackD2Ev;
-    _ZN7android2os15IServiceManager10descriptorE;
-    _ZN7android2os15IServiceManager11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os15IServiceManager12default_implE;
-    _ZN7android2os15IServiceManager14getDefaultImplEv;
-    _ZN7android2os15IServiceManager14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os15IServiceManagerC2Ev;
-    _ZN7android2os15IServiceManagerD0Ev;
-    _ZN7android2os15IServiceManagerD1Ev;
-    _ZN7android2os15IServiceManagerD2Ev;
-    _ZN7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os16BnClientCallbackC2Ev;
-    _ZN7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os16BnServiceManagerC2Ev;
-    _ZN7android2os16BpClientCallback9onClientsERKNS_2spINS_7IBinderEEEb;
-    _ZN7android2os16BpClientCallbackC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpClientCallbackC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager10addServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEEbi;
-    _ZN7android2os16BpServiceManager10getServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager10isDeclaredERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPb;
-    _ZN7android2os16BpServiceManager12checkServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager12listServicesEiPNSt3__16vectorINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS7_IS9_EEEE;
-    _ZN7android2os16BpServiceManager16updatableViaApexERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_8optionalIS8_EE;
-    _ZN7android2os16BpServiceManager19getServiceDebugInfoEPNSt3__16vectorINS0_16ServiceDebugInfoENS2_9allocatorIS4_EEEE;
-    _ZN7android2os16BpServiceManager20getDeclaredInstancesERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_6vectorIS8_NS6_IS8_EEEE;
-    _ZN7android2os16BpServiceManager20tryUnregisterServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager22registerClientCallbackERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEERKNSB_INS0_15IClientCallbackEEE;
-    _ZN7android2os16BpServiceManager24registerForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
-    _ZN7android2os16BpServiceManager26unregisterForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
-    _ZN7android2os16BpServiceManagerC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManagerC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16IServiceCallback10descriptorE;
-    _ZN7android2os16IServiceCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16IServiceCallback12default_implE;
-    _ZN7android2os16IServiceCallback14getDefaultImplEv;
-    _ZN7android2os16IServiceCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os16IServiceCallbackC2Ev;
-    _ZN7android2os16IServiceCallbackD0Ev;
-    _ZN7android2os16IServiceCallbackD1Ev;
-    _ZN7android2os16IServiceCallbackD2Ev;
-    _ZN7android2os16ParcelableHolder14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os16ServiceDebugInfo14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os17BnServiceCallbackC2Ev;
-    _ZN7android2os17BpServiceCallback14onRegistrationERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17BpServiceCallbackC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17BpServiceCallbackC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17PersistableBundle10putBooleanERKNS_8String16Eb;
-    _ZN7android2os17PersistableBundle12putIntVectorERKNS_8String16ERKNSt3__16vectorIiNS5_9allocatorIiEEEE;
-    _ZN7android2os17PersistableBundle13putLongVectorERKNS_8String16ERKNSt3__16vectorIxNS5_9allocatorIxEEEE;
-    _ZN7android2os17PersistableBundle14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os17PersistableBundle15putDoubleVectorERKNS_8String16ERKNSt3__16vectorIdNS5_9allocatorIdEEEE;
-    _ZN7android2os17PersistableBundle15putStringVectorERKNS_8String16ERKNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
-    _ZN7android2os17PersistableBundle16putBooleanVectorERKNS_8String16ERKNSt3__16vectorIbNS5_9allocatorIbEEEE;
-    _ZN7android2os17PersistableBundle19readFromParcelInnerEPKNS_6ParcelEj;
-    _ZN7android2os17PersistableBundle20putPersistableBundleERKNS_8String16ERKS1_;
-    _ZN7android2os17PersistableBundle5eraseERKNS_8String16E;
-    _ZN7android2os17PersistableBundle6putIntERKNS_8String16Ei;
-    _ZN7android2os17PersistableBundle7putLongERKNS_8String16Ex;
-    _ZN7android2os17PersistableBundle9putDoubleERKNS_8String16Ed;
-    _ZN7android2os17PersistableBundle9putStringERKNS_8String16ES4_;
-    _ZN7android2os20ParcelFileDescriptor14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os20ParcelFileDescriptorC1ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
-    _ZN7android2os20ParcelFileDescriptorC1Ev;
-    _ZN7android2os20ParcelFileDescriptorC2ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
-    _ZN7android2os20ParcelFileDescriptorC2Ev;
-    _ZN7android2os20ParcelFileDescriptorD0Ev;
-    _ZN7android2os20ParcelFileDescriptorD1Ev;
-    _ZN7android2os20ParcelFileDescriptorD2Ev;
-    _ZN7android4aerrE;
-    _ZN7android4alogE;
-    _ZN7android4aoutE;
-    _ZN7android6binder20LazyServiceRegistrar10reRegisterEv;
-    _ZN7android6binder20LazyServiceRegistrar11getInstanceEv;
-    _ZN7android6binder20LazyServiceRegistrar12forcePersistEb;
-    _ZN7android6binder20LazyServiceRegistrar13tryUnregisterEv;
-    _ZN7android6binder20LazyServiceRegistrar15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEbi;
-    _ZN7android6binder20LazyServiceRegistrar25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
-    _ZN7android6binder20LazyServiceRegistrarC1Ev;
-    _ZN7android6binder20LazyServiceRegistrarC2Ev;
-    _ZN7android6binder6Status11fromStatusTEi;
-    _ZN7android6binder6Status12setExceptionEiRKNS_7String8E;
-    _ZN7android6binder6Status14readFromParcelERKNS_6ParcelE;
-    _ZN7android6binder6Status14setFromStatusTEi;
-    _ZN7android6binder6Status17exceptionToStringEi;
-    _ZN7android6binder6Status17fromExceptionCodeEi;
-    _ZN7android6binder6Status17fromExceptionCodeEiPKc;
-    _ZN7android6binder6Status17fromExceptionCodeEiRKNS_7String8E;
-    _ZN7android6binder6Status23setServiceSpecificErrorEiRKNS_7String8E;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEi;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEiPKc;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEiRKNS_7String8E;
-    _ZN7android6binder6Status2okEv;
-    _ZN7android6binder6StatusC1Eii;
-    _ZN7android6binder6StatusC1EiiRKNS_7String8E;
-    _ZN7android6binder6StatusC2Eii;
-    _ZN7android6binder6StatusC2EiiRKNS_7String8E;
-    _ZN7android6binder8internal21ClientCounterCallback10reRegisterEv;
-    _ZN7android6binder8internal21ClientCounterCallback12forcePersistEb;
-    _ZN7android6binder8internal21ClientCounterCallback13tryUnregisterEv;
-    _ZN7android6binder8internal21ClientCounterCallback15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEbi;
-    _ZN7android6binder8internal21ClientCounterCallback25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
-    _ZN7android6binder8internal21ClientCounterCallbackC1Ev;
-    _ZN7android6binder8internal21ClientCounterCallbackC2Ev;
-    _ZN7android6Parcel10appendFromEPKS0_jj;
-    _ZN7android6Parcel10markForRpcERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android6Parcel10writeFloatEf;
-    _ZN7android6Parcel10writeInt32Ei;
-    _ZN7android6Parcel10writeInt64Ex;
-    _ZN7android6Parcel11compareDataERKS0_;
-    _ZN7android6Parcel11finishWriteEj;
-    _ZN7android6Parcel11setDataSizeEj;
-    _ZN7android6Parcel11writeDoubleEd;
-    _ZN7android6Parcel11writeObjectERK18flat_binder_objectb;
-    _ZN7android6Parcel11writeUint32Ej;
-    _ZN7android6Parcel11writeUint64Ey;
-    _ZN7android6Parcel12pushAllowFdsEb;
-    _ZN7android6Parcel12restartWriteEj;
-    _ZN7android6Parcel12writeCStringEPKc;
-    _ZN7android6Parcel12writeInplaceEj;
-    _ZN7android6Parcel12writePointerEj;
-    _ZN7android6Parcel12writeString8EPKcj;
-    _ZN7android6Parcel12writeString8ERKNS_7String8E;
-    _ZN7android6Parcel13continueWriteEj;
-    _ZN7android6Parcel13flattenBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel13markForBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel13writeString16EPKDsj;
-    _ZN7android6Parcel13writeString16ERKNS_8String16E;
-    _ZN7android6Parcel13writeString16ERKNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
-    _ZN7android6Parcel13writeString16ERKNSt3__18optionalINS_8String16EEE;
-    _ZN7android6Parcel13writeUnpaddedEPKvj;
-    _ZN7android6Parcel14acquireObjectsEv;
-    _ZN7android6Parcel14freeDataNoInitEv;
-    _ZN7android6Parcel14releaseObjectsEv;
-    _ZN7android6Parcel14writeByteArrayEjPKh;
-    _ZN7android6Parcel15restoreAllowFdsEb;
-    _ZN7android6Parcel15setDataCapacityEj;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__16vectorIbNS1_9allocatorIbEEEE;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIaNS1_9allocatorIaEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIhNS1_9allocatorIhEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
-    _ZN7android6Parcel15writeInt32ArrayEjPKi;
-    _ZN7android6Parcel15writeParcelableERKNS_10ParcelableE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__16vectorIfNS1_9allocatorIfEEEE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__16vectorIiNS1_9allocatorIiEEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__110unique_ptrINS1_6vectorIxNS1_9allocatorIxEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__16vectorIxNS1_9allocatorIxEEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__18optionalINS1_6vectorIxNS1_9allocatorIxEEEEEE;
-    _ZN7android6Parcel16writeNoExceptionEv;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__16vectorIdNS1_9allocatorIdEEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
-    _ZN7android6Parcel17writeNativeHandleEPK13native_handle;
-    _ZN7android6Parcel17writeStrongBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__110unique_ptrINS1_6vectorIyNS1_9allocatorIyEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__16vectorIyNS1_9allocatorIyEEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__18optionalINS1_6vectorIyNS1_9allocatorIyEEEEEE;
-    _ZN7android6Parcel18getGlobalAllocSizeEv;
-    _ZN7android6Parcel19finishFlattenBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel19getGlobalAllocCountEv;
-    _ZN7android6Parcel19ipcSetDataReferenceEPKhjPKyjPFvPS0_S2_jS4_jE;
-    _ZN7android6Parcel19writeFileDescriptorEib;
-    _ZN7android6Parcel19writeInterfaceTokenEPKDsj;
-    _ZN7android6Parcel19writeInterfaceTokenERKNS_8String16E;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
-    _ZN7android6Parcel20closeFileDescriptorsEv;
-    _ZN7android6Parcel22writeDupFileDescriptorEi;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
-    _ZN7android6Parcel25writeParcelFileDescriptorEib;
-    _ZN7android6Parcel25writeUniqueFileDescriptorERKNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android6Parcel26writeRawNullableParcelableEPKNS_10ParcelableE;
-    _ZN7android6Parcel27replaceCallingWorkSourceUidEj;
-    _ZN7android6Parcel28writeDupParcelFileDescriptorEi;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
-    _ZN7android6Parcel35writeDupImmutableBlobFileDescriptorEi;
-    _ZN7android6Parcel4Blob4initEiPvjb;
-    _ZN7android6Parcel4Blob5clearEv;
-    _ZN7android6Parcel4Blob7releaseEv;
-    _ZN7android6Parcel4BlobC1Ev;
-    _ZN7android6Parcel4BlobC2Ev;
-    _ZN7android6Parcel4BlobD1Ev;
-    _ZN7android6Parcel4BlobD2Ev;
-    _ZN7android6Parcel5writeEPKvj;
-    _ZN7android6Parcel5writeERKNS0_26FlattenableHelperInterfaceE;
-    _ZN7android6Parcel7setDataEPKhj;
-    _ZN7android6Parcel8freeDataEv;
-    _ZN7android6Parcel8growDataEj;
-    _ZN7android6Parcel8setErrorEi;
-    _ZN7android6Parcel9initStateEv;
-    _ZN7android6Parcel9writeBlobEjbPNS0_12WritableBlobE;
-    _ZN7android6Parcel9writeBoolEb;
-    _ZN7android6Parcel9writeByteEa;
-    _ZN7android6Parcel9writeCharEDs;
-    _ZN7android6ParcelC1Ev;
-    _ZN7android6ParcelC2Ev;
-    _ZN7android6ParcelD1Ev;
-    _ZN7android6ParcelD2Ev;
-    _ZN7android7BBinder10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android7BBinder10pingBinderEv;
-    _ZN7android7BBinder11getDebugPidEv;
-    _ZN7android7BBinder11isInheritRtEv;
-    _ZN7android7BBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
-    _ZN7android7BBinder11localBinderEv;
-    _ZN7android7BBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
-    _ZN7android7BBinder12detachObjectEPKv;
-    _ZN7android7BBinder12getExtensionEv;
-    _ZN7android7BBinder12setExtensionERKNS_2spINS_7IBinderEEE;
-    _ZN7android7BBinder12setInheritRtEb;
-    _ZN7android7BBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
-    _ZN7android7BBinder15isRequestingSidEv;
-    _ZN7android7BBinder16setRequestingSidEb;
-    _ZN7android7BBinder17getOrCreateExtrasEv;
-    _ZN7android7BBinder21getMinSchedulerPolicyEv;
-    _ZN7android7BBinder21setMinSchedulerPolicyEii;
-    _ZN7android7BBinder23getMinSchedulerPriorityEv;
-    _ZN7android7BBinder4dumpEiRKNS_6VectorINS_8String16EEE;
-    _ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j;
-    _ZN7android7BBinderC1Ev;
-    _ZN7android7BBinderC2Ev;
-    _ZN7android7BBinderD0Ev;
-    _ZN7android7BBinderD1Ev;
-    _ZN7android7BBinderD2Ev;
-    _ZN7android7content2pm18PackageChangeEvent14readFromParcelEPKNS_6ParcelE;
-    _ZN7android7content2pm21IPackageManagerNative10descriptorE;
-    _ZN7android7content2pm21IPackageManagerNative11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm21IPackageManagerNative12default_implE;
-    _ZN7android7content2pm21IPackageManagerNative14getDefaultImplEv;
-    _ZN7android7content2pm21IPackageManagerNative14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
-    _ZN7android7content2pm21IPackageManagerNativeC2Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD0Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD1Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD2Ev;
-    _ZN7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZN7android7content2pm22BnPackageManagerNativeC2Ev;
-    _ZN7android7content2pm22BpPackageManagerNative14getAllPackagesEPNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEE;
-    _ZN7android7content2pm22BpPackageManagerNative15getNamesForUidsERKNSt3__16vectorIiNS3_9allocatorIiEEEEPNS4_INS3_12basic_stringIcNS3_11char_traitsIcEENS5_IcEEEENS5_ISE_EEEE;
-    _ZN7android7content2pm22BpPackageManagerNative16getLocationFlagsERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPi;
-    _ZN7android7content2pm22BpPackageManagerNative16hasSystemFeatureERKNS_8String16EiPb;
-    _ZN7android7content2pm22BpPackageManagerNative19isPackageDebuggableERKNS_8String16EPb;
-    _ZN7android7content2pm22BpPackageManagerNative22getInstallerForPackageERKNS_8String16EPNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative24getVersionCodeForPackageERKNS_8String16EPx;
-    _ZN7android7content2pm22BpPackageManagerNative27hasSha256SigningCertificateERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKNS3_6vectorIhNS7_IhEEEEPb;
-    _ZN7android7content2pm22BpPackageManagerNative28getModuleMetadataPackageNameEPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative29getTargetSdkVersionForPackageERKNS_8String16EPi;
-    _ZN7android7content2pm22BpPackageManagerNative29isAudioPlaybackCaptureAllowedERKNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEEPNS4_IbNS8_IbEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative29registerPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
-    _ZN7android7content2pm22BpPackageManagerNative31unregisterPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
-    _ZN7android7content2pm22BpPackageManagerNativeC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22BpPackageManagerNativeC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22IPackageChangeObserver10descriptorE;
-    _ZN7android7content2pm22IPackageChangeObserver11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22IPackageChangeObserver12default_implE;
-    _ZN7android7content2pm22IPackageChangeObserver14getDefaultImplEv;
-    _ZN7android7content2pm22IPackageChangeObserver14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
-    _ZN7android7content2pm22IPackageChangeObserverC2Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD0Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD1Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD2Ev;
-    _ZN7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZN7android7content2pm23BnPackageChangeObserverC2Ev;
-    _ZN7android7content2pm23BpPackageChangeObserver16onPackageChangedERKNS1_18PackageChangeEventE;
-    _ZN7android7content2pm23BpPackageChangeObserverC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm23BpPackageChangeObserverC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7HexDumpC1EPKvjj;
-    _ZN7android7HexDumpC2EPKvjj;
-    _ZN7android7IBinder11getDebugPidEPi;
-    _ZN7android7IBinder11localBinderEv;
-    _ZN7android7IBinder12getExtensionEPNS_2spIS0_EE;
-    _ZN7android7IBinder12remoteBinderEv;
-    _ZN7android7IBinder12shellCommandERKNS_2spIS0_EEiiiRNS_6VectorINS_8String16EEERKNS1_INS_14IShellCallbackEEERKNS1_INS_15IResultReceiverEEE;
-    _ZN7android7IBinder19queryLocalInterfaceERKNS_8String16E;
-    _ZN7android7IBinderC2Ev;
-    _ZN7android7IBinderD0Ev;
-    _ZN7android7IBinderD1Ev;
-    _ZN7android7IBinderD2Ev;
-    _ZN7android7IMemory10descriptorE;
-    _ZN7android7IMemory11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7IMemory12default_implE;
-    _ZN7android7IMemory14getDefaultImplEv;
-    _ZN7android7IMemory14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android7IMemoryC2Ev;
-    _ZN7android7IMemoryD0Ev;
-    _ZN7android7IMemoryD1Ev;
-    _ZN7android7IMemoryD2Ev;
-    _ZN7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android8BnMemoryC2Ev;
-    _ZN7android8BnMemoryD0Ev;
-    _ZN7android8BnMemoryD1Ev;
-    _ZN7android8BnMemoryD2Ev;
-    _ZN7android8BpBinder10onFirstRefEv;
-    _ZN7android8BpBinder10pingBinderEv;
-    _ZN7android8BpBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
-    _ZN7android8BpBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
-    _ZN7android8BpBinder12detachObjectEPKv;
-    _ZN7android8BpBinder12remoteBinderEv;
-    _ZN7android8BpBinder12sendObituaryEv;
-    _ZN7android8BpBinder12sTrackingMapE;
-    _ZN7android8BpBinder13getCountByUidERNS_6VectorIjEES3_;
-    _ZN7android8BpBinder13ObjectManager4killEv;
-    _ZN7android8BpBinder13ObjectManager6attachEPKvPvS4_PFvS3_S4_S4_E;
-    _ZN7android8BpBinder13ObjectManager6detachEPKv;
-    _ZN7android8BpBinder13ObjectManagerC1Ev;
-    _ZN7android8BpBinder13ObjectManagerC2Ev;
-    _ZN7android8BpBinder13ObjectManagerD1Ev;
-    _ZN7android8BpBinder13ObjectManagerD2Ev;
-    _ZN7android8BpBinder13sTrackingLockE;
-    _ZN7android8BpBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
-    _ZN7android8BpBinder14reportOneDeathERKNS0_8ObituaryE;
-    _ZN7android8BpBinder14sLimitCallbackE;
-    _ZN7android8BpBinder15onLastStrongRefEPKv;
-    _ZN7android8BpBinder15sNumTrackedUidsE;
-    _ZN7android8BpBinder16enableCountByUidEv;
-    _ZN7android8BpBinder16setLimitCallbackEPFviE;
-    _ZN7android8BpBinder17disableCountByUidEv;
-    _ZN7android8BpBinder18sCountByUidEnabledE;
-    _ZN7android8BpBinder19getBinderProxyCountEj;
-    _ZN7android8BpBinder20onIncStrongAttemptedEjPKv;
-    _ZN7android8BpBinder20setCountByUidEnabledEb;
-    _ZN7android8BpBinder26sBinderProxyThrottleCreateE;
-    _ZN7android8BpBinder29sBinderProxyCountLowWatermarkE;
-    _ZN7android8BpBinder29setBinderProxyCountWatermarksEii;
-    _ZN7android8BpBinder30sBinderProxyCountHighWatermarkE;
-    _ZN7android8BpBinder4dumpEiRKNS_6VectorINS_8String16EEE;
-    _ZN7android8BpBinder6createEi;
-    _ZN7android8BpBinder6createERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
-    _ZN7android8BpBinder8transactEjRKNS_6ParcelEPS1_j;
-    _ZN7android8BpBinderC1EONS0_12BinderHandleEi;
-    _ZN7android8BpBinderC1EONS0_9RpcHandleE;
-    _ZN7android8BpBinderC1EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
-    _ZN7android8BpBinderC2EONS0_12BinderHandleEi;
-    _ZN7android8BpBinderC2EONS0_9RpcHandleE;
-    _ZN7android8BpBinderC2EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
-    _ZN7android8BpBinderD0Ev;
-    _ZN7android8BpBinderD1Ev;
-    _ZN7android8BpBinderD2Ev;
-    _ZN7android8BpMemoryC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android8BpMemoryC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android8BpMemoryD0Ev;
-    _ZN7android8BpMemoryD1Ev;
-    _ZN7android8BpMemoryD2Ev;
-    _ZN7android8internal9Stability11getCategoryEPNS_7IBinderE;
-    _ZN7android8internal9Stability11levelStringENS1_5LevelE;
-    _ZN7android8internal9Stability13getLocalLevelEv;
-    _ZN7android8internal9Stability15isDeclaredLevelENS1_5LevelE;
-    _ZN7android8internal9Stability17debugLogStabilityERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability19markCompilationUnitEPNS_7IBinderE;
-    _ZN7android8internal9Stability22tryMarkCompilationUnitEPNS_7IBinderE;
-    _ZN7android8internal9Stability24requiresVintfDeclarationERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability25forceDowngradeToStabilityERKNS_2spINS_7IBinderEEENS1_5LevelE;
-    _ZN7android8internal9Stability30forceDowngradeToLocalStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability31forceDowngradeToSystemStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability31forceDowngradeToVendorStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability5checkENS1_8CategoryENS1_5LevelE;
-    _ZN7android8internal9Stability7setReprEPNS_7IBinderEij;
-    _ZN7android8internal9Stability8Category11debugStringEv;
-    _ZN7android8internal9Stability8markVndkEPNS_7IBinderE;
-    _ZN7android8internal9Stability9markVintfEPNS_7IBinderE;
-    _ZN7android8RpcState11CommandDataC1Ej;
-    _ZN7android8RpcState11CommandDataC2Ej;
-    _ZN7android8RpcState12countBindersEv;
-    _ZN7android8RpcState12getSessionIdERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPi;
-    _ZN7android8RpcState12waitForReplyERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPNS_6ParcelE;
-    _ZN7android8RpcState13getMaxThreadsERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPj;
-    _ZN7android8RpcState13getRootObjectERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android8RpcState13sendDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressE;
-    _ZN7android8RpcState15onBinderLeavingERKNS_2spINS_10RpcSessionEEERKNS1_INS_7IBinderEEEPNS_10RpcAddressE;
-    _ZN7android8RpcState15processTransactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState16onBinderEnteringERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
-    _ZN7android8RpcState16processDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState20getAndExecuteCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android8RpcState20processServerCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState23processTransactInternalERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEENS0_11CommandDataE;
-    _ZN7android8RpcState4dumpEv;
-    _ZN7android8RpcState6rpcRecERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPvj;
-    _ZN7android8RpcState7rpcSendERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPKvj;
-    _ZN7android8RpcState8transactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressEjRKNS_6ParcelERKNS_2spINS_10RpcSessionEEEPSA_j;
-    _ZN7android8RpcState9terminateEv;
-    _ZN7android8RpcStateC1Ev;
-    _ZN7android8RpcStateC2Ev;
-    _ZN7android8RpcStateD1Ev;
-    _ZN7android8RpcStateD2Ev;
-    _ZN7android9BpRefBase10onFirstRefEv;
-    _ZN7android9BpRefBase15onLastStrongRefEPKv;
-    _ZN7android9BpRefBase20onIncStrongAttemptedEjPKv;
-    _ZN7android9BpRefBaseC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android9BpRefBaseC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android9BpRefBaseD0Ev;
-    _ZN7android9BpRefBaseD1Ev;
-    _ZN7android9BpRefBaseD2Ev;
-    _ZN7android9HeapCache10binderDiedERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9HeapCache10dump_heapsEv;
-    _ZN7android9HeapCache8get_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9find_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9free_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9free_heapERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9HeapCacheC1Ev;
-    _ZN7android9HeapCacheC2Ev;
-    _ZN7android9HeapCacheD0Ev;
-    _ZN7android9HeapCacheD1Ev;
-    _ZN7android9HeapCacheD2Ev;
-    _ZN7android9hexStringEPKvj;
-    _ZN7android9RpcServer12listSessionsEv;
-    _ZN7android9RpcServer13getMaxThreadsEv;
-    _ZN7android9RpcServer13getRootObjectEv;
-    _ZN7android9RpcServer13releaseServerEv;
-    _ZN7android9RpcServer13setMaxThreadsEj;
-    _ZN7android9RpcServer13setRootObjectERKNS_2spINS_7IBinderEEE;
-    _ZN7android9RpcServer15setupInetServerEjPj;
-    _ZN7android9RpcServer16setupVsockServerEj;
-    _ZN7android9RpcServer17setRootObjectWeakERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9RpcServer17setupSocketServerERKNS_16RpcSocketAddressE;
-    _ZN7android9RpcServer19establishConnectionEONS_2spIS0_EENS_4base14unique_fd_implINS4_13DefaultCloserEEE;
-    _ZN7android9RpcServer19setupExternalServerENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android9RpcServer20onSessionTerminatingERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android9RpcServer21setupUnixDomainServerEPKc;
-    _ZN7android9RpcServer24numUninitializedSessionsEv;
-    _ZN7android9RpcServer4joinEv;
-    _ZN7android9RpcServer4makeEv;
-    _ZN7android9RpcServer61iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProductionEv;
-    _ZN7android9RpcServer9acceptOneEv;
-    _ZN7android9RpcServer9hasServerEv;
-    _ZN7android9RpcServerC1Ev;
-    _ZN7android9RpcServerC2Ev;
-    _ZN7android9RpcServerD0Ev;
-    _ZN7android9RpcServerD1Ev;
-    _ZN7android9RpcServerD2Ev;
-    _ZN7androidlsERNS_10TextOutputERKNS_7HexDumpE;
-    _ZN7androidlsERNS_10TextOutputERKNS_8TypeCodeE;
-    _ZN7androidlsIA15_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA24_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA2_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA34_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA3_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA43_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA4_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA5_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA8_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA9_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIjEERNS_10TextOutputES2_RKT_;
-    _ZN7androidlsINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEERNS_10TextOutputES9_RKT_;
-    _ZN7androidlsIPcEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIPvEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIyEERNS_10TextOutputES2_RKT_;
-    _ZNK7android10MemoryBase9getMemoryEPiPj;
-    _ZNK7android10RpcAddress13writeToParcelEPNS_6ParcelE;
-    _ZNK7android10RpcAddress15viewRawEmbeddedEv;
-    _ZNK7android10RpcAddress6isZeroEv;
-    _ZNK7android10RpcAddress8toStringEv;
-    _ZNK7android10RpcAddressltERKS0_;
-    _ZNK7android11IMemoryHeap22getInterfaceDescriptorEv;
-    _ZNK7android12BpMemoryHeap12assertMappedEv;
-    _ZNK7android12BpMemoryHeap18assertReallyMappedEv;
-    _ZNK7android12BpMemoryHeap7getBaseEv;
-    _ZNK7android12BpMemoryHeap7getSizeEv;
-    _ZNK7android12BpMemoryHeap8getFlagsEv;
-    _ZNK7android12BpMemoryHeap9getHeapIDEv;
-    _ZNK7android12BpMemoryHeap9getOffsetEv;
-    _ZNK7android12MemoryDealer4dumpEPKc;
-    _ZNK7android12MemoryDealer4heapEv;
-    _ZNK7android12MemoryDealer9allocatorEv;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_compareEPKvSA_;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_destroyEPvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE12do_constructEPvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE15do_move_forwardEPvPKvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE16do_move_backwardEPvPKvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE7do_copyEPvPKvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE8do_splatEPvPKvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_compareES3_S3_;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_destroyEPvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE12do_constructEPvj;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE15do_move_forwardEPvS3_j;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE16do_move_backwardEPvS3_j;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE7do_copyEPvS3_j;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE8do_splatEPvS3_j;
-    _ZNK7android14IPCThreadState13getCallingPidEv;
-    _ZNK7android14IPCThreadState13getCallingSidEv;
-    _ZNK7android14IPCThreadState13getCallingUidEv;
-    _ZNK7android14IPCThreadState18getCallRestrictionEv;
-    _ZNK7android14IPCThreadState19getStrictModePolicyEv;
-    _ZNK7android14IPCThreadState22getServingStackPointerEv;
-    _ZNK7android14IPCThreadState23getCallingWorkSourceUidEv;
-    _ZNK7android14IPCThreadState25shouldPropagateWorkSourceEv;
-    _ZNK7android14IPCThreadState29getLastTransactionBinderFlagsEv;
-    _ZNK7android14IShellCallback22getInterfaceDescriptorEv;
-    _ZNK7android14MemoryHeapBase7getBaseEv;
-    _ZNK7android14MemoryHeapBase7getSizeEv;
-    _ZNK7android14MemoryHeapBase8getFlagsEv;
-    _ZNK7android14MemoryHeapBase9getDeviceEv;
-    _ZNK7android14MemoryHeapBase9getHeapIDEv;
-    _ZNK7android14MemoryHeapBase9getOffsetEv;
-    _ZNK7android15IResultReceiver22getInterfaceDescriptorEv;
-    _ZNK7android15IServiceManager22getInterfaceDescriptorEv;
-    _ZNK7android18BufferedTextOutput9getBufferEv;
-    _ZNK7android18ServiceManagerShim10getServiceERKNS_8String16E;
-    _ZNK7android18ServiceManagerShim12checkServiceERKNS_8String16E;
-    _ZNK7android22SimpleBestFitAllocator4dumpEPKc;
-    _ZNK7android22SimpleBestFitAllocator4dumpERNS_7String8EPKc;
-    _ZNK7android22SimpleBestFitAllocator4sizeEv;
-    _ZNK7android22SimpleBestFitAllocator6dump_lEPKc;
-    _ZNK7android22SimpleBestFitAllocator6dump_lERNS_7String8EPKc;
-    _ZNK7android2os15IClientCallback22getInterfaceDescriptorEv;
-    _ZNK7android2os15IServiceManager22getInterfaceDescriptorEv;
-    _ZNK7android2os16IServiceCallback22getInterfaceDescriptorEv;
-    _ZNK7android2os16ParcelableHolder13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os16ServiceDebugInfo13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle10getBooleanERKNS_8String16EPb;
-    _ZNK7android2os17PersistableBundle10getIntKeysEv;
-    _ZNK7android2os17PersistableBundle11getLongKeysEv;
-    _ZNK7android2os17PersistableBundle12getIntVectorERKNS_8String16EPNSt3__16vectorIiNS5_9allocatorIiEEEE;
-    _ZNK7android2os17PersistableBundle13getDoubleKeysEv;
-    _ZNK7android2os17PersistableBundle13getLongVectorERKNS_8String16EPNSt3__16vectorIxNS5_9allocatorIxEEEE;
-    _ZNK7android2os17PersistableBundle13getStringKeysEv;
-    _ZNK7android2os17PersistableBundle13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle14getBooleanKeysEv;
-    _ZNK7android2os17PersistableBundle15getDoubleVectorERKNS_8String16EPNSt3__16vectorIdNS5_9allocatorIdEEEE;
-    _ZNK7android2os17PersistableBundle15getStringVectorERKNS_8String16EPNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
-    _ZNK7android2os17PersistableBundle16getBooleanVectorERKNS_8String16EPNSt3__16vectorIbNS5_9allocatorIbEEEE;
-    _ZNK7android2os17PersistableBundle16getIntVectorKeysEv;
-    _ZNK7android2os17PersistableBundle17getLongVectorKeysEv;
-    _ZNK7android2os17PersistableBundle18writeToParcelInnerEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle19getDoubleVectorKeysEv;
-    _ZNK7android2os17PersistableBundle19getStringVectorKeysEv;
-    _ZNK7android2os17PersistableBundle20getBooleanVectorKeysEv;
-    _ZNK7android2os17PersistableBundle20getPersistableBundleERKNS_8String16EPS1_;
-    _ZNK7android2os17PersistableBundle24getPersistableBundleKeysEv;
-    _ZNK7android2os17PersistableBundle4sizeEv;
-    _ZNK7android2os17PersistableBundle5emptyEv;
-    _ZNK7android2os17PersistableBundle6getIntERKNS_8String16EPi;
-    _ZNK7android2os17PersistableBundle7getLongERKNS_8String16EPx;
-    _ZNK7android2os17PersistableBundle9getDoubleERKNS_8String16EPd;
-    _ZNK7android2os17PersistableBundle9getStringERKNS_8String16EPS2_;
-    _ZNK7android2os20ParcelFileDescriptor13writeToParcelEPNS_6ParcelE;
-    _ZNK7android6binder6Status13writeToParcelEPNS_6ParcelE;
-    _ZNK7android6binder6Status9toString8Ev;
-    _ZNK7android6Parcel10errorCheckEv;
-    _ZNK7android6Parcel10ipcObjectsEv;
-    _ZNK7android6Parcel10readDoubleEPd;
-    _ZNK7android6Parcel10readDoubleEv;
-    _ZNK7android6Parcel10readObjectEb;
-    _ZNK7android6Parcel10readUint32EPj;
-    _ZNK7android6Parcel10readUint32Ev;
-    _ZNK7android6Parcel10readUint64EPy;
-    _ZNK7android6Parcel10readUint64Ev;
-    _ZNK7android6Parcel10scanForFdsEv;
-    _ZNK7android6Parcel11ipcDataSizeEv;
-    _ZNK7android6Parcel11readCStringEv;
-    _ZNK7android6Parcel11readInplaceEj;
-    _ZNK7android6Parcel11readPointerEPj;
-    _ZNK7android6Parcel11readPointerEv;
-    _ZNK7android6Parcel11readString8EPNS_7String8E;
-    _ZNK7android6Parcel11readString8Ev;
-    _ZNK7android6Parcel12dataCapacityEv;
-    _ZNK7android6Parcel12dataPositionEv;
-    _ZNK7android6Parcel12objectsCountEv;
-    _ZNK7android6Parcel12readString16EPNS_8String16E;
-    _ZNK7android6Parcel12readString16EPNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
-    _ZNK7android6Parcel12readString16EPNSt3__18optionalINS_8String16EEE;
-    _ZNK7android6Parcel12readString16Ev;
-    _ZNK7android6Parcel13markSensitiveEv;
-    _ZNK7android6Parcel14checkInterfaceEPNS_7IBinderE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__16vectorIbNS1_9allocatorIbEEEE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIaNS1_9allocatorIaEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIhNS1_9allocatorIhEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
-    _ZNK7android6Parcel14readParcelableEPNS_10ParcelableE;
-    _ZNK7android6Parcel15ipcObjectsCountEv;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__16vectorIfNS1_9allocatorIfEEEE;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__16vectorIiNS1_9allocatorIiEEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__110unique_ptrINS1_6vectorIxNS1_9allocatorIxEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__16vectorIxNS1_9allocatorIxEEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__18optionalINS1_6vectorIxNS1_9allocatorIxEEEEEE;
-    _ZNK7android6Parcel15setDataPositionEj;
-    _ZNK7android6Parcel15unflattenBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel16enforceInterfaceEPKDsjPNS_14IPCThreadStateE;
-    _ZNK7android6Parcel16enforceInterfaceERKNS_8String16EPNS_14IPCThreadStateE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__16vectorIdNS1_9allocatorIdEEEE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
-    _ZNK7android6Parcel16readNativeHandleEv;
-    _ZNK7android6Parcel16readStrongBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel16readStrongBinderEv;
-    _ZNK7android6Parcel16readStrongBinderINS_2os15IClientCallbackEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readStrongBinderINS_2os16IServiceCallbackEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readStrongBinderINS_7content2pm22IPackageChangeObserverEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__110unique_ptrINS1_6vectorIyNS1_9allocatorIyEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__16vectorIyNS1_9allocatorIyEEEE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__18optionalINS1_6vectorIyNS1_9allocatorIyEEEEEE;
-    _ZNK7android6Parcel16validateReadDataEj;
-    _ZNK7android6Parcel17getBlobAshmemSizeEv;
-    _ZNK7android6Parcel17getOpenAshmemSizeEv;
-    _ZNK7android6Parcel17readExceptionCodeEv;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
-    _ZNK7android6Parcel18hasFileDescriptorsEv;
-    _ZNK7android6Parcel18readFileDescriptorEv;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
-    _ZNK7android6Parcel18readString8InplaceEPj;
-    _ZNK7android6Parcel19readString16InplaceEPj;
-    _ZNK7android6Parcel21finishUnflattenBinderERKNS_2spINS_7IBinderEEEPS3_;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
-    _ZNK7android6Parcel24readCallingWorkSourceUidEv;
-    _ZNK7android6Parcel24readNullableStrongBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel24readParcelFileDescriptorEv;
-    _ZNK7android6Parcel24readUniqueFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
-    _ZNK7android6Parcel30readUniqueParcelFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZNK7android6Parcel37updateWorkSourceRequestHeaderPositionEv;
-    _ZNK7android6Parcel4dataEv;
-    _ZNK7android6Parcel4readEPvj;
-    _ZNK7android6Parcel4readERNS0_26FlattenableHelperInterfaceE;
-    _ZNK7android6Parcel5printERNS_10TextOutputEj;
-    _ZNK7android6Parcel7ipcDataEv;
-    _ZNK7android6Parcel8allowFdsEv;
-    _ZNK7android6Parcel8dataSizeEv;
-    _ZNK7android6Parcel8isForRpcEv;
-    _ZNK7android6Parcel8readBlobEjPNS0_12ReadableBlobE;
-    _ZNK7android6Parcel8readBoolEPb;
-    _ZNK7android6Parcel8readBoolEv;
-    _ZNK7android6Parcel8readByteEPa;
-    _ZNK7android6Parcel8readByteEv;
-    _ZNK7android6Parcel8readCharEPDs;
-    _ZNK7android6Parcel8readCharEv;
-    _ZNK7android6Parcel9dataAvailEv;
-    _ZNK7android6Parcel9readFloatEPf;
-    _ZNK7android6Parcel9readFloatEv;
-    _ZNK7android6Parcel9readInt32EPi;
-    _ZNK7android6Parcel9readInt32Ev;
-    _ZNK7android6Parcel9readInt64EPx;
-    _ZNK7android6Parcel9readInt64Ev;
-    _ZNK7android6VectorIiE10do_destroyEPvj;
-    _ZNK7android6VectorIiE12do_constructEPvj;
-    _ZNK7android6VectorIiE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorIiE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorIiE7do_copyEPvPKvj;
-    _ZNK7android6VectorIiE8do_splatEPvPKvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE10do_destroyEPvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE12do_constructEPvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE7do_copyEPvPKvj;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE8do_splatEPvPKvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE10do_destroyEPvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE12do_constructEPvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE7do_copyEPvPKvj;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE8do_splatEPvPKvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE10do_destroyEPvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE12do_constructEPvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE7do_copyEPvPKvj;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE8do_splatEPvPKvj;
-    _ZNK7android6VectorINS_8String16EE10do_destroyEPvj;
-    _ZNK7android6VectorINS_8String16EE12do_constructEPvj;
-    _ZNK7android6VectorINS_8String16EE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorINS_8String16EE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorINS_8String16EE7do_copyEPvPKvj;
-    _ZNK7android6VectorINS_8String16EE8do_splatEPvPKvj;
-    _ZNK7android6VectorIPNS_7BBinderEE10do_destroyEPvj;
-    _ZNK7android6VectorIPNS_7BBinderEE12do_constructEPvj;
-    _ZNK7android6VectorIPNS_7BBinderEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7BBinderEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7BBinderEE7do_copyEPvPKvj;
-    _ZNK7android6VectorIPNS_7BBinderEE8do_splatEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE10do_destroyEPvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE12do_constructEPvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE7do_copyEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE8do_splatEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE10do_destroyEPvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE12do_constructEPvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE15do_move_forwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE16do_move_backwardEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE7do_copyEPvPKvj;
-    _ZNK7android6VectorIPNS_7RefBaseEE8do_splatEPvPKvj;
-    _ZNK7android7BBinder10findObjectEPKv;
-    _ZNK7android7BBinder13isBinderAliveEv;
-    _ZNK7android7BBinder22getInterfaceDescriptorEv;
-    _ZNK7android7content2pm18PackageChangeEvent13writeToParcelEPNS_6ParcelE;
-    _ZNK7android7content2pm21IPackageManagerNative22getInterfaceDescriptorEv;
-    _ZNK7android7content2pm22IPackageChangeObserver22getInterfaceDescriptorEv;
-    _ZNK7android7IBinder13checkSubclassEPKv;
-    _ZNK7android7IMemory11fastPointerERKNS_2spINS_7IBinderEEEi;
-    _ZNK7android7IMemory15unsecurePointerEv;
-    _ZNK7android7IMemory22getInterfaceDescriptorEv;
-    _ZNK7android7IMemory4sizeEv;
-    _ZNK7android7IMemory6offsetEv;
-    _ZNK7android7IMemory7pointerEv;
-    _ZNK7android8BpBinder10findObjectEPKv;
-    _ZNK7android8BpBinder10rpcAddressEv;
-    _ZNK7android8BpBinder10rpcSessionEv;
-    _ZNK7android8BpBinder11isRpcBinderEv;
-    _ZNK7android8BpBinder12binderHandleEv;
-    _ZNK7android8BpBinder13isBinderAliveEv;
-    _ZNK7android8BpBinder13ObjectManager4findEPKv;
-    _ZNK7android8BpBinder18isDescriptorCachedEv;
-    _ZNK7android8BpBinder22getInterfaceDescriptorEv;
-    _ZNK7android8BpMemory9getMemoryEPiPj;
-    _ZTCN7android10AllocationE0_NS_10IInterfaceE;
-    _ZTCN7android10AllocationE0_NS_10MemoryBaseE;
-    _ZTCN7android10AllocationE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android10AllocationE0_NS_7IMemoryE;
-    _ZTCN7android10AllocationE0_NS_8BnMemoryE;
-    _ZTCN7android10AllocationE4_NS_7BBinderE;
-    _ZTCN7android10AllocationE4_NS_7IBinderE;
-    _ZTCN7android10MemoryBaseE0_NS_10IInterfaceE;
-    _ZTCN7android10MemoryBaseE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android10MemoryBaseE0_NS_7IMemoryE;
-    _ZTCN7android10MemoryBaseE0_NS_8BnMemoryE;
-    _ZTCN7android10MemoryBaseE4_NS_7BBinderE;
-    _ZTCN7android10MemoryBaseE4_NS_7IBinderE;
-    _ZTCN7android10PoolThreadE0_NS_6ThreadE;
-    _ZTCN7android11IMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BnMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BnMemoryHeapE0_NS_11BnInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android12BnMemoryHeapE0_NS_11IMemoryHeapE;
-    _ZTCN7android12BnMemoryHeapE4_NS_7BBinderE;
-    _ZTCN7android12BnMemoryHeapE4_NS_7IBinderE;
-    _ZTCN7android12BpMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BpMemoryHeapE0_NS_11BpInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android12BpMemoryHeapE0_NS_11IMemoryHeapE;
-    _ZTCN7android12BpMemoryHeapE4_NS_9BpRefBaseE;
-    _ZTCN7android14IShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android14MemoryHeapBaseE32_NS_10IInterfaceE;
-    _ZTCN7android14MemoryHeapBaseE32_NS_11BnInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android14MemoryHeapBaseE32_NS_11IMemoryHeapE;
-    _ZTCN7android14MemoryHeapBaseE32_NS_12BnMemoryHeapE;
-    _ZTCN7android14MemoryHeapBaseE36_NS_7BBinderE;
-    _ZTCN7android14MemoryHeapBaseE36_NS_7IBinderE;
-    _ZTCN7android15BnShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android15BnShellCallbackE0_NS_11BnInterfaceINS_14IShellCallbackEEE;
-    _ZTCN7android15BnShellCallbackE0_NS_14IShellCallbackE;
-    _ZTCN7android15BnShellCallbackE4_NS_7BBinderE;
-    _ZTCN7android15BnShellCallbackE4_NS_7IBinderE;
-    _ZTCN7android15BpShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android15BpShellCallbackE0_NS_11BpInterfaceINS_14IShellCallbackEEE;
-    _ZTCN7android15BpShellCallbackE0_NS_14IShellCallbackE;
-    _ZTCN7android15BpShellCallbackE4_NS_9BpRefBaseE;
-    _ZTCN7android15IResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android15IServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android16BnResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android16BnResultReceiverE0_NS_11BnInterfaceINS_15IResultReceiverEEE;
-    _ZTCN7android16BnResultReceiverE0_NS_15IResultReceiverE;
-    _ZTCN7android16BnResultReceiverE4_NS_7BBinderE;
-    _ZTCN7android16BnResultReceiverE4_NS_7IBinderE;
-    _ZTCN7android16BpResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android16BpResultReceiverE0_NS_11BpInterfaceINS_15IResultReceiverEEE;
-    _ZTCN7android16BpResultReceiverE0_NS_15IResultReceiverE;
-    _ZTCN7android16BpResultReceiverE4_NS_9BpRefBaseE;
-    _ZTCN7android18ServiceManagerShimE0_NS_10IInterfaceE;
-    _ZTCN7android18ServiceManagerShimE0_NS_15IServiceManagerE;
-    _ZTCN7android2os15IClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os15IServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnClientCallbackE0_NS0_15IClientCallbackE;
-    _ZTCN7android2os16BnClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnClientCallbackE0_NS_11BnInterfaceINS0_15IClientCallbackEEE;
-    _ZTCN7android2os16BnClientCallbackE4_NS_7BBinderE;
-    _ZTCN7android2os16BnClientCallbackE4_NS_7IBinderE;
-    _ZTCN7android2os16BnServiceManagerE0_NS0_15IServiceManagerE;
-    _ZTCN7android2os16BnServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnServiceManagerE0_NS_11BnInterfaceINS0_15IServiceManagerEEE;
-    _ZTCN7android2os16BnServiceManagerE4_NS_7BBinderE;
-    _ZTCN7android2os16BnServiceManagerE4_NS_7IBinderE;
-    _ZTCN7android2os16BpClientCallbackE0_NS0_15IClientCallbackE;
-    _ZTCN7android2os16BpClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BpClientCallbackE0_NS_11BpInterfaceINS0_15IClientCallbackEEE;
-    _ZTCN7android2os16BpClientCallbackE4_NS_9BpRefBaseE;
-    _ZTCN7android2os16BpServiceManagerE0_NS0_15IServiceManagerE;
-    _ZTCN7android2os16BpServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BpServiceManagerE0_NS_11BpInterfaceINS0_15IServiceManagerEEE;
-    _ZTCN7android2os16BpServiceManagerE4_NS_9BpRefBaseE;
-    _ZTCN7android2os16IServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS0_16IServiceCallbackE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS_11BnInterfaceINS0_16IServiceCallbackEEE;
-    _ZTCN7android2os17BnServiceCallbackE4_NS_7BBinderE;
-    _ZTCN7android2os17BnServiceCallbackE4_NS_7IBinderE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS0_16IServiceCallbackE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS_11BpInterfaceINS0_16IServiceCallbackEEE;
-    _ZTCN7android2os17BpServiceCallbackE4_NS_9BpRefBaseE;
-    _ZTCN7android7BBinderE0_NS_7IBinderE;
-    _ZTCN7android7content2pm21IPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_11BnInterfaceINS1_21IPackageManagerNativeEEE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE4_NS_7BBinderE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE4_NS_7IBinderE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_11BpInterfaceINS1_21IPackageManagerNativeEEE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE4_NS_9BpRefBaseE;
-    _ZTCN7android7content2pm22IPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_11BnInterfaceINS1_22IPackageChangeObserverEEE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE4_NS_7BBinderE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE4_NS_7IBinderE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_11BpInterfaceINS1_22IPackageChangeObserverEEE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE4_NS_9BpRefBaseE;
-    _ZTCN7android7IMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BnMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BnMemoryE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android8BnMemoryE0_NS_7IMemoryE;
-    _ZTCN7android8BnMemoryE4_NS_7BBinderE;
-    _ZTCN7android8BnMemoryE4_NS_7IBinderE;
-    _ZTCN7android8BpBinderE0_NS_7IBinderE;
-    _ZTCN7android8BpMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BpMemoryE0_NS_11BpInterfaceINS_7IMemoryEEE;
-    _ZTCN7android8BpMemoryE0_NS_7IMemoryE;
-    _ZTCN7android8BpMemoryE4_NS_9BpRefBaseE;
-    _ZTCN7android9HeapCacheE0_NS_7IBinder14DeathRecipientE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_13basic_istreamIcS2_EE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_14basic_iostreamIcS2_EE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE8_NS_13basic_ostreamIcS2_EE;
-    _ZThn4_N7android10AllocationD0Ev;
-    _ZThn4_N7android10AllocationD1Ev;
-    _ZThn4_N7android10MemoryBaseD0Ev;
-    _ZThn4_N7android10MemoryBaseD1Ev;
-    _ZThn4_N7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn4_N7android12BnMemoryHeapD0Ev;
-    _ZThn4_N7android12BnMemoryHeapD1Ev;
-    _ZThn4_N7android12BpMemoryHeapD0Ev;
-    _ZThn4_N7android12BpMemoryHeapD1Ev;
-    _ZThn4_N7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn4_N7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn4_N7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn4_N7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn4_N7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn4_N7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZThn4_N7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZThn4_N7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn4_N7android8BnMemoryD0Ev;
-    _ZThn4_N7android8BnMemoryD1Ev;
-    _ZThn4_N7android8BpMemoryD0Ev;
-    _ZThn4_N7android8BpMemoryD1Ev;
-    _ZTTN7android10AllocationE;
-    _ZTTN7android10IInterfaceE;
-    _ZTTN7android10MemoryBaseE;
-    _ZTTN7android10PoolThreadE;
-    _ZTTN7android10RpcSessionE;
-    _ZTTN7android11IMemoryHeapE;
-    _ZTTN7android12BnMemoryHeapE;
-    _ZTTN7android12BpMemoryHeapE;
-    _ZTTN7android12ProcessStateE;
-    _ZTTN7android14IShellCallbackE;
-    _ZTTN7android14MemoryHeapBaseE;
-    _ZTTN7android15BnShellCallbackE;
-    _ZTTN7android15BpShellCallbackE;
-    _ZTTN7android15IResultReceiverE;
-    _ZTTN7android15IServiceManagerE;
-    _ZTTN7android16BnResultReceiverE;
-    _ZTTN7android16BpResultReceiverE;
-    _ZTTN7android18ServiceManagerShimE;
-    _ZTTN7android2os15IClientCallbackE;
-    _ZTTN7android2os15IServiceManagerE;
-    _ZTTN7android2os16BnClientCallbackE;
-    _ZTTN7android2os16BnServiceManagerE;
-    _ZTTN7android2os16BpClientCallbackE;
-    _ZTTN7android2os16BpServiceManagerE;
-    _ZTTN7android2os16IServiceCallbackE;
-    _ZTTN7android2os17BnServiceCallbackE;
-    _ZTTN7android2os17BpServiceCallbackE;
-    _ZTTN7android7BBinderE;
-    _ZTTN7android7content2pm21IPackageManagerNativeE;
-    _ZTTN7android7content2pm22BnPackageManagerNativeE;
-    _ZTTN7android7content2pm22BpPackageManagerNativeE;
-    _ZTTN7android7content2pm22IPackageChangeObserverE;
-    _ZTTN7android7content2pm23BnPackageChangeObserverE;
-    _ZTTN7android7content2pm23BpPackageChangeObserverE;
-    _ZTTN7android7IBinderE;
-    _ZTTN7android7IMemoryE;
-    _ZTTN7android8BnMemoryE;
-    _ZTTN7android8BpBinderE;
-    _ZTTN7android8BpMemoryE;
-    _ZTTN7android9BpRefBaseE;
-    _ZTTN7android9HeapCacheE;
-    _ZTTN7android9RpcServerE;
-    _ZTTNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE;
-    _ZTv0_n12_N7android10AllocationD0Ev;
-    _ZTv0_n12_N7android10AllocationD1Ev;
-    _ZTv0_n12_N7android10IInterfaceD0Ev;
-    _ZTv0_n12_N7android10IInterfaceD1Ev;
-    _ZTv0_n12_N7android10MemoryBaseD0Ev;
-    _ZTv0_n12_N7android10MemoryBaseD1Ev;
-    _ZTv0_n12_N7android10RpcSessionD0Ev;
-    _ZTv0_n12_N7android10RpcSessionD1Ev;
-    _ZTv0_n12_N7android11IMemoryHeapD0Ev;
-    _ZTv0_n12_N7android11IMemoryHeapD1Ev;
-    _ZTv0_n12_N7android12BnMemoryHeapD0Ev;
-    _ZTv0_n12_N7android12BnMemoryHeapD1Ev;
-    _ZTv0_n12_N7android12BpMemoryHeapD0Ev;
-    _ZTv0_n12_N7android12BpMemoryHeapD1Ev;
-    _ZTv0_n12_N7android12ProcessStateD0Ev;
-    _ZTv0_n12_N7android12ProcessStateD1Ev;
-    _ZTv0_n12_N7android14IShellCallbackD0Ev;
-    _ZTv0_n12_N7android14IShellCallbackD1Ev;
-    _ZTv0_n12_N7android14MemoryHeapBaseD0Ev;
-    _ZTv0_n12_N7android14MemoryHeapBaseD1Ev;
-    _ZTv0_n12_N7android15IResultReceiverD0Ev;
-    _ZTv0_n12_N7android15IResultReceiverD1Ev;
-    _ZTv0_n12_N7android15IServiceManagerD0Ev;
-    _ZTv0_n12_N7android15IServiceManagerD1Ev;
-    _ZTv0_n12_N7android2os15IClientCallbackD0Ev;
-    _ZTv0_n12_N7android2os15IClientCallbackD1Ev;
-    _ZTv0_n12_N7android2os15IServiceManagerD0Ev;
-    _ZTv0_n12_N7android2os15IServiceManagerD1Ev;
-    _ZTv0_n12_N7android2os16IServiceCallbackD0Ev;
-    _ZTv0_n12_N7android2os16IServiceCallbackD1Ev;
-    _ZTv0_n12_N7android7BBinderD0Ev;
-    _ZTv0_n12_N7android7BBinderD1Ev;
-    _ZTv0_n12_N7android7content2pm21IPackageManagerNativeD0Ev;
-    _ZTv0_n12_N7android7content2pm21IPackageManagerNativeD1Ev;
-    _ZTv0_n12_N7android7content2pm22IPackageChangeObserverD0Ev;
-    _ZTv0_n12_N7android7content2pm22IPackageChangeObserverD1Ev;
-    _ZTv0_n12_N7android7IBinderD0Ev;
-    _ZTv0_n12_N7android7IBinderD1Ev;
-    _ZTv0_n12_N7android7IMemoryD0Ev;
-    _ZTv0_n12_N7android7IMemoryD1Ev;
-    _ZTv0_n12_N7android8BnMemoryD0Ev;
-    _ZTv0_n12_N7android8BnMemoryD1Ev;
-    _ZTv0_n12_N7android8BpBinderD0Ev;
-    _ZTv0_n12_N7android8BpBinderD1Ev;
-    _ZTv0_n12_N7android8BpMemoryD0Ev;
-    _ZTv0_n12_N7android8BpMemoryD1Ev;
-    _ZTv0_n12_N7android9BpRefBaseD0Ev;
-    _ZTv0_n12_N7android9BpRefBaseD1Ev;
-    _ZTv0_n12_N7android9HeapCacheD0Ev;
-    _ZTv0_n12_N7android9HeapCacheD1Ev;
-    _ZTv0_n12_N7android9RpcServerD0Ev;
-    _ZTv0_n12_N7android9RpcServerD1Ev;
-    _ZTv0_n16_N7android14MemoryHeapBaseD0Ev;
-    _ZTv0_n16_N7android14MemoryHeapBaseD1Ev;
-    _ZTv0_n16_N7android8BpBinder10onFirstRefEv;
-    _ZTv0_n16_N7android9BpRefBase10onFirstRefEv;
-    _ZTv0_n20_N7android8BpBinder15onLastStrongRefEPKv;
-    _ZTv0_n20_N7android9BpRefBase15onLastStrongRefEPKv;
-    _ZTv0_n24_N7android8BpBinder20onIncStrongAttemptedEjPKv;
-    _ZTv0_n24_N7android9BpRefBase20onIncStrongAttemptedEjPKv;
-    _ZTv0_n28_NK7android14MemoryHeapBase9getHeapIDEv;
-    _ZTv0_n32_NK7android14MemoryHeapBase7getBaseEv;
-    _ZTv0_n36_NK7android14MemoryHeapBase7getSizeEv;
-    _ZTv0_n40_NK7android14MemoryHeapBase8getFlagsEv;
-    _ZTv0_n44_NK7android14MemoryHeapBase9getOffsetEv;
-    _ZTvn4_n16_N7android14MemoryHeapBaseD0Ev;
-    _ZTvn4_n16_N7android14MemoryHeapBaseD1Ev;
-    _ZTVN7android10AllocationE;
-    _ZTVN7android10IInterfaceE;
-    _ZTVN7android10MemoryBaseE;
-    _ZTVN7android10PoolThreadE;
-    _ZTVN7android10RpcSession13RpcConnectionE;
-    _ZTVN7android10RpcSessionE;
-    _ZTVN7android10TextOutputE;
-    _ZTVN7android11IMemoryHeapE;
-    _ZTVN7android12BnMemoryHeapE;
-    _ZTVN7android12BpMemoryHeapE;
-    _ZTVN7android12FdTextOutputE;
-    _ZTVN7android12MemoryDealerE;
-    _ZTVN7android12ProcessStateE;
-    _ZTVN7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEEE;
-    _ZTVN7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEEE;
-    _ZTVN7android13LogTextOutputE;
-    _ZTVN7android14IShellCallbackE;
-    _ZTVN7android14MemoryHeapBaseE;
-    _ZTVN7android15BnShellCallbackE;
-    _ZTVN7android15BpShellCallbackE;
-    _ZTVN7android15IResultReceiverE;
-    _ZTVN7android15IServiceManagerE;
-    _ZTVN7android16BnResultReceiverE;
-    _ZTVN7android16BpResultReceiverE;
-    _ZTVN7android17InetSocketAddressE;
-    _ZTVN7android17UnixSocketAddressE;
-    _ZTVN7android18BufferedTextOutput11BufferStateE;
-    _ZTVN7android18BufferedTextOutputE;
-    _ZTVN7android18ServiceManagerShimE;
-    _ZTVN7android18VsockSocketAddressE;
-    _ZTVN7android2os15IClientCallbackE;
-    _ZTVN7android2os15IServiceManagerE;
-    _ZTVN7android2os16BnClientCallbackE;
-    _ZTVN7android2os16BnServiceManagerE;
-    _ZTVN7android2os16BpClientCallbackE;
-    _ZTVN7android2os16BpServiceManagerE;
-    _ZTVN7android2os16IServiceCallbackE;
-    _ZTVN7android2os16ParcelableHolderE;
-    _ZTVN7android2os16ServiceDebugInfoE;
-    _ZTVN7android2os17BnServiceCallbackE;
-    _ZTVN7android2os17BpServiceCallbackE;
-    _ZTVN7android2os17PersistableBundleE;
-    _ZTVN7android2os20ParcelFileDescriptorE;
-    _ZTVN7android6VectorIiEE;
-    _ZTVN7android6VectorINS_12ProcessState12handle_entryEEE;
-    _ZTVN7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEEE;
-    _ZTVN7android6VectorINS_8BpBinder8ObituaryEEE;
-    _ZTVN7android6VectorINS_8String16EEE;
-    _ZTVN7android6VectorIPNS_7BBinderEEE;
-    _ZTVN7android6VectorIPNS_7RefBase12weakref_typeEEE;
-    _ZTVN7android6VectorIPNS_7RefBaseEEE;
-    _ZTVN7android7BBinderE;
-    _ZTVN7android7content2pm18PackageChangeEventE;
-    _ZTVN7android7content2pm21IPackageManagerNativeE;
-    _ZTVN7android7content2pm22BnPackageManagerNativeE;
-    _ZTVN7android7content2pm22BpPackageManagerNativeE;
-    _ZTVN7android7content2pm22IPackageChangeObserverE;
-    _ZTVN7android7content2pm23BnPackageChangeObserverE;
-    _ZTVN7android7content2pm23BpPackageChangeObserverE;
-    _ZTVN7android7IBinderE;
-    _ZTVN7android7IMemoryE;
-    _ZTVN7android8BnMemoryE;
-    _ZTVN7android8BpBinderE;
-    _ZTVN7android8BpMemoryE;
-    _ZTVN7android9BpRefBaseE;
-    _ZTVN7android9HeapCacheE;
-    _ZTVN7android9RpcServerE;
-  local:
-    *;
-};
diff --git a/libs/binder/libbinder.arm64.map b/libs/binder/libbinder.arm64.map
deleted file mode 100644
index 1d3da4c..0000000
--- a/libs/binder/libbinder.arm64.map
+++ /dev/null
@@ -1,1396 +0,0 @@
-# b/190148312: Populate with correct list of ABI symbols
-LIBBINDER {
-  global:
-    getBinderKernelReferences;
-    kDefaultDriver;
-    _ZN7android10AllocationC1ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEElm;
-    _ZN7android10AllocationC2ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEElm;
-    _ZN7android10AllocationD0Ev;
-    _ZN7android10AllocationD1Ev;
-    _ZN7android10AllocationD2Ev;
-    _ZN7android10IInterface8asBinderEPKS0_;
-    _ZN7android10IInterface8asBinderERKNS_2spIS0_EE;
-    _ZN7android10IInterfaceC2Ev;
-    _ZN7android10IInterfaceD0Ev;
-    _ZN7android10IInterfaceD1Ev;
-    _ZN7android10IInterfaceD2Ev;
-    _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEElm;
-    _ZN7android10MemoryBaseC2ERKNS_2spINS_11IMemoryHeapEEElm;
-    _ZN7android10MemoryBaseD0Ev;
-    _ZN7android10MemoryBaseD1Ev;
-    _ZN7android10MemoryBaseD2Ev;
-    _ZN7android10RpcAddress14readFromParcelERKNS_6ParcelE;
-    _ZN7android10RpcAddress15fromRawEmbeddedEPKNS_14RpcWireAddressE;
-    _ZN7android10RpcAddress4zeroEv;
-    _ZN7android10RpcAddress6uniqueEv;
-    _ZN7android10RpcAddressC1Ev;
-    _ZN7android10RpcAddressC2Ev;
-    _ZN7android10RpcAddressD1Ev;
-    _ZN7android10RpcAddressD2Ev;
-    _ZN7android10RpcSession12setForServerERKNS_2wpINS_9RpcServerEEEi;
-    _ZN7android10RpcSession13getRootObjectEv;
-    _ZN7android10RpcSession13sendDecStrongERKNS_10RpcAddressE;
-    _ZN7android10RpcSession15setupInetClientEPKcj;
-    _ZN7android10RpcSession15terminateLockedEv;
-    _ZN7android10RpcSession16setupVsockClientEjj;
-    _ZN7android10RpcSession17setupSocketClientERKNS_16RpcSocketAddressE;
-    _ZN7android10RpcSession19addClientConnectionENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession19ExclusiveConnection14findConnectionEiPNS_2spINS0_13RpcConnectionEEES5_RNSt3__16vectorIS4_NS6_9allocatorIS4_EEEEm;
-    _ZN7android10RpcSession19ExclusiveConnectionC1ERKNS_2spIS0_EENS0_13ConnectionUseE;
-    _ZN7android10RpcSession19ExclusiveConnectionC2ERKNS_2spIS0_EENS0_13ConnectionUseE;
-    _ZN7android10RpcSession19ExclusiveConnectionD1Ev;
-    _ZN7android10RpcSession19ExclusiveConnectionD2Ev;
-    _ZN7android10RpcSession19getRemoteMaxThreadsEPm;
-    _ZN7android10RpcSession20setupOneSocketClientERKNS_16RpcSocketAddressEi;
-    _ZN7android10RpcSession21setupUnixDomainClientEPKc;
-    _ZN7android10RpcSession22addNullDebuggingClientEv;
-    _ZN7android10RpcSession22removeServerConnectionERKNS_2spINS0_13RpcConnectionEEE;
-    _ZN7android10RpcSession24assignServerToThisThreadENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession4joinENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession4makeEv;
-    _ZN7android10RpcSession6readIdEv;
-    _ZN7android10RpcSession6serverEv;
-    _ZN7android10RpcSession7preJoinENSt3__16threadE;
-    _ZN7android10RpcSession8transactERKNS_10RpcAddressEjRKNS_6ParcelEPS4_j;
-    _ZN7android10RpcSessionC1Ev;
-    _ZN7android10RpcSessionC2Ev;
-    _ZN7android10RpcSessionD0Ev;
-    _ZN7android10RpcSessionD1Ev;
-    _ZN7android10RpcSessionD2Ev;
-    _ZN7android10TextOutputC2Ev;
-    _ZN7android10TextOutputD0Ev;
-    _ZN7android10TextOutputD1Ev;
-    _ZN7android10TextOutputD2Ev;
-    _ZN7android10zeroMemoryEPhm;
-    _ZN7android11BnInterfaceINS_11IMemoryHeapEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_14IShellCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_15IResultReceiverEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_21IPermissionControllerEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os15IClientCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os15IServiceManagerEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os16IServiceCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7content2pm21IPackageManagerNativeEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7content2pm22IPackageChangeObserverEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7IMemoryEE10onAsBinderEv;
-    _ZN7android11IMemoryHeap10descriptorE;
-    _ZN7android11IMemoryHeap11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android11IMemoryHeap12default_implE;
-    _ZN7android11IMemoryHeap14getDefaultImplEv;
-    _ZN7android11IMemoryHeap14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android11IMemoryHeapC2Ev;
-    _ZN7android11IMemoryHeapD0Ev;
-    _ZN7android11IMemoryHeapD1Ev;
-    _ZN7android11IMemoryHeapD2Ev;
-    _ZN7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android12BnMemoryHeapC2Ev;
-    _ZN7android12BnMemoryHeapD0Ev;
-    _ZN7android12BnMemoryHeapD1Ev;
-    _ZN7android12BnMemoryHeapD2Ev;
-    _ZN7android12BpMemoryHeapC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android12BpMemoryHeapC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android12BpMemoryHeapD0Ev;
-    _ZN7android12BpMemoryHeapD1Ev;
-    _ZN7android12BpMemoryHeapD2Ev;
-    _ZN7android12gTextBuffersE;
-    _ZN7android12MemoryDealer10deallocateEm;
-    _ZN7android12MemoryDealer22getAllocationAlignmentEv;
-    _ZN7android12MemoryDealer8allocateEm;
-    _ZN7android12MemoryDealerC1EmPKcj;
-    _ZN7android12MemoryDealerC2EmPKcj;
-    _ZN7android12MemoryDealerD0Ev;
-    _ZN7android12MemoryDealerD1Ev;
-    _ZN7android12MemoryDealerD2Ev;
-    _ZN7android12printHexDataEiPKvmmimbPFvPvPKcES2_;
-    _ZN7android12ProcessState10selfOrNullEv;
-    _ZN7android12ProcessState13expungeHandleEiPNS_7IBinderE;
-    _ZN7android12ProcessState13getDriverNameEv;
-    _ZN7android12ProcessState14initWithDriverEPKc;
-    _ZN7android12ProcessState15startThreadPoolEv;
-    _ZN7android12ProcessState16getContextObjectERKNS_2spINS_7IBinderEEE;
-    _ZN7android12ProcessState17spawnPooledThreadEb;
-    _ZN7android12ProcessState18giveThreadPoolNameEv;
-    _ZN7android12ProcessState18lookupHandleLockedEi;
-    _ZN7android12ProcessState18setCallRestrictionENS0_15CallRestrictionE;
-    _ZN7android12ProcessState19getKernelReferencesEmPm;
-    _ZN7android12ProcessState20becomeContextManagerEv;
-    _ZN7android12ProcessState20makeBinderThreadNameEv;
-    _ZN7android12ProcessState23getStrongProxyForHandleEi;
-    _ZN7android12ProcessState24getStrongRefCountForNodeERKNS_2spINS_8BpBinderEEE;
-    _ZN7android12ProcessState25enableOnewaySpamDetectionEb;
-    _ZN7android12ProcessState27setThreadPoolMaxThreadCountEm;
-    _ZN7android12ProcessState4initEPKcb;
-    _ZN7android12ProcessState4selfEv;
-    _ZN7android12ProcessStateC1EPKc;
-    _ZN7android12ProcessStateC2EPKc;
-    _ZN7android12ProcessStateD0Ev;
-    _ZN7android12ProcessStateD1Ev;
-    _ZN7android12ProcessStateD2Ev;
-    _ZN7android13printTypeCodeEjPFvPvPKcES0_;
-    _ZN7android14IPCThreadState10freeBufferEPNS_6ParcelEPKhmPKym;
-    _ZN7android14IPCThreadState10selfOrNullEv;
-    _ZN7android14IPCThreadState11clearCallerEv;
-    _ZN7android14IPCThreadState11stopProcessEb;
-    _ZN7android14IPCThreadState12setupPollingEPi;
-    _ZN7android14IPCThreadState13decWeakHandleEi;
-    _ZN7android14IPCThreadState13expungeHandleEiPNS_7IBinderE;
-    _ZN7android14IPCThreadState13flushCommandsEv;
-    _ZN7android14IPCThreadState13flushIfNeededEv;
-    _ZN7android14IPCThreadState13incWeakHandleEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState14clearLastErrorEv;
-    _ZN7android14IPCThreadState14executeCommandEi;
-    _ZN7android14IPCThreadState14joinThreadPoolEb;
-    _ZN7android14IPCThreadState14talkWithDriverEb;
-    _ZN7android14IPCThreadState15decStrongHandleEi;
-    _ZN7android14IPCThreadState15incStrongHandleEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState15waitForResponseEPNS_6ParcelEPi;
-    _ZN7android14IPCThreadState16threadDestructorEPv;
-    _ZN7android14IPCThreadState18setCallRestrictionENS_12ProcessState15CallRestrictionE;
-    _ZN7android14IPCThreadState19setStrictModePolicyEi;
-    _ZN7android14IPCThreadState19setTheContextObjectERKNS_2spINS_7BBinderEEE;
-    _ZN7android14IPCThreadState20clearCallingIdentityEv;
-    _ZN7android14IPCThreadState20getAndExecuteCommandEv;
-    _ZN7android14IPCThreadState20getProcessFreezeInfoEiPbS1_;
-    _ZN7android14IPCThreadState20getProcessFreezeInfoEiPjS1_;
-    _ZN7android14IPCThreadState20handlePolledCommandsEv;
-    _ZN7android14IPCThreadState20processPendingDerefsEv;
-    _ZN7android14IPCThreadState20writeTransactionDataEijijRKNS_6ParcelEPi;
-    _ZN7android14IPCThreadState22attemptIncStrongHandleEi;
-    _ZN7android14IPCThreadState22clearCallingWorkSourceEv;
-    _ZN7android14IPCThreadState22clearDeathNotificationEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState22processPostWriteDerefsEv;
-    _ZN7android14IPCThreadState22restoreCallingIdentityEl;
-    _ZN7android14IPCThreadState23setCallingWorkSourceUidEj;
-    _ZN7android14IPCThreadState24clearPropagateWorkSourceEv;
-    _ZN7android14IPCThreadState24requestDeathNotificationEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState24restoreCallingWorkSourceEl;
-    _ZN7android14IPCThreadState25blockUntilThreadAvailableEv;
-    _ZN7android14IPCThreadState27disableBackgroundSchedulingEb;
-    _ZN7android14IPCThreadState28backgroundSchedulingDisabledEv;
-    _ZN7android14IPCThreadState29setLastTransactionBinderFlagsEi;
-    _ZN7android14IPCThreadState41setCallingWorkSourceUidWithoutPropagationEj;
-    _ZN7android14IPCThreadState4selfEv;
-    _ZN7android14IPCThreadState6freezeEibj;
-    _ZN7android14IPCThreadState7processEv;
-    _ZN7android14IPCThreadState8shutdownEv;
-    _ZN7android14IPCThreadState8transactEijRKNS_6ParcelEPS1_j;
-    _ZN7android14IPCThreadState9sendReplyERKNS_6ParcelEj;
-    _ZN7android14IPCThreadStateC1Ev;
-    _ZN7android14IPCThreadStateC2Ev;
-    _ZN7android14IPCThreadStateD1Ev;
-    _ZN7android14IPCThreadStateD2Ev;
-    _ZN7android14IShellCallback10descriptorE;
-    _ZN7android14IShellCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android14IShellCallback12default_implE;
-    _ZN7android14IShellCallback14getDefaultImplEv;
-    _ZN7android14IShellCallback14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android14IShellCallbackC2Ev;
-    _ZN7android14IShellCallbackD0Ev;
-    _ZN7android14IShellCallbackD1Ev;
-    _ZN7android14IShellCallbackD2Ev;
-    _ZN7android14MemoryHeapBase4initEiPvmiPKc;
-    _ZN7android14MemoryHeapBase5mapfdEibml;
-    _ZN7android14MemoryHeapBase7disposeEv;
-    _ZN7android14MemoryHeapBaseC1Eimjl;
-    _ZN7android14MemoryHeapBaseC1EmjPKc;
-    _ZN7android14MemoryHeapBaseC1EPKcmj;
-    _ZN7android14MemoryHeapBaseC1Ev;
-    _ZN7android14MemoryHeapBaseC2Eimjl;
-    _ZN7android14MemoryHeapBaseC2EmjPKc;
-    _ZN7android14MemoryHeapBaseC2EPKcmj;
-    _ZN7android14MemoryHeapBaseC2Ev;
-    _ZN7android14MemoryHeapBaseD0Ev;
-    _ZN7android14MemoryHeapBaseD1Ev;
-    _ZN7android14MemoryHeapBaseD2Ev;
-    _ZN7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android15checkPermissionERKNS_8String16Eij;
-    _ZN7android15IResultReceiver10descriptorE;
-    _ZN7android15IResultReceiver11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android15IResultReceiver12default_implE;
-    _ZN7android15IResultReceiver14getDefaultImplEv;
-    _ZN7android15IResultReceiver14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android15IResultReceiverC2Ev;
-    _ZN7android15IResultReceiverD0Ev;
-    _ZN7android15IResultReceiverD1Ev;
-    _ZN7android15IResultReceiverD2Ev;
-    _ZN7android15IServiceManagerC2Ev;
-    _ZN7android15IServiceManagerD0Ev;
-    _ZN7android15IServiceManagerD1Ev;
-    _ZN7android15IServiceManagerD2Ev;
-    _ZN7android15PermissionCache10purgeCacheEv;
-    _ZN7android15PermissionCache15checkPermissionERKNS_8String16Eij;
-    _ZN7android15PermissionCache22checkCallingPermissionERKNS_8String16E;
-    _ZN7android15PermissionCache22checkCallingPermissionERKNS_8String16EPiS4_;
-    _ZN7android15PermissionCache5cacheERKNS_8String16Ejb;
-    _ZN7android15PermissionCache5purgeEv;
-    _ZN7android15PermissionCacheC1Ev;
-    _ZN7android15PermissionCacheC2Ev;
-    _ZN7android15stringForIndentEi;
-    _ZN7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android18BufferedTextOutput10moveIndentEi;
-    _ZN7android18BufferedTextOutput10pushBundleEv;
-    _ZN7android18BufferedTextOutput5printEPKcm;
-    _ZN7android18BufferedTextOutput9popBundleEv;
-    _ZN7android18BufferedTextOutputC2Ej;
-    _ZN7android18BufferedTextOutputD0Ev;
-    _ZN7android18BufferedTextOutputD1Ev;
-    _ZN7android18BufferedTextOutputD2Ev;
-    _ZN7android18ServiceManagerShim10addServiceERKNS_8String16ERKNS_2spINS_7IBinderEEEbi;
-    _ZN7android18ServiceManagerShim10isDeclaredERKNS_8String16E;
-    _ZN7android18ServiceManagerShim12listServicesEi;
-    _ZN7android18ServiceManagerShim14waitForServiceERKNS_8String16E;
-    _ZN7android18ServiceManagerShim16updatableViaApexERKNS_8String16E;
-    _ZN7android18ServiceManagerShim20getDeclaredInstancesERKNS_8String16E;
-    _ZN7android18ServiceManagerShimC1ERKNS_2spINS_2os15IServiceManagerEEE;
-    _ZN7android18ServiceManagerShimC2ERKNS_2spINS_2os15IServiceManagerEEE;
-    _ZN7android18the_context_objectE;
-    _ZN7android20PermissionController10getServiceEv;
-    _ZN7android20PermissionController13getPackageUidERKNS_8String16Ei;
-    _ZN7android20PermissionController15checkPermissionERKNS_8String16Eii;
-    _ZN7android20PermissionController17getPackagesForUidEjRNS_6VectorINS_8String16EEE;
-    _ZN7android20PermissionController19isRuntimePermissionERKNS_8String16E;
-    _ZN7android20PermissionController6noteOpERKNS_8String16EiS3_;
-    _ZN7android20PermissionControllerC1Ev;
-    _ZN7android20PermissionControllerC2Ev;
-    _ZN7android21defaultServiceManagerEv;
-    _ZN7android21IPermissionController10descriptorE;
-    _ZN7android21IPermissionController11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android21IPermissionController12default_implE;
-    _ZN7android21IPermissionController14getDefaultImplEv;
-    _ZN7android21IPermissionController14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android21IPermissionControllerC2Ev;
-    _ZN7android21IPermissionControllerD0Ev;
-    _ZN7android21IPermissionControllerD1Ev;
-    _ZN7android21IPermissionControllerD2Ev;
-    _ZN7android22BnPermissionController10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android22checkCallingPermissionERKNS_8String16E;
-    _ZN7android22checkCallingPermissionERKNS_8String16EPiS3_;
-    _ZN7android22SimpleBestFitAllocator10deallocateEm;
-    _ZN7android22SimpleBestFitAllocator12kMemoryAlignE;
-    _ZN7android22SimpleBestFitAllocator5allocEmj;
-    _ZN7android22SimpleBestFitAllocator7deallocEm;
-    _ZN7android22SimpleBestFitAllocator8allocateEmj;
-    _ZN7android22SimpleBestFitAllocatorC1Em;
-    _ZN7android22SimpleBestFitAllocatorC2Em;
-    _ZN7android22SimpleBestFitAllocatorD1Ev;
-    _ZN7android22SimpleBestFitAllocatorD2Ev;
-    _ZN7android24setDefaultServiceManagerERKNS_2spINS_15IServiceManagerEEE;
-    _ZN7android2os15IClientCallback10descriptorE;
-    _ZN7android2os15IClientCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os15IClientCallback12default_implE;
-    _ZN7android2os15IClientCallback14getDefaultImplEv;
-    _ZN7android2os15IClientCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os15IClientCallbackC2Ev;
-    _ZN7android2os15IClientCallbackD0Ev;
-    _ZN7android2os15IClientCallbackD1Ev;
-    _ZN7android2os15IClientCallbackD2Ev;
-    _ZN7android2os15IServiceManager10descriptorE;
-    _ZN7android2os15IServiceManager11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os15IServiceManager12default_implE;
-    _ZN7android2os15IServiceManager14getDefaultImplEv;
-    _ZN7android2os15IServiceManager14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os15IServiceManagerC2Ev;
-    _ZN7android2os15IServiceManagerD0Ev;
-    _ZN7android2os15IServiceManagerD1Ev;
-    _ZN7android2os15IServiceManagerD2Ev;
-    _ZN7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os16BnClientCallbackC2Ev;
-    _ZN7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os16BnServiceManagerC2Ev;
-    _ZN7android2os16BpClientCallback9onClientsERKNS_2spINS_7IBinderEEEb;
-    _ZN7android2os16BpClientCallbackC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpClientCallbackC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager10addServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEEbi;
-    _ZN7android2os16BpServiceManager10getServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager10isDeclaredERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPb;
-    _ZN7android2os16BpServiceManager12checkServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager12listServicesEiPNSt3__16vectorINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS7_IS9_EEEE;
-    _ZN7android2os16BpServiceManager16updatableViaApexERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_8optionalIS8_EE;
-    _ZN7android2os16BpServiceManager19getServiceDebugInfoEPNSt3__16vectorINS0_16ServiceDebugInfoENS2_9allocatorIS4_EEEE;
-    _ZN7android2os16BpServiceManager20getDeclaredInstancesERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_6vectorIS8_NS6_IS8_EEEE;
-    _ZN7android2os16BpServiceManager20tryUnregisterServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager22registerClientCallbackERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEERKNSB_INS0_15IClientCallbackEEE;
-    _ZN7android2os16BpServiceManager24registerForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
-    _ZN7android2os16BpServiceManager26unregisterForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
-    _ZN7android2os16BpServiceManagerC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManagerC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16IServiceCallback10descriptorE;
-    _ZN7android2os16IServiceCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16IServiceCallback12default_implE;
-    _ZN7android2os16IServiceCallback14getDefaultImplEv;
-    _ZN7android2os16IServiceCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os16IServiceCallbackC2Ev;
-    _ZN7android2os16IServiceCallbackD0Ev;
-    _ZN7android2os16IServiceCallbackD1Ev;
-    _ZN7android2os16IServiceCallbackD2Ev;
-    _ZN7android2os16ParcelableHolder14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os16ServiceDebugInfo14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os17BnServiceCallbackC2Ev;
-    _ZN7android2os17BpServiceCallback14onRegistrationERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17BpServiceCallbackC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17BpServiceCallbackC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17PersistableBundle10putBooleanERKNS_8String16Eb;
-    _ZN7android2os17PersistableBundle12putIntVectorERKNS_8String16ERKNSt3__16vectorIiNS5_9allocatorIiEEEE;
-    _ZN7android2os17PersistableBundle13putLongVectorERKNS_8String16ERKNSt3__16vectorIlNS5_9allocatorIlEEEE;
-    _ZN7android2os17PersistableBundle14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os17PersistableBundle15putDoubleVectorERKNS_8String16ERKNSt3__16vectorIdNS5_9allocatorIdEEEE;
-    _ZN7android2os17PersistableBundle15putStringVectorERKNS_8String16ERKNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
-    _ZN7android2os17PersistableBundle16putBooleanVectorERKNS_8String16ERKNSt3__16vectorIbNS5_9allocatorIbEEEE;
-    _ZN7android2os17PersistableBundle19readFromParcelInnerEPKNS_6ParcelEm;
-    _ZN7android2os17PersistableBundle20putPersistableBundleERKNS_8String16ERKS1_;
-    _ZN7android2os17PersistableBundle5eraseERKNS_8String16E;
-    _ZN7android2os17PersistableBundle6putIntERKNS_8String16Ei;
-    _ZN7android2os17PersistableBundle7putLongERKNS_8String16El;
-    _ZN7android2os17PersistableBundle9putDoubleERKNS_8String16Ed;
-    _ZN7android2os17PersistableBundle9putStringERKNS_8String16ES4_;
-    _ZN7android2os20ParcelFileDescriptor14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os20ParcelFileDescriptorC1ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
-    _ZN7android2os20ParcelFileDescriptorC1Ev;
-    _ZN7android2os20ParcelFileDescriptorC2ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
-    _ZN7android2os20ParcelFileDescriptorC2Ev;
-    _ZN7android2os20ParcelFileDescriptorD0Ev;
-    _ZN7android2os20ParcelFileDescriptorD1Ev;
-    _ZN7android2os20ParcelFileDescriptorD2Ev;
-    _ZN7android4aerrE;
-    _ZN7android4alogE;
-    _ZN7android4aoutE;
-    _ZN7android6binder20LazyServiceRegistrar10reRegisterEv;
-    _ZN7android6binder20LazyServiceRegistrar11getInstanceEv;
-    _ZN7android6binder20LazyServiceRegistrar12forcePersistEb;
-    _ZN7android6binder20LazyServiceRegistrar13tryUnregisterEv;
-    _ZN7android6binder20LazyServiceRegistrar15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEbi;
-    _ZN7android6binder20LazyServiceRegistrar25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
-    _ZN7android6binder20LazyServiceRegistrarC1Ev;
-    _ZN7android6binder20LazyServiceRegistrarC2Ev;
-    _ZN7android6binder6Status11fromStatusTEi;
-    _ZN7android6binder6Status12setExceptionEiRKNS_7String8E;
-    _ZN7android6binder6Status14readFromParcelERKNS_6ParcelE;
-    _ZN7android6binder6Status14setFromStatusTEi;
-    _ZN7android6binder6Status17exceptionToStringEi;
-    _ZN7android6binder6Status17fromExceptionCodeEi;
-    _ZN7android6binder6Status17fromExceptionCodeEiPKc;
-    _ZN7android6binder6Status17fromExceptionCodeEiRKNS_7String8E;
-    _ZN7android6binder6Status23setServiceSpecificErrorEiRKNS_7String8E;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEi;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEiPKc;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEiRKNS_7String8E;
-    _ZN7android6binder6Status2okEv;
-    _ZN7android6binder6StatusC1Eii;
-    _ZN7android6binder6StatusC1EiiRKNS_7String8E;
-    _ZN7android6binder6StatusC2Eii;
-    _ZN7android6binder6StatusC2EiiRKNS_7String8E;
-    _ZN7android6binder8internal21ClientCounterCallback10reRegisterEv;
-    _ZN7android6binder8internal21ClientCounterCallback12forcePersistEb;
-    _ZN7android6binder8internal21ClientCounterCallback13tryUnregisterEv;
-    _ZN7android6binder8internal21ClientCounterCallback15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEbi;
-    _ZN7android6binder8internal21ClientCounterCallback25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
-    _ZN7android6binder8internal21ClientCounterCallbackC1Ev;
-    _ZN7android6binder8internal21ClientCounterCallbackC2Ev;
-    _ZN7android6Parcel10appendFromEPKS0_mm;
-    _ZN7android6Parcel10markForRpcERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android6Parcel10writeFloatEf;
-    _ZN7android6Parcel10writeInt32Ei;
-    _ZN7android6Parcel10writeInt64El;
-    _ZN7android6Parcel11compareDataERKS0_;
-    _ZN7android6Parcel11finishWriteEm;
-    _ZN7android6Parcel11setDataSizeEm;
-    _ZN7android6Parcel11writeDoubleEd;
-    _ZN7android6Parcel11writeObjectERK18flat_binder_objectb;
-    _ZN7android6Parcel11writeUint32Ej;
-    _ZN7android6Parcel11writeUint64Em;
-    _ZN7android6Parcel12pushAllowFdsEb;
-    _ZN7android6Parcel12restartWriteEm;
-    _ZN7android6Parcel12writeCStringEPKc;
-    _ZN7android6Parcel12writeInplaceEm;
-    _ZN7android6Parcel12writePointerEm;
-    _ZN7android6Parcel12writeString8EPKcm;
-    _ZN7android6Parcel12writeString8ERKNS_7String8E;
-    _ZN7android6Parcel13continueWriteEm;
-    _ZN7android6Parcel13flattenBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel13markForBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel13writeString16EPKDsm;
-    _ZN7android6Parcel13writeString16ERKNS_8String16E;
-    _ZN7android6Parcel13writeString16ERKNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
-    _ZN7android6Parcel13writeString16ERKNSt3__18optionalINS_8String16EEE;
-    _ZN7android6Parcel13writeUnpaddedEPKvm;
-    _ZN7android6Parcel14acquireObjectsEv;
-    _ZN7android6Parcel14freeDataNoInitEv;
-    _ZN7android6Parcel14releaseObjectsEv;
-    _ZN7android6Parcel14writeByteArrayEmPKh;
-    _ZN7android6Parcel15restoreAllowFdsEb;
-    _ZN7android6Parcel15setDataCapacityEm;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__16vectorIbNS1_9allocatorIbEEEE;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIaNS1_9allocatorIaEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIhNS1_9allocatorIhEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
-    _ZN7android6Parcel15writeInt32ArrayEmPKi;
-    _ZN7android6Parcel15writeParcelableERKNS_10ParcelableE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__16vectorIfNS1_9allocatorIfEEEE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__16vectorIiNS1_9allocatorIiEEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__110unique_ptrINS1_6vectorIlNS1_9allocatorIlEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__16vectorIlNS1_9allocatorIlEEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__18optionalINS1_6vectorIlNS1_9allocatorIlEEEEEE;
-    _ZN7android6Parcel16writeNoExceptionEv;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__16vectorIdNS1_9allocatorIdEEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
-    _ZN7android6Parcel17writeNativeHandleEPK13native_handle;
-    _ZN7android6Parcel17writeStrongBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__110unique_ptrINS1_6vectorImNS1_9allocatorImEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__16vectorImNS1_9allocatorImEEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__18optionalINS1_6vectorImNS1_9allocatorImEEEEEE;
-    _ZN7android6Parcel18getGlobalAllocSizeEv;
-    _ZN7android6Parcel19finishFlattenBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel19getGlobalAllocCountEv;
-    _ZN7android6Parcel19ipcSetDataReferenceEPKhmPKymPFvPS0_S2_mS4_mE;
-    _ZN7android6Parcel19writeFileDescriptorEib;
-    _ZN7android6Parcel19writeInterfaceTokenEPKDsm;
-    _ZN7android6Parcel19writeInterfaceTokenERKNS_8String16E;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
-    _ZN7android6Parcel20closeFileDescriptorsEv;
-    _ZN7android6Parcel22writeDupFileDescriptorEi;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
-    _ZN7android6Parcel25writeParcelFileDescriptorEib;
-    _ZN7android6Parcel25writeUniqueFileDescriptorERKNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android6Parcel26writeRawNullableParcelableEPKNS_10ParcelableE;
-    _ZN7android6Parcel27replaceCallingWorkSourceUidEj;
-    _ZN7android6Parcel28writeDupParcelFileDescriptorEi;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
-    _ZN7android6Parcel35writeDupImmutableBlobFileDescriptorEi;
-    _ZN7android6Parcel4Blob4initEiPvmb;
-    _ZN7android6Parcel4Blob5clearEv;
-    _ZN7android6Parcel4Blob7releaseEv;
-    _ZN7android6Parcel4BlobC1Ev;
-    _ZN7android6Parcel4BlobC2Ev;
-    _ZN7android6Parcel4BlobD1Ev;
-    _ZN7android6Parcel4BlobD2Ev;
-    _ZN7android6Parcel5writeEPKvm;
-    _ZN7android6Parcel5writeERKNS0_26FlattenableHelperInterfaceE;
-    _ZN7android6Parcel7setDataEPKhm;
-    _ZN7android6Parcel8freeDataEv;
-    _ZN7android6Parcel8growDataEm;
-    _ZN7android6Parcel8setErrorEi;
-    _ZN7android6Parcel9initStateEv;
-    _ZN7android6Parcel9writeBlobEmbPNS0_12WritableBlobE;
-    _ZN7android6Parcel9writeBoolEb;
-    _ZN7android6Parcel9writeByteEa;
-    _ZN7android6Parcel9writeCharEDs;
-    _ZN7android6ParcelC1Ev;
-    _ZN7android6ParcelC2Ev;
-    _ZN7android6ParcelD1Ev;
-    _ZN7android6ParcelD2Ev;
-    _ZN7android7BBinder10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android7BBinder10pingBinderEv;
-    _ZN7android7BBinder11getDebugPidEv;
-    _ZN7android7BBinder11isInheritRtEv;
-    _ZN7android7BBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
-    _ZN7android7BBinder11localBinderEv;
-    _ZN7android7BBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
-    _ZN7android7BBinder12detachObjectEPKv;
-    _ZN7android7BBinder12getExtensionEv;
-    _ZN7android7BBinder12setExtensionERKNS_2spINS_7IBinderEEE;
-    _ZN7android7BBinder12setInheritRtEb;
-    _ZN7android7BBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
-    _ZN7android7BBinder15isRequestingSidEv;
-    _ZN7android7BBinder16setRequestingSidEb;
-    _ZN7android7BBinder17getOrCreateExtrasEv;
-    _ZN7android7BBinder21getMinSchedulerPolicyEv;
-    _ZN7android7BBinder21setMinSchedulerPolicyEii;
-    _ZN7android7BBinder23getMinSchedulerPriorityEv;
-    _ZN7android7BBinder4dumpEiRKNS_6VectorINS_8String16EEE;
-    _ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j;
-    _ZN7android7BBinderC1Ev;
-    _ZN7android7BBinderC2Ev;
-    _ZN7android7BBinderD0Ev;
-    _ZN7android7BBinderD1Ev;
-    _ZN7android7BBinderD2Ev;
-    _ZN7android7content2pm18PackageChangeEvent14readFromParcelEPKNS_6ParcelE;
-    _ZN7android7content2pm21IPackageManagerNative10descriptorE;
-    _ZN7android7content2pm21IPackageManagerNative11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm21IPackageManagerNative12default_implE;
-    _ZN7android7content2pm21IPackageManagerNative14getDefaultImplEv;
-    _ZN7android7content2pm21IPackageManagerNative14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
-    _ZN7android7content2pm21IPackageManagerNativeC2Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD0Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD1Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD2Ev;
-    _ZN7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZN7android7content2pm22BnPackageManagerNativeC2Ev;
-    _ZN7android7content2pm22BpPackageManagerNative14getAllPackagesEPNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEE;
-    _ZN7android7content2pm22BpPackageManagerNative15getNamesForUidsERKNSt3__16vectorIiNS3_9allocatorIiEEEEPNS4_INS3_12basic_stringIcNS3_11char_traitsIcEENS5_IcEEEENS5_ISE_EEEE;
-    _ZN7android7content2pm22BpPackageManagerNative16getLocationFlagsERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPi;
-    _ZN7android7content2pm22BpPackageManagerNative16hasSystemFeatureERKNS_8String16EiPb;
-    _ZN7android7content2pm22BpPackageManagerNative19isPackageDebuggableERKNS_8String16EPb;
-    _ZN7android7content2pm22BpPackageManagerNative22getInstallerForPackageERKNS_8String16EPNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative24getVersionCodeForPackageERKNS_8String16EPl;
-    _ZN7android7content2pm22BpPackageManagerNative27hasSha256SigningCertificateERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKNS3_6vectorIhNS7_IhEEEEPb;
-    _ZN7android7content2pm22BpPackageManagerNative28getModuleMetadataPackageNameEPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative29getTargetSdkVersionForPackageERKNS_8String16EPi;
-    _ZN7android7content2pm22BpPackageManagerNative29isAudioPlaybackCaptureAllowedERKNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEEPNS4_IbNS8_IbEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative29registerPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
-    _ZN7android7content2pm22BpPackageManagerNative31unregisterPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
-    _ZN7android7content2pm22BpPackageManagerNativeC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22BpPackageManagerNativeC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22IPackageChangeObserver10descriptorE;
-    _ZN7android7content2pm22IPackageChangeObserver11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22IPackageChangeObserver12default_implE;
-    _ZN7android7content2pm22IPackageChangeObserver14getDefaultImplEv;
-    _ZN7android7content2pm22IPackageChangeObserver14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
-    _ZN7android7content2pm22IPackageChangeObserverC2Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD0Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD1Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD2Ev;
-    _ZN7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZN7android7content2pm23BnPackageChangeObserverC2Ev;
-    _ZN7android7content2pm23BpPackageChangeObserver16onPackageChangedERKNS1_18PackageChangeEventE;
-    _ZN7android7content2pm23BpPackageChangeObserverC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm23BpPackageChangeObserverC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7HexDumpC1EPKvmm;
-    _ZN7android7HexDumpC2EPKvmm;
-    _ZN7android7IBinder11getDebugPidEPi;
-    _ZN7android7IBinder11localBinderEv;
-    _ZN7android7IBinder12getExtensionEPNS_2spIS0_EE;
-    _ZN7android7IBinder12remoteBinderEv;
-    _ZN7android7IBinder12shellCommandERKNS_2spIS0_EEiiiRNS_6VectorINS_8String16EEERKNS1_INS_14IShellCallbackEEERKNS1_INS_15IResultReceiverEEE;
-    _ZN7android7IBinder19queryLocalInterfaceERKNS_8String16E;
-    _ZN7android7IBinderC2Ev;
-    _ZN7android7IBinderD0Ev;
-    _ZN7android7IBinderD1Ev;
-    _ZN7android7IBinderD2Ev;
-    _ZN7android7IMemory10descriptorE;
-    _ZN7android7IMemory11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7IMemory12default_implE;
-    _ZN7android7IMemory14getDefaultImplEv;
-    _ZN7android7IMemory14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android7IMemoryC2Ev;
-    _ZN7android7IMemoryD0Ev;
-    _ZN7android7IMemoryD1Ev;
-    _ZN7android7IMemoryD2Ev;
-    _ZN7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android8BnMemoryC2Ev;
-    _ZN7android8BnMemoryD0Ev;
-    _ZN7android8BnMemoryD1Ev;
-    _ZN7android8BnMemoryD2Ev;
-    _ZN7android8BpBinder10onFirstRefEv;
-    _ZN7android8BpBinder10pingBinderEv;
-    _ZN7android8BpBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
-    _ZN7android8BpBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
-    _ZN7android8BpBinder12detachObjectEPKv;
-    _ZN7android8BpBinder12remoteBinderEv;
-    _ZN7android8BpBinder12sendObituaryEv;
-    _ZN7android8BpBinder12sTrackingMapE;
-    _ZN7android8BpBinder13getCountByUidERNS_6VectorIjEES3_;
-    _ZN7android8BpBinder13ObjectManager4killEv;
-    _ZN7android8BpBinder13ObjectManager6attachEPKvPvS4_PFvS3_S4_S4_E;
-    _ZN7android8BpBinder13ObjectManager6detachEPKv;
-    _ZN7android8BpBinder13ObjectManagerC1Ev;
-    _ZN7android8BpBinder13ObjectManagerC2Ev;
-    _ZN7android8BpBinder13ObjectManagerD1Ev;
-    _ZN7android8BpBinder13ObjectManagerD2Ev;
-    _ZN7android8BpBinder13sTrackingLockE;
-    _ZN7android8BpBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
-    _ZN7android8BpBinder14reportOneDeathERKNS0_8ObituaryE;
-    _ZN7android8BpBinder14sLimitCallbackE;
-    _ZN7android8BpBinder15onLastStrongRefEPKv;
-    _ZN7android8BpBinder15sNumTrackedUidsE;
-    _ZN7android8BpBinder16enableCountByUidEv;
-    _ZN7android8BpBinder16setLimitCallbackEPFviE;
-    _ZN7android8BpBinder17disableCountByUidEv;
-    _ZN7android8BpBinder18sCountByUidEnabledE;
-    _ZN7android8BpBinder19getBinderProxyCountEj;
-    _ZN7android8BpBinder20onIncStrongAttemptedEjPKv;
-    _ZN7android8BpBinder20setCountByUidEnabledEb;
-    _ZN7android8BpBinder26sBinderProxyThrottleCreateE;
-    _ZN7android8BpBinder29sBinderProxyCountLowWatermarkE;
-    _ZN7android8BpBinder29setBinderProxyCountWatermarksEii;
-    _ZN7android8BpBinder30sBinderProxyCountHighWatermarkE;
-    _ZN7android8BpBinder4dumpEiRKNS_6VectorINS_8String16EEE;
-    _ZN7android8BpBinder6createEi;
-    _ZN7android8BpBinder6createERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
-    _ZN7android8BpBinder8transactEjRKNS_6ParcelEPS1_j;
-    _ZN7android8BpBinderC1EONS0_12BinderHandleEi;
-    _ZN7android8BpBinderC1EONS0_9RpcHandleE;
-    _ZN7android8BpBinderC1EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
-    _ZN7android8BpBinderC2EONS0_12BinderHandleEi;
-    _ZN7android8BpBinderC2EONS0_9RpcHandleE;
-    _ZN7android8BpBinderC2EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
-    _ZN7android8BpBinderD0Ev;
-    _ZN7android8BpBinderD1Ev;
-    _ZN7android8BpBinderD2Ev;
-    _ZN7android8BpMemoryC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android8BpMemoryC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android8BpMemoryD0Ev;
-    _ZN7android8BpMemoryD1Ev;
-    _ZN7android8BpMemoryD2Ev;
-    _ZN7android8internal9Stability11getCategoryEPNS_7IBinderE;
-    _ZN7android8internal9Stability11levelStringENS1_5LevelE;
-    _ZN7android8internal9Stability13getLocalLevelEv;
-    _ZN7android8internal9Stability15isDeclaredLevelENS1_5LevelE;
-    _ZN7android8internal9Stability17debugLogStabilityERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability19markCompilationUnitEPNS_7IBinderE;
-    _ZN7android8internal9Stability22tryMarkCompilationUnitEPNS_7IBinderE;
-    _ZN7android8internal9Stability24requiresVintfDeclarationERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability25forceDowngradeToStabilityERKNS_2spINS_7IBinderEEENS1_5LevelE;
-    _ZN7android8internal9Stability30forceDowngradeToLocalStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability31forceDowngradeToSystemStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability31forceDowngradeToVendorStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability5checkENS1_8CategoryENS1_5LevelE;
-    _ZN7android8internal9Stability7setReprEPNS_7IBinderEij;
-    _ZN7android8internal9Stability8Category11debugStringEv;
-    _ZN7android8internal9Stability8markVndkEPNS_7IBinderE;
-    _ZN7android8internal9Stability9markVintfEPNS_7IBinderE;
-    _ZN7android8RpcState11CommandDataC1Em;
-    _ZN7android8RpcState11CommandDataC2Em;
-    _ZN7android8RpcState12countBindersEv;
-    _ZN7android8RpcState12getSessionIdERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPi;
-    _ZN7android8RpcState12waitForReplyERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPNS_6ParcelE;
-    _ZN7android8RpcState13getMaxThreadsERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPm;
-    _ZN7android8RpcState13getRootObjectERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android8RpcState13sendDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressE;
-    _ZN7android8RpcState15onBinderLeavingERKNS_2spINS_10RpcSessionEEERKNS1_INS_7IBinderEEEPNS_10RpcAddressE;
-    _ZN7android8RpcState15processTransactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState16onBinderEnteringERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
-    _ZN7android8RpcState16processDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState20getAndExecuteCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android8RpcState20processServerCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState23processTransactInternalERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEENS0_11CommandDataE;
-    _ZN7android8RpcState4dumpEv;
-    _ZN7android8RpcState6rpcRecERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPvm;
-    _ZN7android8RpcState7rpcSendERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPKvm;
-    _ZN7android8RpcState8transactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressEjRKNS_6ParcelERKNS_2spINS_10RpcSessionEEEPSA_j;
-    _ZN7android8RpcState9terminateEv;
-    _ZN7android8RpcStateC1Ev;
-    _ZN7android8RpcStateC2Ev;
-    _ZN7android8RpcStateD1Ev;
-    _ZN7android8RpcStateD2Ev;
-    _ZN7android9BpRefBase10onFirstRefEv;
-    _ZN7android9BpRefBase15onLastStrongRefEPKv;
-    _ZN7android9BpRefBase20onIncStrongAttemptedEjPKv;
-    _ZN7android9BpRefBaseC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android9BpRefBaseC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android9BpRefBaseD0Ev;
-    _ZN7android9BpRefBaseD1Ev;
-    _ZN7android9BpRefBaseD2Ev;
-    _ZN7android9HeapCache10binderDiedERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9HeapCache10dump_heapsEv;
-    _ZN7android9HeapCache8get_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9find_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9free_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9free_heapERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9HeapCacheC1Ev;
-    _ZN7android9HeapCacheC2Ev;
-    _ZN7android9HeapCacheD0Ev;
-    _ZN7android9HeapCacheD1Ev;
-    _ZN7android9HeapCacheD2Ev;
-    _ZN7android9hexStringEPKvm;
-    _ZN7android9RpcServer12listSessionsEv;
-    _ZN7android9RpcServer13getMaxThreadsEv;
-    _ZN7android9RpcServer13getRootObjectEv;
-    _ZN7android9RpcServer13releaseServerEv;
-    _ZN7android9RpcServer13setMaxThreadsEm;
-    _ZN7android9RpcServer13setRootObjectERKNS_2spINS_7IBinderEEE;
-    _ZN7android9RpcServer15setupInetServerEjPj;
-    _ZN7android9RpcServer16setupVsockServerEj;
-    _ZN7android9RpcServer17setRootObjectWeakERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9RpcServer17setupSocketServerERKNS_16RpcSocketAddressE;
-    _ZN7android9RpcServer19establishConnectionEONS_2spIS0_EENS_4base14unique_fd_implINS4_13DefaultCloserEEE;
-    _ZN7android9RpcServer19setupExternalServerENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android9RpcServer20onSessionTerminatingERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android9RpcServer21setupUnixDomainServerEPKc;
-    _ZN7android9RpcServer24numUninitializedSessionsEv;
-    _ZN7android9RpcServer4joinEv;
-    _ZN7android9RpcServer4makeEv;
-    _ZN7android9RpcServer61iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProductionEv;
-    _ZN7android9RpcServer9acceptOneEv;
-    _ZN7android9RpcServer9hasServerEv;
-    _ZN7android9RpcServerC1Ev;
-    _ZN7android9RpcServerC2Ev;
-    _ZN7android9RpcServerD0Ev;
-    _ZN7android9RpcServerD1Ev;
-    _ZN7android9RpcServerD2Ev;
-    _ZN7android9SingletonINS_15PermissionCacheEE11getInstanceEv;
-    _ZN7android9SingletonINS_15PermissionCacheEE11hasInstanceEv;
-    _ZN7android9SingletonINS_15PermissionCacheEE5sLockE;
-    _ZN7android9SingletonINS_15PermissionCacheEE9sInstanceE;
-    _ZN7android9SingletonINS_15PermissionCacheEEC1Ev;
-    _ZN7android9SingletonINS_15PermissionCacheEEC2Ev;
-    _ZN7android9SingletonINS_15PermissionCacheEED1Ev;
-    _ZN7android9SingletonINS_15PermissionCacheEED2Ev;
-    _ZN7androidlsERNS_10TextOutputERKNS_7HexDumpE;
-    _ZN7androidlsERNS_10TextOutputERKNS_8TypeCodeE;
-    _ZN7androidlsIA15_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA24_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA2_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA34_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA3_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA43_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA4_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA5_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA8_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA9_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIjEERNS_10TextOutputES2_RKT_;
-    _ZN7androidlsImEERNS_10TextOutputES2_RKT_;
-    _ZN7androidlsINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEERNS_10TextOutputES9_RKT_;
-    _ZN7androidlsIPcEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIPvEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIyEERNS_10TextOutputES2_RKT_;
-    _ZNK7android10MemoryBase9getMemoryEPlPm;
-    _ZNK7android10RpcAddress13writeToParcelEPNS_6ParcelE;
-    _ZNK7android10RpcAddress15viewRawEmbeddedEv;
-    _ZNK7android10RpcAddress6isZeroEv;
-    _ZNK7android10RpcAddress8toStringEv;
-    _ZNK7android10RpcAddressltERKS0_;
-    _ZNK7android11IMemoryHeap22getInterfaceDescriptorEv;
-    _ZNK7android12BpMemoryHeap12assertMappedEv;
-    _ZNK7android12BpMemoryHeap18assertReallyMappedEv;
-    _ZNK7android12BpMemoryHeap7getBaseEv;
-    _ZNK7android12BpMemoryHeap7getSizeEv;
-    _ZNK7android12BpMemoryHeap8getFlagsEv;
-    _ZNK7android12BpMemoryHeap9getHeapIDEv;
-    _ZNK7android12BpMemoryHeap9getOffsetEv;
-    _ZNK7android12MemoryDealer4dumpEPKc;
-    _ZNK7android12MemoryDealer4heapEv;
-    _ZNK7android12MemoryDealer9allocatorEv;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE10do_compareEPKvS5_;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE10do_destroyEPvm;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE12do_constructEPvm;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE15do_move_forwardEPvPKvm;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE16do_move_backwardEPvPKvm;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE7do_copyEPvPKvm;
-    _ZNK7android12SortedVectorINS_15PermissionCache5EntryEE8do_splatEPvPKvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_compareEPKvSA_;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_destroyEPvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE12do_constructEPvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE15do_move_forwardEPvPKvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE16do_move_backwardEPvPKvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE7do_copyEPvPKvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE8do_splatEPvPKvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_compareES3_S3_;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_destroyEPvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE12do_constructEPvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE15do_move_forwardEPvS3_m;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE16do_move_backwardEPvS3_m;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE7do_copyEPvS3_m;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE8do_splatEPvS3_m;
-    _ZNK7android12SortedVectorINS_8String16EE10do_compareEPKvS4_;
-    _ZNK7android12SortedVectorINS_8String16EE10do_destroyEPvm;
-    _ZNK7android12SortedVectorINS_8String16EE12do_constructEPvm;
-    _ZNK7android12SortedVectorINS_8String16EE15do_move_forwardEPvPKvm;
-    _ZNK7android12SortedVectorINS_8String16EE16do_move_backwardEPvPKvm;
-    _ZNK7android12SortedVectorINS_8String16EE7do_copyEPvPKvm;
-    _ZNK7android12SortedVectorINS_8String16EE8do_splatEPvPKvm;
-    _ZNK7android14IPCThreadState13getCallingPidEv;
-    _ZNK7android14IPCThreadState13getCallingSidEv;
-    _ZNK7android14IPCThreadState13getCallingUidEv;
-    _ZNK7android14IPCThreadState18getCallRestrictionEv;
-    _ZNK7android14IPCThreadState19getStrictModePolicyEv;
-    _ZNK7android14IPCThreadState22getServingStackPointerEv;
-    _ZNK7android14IPCThreadState23getCallingWorkSourceUidEv;
-    _ZNK7android14IPCThreadState25shouldPropagateWorkSourceEv;
-    _ZNK7android14IPCThreadState29getLastTransactionBinderFlagsEv;
-    _ZNK7android14IShellCallback22getInterfaceDescriptorEv;
-    _ZNK7android14MemoryHeapBase7getBaseEv;
-    _ZNK7android14MemoryHeapBase7getSizeEv;
-    _ZNK7android14MemoryHeapBase8getFlagsEv;
-    _ZNK7android14MemoryHeapBase9getDeviceEv;
-    _ZNK7android14MemoryHeapBase9getHeapIDEv;
-    _ZNK7android14MemoryHeapBase9getOffsetEv;
-    _ZNK7android15IResultReceiver22getInterfaceDescriptorEv;
-    _ZNK7android15IServiceManager22getInterfaceDescriptorEv;
-    _ZNK7android15PermissionCache5checkEPbRKNS_8String16Ej;
-    _ZNK7android18BufferedTextOutput9getBufferEv;
-    _ZNK7android18ServiceManagerShim10getServiceERKNS_8String16E;
-    _ZNK7android18ServiceManagerShim12checkServiceERKNS_8String16E;
-    _ZNK7android21IPermissionController22getInterfaceDescriptorEv;
-    _ZNK7android22SimpleBestFitAllocator4dumpEPKc;
-    _ZNK7android22SimpleBestFitAllocator4dumpERNS_7String8EPKc;
-    _ZNK7android22SimpleBestFitAllocator4sizeEv;
-    _ZNK7android22SimpleBestFitAllocator6dump_lEPKc;
-    _ZNK7android22SimpleBestFitAllocator6dump_lERNS_7String8EPKc;
-    _ZNK7android2os15IClientCallback22getInterfaceDescriptorEv;
-    _ZNK7android2os15IServiceManager22getInterfaceDescriptorEv;
-    _ZNK7android2os16IServiceCallback22getInterfaceDescriptorEv;
-    _ZNK7android2os16ParcelableHolder13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os16ServiceDebugInfo13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle10getBooleanERKNS_8String16EPb;
-    _ZNK7android2os17PersistableBundle10getIntKeysEv;
-    _ZNK7android2os17PersistableBundle11getLongKeysEv;
-    _ZNK7android2os17PersistableBundle12getIntVectorERKNS_8String16EPNSt3__16vectorIiNS5_9allocatorIiEEEE;
-    _ZNK7android2os17PersistableBundle13getDoubleKeysEv;
-    _ZNK7android2os17PersistableBundle13getLongVectorERKNS_8String16EPNSt3__16vectorIlNS5_9allocatorIlEEEE;
-    _ZNK7android2os17PersistableBundle13getStringKeysEv;
-    _ZNK7android2os17PersistableBundle13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle14getBooleanKeysEv;
-    _ZNK7android2os17PersistableBundle15getDoubleVectorERKNS_8String16EPNSt3__16vectorIdNS5_9allocatorIdEEEE;
-    _ZNK7android2os17PersistableBundle15getStringVectorERKNS_8String16EPNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
-    _ZNK7android2os17PersistableBundle16getBooleanVectorERKNS_8String16EPNSt3__16vectorIbNS5_9allocatorIbEEEE;
-    _ZNK7android2os17PersistableBundle16getIntVectorKeysEv;
-    _ZNK7android2os17PersistableBundle17getLongVectorKeysEv;
-    _ZNK7android2os17PersistableBundle18writeToParcelInnerEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle19getDoubleVectorKeysEv;
-    _ZNK7android2os17PersistableBundle19getStringVectorKeysEv;
-    _ZNK7android2os17PersistableBundle20getBooleanVectorKeysEv;
-    _ZNK7android2os17PersistableBundle20getPersistableBundleERKNS_8String16EPS1_;
-    _ZNK7android2os17PersistableBundle24getPersistableBundleKeysEv;
-    _ZNK7android2os17PersistableBundle4sizeEv;
-    _ZNK7android2os17PersistableBundle5emptyEv;
-    _ZNK7android2os17PersistableBundle6getIntERKNS_8String16EPi;
-    _ZNK7android2os17PersistableBundle7getLongERKNS_8String16EPl;
-    _ZNK7android2os17PersistableBundle9getDoubleERKNS_8String16EPd;
-    _ZNK7android2os17PersistableBundle9getStringERKNS_8String16EPS2_;
-    _ZNK7android2os20ParcelFileDescriptor13writeToParcelEPNS_6ParcelE;
-    _ZNK7android6binder6Status13writeToParcelEPNS_6ParcelE;
-    _ZNK7android6binder6Status9toString8Ev;
-    _ZNK7android6Parcel10errorCheckEv;
-    _ZNK7android6Parcel10ipcObjectsEv;
-    _ZNK7android6Parcel10readDoubleEPd;
-    _ZNK7android6Parcel10readDoubleEv;
-    _ZNK7android6Parcel10readObjectEb;
-    _ZNK7android6Parcel10readUint32EPj;
-    _ZNK7android6Parcel10readUint32Ev;
-    _ZNK7android6Parcel10readUint64EPm;
-    _ZNK7android6Parcel10readUint64Ev;
-    _ZNK7android6Parcel10scanForFdsEv;
-    _ZNK7android6Parcel11ipcDataSizeEv;
-    _ZNK7android6Parcel11readCStringEv;
-    _ZNK7android6Parcel11readInplaceEm;
-    _ZNK7android6Parcel11readPointerEPm;
-    _ZNK7android6Parcel11readPointerEv;
-    _ZNK7android6Parcel11readString8EPNS_7String8E;
-    _ZNK7android6Parcel11readString8Ev;
-    _ZNK7android6Parcel12dataCapacityEv;
-    _ZNK7android6Parcel12dataPositionEv;
-    _ZNK7android6Parcel12objectsCountEv;
-    _ZNK7android6Parcel12readString16EPNS_8String16E;
-    _ZNK7android6Parcel12readString16EPNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
-    _ZNK7android6Parcel12readString16EPNSt3__18optionalINS_8String16EEE;
-    _ZNK7android6Parcel12readString16Ev;
-    _ZNK7android6Parcel13markSensitiveEv;
-    _ZNK7android6Parcel14checkInterfaceEPNS_7IBinderE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__16vectorIbNS1_9allocatorIbEEEE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIaNS1_9allocatorIaEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIhNS1_9allocatorIhEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
-    _ZNK7android6Parcel14readParcelableEPNS_10ParcelableE;
-    _ZNK7android6Parcel15ipcObjectsCountEv;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__16vectorIfNS1_9allocatorIfEEEE;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__16vectorIiNS1_9allocatorIiEEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__110unique_ptrINS1_6vectorIlNS1_9allocatorIlEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__16vectorIlNS1_9allocatorIlEEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__18optionalINS1_6vectorIlNS1_9allocatorIlEEEEEE;
-    _ZNK7android6Parcel15setDataPositionEm;
-    _ZNK7android6Parcel15unflattenBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel16enforceInterfaceEPKDsmPNS_14IPCThreadStateE;
-    _ZNK7android6Parcel16enforceInterfaceERKNS_8String16EPNS_14IPCThreadStateE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__16vectorIdNS1_9allocatorIdEEEE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
-    _ZNK7android6Parcel16readNativeHandleEv;
-    _ZNK7android6Parcel16readStrongBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel16readStrongBinderEv;
-    _ZNK7android6Parcel16readStrongBinderINS_2os15IClientCallbackEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readStrongBinderINS_2os16IServiceCallbackEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readStrongBinderINS_7content2pm22IPackageChangeObserverEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__110unique_ptrINS1_6vectorImNS1_9allocatorImEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__16vectorImNS1_9allocatorImEEEE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__18optionalINS1_6vectorImNS1_9allocatorImEEEEEE;
-    _ZNK7android6Parcel16validateReadDataEm;
-    _ZNK7android6Parcel17getBlobAshmemSizeEv;
-    _ZNK7android6Parcel17getOpenAshmemSizeEv;
-    _ZNK7android6Parcel17readExceptionCodeEv;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
-    _ZNK7android6Parcel18hasFileDescriptorsEv;
-    _ZNK7android6Parcel18readFileDescriptorEv;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
-    _ZNK7android6Parcel18readString8InplaceEPm;
-    _ZNK7android6Parcel19readString16InplaceEPm;
-    _ZNK7android6Parcel21finishUnflattenBinderERKNS_2spINS_7IBinderEEEPS3_;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
-    _ZNK7android6Parcel24readCallingWorkSourceUidEv;
-    _ZNK7android6Parcel24readNullableStrongBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel24readParcelFileDescriptorEv;
-    _ZNK7android6Parcel24readUniqueFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
-    _ZNK7android6Parcel30readUniqueParcelFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZNK7android6Parcel37updateWorkSourceRequestHeaderPositionEv;
-    _ZNK7android6Parcel4dataEv;
-    _ZNK7android6Parcel4readEPvm;
-    _ZNK7android6Parcel4readERNS0_26FlattenableHelperInterfaceE;
-    _ZNK7android6Parcel5printERNS_10TextOutputEj;
-    _ZNK7android6Parcel7ipcDataEv;
-    _ZNK7android6Parcel8allowFdsEv;
-    _ZNK7android6Parcel8dataSizeEv;
-    _ZNK7android6Parcel8isForRpcEv;
-    _ZNK7android6Parcel8readBlobEmPNS0_12ReadableBlobE;
-    _ZNK7android6Parcel8readBoolEPb;
-    _ZNK7android6Parcel8readBoolEv;
-    _ZNK7android6Parcel8readByteEPa;
-    _ZNK7android6Parcel8readByteEv;
-    _ZNK7android6Parcel8readCharEPDs;
-    _ZNK7android6Parcel8readCharEv;
-    _ZNK7android6Parcel9dataAvailEv;
-    _ZNK7android6Parcel9readFloatEPf;
-    _ZNK7android6Parcel9readFloatEv;
-    _ZNK7android6Parcel9readInt32EPi;
-    _ZNK7android6Parcel9readInt32Ev;
-    _ZNK7android6Parcel9readInt64EPl;
-    _ZNK7android6Parcel9readInt64Ev;
-    _ZNK7android6VectorIiE10do_destroyEPvm;
-    _ZNK7android6VectorIiE12do_constructEPvm;
-    _ZNK7android6VectorIiE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorIiE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorIiE7do_copyEPvPKvm;
-    _ZNK7android6VectorIiE8do_splatEPvPKvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE10do_destroyEPvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE12do_constructEPvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE7do_copyEPvPKvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE8do_splatEPvPKvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE10do_destroyEPvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE12do_constructEPvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE7do_copyEPvPKvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE8do_splatEPvPKvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE10do_destroyEPvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE12do_constructEPvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE7do_copyEPvPKvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE8do_splatEPvPKvm;
-    _ZNK7android6VectorINS_8String16EE10do_destroyEPvm;
-    _ZNK7android6VectorINS_8String16EE12do_constructEPvm;
-    _ZNK7android6VectorINS_8String16EE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorINS_8String16EE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorINS_8String16EE7do_copyEPvPKvm;
-    _ZNK7android6VectorINS_8String16EE8do_splatEPvPKvm;
-    _ZNK7android6VectorIPNS_7BBinderEE10do_destroyEPvm;
-    _ZNK7android6VectorIPNS_7BBinderEE12do_constructEPvm;
-    _ZNK7android6VectorIPNS_7BBinderEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7BBinderEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7BBinderEE7do_copyEPvPKvm;
-    _ZNK7android6VectorIPNS_7BBinderEE8do_splatEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE10do_destroyEPvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE12do_constructEPvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE7do_copyEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE8do_splatEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE10do_destroyEPvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE12do_constructEPvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE7do_copyEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE8do_splatEPvPKvm;
-    _ZNK7android7BBinder10findObjectEPKv;
-    _ZNK7android7BBinder13isBinderAliveEv;
-    _ZNK7android7BBinder22getInterfaceDescriptorEv;
-    _ZNK7android7content2pm18PackageChangeEvent13writeToParcelEPNS_6ParcelE;
-    _ZNK7android7content2pm21IPackageManagerNative22getInterfaceDescriptorEv;
-    _ZNK7android7content2pm22IPackageChangeObserver22getInterfaceDescriptorEv;
-    _ZNK7android7IBinder13checkSubclassEPKv;
-    _ZNK7android7IMemory11fastPointerERKNS_2spINS_7IBinderEEEl;
-    _ZNK7android7IMemory15unsecurePointerEv;
-    _ZNK7android7IMemory22getInterfaceDescriptorEv;
-    _ZNK7android7IMemory4sizeEv;
-    _ZNK7android7IMemory6offsetEv;
-    _ZNK7android7IMemory7pointerEv;
-    _ZNK7android8BpBinder10findObjectEPKv;
-    _ZNK7android8BpBinder10rpcAddressEv;
-    _ZNK7android8BpBinder10rpcSessionEv;
-    _ZNK7android8BpBinder11isRpcBinderEv;
-    _ZNK7android8BpBinder12binderHandleEv;
-    _ZNK7android8BpBinder13isBinderAliveEv;
-    _ZNK7android8BpBinder13ObjectManager4findEPKv;
-    _ZNK7android8BpBinder18isDescriptorCachedEv;
-    _ZNK7android8BpBinder22getInterfaceDescriptorEv;
-    _ZNK7android8BpMemory9getMemoryEPlPm;
-    _ZTCN7android10AllocationE0_NS_10IInterfaceE;
-    _ZTCN7android10AllocationE0_NS_10MemoryBaseE;
-    _ZTCN7android10AllocationE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android10AllocationE0_NS_7IMemoryE;
-    _ZTCN7android10AllocationE0_NS_8BnMemoryE;
-    _ZTCN7android10AllocationE8_NS_7BBinderE;
-    _ZTCN7android10AllocationE8_NS_7IBinderE;
-    _ZTCN7android10MemoryBaseE0_NS_10IInterfaceE;
-    _ZTCN7android10MemoryBaseE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android10MemoryBaseE0_NS_7IMemoryE;
-    _ZTCN7android10MemoryBaseE0_NS_8BnMemoryE;
-    _ZTCN7android10MemoryBaseE8_NS_7BBinderE;
-    _ZTCN7android10MemoryBaseE8_NS_7IBinderE;
-    _ZTCN7android10PoolThreadE0_NS_6ThreadE;
-    _ZTCN7android11IMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BnMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BnMemoryHeapE0_NS_11BnInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android12BnMemoryHeapE0_NS_11IMemoryHeapE;
-    _ZTCN7android12BnMemoryHeapE8_NS_7BBinderE;
-    _ZTCN7android12BnMemoryHeapE8_NS_7IBinderE;
-    _ZTCN7android12BpMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BpMemoryHeapE0_NS_11BpInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android12BpMemoryHeapE0_NS_11IMemoryHeapE;
-    _ZTCN7android12BpMemoryHeapE8_NS_9BpRefBaseE;
-    _ZTCN7android14IShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android14MemoryHeapBaseE64_NS_10IInterfaceE;
-    _ZTCN7android14MemoryHeapBaseE64_NS_11BnInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android14MemoryHeapBaseE64_NS_11IMemoryHeapE;
-    _ZTCN7android14MemoryHeapBaseE64_NS_12BnMemoryHeapE;
-    _ZTCN7android14MemoryHeapBaseE72_NS_7BBinderE;
-    _ZTCN7android14MemoryHeapBaseE72_NS_7IBinderE;
-    _ZTCN7android15BnShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android15BnShellCallbackE0_NS_11BnInterfaceINS_14IShellCallbackEEE;
-    _ZTCN7android15BnShellCallbackE0_NS_14IShellCallbackE;
-    _ZTCN7android15BnShellCallbackE8_NS_7BBinderE;
-    _ZTCN7android15BnShellCallbackE8_NS_7IBinderE;
-    _ZTCN7android15BpShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android15BpShellCallbackE0_NS_11BpInterfaceINS_14IShellCallbackEEE;
-    _ZTCN7android15BpShellCallbackE0_NS_14IShellCallbackE;
-    _ZTCN7android15BpShellCallbackE8_NS_9BpRefBaseE;
-    _ZTCN7android15IResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android15IServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android16BnResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android16BnResultReceiverE0_NS_11BnInterfaceINS_15IResultReceiverEEE;
-    _ZTCN7android16BnResultReceiverE0_NS_15IResultReceiverE;
-    _ZTCN7android16BnResultReceiverE8_NS_7BBinderE;
-    _ZTCN7android16BnResultReceiverE8_NS_7IBinderE;
-    _ZTCN7android16BpResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android16BpResultReceiverE0_NS_11BpInterfaceINS_15IResultReceiverEEE;
-    _ZTCN7android16BpResultReceiverE0_NS_15IResultReceiverE;
-    _ZTCN7android16BpResultReceiverE8_NS_9BpRefBaseE;
-    _ZTCN7android18ServiceManagerShimE0_NS_10IInterfaceE;
-    _ZTCN7android18ServiceManagerShimE0_NS_15IServiceManagerE;
-    _ZTCN7android21IPermissionControllerE0_NS_10IInterfaceE;
-    _ZTCN7android22BnPermissionControllerE0_NS_10IInterfaceE;
-    _ZTCN7android22BnPermissionControllerE0_NS_11BnInterfaceINS_21IPermissionControllerEEE;
-    _ZTCN7android22BnPermissionControllerE0_NS_21IPermissionControllerE;
-    _ZTCN7android22BnPermissionControllerE8_NS_7BBinderE;
-    _ZTCN7android22BnPermissionControllerE8_NS_7IBinderE;
-    _ZTCN7android22BpPermissionControllerE0_NS_10IInterfaceE;
-    _ZTCN7android22BpPermissionControllerE0_NS_11BpInterfaceINS_21IPermissionControllerEEE;
-    _ZTCN7android22BpPermissionControllerE0_NS_21IPermissionControllerE;
-    _ZTCN7android22BpPermissionControllerE8_NS_9BpRefBaseE;
-    _ZTCN7android2os15IClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os15IServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnClientCallbackE0_NS0_15IClientCallbackE;
-    _ZTCN7android2os16BnClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnClientCallbackE0_NS_11BnInterfaceINS0_15IClientCallbackEEE;
-    _ZTCN7android2os16BnClientCallbackE8_NS_7BBinderE;
-    _ZTCN7android2os16BnClientCallbackE8_NS_7IBinderE;
-    _ZTCN7android2os16BnServiceManagerE0_NS0_15IServiceManagerE;
-    _ZTCN7android2os16BnServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnServiceManagerE0_NS_11BnInterfaceINS0_15IServiceManagerEEE;
-    _ZTCN7android2os16BnServiceManagerE8_NS_7BBinderE;
-    _ZTCN7android2os16BnServiceManagerE8_NS_7IBinderE;
-    _ZTCN7android2os16BpClientCallbackE0_NS0_15IClientCallbackE;
-    _ZTCN7android2os16BpClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BpClientCallbackE0_NS_11BpInterfaceINS0_15IClientCallbackEEE;
-    _ZTCN7android2os16BpClientCallbackE8_NS_9BpRefBaseE;
-    _ZTCN7android2os16BpServiceManagerE0_NS0_15IServiceManagerE;
-    _ZTCN7android2os16BpServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BpServiceManagerE0_NS_11BpInterfaceINS0_15IServiceManagerEEE;
-    _ZTCN7android2os16BpServiceManagerE8_NS_9BpRefBaseE;
-    _ZTCN7android2os16IServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS0_16IServiceCallbackE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS_11BnInterfaceINS0_16IServiceCallbackEEE;
-    _ZTCN7android2os17BnServiceCallbackE8_NS_7BBinderE;
-    _ZTCN7android2os17BnServiceCallbackE8_NS_7IBinderE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS0_16IServiceCallbackE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS_11BpInterfaceINS0_16IServiceCallbackEEE;
-    _ZTCN7android2os17BpServiceCallbackE8_NS_9BpRefBaseE;
-    _ZTCN7android7BBinderE0_NS_7IBinderE;
-    _ZTCN7android7content2pm21IPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_11BnInterfaceINS1_21IPackageManagerNativeEEE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE8_NS_7BBinderE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE8_NS_7IBinderE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_11BpInterfaceINS1_21IPackageManagerNativeEEE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE8_NS_9BpRefBaseE;
-    _ZTCN7android7content2pm22IPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_11BnInterfaceINS1_22IPackageChangeObserverEEE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE8_NS_7BBinderE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE8_NS_7IBinderE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_11BpInterfaceINS1_22IPackageChangeObserverEEE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE8_NS_9BpRefBaseE;
-    _ZTCN7android7IMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BnMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BnMemoryE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android8BnMemoryE0_NS_7IMemoryE;
-    _ZTCN7android8BnMemoryE8_NS_7BBinderE;
-    _ZTCN7android8BnMemoryE8_NS_7IBinderE;
-    _ZTCN7android8BpBinderE0_NS_7IBinderE;
-    _ZTCN7android8BpMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BpMemoryE0_NS_11BpInterfaceINS_7IMemoryEEE;
-    _ZTCN7android8BpMemoryE0_NS_7IMemoryE;
-    _ZTCN7android8BpMemoryE8_NS_9BpRefBaseE;
-    _ZTCN7android9HeapCacheE0_NS_7IBinder14DeathRecipientE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_13basic_istreamIcS2_EE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_14basic_iostreamIcS2_EE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE16_NS_13basic_ostreamIcS2_EE;
-    _ZThn8_N7android10AllocationD0Ev;
-    _ZThn8_N7android10AllocationD1Ev;
-    _ZThn8_N7android10MemoryBaseD0Ev;
-    _ZThn8_N7android10MemoryBaseD1Ev;
-    _ZThn8_N7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn8_N7android12BnMemoryHeapD0Ev;
-    _ZThn8_N7android12BnMemoryHeapD1Ev;
-    _ZThn8_N7android12BpMemoryHeapD0Ev;
-    _ZThn8_N7android12BpMemoryHeapD1Ev;
-    _ZThn8_N7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn8_N7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn8_N7android22BnPermissionController10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn8_N7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn8_N7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn8_N7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn8_N7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZThn8_N7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZThn8_N7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn8_N7android8BnMemoryD0Ev;
-    _ZThn8_N7android8BnMemoryD1Ev;
-    _ZThn8_N7android8BpMemoryD0Ev;
-    _ZThn8_N7android8BpMemoryD1Ev;
-    _ZTTN7android10AllocationE;
-    _ZTTN7android10IInterfaceE;
-    _ZTTN7android10MemoryBaseE;
-    _ZTTN7android10PoolThreadE;
-    _ZTTN7android10RpcSessionE;
-    _ZTTN7android11IMemoryHeapE;
-    _ZTTN7android12BnMemoryHeapE;
-    _ZTTN7android12BpMemoryHeapE;
-    _ZTTN7android12ProcessStateE;
-    _ZTTN7android14IShellCallbackE;
-    _ZTTN7android14MemoryHeapBaseE;
-    _ZTTN7android15BnShellCallbackE;
-    _ZTTN7android15BpShellCallbackE;
-    _ZTTN7android15IResultReceiverE;
-    _ZTTN7android15IServiceManagerE;
-    _ZTTN7android16BnResultReceiverE;
-    _ZTTN7android16BpResultReceiverE;
-    _ZTTN7android18ServiceManagerShimE;
-    _ZTTN7android21IPermissionControllerE;
-    _ZTTN7android22BnPermissionControllerE;
-    _ZTTN7android22BpPermissionControllerE;
-    _ZTTN7android2os15IClientCallbackE;
-    _ZTTN7android2os15IServiceManagerE;
-    _ZTTN7android2os16BnClientCallbackE;
-    _ZTTN7android2os16BnServiceManagerE;
-    _ZTTN7android2os16BpClientCallbackE;
-    _ZTTN7android2os16BpServiceManagerE;
-    _ZTTN7android2os16IServiceCallbackE;
-    _ZTTN7android2os17BnServiceCallbackE;
-    _ZTTN7android2os17BpServiceCallbackE;
-    _ZTTN7android7BBinderE;
-    _ZTTN7android7content2pm21IPackageManagerNativeE;
-    _ZTTN7android7content2pm22BnPackageManagerNativeE;
-    _ZTTN7android7content2pm22BpPackageManagerNativeE;
-    _ZTTN7android7content2pm22IPackageChangeObserverE;
-    _ZTTN7android7content2pm23BnPackageChangeObserverE;
-    _ZTTN7android7content2pm23BpPackageChangeObserverE;
-    _ZTTN7android7IBinderE;
-    _ZTTN7android7IMemoryE;
-    _ZTTN7android8BnMemoryE;
-    _ZTTN7android8BpBinderE;
-    _ZTTN7android8BpMemoryE;
-    _ZTTN7android9BpRefBaseE;
-    _ZTTN7android9HeapCacheE;
-    _ZTTN7android9RpcServerE;
-    _ZTTNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE;
-    _ZTv0_n24_N7android10AllocationD0Ev;
-    _ZTv0_n24_N7android10AllocationD1Ev;
-    _ZTv0_n24_N7android10IInterfaceD0Ev;
-    _ZTv0_n24_N7android10IInterfaceD1Ev;
-    _ZTv0_n24_N7android10MemoryBaseD0Ev;
-    _ZTv0_n24_N7android10MemoryBaseD1Ev;
-    _ZTv0_n24_N7android10RpcSessionD0Ev;
-    _ZTv0_n24_N7android10RpcSessionD1Ev;
-    _ZTv0_n24_N7android11IMemoryHeapD0Ev;
-    _ZTv0_n24_N7android11IMemoryHeapD1Ev;
-    _ZTv0_n24_N7android12BnMemoryHeapD0Ev;
-    _ZTv0_n24_N7android12BnMemoryHeapD1Ev;
-    _ZTv0_n24_N7android12BpMemoryHeapD0Ev;
-    _ZTv0_n24_N7android12BpMemoryHeapD1Ev;
-    _ZTv0_n24_N7android12ProcessStateD0Ev;
-    _ZTv0_n24_N7android12ProcessStateD1Ev;
-    _ZTv0_n24_N7android14IShellCallbackD0Ev;
-    _ZTv0_n24_N7android14IShellCallbackD1Ev;
-    _ZTv0_n24_N7android14MemoryHeapBaseD0Ev;
-    _ZTv0_n24_N7android14MemoryHeapBaseD1Ev;
-    _ZTv0_n24_N7android15IResultReceiverD0Ev;
-    _ZTv0_n24_N7android15IResultReceiverD1Ev;
-    _ZTv0_n24_N7android15IServiceManagerD0Ev;
-    _ZTv0_n24_N7android15IServiceManagerD1Ev;
-    _ZTv0_n24_N7android21IPermissionControllerD0Ev;
-    _ZTv0_n24_N7android21IPermissionControllerD1Ev;
-    _ZTv0_n24_N7android2os15IClientCallbackD0Ev;
-    _ZTv0_n24_N7android2os15IClientCallbackD1Ev;
-    _ZTv0_n24_N7android2os15IServiceManagerD0Ev;
-    _ZTv0_n24_N7android2os15IServiceManagerD1Ev;
-    _ZTv0_n24_N7android2os16IServiceCallbackD0Ev;
-    _ZTv0_n24_N7android2os16IServiceCallbackD1Ev;
-    _ZTv0_n24_N7android7BBinderD0Ev;
-    _ZTv0_n24_N7android7BBinderD1Ev;
-    _ZTv0_n24_N7android7content2pm21IPackageManagerNativeD0Ev;
-    _ZTv0_n24_N7android7content2pm21IPackageManagerNativeD1Ev;
-    _ZTv0_n24_N7android7content2pm22IPackageChangeObserverD0Ev;
-    _ZTv0_n24_N7android7content2pm22IPackageChangeObserverD1Ev;
-    _ZTv0_n24_N7android7IBinderD0Ev;
-    _ZTv0_n24_N7android7IBinderD1Ev;
-    _ZTv0_n24_N7android7IMemoryD0Ev;
-    _ZTv0_n24_N7android7IMemoryD1Ev;
-    _ZTv0_n24_N7android8BnMemoryD0Ev;
-    _ZTv0_n24_N7android8BnMemoryD1Ev;
-    _ZTv0_n24_N7android8BpBinderD0Ev;
-    _ZTv0_n24_N7android8BpBinderD1Ev;
-    _ZTv0_n24_N7android8BpMemoryD0Ev;
-    _ZTv0_n24_N7android8BpMemoryD1Ev;
-    _ZTv0_n24_N7android9BpRefBaseD0Ev;
-    _ZTv0_n24_N7android9BpRefBaseD1Ev;
-    _ZTv0_n24_N7android9HeapCacheD0Ev;
-    _ZTv0_n24_N7android9HeapCacheD1Ev;
-    _ZTv0_n24_N7android9RpcServerD0Ev;
-    _ZTv0_n24_N7android9RpcServerD1Ev;
-    _ZTv0_n32_N7android14MemoryHeapBaseD0Ev;
-    _ZTv0_n32_N7android14MemoryHeapBaseD1Ev;
-    _ZTv0_n32_N7android8BpBinder10onFirstRefEv;
-    _ZTv0_n32_N7android9BpRefBase10onFirstRefEv;
-    _ZTv0_n40_N7android8BpBinder15onLastStrongRefEPKv;
-    _ZTv0_n40_N7android9BpRefBase15onLastStrongRefEPKv;
-    _ZTv0_n48_N7android8BpBinder20onIncStrongAttemptedEjPKv;
-    _ZTv0_n48_N7android9BpRefBase20onIncStrongAttemptedEjPKv;
-    _ZTv0_n56_NK7android14MemoryHeapBase9getHeapIDEv;
-    _ZTv0_n64_NK7android14MemoryHeapBase7getBaseEv;
-    _ZTv0_n72_NK7android14MemoryHeapBase7getSizeEv;
-    _ZTv0_n80_NK7android14MemoryHeapBase8getFlagsEv;
-    _ZTv0_n88_NK7android14MemoryHeapBase9getOffsetEv;
-    _ZTVN7android10AllocationE;
-    _ZTVN7android10IInterfaceE;
-    _ZTVN7android10MemoryBaseE;
-    _ZTVN7android10PoolThreadE;
-    _ZTVN7android10RpcSession13RpcConnectionE;
-    _ZTVN7android10RpcSessionE;
-    _ZTVN7android10TextOutputE;
-    _ZTVN7android11IMemoryHeapE;
-    _ZTVN7android12BnMemoryHeapE;
-    _ZTVN7android12BpMemoryHeapE;
-    _ZTVN7android12FdTextOutputE;
-    _ZTVN7android12MemoryDealerE;
-    _ZTVN7android12ProcessStateE;
-    _ZTVN7android12SortedVectorINS_15PermissionCache5EntryEEE;
-    _ZTVN7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEEE;
-    _ZTVN7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEEE;
-    _ZTVN7android12SortedVectorINS_8String16EEE;
-    _ZTVN7android13LogTextOutputE;
-    _ZTVN7android14IShellCallbackE;
-    _ZTVN7android14MemoryHeapBaseE;
-    _ZTVN7android15BnShellCallbackE;
-    _ZTVN7android15BpShellCallbackE;
-    _ZTVN7android15IResultReceiverE;
-    _ZTVN7android15IServiceManagerE;
-    _ZTVN7android16BnResultReceiverE;
-    _ZTVN7android16BpResultReceiverE;
-    _ZTVN7android17InetSocketAddressE;
-    _ZTVN7android17UnixSocketAddressE;
-    _ZTVN7android18BufferedTextOutput11BufferStateE;
-    _ZTVN7android18BufferedTextOutputE;
-    _ZTVN7android18ServiceManagerShimE;
-    _ZTVN7android18VsockSocketAddressE;
-    _ZTVN7android21IPermissionControllerE;
-    _ZTVN7android22BnPermissionControllerE;
-    _ZTVN7android22BpPermissionControllerE;
-    _ZTVN7android2os15IClientCallbackE;
-    _ZTVN7android2os15IServiceManagerE;
-    _ZTVN7android2os16BnClientCallbackE;
-    _ZTVN7android2os16BnServiceManagerE;
-    _ZTVN7android2os16BpClientCallbackE;
-    _ZTVN7android2os16BpServiceManagerE;
-    _ZTVN7android2os16IServiceCallbackE;
-    _ZTVN7android2os16ParcelableHolderE;
-    _ZTVN7android2os16ServiceDebugInfoE;
-    _ZTVN7android2os17BnServiceCallbackE;
-    _ZTVN7android2os17BpServiceCallbackE;
-    _ZTVN7android2os17PersistableBundleE;
-    _ZTVN7android2os20ParcelFileDescriptorE;
-    _ZTVN7android6VectorIiEE;
-    _ZTVN7android6VectorINS_12ProcessState12handle_entryEEE;
-    _ZTVN7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEEE;
-    _ZTVN7android6VectorINS_8BpBinder8ObituaryEEE;
-    _ZTVN7android6VectorINS_8String16EEE;
-    _ZTVN7android6VectorIPNS_7BBinderEEE;
-    _ZTVN7android6VectorIPNS_7RefBase12weakref_typeEEE;
-    _ZTVN7android6VectorIPNS_7RefBaseEEE;
-    _ZTVN7android7BBinderE;
-    _ZTVN7android7content2pm18PackageChangeEventE;
-    _ZTVN7android7content2pm21IPackageManagerNativeE;
-    _ZTVN7android7content2pm22BnPackageManagerNativeE;
-    _ZTVN7android7content2pm22BpPackageManagerNativeE;
-    _ZTVN7android7content2pm22IPackageChangeObserverE;
-    _ZTVN7android7content2pm23BnPackageChangeObserverE;
-    _ZTVN7android7content2pm23BpPackageChangeObserverE;
-    _ZTVN7android7IBinderE;
-    _ZTVN7android7IMemoryE;
-    _ZTVN7android8BnMemoryE;
-    _ZTVN7android8BpBinderE;
-    _ZTVN7android8BpMemoryE;
-    _ZTVN7android9BpRefBaseE;
-    _ZTVN7android9HeapCacheE;
-    _ZTVN7android9RpcServerE;
-    _ZTvn8_n32_N7android14MemoryHeapBaseD0Ev;
-    _ZTvn8_n32_N7android14MemoryHeapBaseD1Ev;
-  local:
-    *;
-};
diff --git a/libs/binder/libbinder.arm64.vendor.map b/libs/binder/libbinder.arm64.vendor.map
deleted file mode 100644
index df6aa66..0000000
--- a/libs/binder/libbinder.arm64.vendor.map
+++ /dev/null
@@ -1,1320 +0,0 @@
-# b/190148312: Populate with correct list of ABI symbols
-LIBBINDER {
-  global:
-    getBinderKernelReferences;
-    kDefaultDriver;
-    _ZN7android10AllocationC1ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEElm;
-    _ZN7android10AllocationC2ERKNS_2spINS_12MemoryDealerEEERKNS1_INS_11IMemoryHeapEEElm;
-    _ZN7android10AllocationD0Ev;
-    _ZN7android10AllocationD1Ev;
-    _ZN7android10AllocationD2Ev;
-    _ZN7android10IInterface8asBinderEPKS0_;
-    _ZN7android10IInterface8asBinderERKNS_2spIS0_EE;
-    _ZN7android10IInterfaceC2Ev;
-    _ZN7android10IInterfaceD0Ev;
-    _ZN7android10IInterfaceD1Ev;
-    _ZN7android10IInterfaceD2Ev;
-    _ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEElm;
-    _ZN7android10MemoryBaseC2ERKNS_2spINS_11IMemoryHeapEEElm;
-    _ZN7android10MemoryBaseD0Ev;
-    _ZN7android10MemoryBaseD1Ev;
-    _ZN7android10MemoryBaseD2Ev;
-    _ZN7android10RpcAddress14readFromParcelERKNS_6ParcelE;
-    _ZN7android10RpcAddress15fromRawEmbeddedEPKNS_14RpcWireAddressE;
-    _ZN7android10RpcAddress4zeroEv;
-    _ZN7android10RpcAddress6uniqueEv;
-    _ZN7android10RpcAddressC1Ev;
-    _ZN7android10RpcAddressC2Ev;
-    _ZN7android10RpcAddressD1Ev;
-    _ZN7android10RpcAddressD2Ev;
-    _ZN7android10RpcSession12setForServerERKNS_2wpINS_9RpcServerEEEi;
-    _ZN7android10RpcSession13getRootObjectEv;
-    _ZN7android10RpcSession13sendDecStrongERKNS_10RpcAddressE;
-    _ZN7android10RpcSession15setupInetClientEPKcj;
-    _ZN7android10RpcSession15terminateLockedEv;
-    _ZN7android10RpcSession16setupVsockClientEjj;
-    _ZN7android10RpcSession17setupSocketClientERKNS_16RpcSocketAddressE;
-    _ZN7android10RpcSession19addClientConnectionENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession19ExclusiveConnection14findConnectionEiPNS_2spINS0_13RpcConnectionEEES5_RNSt3__16vectorIS4_NS6_9allocatorIS4_EEEEm;
-    _ZN7android10RpcSession19ExclusiveConnectionC1ERKNS_2spIS0_EENS0_13ConnectionUseE;
-    _ZN7android10RpcSession19ExclusiveConnectionC2ERKNS_2spIS0_EENS0_13ConnectionUseE;
-    _ZN7android10RpcSession19ExclusiveConnectionD1Ev;
-    _ZN7android10RpcSession19ExclusiveConnectionD2Ev;
-    _ZN7android10RpcSession19getRemoteMaxThreadsEPm;
-    _ZN7android10RpcSession20setupOneSocketClientERKNS_16RpcSocketAddressEi;
-    _ZN7android10RpcSession21setupUnixDomainClientEPKc;
-    _ZN7android10RpcSession22addNullDebuggingClientEv;
-    _ZN7android10RpcSession22removeServerConnectionERKNS_2spINS0_13RpcConnectionEEE;
-    _ZN7android10RpcSession24assignServerToThisThreadENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession4joinENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android10RpcSession4makeEv;
-    _ZN7android10RpcSession6readIdEv;
-    _ZN7android10RpcSession6serverEv;
-    _ZN7android10RpcSession7preJoinENSt3__16threadE;
-    _ZN7android10RpcSession8transactERKNS_10RpcAddressEjRKNS_6ParcelEPS4_j;
-    _ZN7android10RpcSessionC1Ev;
-    _ZN7android10RpcSessionC2Ev;
-    _ZN7android10RpcSessionD0Ev;
-    _ZN7android10RpcSessionD1Ev;
-    _ZN7android10RpcSessionD2Ev;
-    _ZN7android10TextOutputC2Ev;
-    _ZN7android10TextOutputD0Ev;
-    _ZN7android10TextOutputD1Ev;
-    _ZN7android10TextOutputD2Ev;
-    _ZN7android10zeroMemoryEPhm;
-    _ZN7android11BnInterfaceINS_11IMemoryHeapEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_14IShellCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_15IResultReceiverEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os15IClientCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os15IServiceManagerEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_2os16IServiceCallbackEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7content2pm21IPackageManagerNativeEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7content2pm22IPackageChangeObserverEE10onAsBinderEv;
-    _ZN7android11BnInterfaceINS_7IMemoryEE10onAsBinderEv;
-    _ZN7android11IMemoryHeap10descriptorE;
-    _ZN7android11IMemoryHeap11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android11IMemoryHeap12default_implE;
-    _ZN7android11IMemoryHeap14getDefaultImplEv;
-    _ZN7android11IMemoryHeap14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android11IMemoryHeapC2Ev;
-    _ZN7android11IMemoryHeapD0Ev;
-    _ZN7android11IMemoryHeapD1Ev;
-    _ZN7android11IMemoryHeapD2Ev;
-    _ZN7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android12BnMemoryHeapC2Ev;
-    _ZN7android12BnMemoryHeapD0Ev;
-    _ZN7android12BnMemoryHeapD1Ev;
-    _ZN7android12BnMemoryHeapD2Ev;
-    _ZN7android12BpMemoryHeapC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android12BpMemoryHeapC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android12BpMemoryHeapD0Ev;
-    _ZN7android12BpMemoryHeapD1Ev;
-    _ZN7android12BpMemoryHeapD2Ev;
-    _ZN7android12gTextBuffersE;
-    _ZN7android12MemoryDealer10deallocateEm;
-    _ZN7android12MemoryDealer22getAllocationAlignmentEv;
-    _ZN7android12MemoryDealer8allocateEm;
-    _ZN7android12MemoryDealerC1EmPKcj;
-    _ZN7android12MemoryDealerC2EmPKcj;
-    _ZN7android12MemoryDealerD0Ev;
-    _ZN7android12MemoryDealerD1Ev;
-    _ZN7android12MemoryDealerD2Ev;
-    _ZN7android12printHexDataEiPKvmmimbPFvPvPKcES2_;
-    _ZN7android12ProcessState10selfOrNullEv;
-    _ZN7android12ProcessState13expungeHandleEiPNS_7IBinderE;
-    _ZN7android12ProcessState13getDriverNameEv;
-    _ZN7android12ProcessState14initWithDriverEPKc;
-    _ZN7android12ProcessState15startThreadPoolEv;
-    _ZN7android12ProcessState16getContextObjectERKNS_2spINS_7IBinderEEE;
-    _ZN7android12ProcessState17spawnPooledThreadEb;
-    _ZN7android12ProcessState18giveThreadPoolNameEv;
-    _ZN7android12ProcessState18lookupHandleLockedEi;
-    _ZN7android12ProcessState18setCallRestrictionENS0_15CallRestrictionE;
-    _ZN7android12ProcessState19getKernelReferencesEmPm;
-    _ZN7android12ProcessState20becomeContextManagerEv;
-    _ZN7android12ProcessState20makeBinderThreadNameEv;
-    _ZN7android12ProcessState23getStrongProxyForHandleEi;
-    _ZN7android12ProcessState24getStrongRefCountForNodeERKNS_2spINS_8BpBinderEEE;
-    _ZN7android12ProcessState25enableOnewaySpamDetectionEb;
-    _ZN7android12ProcessState27setThreadPoolMaxThreadCountEm;
-    _ZN7android12ProcessState4initEPKcb;
-    _ZN7android12ProcessState4selfEv;
-    _ZN7android12ProcessStateC1EPKc;
-    _ZN7android12ProcessStateC2EPKc;
-    _ZN7android12ProcessStateD0Ev;
-    _ZN7android12ProcessStateD1Ev;
-    _ZN7android12ProcessStateD2Ev;
-    _ZN7android13printTypeCodeEjPFvPvPKcES0_;
-    _ZN7android14IPCThreadState10freeBufferEPNS_6ParcelEPKhmPKym;
-    _ZN7android14IPCThreadState10selfOrNullEv;
-    _ZN7android14IPCThreadState11clearCallerEv;
-    _ZN7android14IPCThreadState11stopProcessEb;
-    _ZN7android14IPCThreadState12setupPollingEPi;
-    _ZN7android14IPCThreadState13decWeakHandleEi;
-    _ZN7android14IPCThreadState13expungeHandleEiPNS_7IBinderE;
-    _ZN7android14IPCThreadState13flushCommandsEv;
-    _ZN7android14IPCThreadState13flushIfNeededEv;
-    _ZN7android14IPCThreadState13incWeakHandleEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState14clearLastErrorEv;
-    _ZN7android14IPCThreadState14executeCommandEi;
-    _ZN7android14IPCThreadState14joinThreadPoolEb;
-    _ZN7android14IPCThreadState14talkWithDriverEb;
-    _ZN7android14IPCThreadState15decStrongHandleEi;
-    _ZN7android14IPCThreadState15incStrongHandleEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState15waitForResponseEPNS_6ParcelEPi;
-    _ZN7android14IPCThreadState16threadDestructorEPv;
-    _ZN7android14IPCThreadState18setCallRestrictionENS_12ProcessState15CallRestrictionE;
-    _ZN7android14IPCThreadState19setStrictModePolicyEi;
-    _ZN7android14IPCThreadState19setTheContextObjectERKNS_2spINS_7BBinderEEE;
-    _ZN7android14IPCThreadState20clearCallingIdentityEv;
-    _ZN7android14IPCThreadState20getAndExecuteCommandEv;
-    _ZN7android14IPCThreadState20getProcessFreezeInfoEiPbS1_;
-    _ZN7android14IPCThreadState20handlePolledCommandsEv;
-    _ZN7android14IPCThreadState20processPendingDerefsEv;
-    _ZN7android14IPCThreadState20writeTransactionDataEijijRKNS_6ParcelEPi;
-    _ZN7android14IPCThreadState22attemptIncStrongHandleEi;
-    _ZN7android14IPCThreadState22clearCallingWorkSourceEv;
-    _ZN7android14IPCThreadState22clearDeathNotificationEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState22processPostWriteDerefsEv;
-    _ZN7android14IPCThreadState22restoreCallingIdentityEl;
-    _ZN7android14IPCThreadState23setCallingWorkSourceUidEj;
-    _ZN7android14IPCThreadState24clearPropagateWorkSourceEv;
-    _ZN7android14IPCThreadState24requestDeathNotificationEiPNS_8BpBinderE;
-    _ZN7android14IPCThreadState24restoreCallingWorkSourceEl;
-    _ZN7android14IPCThreadState25blockUntilThreadAvailableEv;
-    _ZN7android14IPCThreadState27disableBackgroundSchedulingEb;
-    _ZN7android14IPCThreadState28backgroundSchedulingDisabledEv;
-    _ZN7android14IPCThreadState29setLastTransactionBinderFlagsEi;
-    _ZN7android14IPCThreadState41setCallingWorkSourceUidWithoutPropagationEj;
-    _ZN7android14IPCThreadState4selfEv;
-    _ZN7android14IPCThreadState6freezeEibj;
-    _ZN7android14IPCThreadState7processEv;
-    _ZN7android14IPCThreadState8shutdownEv;
-    _ZN7android14IPCThreadState8transactEijRKNS_6ParcelEPS1_j;
-    _ZN7android14IPCThreadState9sendReplyERKNS_6ParcelEj;
-    _ZN7android14IPCThreadStateC1Ev;
-    _ZN7android14IPCThreadStateC2Ev;
-    _ZN7android14IPCThreadStateD1Ev;
-    _ZN7android14IPCThreadStateD2Ev;
-    _ZN7android14IShellCallback10descriptorE;
-    _ZN7android14IShellCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android14IShellCallback12default_implE;
-    _ZN7android14IShellCallback14getDefaultImplEv;
-    _ZN7android14IShellCallback14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android14IShellCallbackC2Ev;
-    _ZN7android14IShellCallbackD0Ev;
-    _ZN7android14IShellCallbackD1Ev;
-    _ZN7android14IShellCallbackD2Ev;
-    _ZN7android14MemoryHeapBase4initEiPvmiPKc;
-    _ZN7android14MemoryHeapBase5mapfdEibml;
-    _ZN7android14MemoryHeapBase7disposeEv;
-    _ZN7android14MemoryHeapBaseC1Eimjl;
-    _ZN7android14MemoryHeapBaseC1EmjPKc;
-    _ZN7android14MemoryHeapBaseC1EPKcmj;
-    _ZN7android14MemoryHeapBaseC1Ev;
-    _ZN7android14MemoryHeapBaseC2Eimjl;
-    _ZN7android14MemoryHeapBaseC2EmjPKc;
-    _ZN7android14MemoryHeapBaseC2EPKcmj;
-    _ZN7android14MemoryHeapBaseC2Ev;
-    _ZN7android14MemoryHeapBaseD0Ev;
-    _ZN7android14MemoryHeapBaseD1Ev;
-    _ZN7android14MemoryHeapBaseD2Ev;
-    _ZN7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android15IResultReceiver10descriptorE;
-    _ZN7android15IResultReceiver11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android15IResultReceiver12default_implE;
-    _ZN7android15IResultReceiver14getDefaultImplEv;
-    _ZN7android15IResultReceiver14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android15IResultReceiverC2Ev;
-    _ZN7android15IResultReceiverD0Ev;
-    _ZN7android15IResultReceiverD1Ev;
-    _ZN7android15IResultReceiverD2Ev;
-    _ZN7android15IServiceManagerC2Ev;
-    _ZN7android15IServiceManagerD0Ev;
-    _ZN7android15IServiceManagerD1Ev;
-    _ZN7android15IServiceManagerD2Ev;
-    _ZN7android15stringForIndentEi;
-    _ZN7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android18BufferedTextOutput10moveIndentEi;
-    _ZN7android18BufferedTextOutput10pushBundleEv;
-    _ZN7android18BufferedTextOutput5printEPKcm;
-    _ZN7android18BufferedTextOutput9popBundleEv;
-    _ZN7android18BufferedTextOutputC2Ej;
-    _ZN7android18BufferedTextOutputD0Ev;
-    _ZN7android18BufferedTextOutputD1Ev;
-    _ZN7android18BufferedTextOutputD2Ev;
-    _ZN7android18ServiceManagerShim10addServiceERKNS_8String16ERKNS_2spINS_7IBinderEEEbi;
-    _ZN7android18ServiceManagerShim10isDeclaredERKNS_8String16E;
-    _ZN7android18ServiceManagerShim12listServicesEi;
-    _ZN7android18ServiceManagerShim14waitForServiceERKNS_8String16E;
-    _ZN7android18ServiceManagerShim16updatableViaApexERKNS_8String16E;
-    _ZN7android18ServiceManagerShim20getDeclaredInstancesERKNS_8String16E;
-    _ZN7android18ServiceManagerShimC1ERKNS_2spINS_2os15IServiceManagerEEE;
-    _ZN7android18ServiceManagerShimC2ERKNS_2spINS_2os15IServiceManagerEEE;
-    _ZN7android18the_context_objectE;
-    _ZN7android21defaultServiceManagerEv;
-    _ZN7android22SimpleBestFitAllocator10deallocateEm;
-    _ZN7android22SimpleBestFitAllocator12kMemoryAlignE;
-    _ZN7android22SimpleBestFitAllocator5allocEmj;
-    _ZN7android22SimpleBestFitAllocator7deallocEm;
-    _ZN7android22SimpleBestFitAllocator8allocateEmj;
-    _ZN7android22SimpleBestFitAllocatorC1Em;
-    _ZN7android22SimpleBestFitAllocatorC2Em;
-    _ZN7android22SimpleBestFitAllocatorD1Ev;
-    _ZN7android22SimpleBestFitAllocatorD2Ev;
-    _ZN7android24setDefaultServiceManagerERKNS_2spINS_15IServiceManagerEEE;
-    _ZN7android2os15IClientCallback10descriptorE;
-    _ZN7android2os15IClientCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os15IClientCallback12default_implE;
-    _ZN7android2os15IClientCallback14getDefaultImplEv;
-    _ZN7android2os15IClientCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os15IClientCallbackC2Ev;
-    _ZN7android2os15IClientCallbackD0Ev;
-    _ZN7android2os15IClientCallbackD1Ev;
-    _ZN7android2os15IClientCallbackD2Ev;
-    _ZN7android2os15IServiceManager10descriptorE;
-    _ZN7android2os15IServiceManager11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os15IServiceManager12default_implE;
-    _ZN7android2os15IServiceManager14getDefaultImplEv;
-    _ZN7android2os15IServiceManager14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os15IServiceManagerC2Ev;
-    _ZN7android2os15IServiceManagerD0Ev;
-    _ZN7android2os15IServiceManagerD1Ev;
-    _ZN7android2os15IServiceManagerD2Ev;
-    _ZN7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os16BnClientCallbackC2Ev;
-    _ZN7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os16BnServiceManagerC2Ev;
-    _ZN7android2os16BpClientCallback9onClientsERKNS_2spINS_7IBinderEEEb;
-    _ZN7android2os16BpClientCallbackC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpClientCallbackC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager10addServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEEbi;
-    _ZN7android2os16BpServiceManager10getServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager10isDeclaredERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPb;
-    _ZN7android2os16BpServiceManager12checkServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager12listServicesEiPNSt3__16vectorINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS7_IS9_EEEE;
-    _ZN7android2os16BpServiceManager16updatableViaApexERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_8optionalIS8_EE;
-    _ZN7android2os16BpServiceManager19getServiceDebugInfoEPNSt3__16vectorINS0_16ServiceDebugInfoENS2_9allocatorIS4_EEEE;
-    _ZN7android2os16BpServiceManager20getDeclaredInstancesERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEPNS2_6vectorIS8_NS6_IS8_EEEE;
-    _ZN7android2os16BpServiceManager20tryUnregisterServiceERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManager22registerClientCallbackERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEERKNSB_INS0_15IClientCallbackEEE;
-    _ZN7android2os16BpServiceManager24registerForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
-    _ZN7android2os16BpServiceManager26unregisterForNotificationsERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS0_16IServiceCallbackEEE;
-    _ZN7android2os16BpServiceManagerC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16BpServiceManagerC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16IServiceCallback10descriptorE;
-    _ZN7android2os16IServiceCallback11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os16IServiceCallback12default_implE;
-    _ZN7android2os16IServiceCallback14getDefaultImplEv;
-    _ZN7android2os16IServiceCallback14setDefaultImplENSt3__110unique_ptrIS1_NS2_14default_deleteIS1_EEEE;
-    _ZN7android2os16IServiceCallbackC2Ev;
-    _ZN7android2os16IServiceCallbackD0Ev;
-    _ZN7android2os16IServiceCallbackD1Ev;
-    _ZN7android2os16IServiceCallbackD2Ev;
-    _ZN7android2os16ParcelableHolder14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os16ServiceDebugInfo14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZN7android2os17BnServiceCallbackC2Ev;
-    _ZN7android2os17BpServiceCallback14onRegistrationERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17BpServiceCallbackC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17BpServiceCallbackC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android2os17PersistableBundle10putBooleanERKNS_8String16Eb;
-    _ZN7android2os17PersistableBundle12putIntVectorERKNS_8String16ERKNSt3__16vectorIiNS5_9allocatorIiEEEE;
-    _ZN7android2os17PersistableBundle13putLongVectorERKNS_8String16ERKNSt3__16vectorIlNS5_9allocatorIlEEEE;
-    _ZN7android2os17PersistableBundle14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os17PersistableBundle15putDoubleVectorERKNS_8String16ERKNSt3__16vectorIdNS5_9allocatorIdEEEE;
-    _ZN7android2os17PersistableBundle15putStringVectorERKNS_8String16ERKNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
-    _ZN7android2os17PersistableBundle16putBooleanVectorERKNS_8String16ERKNSt3__16vectorIbNS5_9allocatorIbEEEE;
-    _ZN7android2os17PersistableBundle19readFromParcelInnerEPKNS_6ParcelEm;
-    _ZN7android2os17PersistableBundle20putPersistableBundleERKNS_8String16ERKS1_;
-    _ZN7android2os17PersistableBundle5eraseERKNS_8String16E;
-    _ZN7android2os17PersistableBundle6putIntERKNS_8String16Ei;
-    _ZN7android2os17PersistableBundle7putLongERKNS_8String16El;
-    _ZN7android2os17PersistableBundle9putDoubleERKNS_8String16Ed;
-    _ZN7android2os17PersistableBundle9putStringERKNS_8String16ES4_;
-    _ZN7android2os20ParcelFileDescriptor14readFromParcelEPKNS_6ParcelE;
-    _ZN7android2os20ParcelFileDescriptorC1ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
-    _ZN7android2os20ParcelFileDescriptorC1Ev;
-    _ZN7android2os20ParcelFileDescriptorC2ENS_4base14unique_fd_implINS2_13DefaultCloserEEE;
-    _ZN7android2os20ParcelFileDescriptorC2Ev;
-    _ZN7android2os20ParcelFileDescriptorD0Ev;
-    _ZN7android2os20ParcelFileDescriptorD1Ev;
-    _ZN7android2os20ParcelFileDescriptorD2Ev;
-    _ZN7android4aerrE;
-    _ZN7android4alogE;
-    _ZN7android4aoutE;
-    _ZN7android6binder20LazyServiceRegistrar10reRegisterEv;
-    _ZN7android6binder20LazyServiceRegistrar11getInstanceEv;
-    _ZN7android6binder20LazyServiceRegistrar12forcePersistEb;
-    _ZN7android6binder20LazyServiceRegistrar13tryUnregisterEv;
-    _ZN7android6binder20LazyServiceRegistrar15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEEbi;
-    _ZN7android6binder20LazyServiceRegistrar25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
-    _ZN7android6binder20LazyServiceRegistrarC1Ev;
-    _ZN7android6binder20LazyServiceRegistrarC2Ev;
-    _ZN7android6binder6Status11fromStatusTEi;
-    _ZN7android6binder6Status12setExceptionEiRKNS_7String8E;
-    _ZN7android6binder6Status14readFromParcelERKNS_6ParcelE;
-    _ZN7android6binder6Status14setFromStatusTEi;
-    _ZN7android6binder6Status17exceptionToStringEi;
-    _ZN7android6binder6Status17fromExceptionCodeEi;
-    _ZN7android6binder6Status17fromExceptionCodeEiPKc;
-    _ZN7android6binder6Status17fromExceptionCodeEiRKNS_7String8E;
-    _ZN7android6binder6Status23setServiceSpecificErrorEiRKNS_7String8E;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEi;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEiPKc;
-    _ZN7android6binder6Status24fromServiceSpecificErrorEiRKNS_7String8E;
-    _ZN7android6binder6Status2okEv;
-    _ZN7android6binder6StatusC1Eii;
-    _ZN7android6binder6StatusC1EiiRKNS_7String8E;
-    _ZN7android6binder6StatusC2Eii;
-    _ZN7android6binder6StatusC2EiiRKNS_7String8E;
-    _ZN7android6binder8internal21ClientCounterCallback10reRegisterEv;
-    _ZN7android6binder8internal21ClientCounterCallback12forcePersistEb;
-    _ZN7android6binder8internal21ClientCounterCallback13tryUnregisterEv;
-    _ZN7android6binder8internal21ClientCounterCallback15registerServiceERKNS_2spINS_7IBinderEEERKNSt3__112basic_stringIcNS8_11char_traitsIcEENS8_9allocatorIcEEEEbi;
-    _ZN7android6binder8internal21ClientCounterCallback25setActiveServicesCallbackERKNSt3__18functionIFbbEEE;
-    _ZN7android6binder8internal21ClientCounterCallbackC1Ev;
-    _ZN7android6binder8internal21ClientCounterCallbackC2Ev;
-    _ZN7android6Parcel10appendFromEPKS0_mm;
-    _ZN7android6Parcel10markForRpcERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android6Parcel10writeFloatEf;
-    _ZN7android6Parcel10writeInt32Ei;
-    _ZN7android6Parcel10writeInt64El;
-    _ZN7android6Parcel11compareDataERKS0_;
-    _ZN7android6Parcel11finishWriteEm;
-    _ZN7android6Parcel11setDataSizeEm;
-    _ZN7android6Parcel11writeDoubleEd;
-    _ZN7android6Parcel11writeObjectERK18flat_binder_objectb;
-    _ZN7android6Parcel11writeUint32Ej;
-    _ZN7android6Parcel11writeUint64Em;
-    _ZN7android6Parcel12pushAllowFdsEb;
-    _ZN7android6Parcel12restartWriteEm;
-    _ZN7android6Parcel12writeCStringEPKc;
-    _ZN7android6Parcel12writeInplaceEm;
-    _ZN7android6Parcel12writePointerEm;
-    _ZN7android6Parcel12writeString8EPKcm;
-    _ZN7android6Parcel12writeString8ERKNS_7String8E;
-    _ZN7android6Parcel13continueWriteEm;
-    _ZN7android6Parcel13flattenBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel13markForBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel13writeString16EPKDsm;
-    _ZN7android6Parcel13writeString16ERKNS_8String16E;
-    _ZN7android6Parcel13writeString16ERKNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
-    _ZN7android6Parcel13writeString16ERKNSt3__18optionalINS_8String16EEE;
-    _ZN7android6Parcel13writeUnpaddedEPKvm;
-    _ZN7android6Parcel14acquireObjectsEv;
-    _ZN7android6Parcel14freeDataNoInitEv;
-    _ZN7android6Parcel14releaseObjectsEv;
-    _ZN7android6Parcel14writeByteArrayEmPKh;
-    _ZN7android6Parcel15restoreAllowFdsEb;
-    _ZN7android6Parcel15setDataCapacityEm;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__16vectorIbNS1_9allocatorIbEEEE;
-    _ZN7android6Parcel15writeBoolVectorERKNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIaNS1_9allocatorIaEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__16vectorIhNS1_9allocatorIhEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
-    _ZN7android6Parcel15writeByteVectorERKNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
-    _ZN7android6Parcel15writeCharVectorERKNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
-    _ZN7android6Parcel15writeInt32ArrayEmPKi;
-    _ZN7android6Parcel15writeParcelableERKNS_10ParcelableE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__16vectorIfNS1_9allocatorIfEEEE;
-    _ZN7android6Parcel16writeFloatVectorERKNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__16vectorIiNS1_9allocatorIiEEEE;
-    _ZN7android6Parcel16writeInt32VectorERKNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__110unique_ptrINS1_6vectorIlNS1_9allocatorIlEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__16vectorIlNS1_9allocatorIlEEEE;
-    _ZN7android6Parcel16writeInt64VectorERKNSt3__18optionalINS1_6vectorIlNS1_9allocatorIlEEEEEE;
-    _ZN7android6Parcel16writeNoExceptionEv;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
-    _ZN7android6Parcel16writeUtf8AsUtf16ERKNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__16vectorIdNS1_9allocatorIdEEEE;
-    _ZN7android6Parcel17writeDoubleVectorERKNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
-    _ZN7android6Parcel17writeNativeHandleEPK13native_handle;
-    _ZN7android6Parcel17writeStrongBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__110unique_ptrINS1_6vectorImNS1_9allocatorImEEEENS1_14default_deleteIS6_EEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__16vectorImNS1_9allocatorImEEEE;
-    _ZN7android6Parcel17writeUint64VectorERKNSt3__18optionalINS1_6vectorImNS1_9allocatorImEEEEEE;
-    _ZN7android6Parcel18getGlobalAllocSizeEv;
-    _ZN7android6Parcel19finishFlattenBinderERKNS_2spINS_7IBinderEEE;
-    _ZN7android6Parcel19getGlobalAllocCountEv;
-    _ZN7android6Parcel19ipcSetDataReferenceEPKhmPKymPFvPS0_S2_mS4_mE;
-    _ZN7android6Parcel19writeFileDescriptorEib;
-    _ZN7android6Parcel19writeInterfaceTokenEPKDsm;
-    _ZN7android6Parcel19writeInterfaceTokenERKNS_8String16E;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
-    _ZN7android6Parcel19writeString16VectorERKNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
-    _ZN7android6Parcel20closeFileDescriptorsEv;
-    _ZN7android6Parcel22writeDupFileDescriptorEi;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
-    _ZN7android6Parcel23writeStrongBinderVectorERKNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
-    _ZN7android6Parcel25writeParcelFileDescriptorEib;
-    _ZN7android6Parcel25writeUniqueFileDescriptorERKNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android6Parcel26writeRawNullableParcelableEPKNS_10ParcelableE;
-    _ZN7android6Parcel27replaceCallingWorkSourceUidEj;
-    _ZN7android6Parcel28writeDupParcelFileDescriptorEi;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
-    _ZN7android6Parcel28writeUtf8VectorAsUtf16VectorERKNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
-    _ZN7android6Parcel31writeUniqueFileDescriptorVectorERKNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
-    _ZN7android6Parcel35writeDupImmutableBlobFileDescriptorEi;
-    _ZN7android6Parcel4Blob4initEiPvmb;
-    _ZN7android6Parcel4Blob5clearEv;
-    _ZN7android6Parcel4Blob7releaseEv;
-    _ZN7android6Parcel4BlobC1Ev;
-    _ZN7android6Parcel4BlobC2Ev;
-    _ZN7android6Parcel4BlobD1Ev;
-    _ZN7android6Parcel4BlobD2Ev;
-    _ZN7android6Parcel5writeEPKvm;
-    _ZN7android6Parcel5writeERKNS0_26FlattenableHelperInterfaceE;
-    _ZN7android6Parcel7setDataEPKhm;
-    _ZN7android6Parcel8freeDataEv;
-    _ZN7android6Parcel8growDataEm;
-    _ZN7android6Parcel8setErrorEi;
-    _ZN7android6Parcel9initStateEv;
-    _ZN7android6Parcel9writeBlobEmbPNS0_12WritableBlobE;
-    _ZN7android6Parcel9writeBoolEb;
-    _ZN7android6Parcel9writeByteEa;
-    _ZN7android6Parcel9writeCharEDs;
-    _ZN7android6ParcelC1Ev;
-    _ZN7android6ParcelC2Ev;
-    _ZN7android6ParcelD1Ev;
-    _ZN7android6ParcelD2Ev;
-    _ZN7android7BBinder10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android7BBinder10pingBinderEv;
-    _ZN7android7BBinder11getDebugPidEv;
-    _ZN7android7BBinder11isInheritRtEv;
-    _ZN7android7BBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
-    _ZN7android7BBinder11localBinderEv;
-    _ZN7android7BBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
-    _ZN7android7BBinder12detachObjectEPKv;
-    _ZN7android7BBinder12getExtensionEv;
-    _ZN7android7BBinder12setExtensionERKNS_2spINS_7IBinderEEE;
-    _ZN7android7BBinder12setInheritRtEb;
-    _ZN7android7BBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
-    _ZN7android7BBinder15isRequestingSidEv;
-    _ZN7android7BBinder16setRequestingSidEb;
-    _ZN7android7BBinder17getOrCreateExtrasEv;
-    _ZN7android7BBinder21getMinSchedulerPolicyEv;
-    _ZN7android7BBinder21setMinSchedulerPolicyEii;
-    _ZN7android7BBinder23getMinSchedulerPriorityEv;
-    _ZN7android7BBinder4dumpEiRKNS_6VectorINS_8String16EEE;
-    _ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j;
-    _ZN7android7BBinderC1Ev;
-    _ZN7android7BBinderC2Ev;
-    _ZN7android7BBinderD0Ev;
-    _ZN7android7BBinderD1Ev;
-    _ZN7android7BBinderD2Ev;
-    _ZN7android7content2pm18PackageChangeEvent14readFromParcelEPKNS_6ParcelE;
-    _ZN7android7content2pm21IPackageManagerNative10descriptorE;
-    _ZN7android7content2pm21IPackageManagerNative11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm21IPackageManagerNative12default_implE;
-    _ZN7android7content2pm21IPackageManagerNative14getDefaultImplEv;
-    _ZN7android7content2pm21IPackageManagerNative14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
-    _ZN7android7content2pm21IPackageManagerNativeC2Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD0Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD1Ev;
-    _ZN7android7content2pm21IPackageManagerNativeD2Ev;
-    _ZN7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZN7android7content2pm22BnPackageManagerNativeC2Ev;
-    _ZN7android7content2pm22BpPackageManagerNative14getAllPackagesEPNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEE;
-    _ZN7android7content2pm22BpPackageManagerNative15getNamesForUidsERKNSt3__16vectorIiNS3_9allocatorIiEEEEPNS4_INS3_12basic_stringIcNS3_11char_traitsIcEENS5_IcEEEENS5_ISE_EEEE;
-    _ZN7android7content2pm22BpPackageManagerNative16getLocationFlagsERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPi;
-    _ZN7android7content2pm22BpPackageManagerNative16hasSystemFeatureERKNS_8String16EiPb;
-    _ZN7android7content2pm22BpPackageManagerNative19isPackageDebuggableERKNS_8String16EPb;
-    _ZN7android7content2pm22BpPackageManagerNative22getInstallerForPackageERKNS_8String16EPNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative24getVersionCodeForPackageERKNS_8String16EPl;
-    _ZN7android7content2pm22BpPackageManagerNative27hasSha256SigningCertificateERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKNS3_6vectorIhNS7_IhEEEEPb;
-    _ZN7android7content2pm22BpPackageManagerNative28getModuleMetadataPackageNameEPNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative29getTargetSdkVersionForPackageERKNS_8String16EPi;
-    _ZN7android7content2pm22BpPackageManagerNative29isAudioPlaybackCaptureAllowedERKNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEEPNS4_IbNS8_IbEEEE;
-    _ZN7android7content2pm22BpPackageManagerNative29registerPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
-    _ZN7android7content2pm22BpPackageManagerNative31unregisterPackageChangeObserverERKNS_2spINS1_22IPackageChangeObserverEEE;
-    _ZN7android7content2pm22BpPackageManagerNativeC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22BpPackageManagerNativeC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22IPackageChangeObserver10descriptorE;
-    _ZN7android7content2pm22IPackageChangeObserver11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm22IPackageChangeObserver12default_implE;
-    _ZN7android7content2pm22IPackageChangeObserver14getDefaultImplEv;
-    _ZN7android7content2pm22IPackageChangeObserver14setDefaultImplENSt3__110unique_ptrIS2_NS3_14default_deleteIS2_EEEE;
-    _ZN7android7content2pm22IPackageChangeObserverC2Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD0Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD1Ev;
-    _ZN7android7content2pm22IPackageChangeObserverD2Ev;
-    _ZN7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZN7android7content2pm23BnPackageChangeObserverC2Ev;
-    _ZN7android7content2pm23BpPackageChangeObserver16onPackageChangedERKNS1_18PackageChangeEventE;
-    _ZN7android7content2pm23BpPackageChangeObserverC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7content2pm23BpPackageChangeObserverC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android7HexDumpC1EPKvmm;
-    _ZN7android7HexDumpC2EPKvmm;
-    _ZN7android7IBinder11getDebugPidEPi;
-    _ZN7android7IBinder11localBinderEv;
-    _ZN7android7IBinder12getExtensionEPNS_2spIS0_EE;
-    _ZN7android7IBinder12remoteBinderEv;
-    _ZN7android7IBinder12shellCommandERKNS_2spIS0_EEiiiRNS_6VectorINS_8String16EEERKNS1_INS_14IShellCallbackEEERKNS1_INS_15IResultReceiverEEE;
-    _ZN7android7IBinder19queryLocalInterfaceERKNS_8String16E;
-    _ZN7android7IBinderC2Ev;
-    _ZN7android7IBinderD0Ev;
-    _ZN7android7IBinderD1Ev;
-    _ZN7android7IBinderD2Ev;
-    _ZN7android7IMemory10descriptorE;
-    _ZN7android7IMemory11asInterfaceERKNS_2spINS_7IBinderEEE;
-    _ZN7android7IMemory12default_implE;
-    _ZN7android7IMemory14getDefaultImplEv;
-    _ZN7android7IMemory14setDefaultImplENSt3__110unique_ptrIS0_NS1_14default_deleteIS0_EEEE;
-    _ZN7android7IMemoryC2Ev;
-    _ZN7android7IMemoryD0Ev;
-    _ZN7android7IMemoryD1Ev;
-    _ZN7android7IMemoryD2Ev;
-    _ZN7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZN7android8BnMemoryC2Ev;
-    _ZN7android8BnMemoryD0Ev;
-    _ZN7android8BnMemoryD1Ev;
-    _ZN7android8BnMemoryD2Ev;
-    _ZN7android8BpBinder10onFirstRefEv;
-    _ZN7android8BpBinder10pingBinderEv;
-    _ZN7android8BpBinder11linkToDeathERKNS_2spINS_7IBinder14DeathRecipientEEEPvj;
-    _ZN7android8BpBinder12attachObjectEPKvPvS3_PFvS2_S3_S3_E;
-    _ZN7android8BpBinder12detachObjectEPKv;
-    _ZN7android8BpBinder12remoteBinderEv;
-    _ZN7android8BpBinder12sendObituaryEv;
-    _ZN7android8BpBinder12sTrackingMapE;
-    _ZN7android8BpBinder13getCountByUidERNS_6VectorIjEES3_;
-    _ZN7android8BpBinder13ObjectManager4killEv;
-    _ZN7android8BpBinder13ObjectManager6attachEPKvPvS4_PFvS3_S4_S4_E;
-    _ZN7android8BpBinder13ObjectManager6detachEPKv;
-    _ZN7android8BpBinder13ObjectManagerC1Ev;
-    _ZN7android8BpBinder13ObjectManagerC2Ev;
-    _ZN7android8BpBinder13ObjectManagerD1Ev;
-    _ZN7android8BpBinder13ObjectManagerD2Ev;
-    _ZN7android8BpBinder13sTrackingLockE;
-    _ZN7android8BpBinder13unlinkToDeathERKNS_2wpINS_7IBinder14DeathRecipientEEEPvjPS4_;
-    _ZN7android8BpBinder14reportOneDeathERKNS0_8ObituaryE;
-    _ZN7android8BpBinder14sLimitCallbackE;
-    _ZN7android8BpBinder15onLastStrongRefEPKv;
-    _ZN7android8BpBinder15sNumTrackedUidsE;
-    _ZN7android8BpBinder16enableCountByUidEv;
-    _ZN7android8BpBinder16setLimitCallbackEPFviE;
-    _ZN7android8BpBinder17disableCountByUidEv;
-    _ZN7android8BpBinder18sCountByUidEnabledE;
-    _ZN7android8BpBinder19getBinderProxyCountEj;
-    _ZN7android8BpBinder20onIncStrongAttemptedEjPKv;
-    _ZN7android8BpBinder20setCountByUidEnabledEb;
-    _ZN7android8BpBinder26sBinderProxyThrottleCreateE;
-    _ZN7android8BpBinder29sBinderProxyCountLowWatermarkE;
-    _ZN7android8BpBinder29setBinderProxyCountWatermarksEii;
-    _ZN7android8BpBinder30sBinderProxyCountHighWatermarkE;
-    _ZN7android8BpBinder4dumpEiRKNS_6VectorINS_8String16EEE;
-    _ZN7android8BpBinder6createEi;
-    _ZN7android8BpBinder6createERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
-    _ZN7android8BpBinder8transactEjRKNS_6ParcelEPS1_j;
-    _ZN7android8BpBinderC1EONS0_12BinderHandleEi;
-    _ZN7android8BpBinderC1EONS0_9RpcHandleE;
-    _ZN7android8BpBinderC1EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
-    _ZN7android8BpBinderC2EONS0_12BinderHandleEi;
-    _ZN7android8BpBinderC2EONS0_9RpcHandleE;
-    _ZN7android8BpBinderC2EONSt3__17variantIJNS0_12BinderHandleENS0_9RpcHandleEEEE;
-    _ZN7android8BpBinderD0Ev;
-    _ZN7android8BpBinderD1Ev;
-    _ZN7android8BpBinderD2Ev;
-    _ZN7android8BpMemoryC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android8BpMemoryC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android8BpMemoryD0Ev;
-    _ZN7android8BpMemoryD1Ev;
-    _ZN7android8BpMemoryD2Ev;
-    _ZN7android8internal9Stability11getCategoryEPNS_7IBinderE;
-    _ZN7android8internal9Stability11levelStringENS1_5LevelE;
-    _ZN7android8internal9Stability13getLocalLevelEv;
-    _ZN7android8internal9Stability15isDeclaredLevelENS1_5LevelE;
-    _ZN7android8internal9Stability17debugLogStabilityERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability19markCompilationUnitEPNS_7IBinderE;
-    _ZN7android8internal9Stability22tryMarkCompilationUnitEPNS_7IBinderE;
-    _ZN7android8internal9Stability24requiresVintfDeclarationERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability25forceDowngradeToStabilityERKNS_2spINS_7IBinderEEENS1_5LevelE;
-    _ZN7android8internal9Stability30forceDowngradeToLocalStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability31forceDowngradeToSystemStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability31forceDowngradeToVendorStabilityERKNS_2spINS_7IBinderEEE;
-    _ZN7android8internal9Stability5checkENS1_8CategoryENS1_5LevelE;
-    _ZN7android8internal9Stability7setReprEPNS_7IBinderEij;
-    _ZN7android8internal9Stability8Category11debugStringEv;
-    _ZN7android8internal9Stability8markVndkEPNS_7IBinderE;
-    _ZN7android8internal9Stability9markVintfEPNS_7IBinderE;
-    _ZN7android8RpcState11CommandDataC1Em;
-    _ZN7android8RpcState11CommandDataC2Em;
-    _ZN7android8RpcState12countBindersEv;
-    _ZN7android8RpcState12getSessionIdERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPi;
-    _ZN7android8RpcState12waitForReplyERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPNS_6ParcelE;
-    _ZN7android8RpcState13getMaxThreadsERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEEPm;
-    _ZN7android8RpcState13getRootObjectERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android8RpcState13sendDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressE;
-    _ZN7android8RpcState15onBinderLeavingERKNS_2spINS_10RpcSessionEEERKNS1_INS_7IBinderEEEPNS_10RpcAddressE;
-    _ZN7android8RpcState15processTransactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState16onBinderEnteringERKNS_2spINS_10RpcSessionEEERKNS_10RpcAddressE;
-    _ZN7android8RpcState16processDecStrongERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState20getAndExecuteCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android8RpcState20processServerCommandERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEERKNS_13RpcWireHeaderE;
-    _ZN7android8RpcState23processTransactInternalERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_2spINS_10RpcSessionEEENS0_11CommandDataE;
-    _ZN7android8RpcState4dumpEv;
-    _ZN7android8RpcState6rpcRecERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPvm;
-    _ZN7android8RpcState7rpcSendERKNS_4base14unique_fd_implINS1_13DefaultCloserEEEPKcPKvm;
-    _ZN7android8RpcState8transactERKNS_4base14unique_fd_implINS1_13DefaultCloserEEERKNS_10RpcAddressEjRKNS_6ParcelERKNS_2spINS_10RpcSessionEEEPSA_j;
-    _ZN7android8RpcState9terminateEv;
-    _ZN7android8RpcStateC1Ev;
-    _ZN7android8RpcStateC2Ev;
-    _ZN7android8RpcStateD1Ev;
-    _ZN7android8RpcStateD2Ev;
-    _ZN7android9BpRefBase10onFirstRefEv;
-    _ZN7android9BpRefBase15onLastStrongRefEPKv;
-    _ZN7android9BpRefBase20onIncStrongAttemptedEjPKv;
-    _ZN7android9BpRefBaseC1ERKNS_2spINS_7IBinderEEE;
-    _ZN7android9BpRefBaseC2ERKNS_2spINS_7IBinderEEE;
-    _ZN7android9BpRefBaseD0Ev;
-    _ZN7android9BpRefBaseD1Ev;
-    _ZN7android9BpRefBaseD2Ev;
-    _ZN7android9HeapCache10binderDiedERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9HeapCache10dump_heapsEv;
-    _ZN7android9HeapCache8get_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9find_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9free_heapERKNS_2spINS_7IBinderEEE;
-    _ZN7android9HeapCache9free_heapERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9HeapCacheC1Ev;
-    _ZN7android9HeapCacheC2Ev;
-    _ZN7android9HeapCacheD0Ev;
-    _ZN7android9HeapCacheD1Ev;
-    _ZN7android9HeapCacheD2Ev;
-    _ZN7android9hexStringEPKvm;
-    _ZN7android9RpcServer12listSessionsEv;
-    _ZN7android9RpcServer13getMaxThreadsEv;
-    _ZN7android9RpcServer13getRootObjectEv;
-    _ZN7android9RpcServer13releaseServerEv;
-    _ZN7android9RpcServer13setMaxThreadsEm;
-    _ZN7android9RpcServer13setRootObjectERKNS_2spINS_7IBinderEEE;
-    _ZN7android9RpcServer15setupInetServerEjPj;
-    _ZN7android9RpcServer16setupVsockServerEj;
-    _ZN7android9RpcServer17setRootObjectWeakERKNS_2wpINS_7IBinderEEE;
-    _ZN7android9RpcServer17setupSocketServerERKNS_16RpcSocketAddressE;
-    _ZN7android9RpcServer19establishConnectionEONS_2spIS0_EENS_4base14unique_fd_implINS4_13DefaultCloserEEE;
-    _ZN7android9RpcServer19setupExternalServerENS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZN7android9RpcServer20onSessionTerminatingERKNS_2spINS_10RpcSessionEEE;
-    _ZN7android9RpcServer21setupUnixDomainServerEPKc;
-    _ZN7android9RpcServer24numUninitializedSessionsEv;
-    _ZN7android9RpcServer4joinEv;
-    _ZN7android9RpcServer4makeEv;
-    _ZN7android9RpcServer61iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProductionEv;
-    _ZN7android9RpcServer9acceptOneEv;
-    _ZN7android9RpcServer9hasServerEv;
-    _ZN7android9RpcServerC1Ev;
-    _ZN7android9RpcServerC2Ev;
-    _ZN7android9RpcServerD0Ev;
-    _ZN7android9RpcServerD1Ev;
-    _ZN7android9RpcServerD2Ev;
-    _ZN7androidlsERNS_10TextOutputERKNS_7HexDumpE;
-    _ZN7androidlsERNS_10TextOutputERKNS_8TypeCodeE;
-    _ZN7androidlsIA15_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA24_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA2_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA34_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA3_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA43_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA4_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA5_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA8_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIA9_cEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIjEERNS_10TextOutputES2_RKT_;
-    _ZN7androidlsImEERNS_10TextOutputES2_RKT_;
-    _ZN7androidlsINSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEERNS_10TextOutputES9_RKT_;
-    _ZN7androidlsIPcEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIPvEERNS_10TextOutputES3_RKT_;
-    _ZN7androidlsIyEERNS_10TextOutputES2_RKT_;
-    _ZNK7android10MemoryBase9getMemoryEPlPm;
-    _ZNK7android10RpcAddress13writeToParcelEPNS_6ParcelE;
-    _ZNK7android10RpcAddress15viewRawEmbeddedEv;
-    _ZNK7android10RpcAddress6isZeroEv;
-    _ZNK7android10RpcAddress8toStringEv;
-    _ZNK7android10RpcAddressltERKS0_;
-    _ZNK7android11IMemoryHeap22getInterfaceDescriptorEv;
-    _ZNK7android12BpMemoryHeap12assertMappedEv;
-    _ZNK7android12BpMemoryHeap18assertReallyMappedEv;
-    _ZNK7android12BpMemoryHeap7getBaseEv;
-    _ZNK7android12BpMemoryHeap7getSizeEv;
-    _ZNK7android12BpMemoryHeap8getFlagsEv;
-    _ZNK7android12BpMemoryHeap9getHeapIDEv;
-    _ZNK7android12BpMemoryHeap9getOffsetEv;
-    _ZNK7android12MemoryDealer4dumpEPKc;
-    _ZNK7android12MemoryDealer4heapEv;
-    _ZNK7android12MemoryDealer9allocatorEv;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_compareEPKvSA_;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE10do_destroyEPvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE12do_constructEPvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE15do_move_forwardEPvPKvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE16do_move_backwardEPvPKvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE7do_copyEPvPKvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEE8do_splatEPvPKvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_compareES3_S3_;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE10do_destroyEPvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE12do_constructEPvm;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE15do_move_forwardEPvS3_m;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE16do_move_backwardEPvS3_m;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE7do_copyEPvS3_m;
-    _ZNK7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEE8do_splatEPvS3_m;
-    _ZNK7android14IPCThreadState13getCallingPidEv;
-    _ZNK7android14IPCThreadState13getCallingSidEv;
-    _ZNK7android14IPCThreadState13getCallingUidEv;
-    _ZNK7android14IPCThreadState18getCallRestrictionEv;
-    _ZNK7android14IPCThreadState19getStrictModePolicyEv;
-    _ZNK7android14IPCThreadState22getServingStackPointerEv;
-    _ZNK7android14IPCThreadState23getCallingWorkSourceUidEv;
-    _ZNK7android14IPCThreadState25shouldPropagateWorkSourceEv;
-    _ZNK7android14IPCThreadState29getLastTransactionBinderFlagsEv;
-    _ZNK7android14IShellCallback22getInterfaceDescriptorEv;
-    _ZNK7android14MemoryHeapBase7getBaseEv;
-    _ZNK7android14MemoryHeapBase7getSizeEv;
-    _ZNK7android14MemoryHeapBase8getFlagsEv;
-    _ZNK7android14MemoryHeapBase9getDeviceEv;
-    _ZNK7android14MemoryHeapBase9getHeapIDEv;
-    _ZNK7android14MemoryHeapBase9getOffsetEv;
-    _ZNK7android15IResultReceiver22getInterfaceDescriptorEv;
-    _ZNK7android15IServiceManager22getInterfaceDescriptorEv;
-    _ZNK7android18BufferedTextOutput9getBufferEv;
-    _ZNK7android18ServiceManagerShim10getServiceERKNS_8String16E;
-    _ZNK7android18ServiceManagerShim12checkServiceERKNS_8String16E;
-    _ZNK7android22SimpleBestFitAllocator4dumpEPKc;
-    _ZNK7android22SimpleBestFitAllocator4dumpERNS_7String8EPKc;
-    _ZNK7android22SimpleBestFitAllocator4sizeEv;
-    _ZNK7android22SimpleBestFitAllocator6dump_lEPKc;
-    _ZNK7android22SimpleBestFitAllocator6dump_lERNS_7String8EPKc;
-    _ZNK7android2os15IClientCallback22getInterfaceDescriptorEv;
-    _ZNK7android2os15IServiceManager22getInterfaceDescriptorEv;
-    _ZNK7android2os16IServiceCallback22getInterfaceDescriptorEv;
-    _ZNK7android2os16ParcelableHolder13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os16ServiceDebugInfo13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle10getBooleanERKNS_8String16EPb;
-    _ZNK7android2os17PersistableBundle10getIntKeysEv;
-    _ZNK7android2os17PersistableBundle11getLongKeysEv;
-    _ZNK7android2os17PersistableBundle12getIntVectorERKNS_8String16EPNSt3__16vectorIiNS5_9allocatorIiEEEE;
-    _ZNK7android2os17PersistableBundle13getDoubleKeysEv;
-    _ZNK7android2os17PersistableBundle13getLongVectorERKNS_8String16EPNSt3__16vectorIlNS5_9allocatorIlEEEE;
-    _ZNK7android2os17PersistableBundle13getStringKeysEv;
-    _ZNK7android2os17PersistableBundle13writeToParcelEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle14getBooleanKeysEv;
-    _ZNK7android2os17PersistableBundle15getDoubleVectorERKNS_8String16EPNSt3__16vectorIdNS5_9allocatorIdEEEE;
-    _ZNK7android2os17PersistableBundle15getStringVectorERKNS_8String16EPNSt3__16vectorIS2_NS5_9allocatorIS2_EEEE;
-    _ZNK7android2os17PersistableBundle16getBooleanVectorERKNS_8String16EPNSt3__16vectorIbNS5_9allocatorIbEEEE;
-    _ZNK7android2os17PersistableBundle16getIntVectorKeysEv;
-    _ZNK7android2os17PersistableBundle17getLongVectorKeysEv;
-    _ZNK7android2os17PersistableBundle18writeToParcelInnerEPNS_6ParcelE;
-    _ZNK7android2os17PersistableBundle19getDoubleVectorKeysEv;
-    _ZNK7android2os17PersistableBundle19getStringVectorKeysEv;
-    _ZNK7android2os17PersistableBundle20getBooleanVectorKeysEv;
-    _ZNK7android2os17PersistableBundle20getPersistableBundleERKNS_8String16EPS1_;
-    _ZNK7android2os17PersistableBundle24getPersistableBundleKeysEv;
-    _ZNK7android2os17PersistableBundle4sizeEv;
-    _ZNK7android2os17PersistableBundle5emptyEv;
-    _ZNK7android2os17PersistableBundle6getIntERKNS_8String16EPi;
-    _ZNK7android2os17PersistableBundle7getLongERKNS_8String16EPl;
-    _ZNK7android2os17PersistableBundle9getDoubleERKNS_8String16EPd;
-    _ZNK7android2os17PersistableBundle9getStringERKNS_8String16EPS2_;
-    _ZNK7android2os20ParcelFileDescriptor13writeToParcelEPNS_6ParcelE;
-    _ZNK7android6binder6Status13writeToParcelEPNS_6ParcelE;
-    _ZNK7android6binder6Status9toString8Ev;
-    _ZNK7android6Parcel10errorCheckEv;
-    _ZNK7android6Parcel10ipcObjectsEv;
-    _ZNK7android6Parcel10readDoubleEPd;
-    _ZNK7android6Parcel10readDoubleEv;
-    _ZNK7android6Parcel10readObjectEb;
-    _ZNK7android6Parcel10readUint32EPj;
-    _ZNK7android6Parcel10readUint32Ev;
-    _ZNK7android6Parcel10readUint64EPm;
-    _ZNK7android6Parcel10readUint64Ev;
-    _ZNK7android6Parcel10scanForFdsEv;
-    _ZNK7android6Parcel11ipcDataSizeEv;
-    _ZNK7android6Parcel11readCStringEv;
-    _ZNK7android6Parcel11readInplaceEm;
-    _ZNK7android6Parcel11readPointerEPm;
-    _ZNK7android6Parcel11readPointerEv;
-    _ZNK7android6Parcel11readString8EPNS_7String8E;
-    _ZNK7android6Parcel11readString8Ev;
-    _ZNK7android6Parcel12dataCapacityEv;
-    _ZNK7android6Parcel12dataPositionEv;
-    _ZNK7android6Parcel12objectsCountEv;
-    _ZNK7android6Parcel12readString16EPNS_8String16E;
-    _ZNK7android6Parcel12readString16EPNSt3__110unique_ptrINS_8String16ENS1_14default_deleteIS3_EEEE;
-    _ZNK7android6Parcel12readString16EPNSt3__18optionalINS_8String16EEE;
-    _ZNK7android6Parcel12readString16Ev;
-    _ZNK7android6Parcel13markSensitiveEv;
-    _ZNK7android6Parcel14checkInterfaceEPNS_7IBinderE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__110unique_ptrINS1_6vectorIbNS1_9allocatorIbEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__16vectorIbNS1_9allocatorIbEEEE;
-    _ZNK7android6Parcel14readBoolVectorEPNSt3__18optionalINS1_6vectorIbNS1_9allocatorIbEEEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIaNS1_9allocatorIaEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__110unique_ptrINS1_6vectorIhNS1_9allocatorIhEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIaNS1_9allocatorIaEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__16vectorIhNS1_9allocatorIhEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIaNS1_9allocatorIaEEEEEE;
-    _ZNK7android6Parcel14readByteVectorEPNSt3__18optionalINS1_6vectorIhNS1_9allocatorIhEEEEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__110unique_ptrINS1_6vectorIDsNS1_9allocatorIDsEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__16vectorIDsNS1_9allocatorIDsEEEE;
-    _ZNK7android6Parcel14readCharVectorEPNSt3__18optionalINS1_6vectorIDsNS1_9allocatorIDsEEEEEE;
-    _ZNK7android6Parcel14readParcelableEPNS_10ParcelableE;
-    _ZNK7android6Parcel15ipcObjectsCountEv;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__110unique_ptrINS1_6vectorIfNS1_9allocatorIfEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__16vectorIfNS1_9allocatorIfEEEE;
-    _ZNK7android6Parcel15readFloatVectorEPNSt3__18optionalINS1_6vectorIfNS1_9allocatorIfEEEEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__110unique_ptrINS1_6vectorIiNS1_9allocatorIiEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__16vectorIiNS1_9allocatorIiEEEE;
-    _ZNK7android6Parcel15readInt32VectorEPNSt3__18optionalINS1_6vectorIiNS1_9allocatorIiEEEEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__110unique_ptrINS1_6vectorIlNS1_9allocatorIlEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__16vectorIlNS1_9allocatorIlEEEE;
-    _ZNK7android6Parcel15readInt64VectorEPNSt3__18optionalINS1_6vectorIlNS1_9allocatorIlEEEEEE;
-    _ZNK7android6Parcel15setDataPositionEm;
-    _ZNK7android6Parcel15unflattenBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel16enforceInterfaceEPKDsmPNS_14IPCThreadStateE;
-    _ZNK7android6Parcel16enforceInterfaceERKNS_8String16EPNS_14IPCThreadStateE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__110unique_ptrINS1_6vectorIdNS1_9allocatorIdEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__16vectorIdNS1_9allocatorIdEEEE;
-    _ZNK7android6Parcel16readDoubleVectorEPNSt3__18optionalINS1_6vectorIdNS1_9allocatorIdEEEEEE;
-    _ZNK7android6Parcel16readNativeHandleEv;
-    _ZNK7android6Parcel16readStrongBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel16readStrongBinderEv;
-    _ZNK7android6Parcel16readStrongBinderINS_2os15IClientCallbackEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readStrongBinderINS_2os16IServiceCallbackEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readStrongBinderINS_7content2pm22IPackageChangeObserverEEEiPNS_2spIT_EE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__110unique_ptrINS1_6vectorImNS1_9allocatorImEEEENS1_14default_deleteIS6_EEEE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__16vectorImNS1_9allocatorImEEEE;
-    _ZNK7android6Parcel16readUint64VectorEPNSt3__18optionalINS1_6vectorImNS1_9allocatorImEEEEEE;
-    _ZNK7android6Parcel16validateReadDataEm;
-    _ZNK7android6Parcel17getBlobAshmemSizeEv;
-    _ZNK7android6Parcel17getOpenAshmemSizeEv;
-    _ZNK7android6Parcel17readExceptionCodeEv;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__110unique_ptrINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS8_EEEE;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE;
-    _ZNK7android6Parcel17readUtf8FromUtf16EPNSt3__18optionalINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEE;
-    _ZNK7android6Parcel18hasFileDescriptorsEv;
-    _ZNK7android6Parcel18readFileDescriptorEv;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS_8String16ENS1_14default_deleteIS4_EEEENS1_9allocatorIS7_EEEENS5_ISA_EEEE;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__16vectorINS_8String16ENS1_9allocatorIS3_EEEE;
-    _ZNK7android6Parcel18readString16VectorEPNSt3__18optionalINS1_6vectorINS2_INS_8String16EEENS1_9allocatorIS5_EEEEEE;
-    _ZNK7android6Parcel18readString8InplaceEPm;
-    _ZNK7android6Parcel19readString16InplaceEPm;
-    _ZNK7android6Parcel21finishUnflattenBinderERKNS_2spINS_7IBinderEEEPS3_;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__110unique_ptrINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEENS1_14default_deleteIS9_EEEE;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__16vectorINS_2spINS_7IBinderEEENS1_9allocatorIS5_EEEE;
-    _ZNK7android6Parcel22readStrongBinderVectorEPNSt3__18optionalINS1_6vectorINS_2spINS_7IBinderEEENS1_9allocatorIS6_EEEEEE;
-    _ZNK7android6Parcel24readCallingWorkSourceUidEv;
-    _ZNK7android6Parcel24readNullableStrongBinderEPNS_2spINS_7IBinderEEE;
-    _ZNK7android6Parcel24readParcelFileDescriptorEv;
-    _ZNK7android6Parcel24readUniqueFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__110unique_ptrINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_14default_deleteIS9_EEEENS7_ISC_EEEENSA_ISE_EEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__16vectorINS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS6_IS8_EEEE;
-    _ZNK7android6Parcel29readUtf8VectorFromUtf16VectorEPNSt3__18optionalINS1_6vectorINS2_INS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__110unique_ptrINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEENS1_14default_deleteISA_EEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__16vectorINS_4base14unique_fd_implINS3_13DefaultCloserEEENS1_9allocatorIS6_EEEE;
-    _ZNK7android6Parcel30readUniqueFileDescriptorVectorEPNSt3__18optionalINS1_6vectorINS_4base14unique_fd_implINS4_13DefaultCloserEEENS1_9allocatorIS7_EEEEEE;
-    _ZNK7android6Parcel30readUniqueParcelFileDescriptorEPNS_4base14unique_fd_implINS1_13DefaultCloserEEE;
-    _ZNK7android6Parcel37updateWorkSourceRequestHeaderPositionEv;
-    _ZNK7android6Parcel4dataEv;
-    _ZNK7android6Parcel4readEPvm;
-    _ZNK7android6Parcel4readERNS0_26FlattenableHelperInterfaceE;
-    _ZNK7android6Parcel5printERNS_10TextOutputEj;
-    _ZNK7android6Parcel7ipcDataEv;
-    _ZNK7android6Parcel8allowFdsEv;
-    _ZNK7android6Parcel8dataSizeEv;
-    _ZNK7android6Parcel8isForRpcEv;
-    _ZNK7android6Parcel8readBlobEmPNS0_12ReadableBlobE;
-    _ZNK7android6Parcel8readBoolEPb;
-    _ZNK7android6Parcel8readBoolEv;
-    _ZNK7android6Parcel8readByteEPa;
-    _ZNK7android6Parcel8readByteEv;
-    _ZNK7android6Parcel8readCharEPDs;
-    _ZNK7android6Parcel8readCharEv;
-    _ZNK7android6Parcel9dataAvailEv;
-    _ZNK7android6Parcel9readFloatEPf;
-    _ZNK7android6Parcel9readFloatEv;
-    _ZNK7android6Parcel9readInt32EPi;
-    _ZNK7android6Parcel9readInt32Ev;
-    _ZNK7android6Parcel9readInt64EPl;
-    _ZNK7android6Parcel9readInt64Ev;
-    _ZNK7android6VectorIiE10do_destroyEPvm;
-    _ZNK7android6VectorIiE12do_constructEPvm;
-    _ZNK7android6VectorIiE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorIiE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorIiE7do_copyEPvPKvm;
-    _ZNK7android6VectorIiE8do_splatEPvPKvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE10do_destroyEPvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE12do_constructEPvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE7do_copyEPvPKvm;
-    _ZNK7android6VectorINS_12ProcessState12handle_entryEE8do_splatEPvPKvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE10do_destroyEPvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE12do_constructEPvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE7do_copyEPvPKvm;
-    _ZNK7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEE8do_splatEPvPKvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE10do_destroyEPvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE12do_constructEPvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE7do_copyEPvPKvm;
-    _ZNK7android6VectorINS_8BpBinder8ObituaryEE8do_splatEPvPKvm;
-    _ZNK7android6VectorINS_8String16EE10do_destroyEPvm;
-    _ZNK7android6VectorINS_8String16EE12do_constructEPvm;
-    _ZNK7android6VectorINS_8String16EE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorINS_8String16EE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorINS_8String16EE7do_copyEPvPKvm;
-    _ZNK7android6VectorINS_8String16EE8do_splatEPvPKvm;
-    _ZNK7android6VectorIPNS_7BBinderEE10do_destroyEPvm;
-    _ZNK7android6VectorIPNS_7BBinderEE12do_constructEPvm;
-    _ZNK7android6VectorIPNS_7BBinderEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7BBinderEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7BBinderEE7do_copyEPvPKvm;
-    _ZNK7android6VectorIPNS_7BBinderEE8do_splatEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE10do_destroyEPvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE12do_constructEPvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE7do_copyEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBase12weakref_typeEE8do_splatEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE10do_destroyEPvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE12do_constructEPvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE15do_move_forwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE16do_move_backwardEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE7do_copyEPvPKvm;
-    _ZNK7android6VectorIPNS_7RefBaseEE8do_splatEPvPKvm;
-    _ZNK7android7BBinder10findObjectEPKv;
-    _ZNK7android7BBinder13isBinderAliveEv;
-    _ZNK7android7BBinder22getInterfaceDescriptorEv;
-    _ZNK7android7content2pm18PackageChangeEvent13writeToParcelEPNS_6ParcelE;
-    _ZNK7android7content2pm21IPackageManagerNative22getInterfaceDescriptorEv;
-    _ZNK7android7content2pm22IPackageChangeObserver22getInterfaceDescriptorEv;
-    _ZNK7android7IBinder13checkSubclassEPKv;
-    _ZNK7android7IMemory11fastPointerERKNS_2spINS_7IBinderEEEl;
-    _ZNK7android7IMemory15unsecurePointerEv;
-    _ZNK7android7IMemory22getInterfaceDescriptorEv;
-    _ZNK7android7IMemory4sizeEv;
-    _ZNK7android7IMemory6offsetEv;
-    _ZNK7android7IMemory7pointerEv;
-    _ZNK7android8BpBinder10findObjectEPKv;
-    _ZNK7android8BpBinder10rpcAddressEv;
-    _ZNK7android8BpBinder10rpcSessionEv;
-    _ZNK7android8BpBinder11isRpcBinderEv;
-    _ZNK7android8BpBinder12binderHandleEv;
-    _ZNK7android8BpBinder13isBinderAliveEv;
-    _ZNK7android8BpBinder13ObjectManager4findEPKv;
-    _ZNK7android8BpBinder18isDescriptorCachedEv;
-    _ZNK7android8BpBinder22getInterfaceDescriptorEv;
-    _ZNK7android8BpMemory9getMemoryEPlPm;
-    _ZTCN7android10AllocationE0_NS_10IInterfaceE;
-    _ZTCN7android10AllocationE0_NS_10MemoryBaseE;
-    _ZTCN7android10AllocationE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android10AllocationE0_NS_7IMemoryE;
-    _ZTCN7android10AllocationE0_NS_8BnMemoryE;
-    _ZTCN7android10AllocationE8_NS_7BBinderE;
-    _ZTCN7android10AllocationE8_NS_7IBinderE;
-    _ZTCN7android10MemoryBaseE0_NS_10IInterfaceE;
-    _ZTCN7android10MemoryBaseE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android10MemoryBaseE0_NS_7IMemoryE;
-    _ZTCN7android10MemoryBaseE0_NS_8BnMemoryE;
-    _ZTCN7android10MemoryBaseE8_NS_7BBinderE;
-    _ZTCN7android10MemoryBaseE8_NS_7IBinderE;
-    _ZTCN7android10PoolThreadE0_NS_6ThreadE;
-    _ZTCN7android11IMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BnMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BnMemoryHeapE0_NS_11BnInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android12BnMemoryHeapE0_NS_11IMemoryHeapE;
-    _ZTCN7android12BnMemoryHeapE8_NS_7BBinderE;
-    _ZTCN7android12BnMemoryHeapE8_NS_7IBinderE;
-    _ZTCN7android12BpMemoryHeapE0_NS_10IInterfaceE;
-    _ZTCN7android12BpMemoryHeapE0_NS_11BpInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android12BpMemoryHeapE0_NS_11IMemoryHeapE;
-    _ZTCN7android12BpMemoryHeapE8_NS_9BpRefBaseE;
-    _ZTCN7android14IShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android14MemoryHeapBaseE64_NS_10IInterfaceE;
-    _ZTCN7android14MemoryHeapBaseE64_NS_11BnInterfaceINS_11IMemoryHeapEEE;
-    _ZTCN7android14MemoryHeapBaseE64_NS_11IMemoryHeapE;
-    _ZTCN7android14MemoryHeapBaseE64_NS_12BnMemoryHeapE;
-    _ZTCN7android14MemoryHeapBaseE72_NS_7BBinderE;
-    _ZTCN7android14MemoryHeapBaseE72_NS_7IBinderE;
-    _ZTCN7android15BnShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android15BnShellCallbackE0_NS_11BnInterfaceINS_14IShellCallbackEEE;
-    _ZTCN7android15BnShellCallbackE0_NS_14IShellCallbackE;
-    _ZTCN7android15BnShellCallbackE8_NS_7BBinderE;
-    _ZTCN7android15BnShellCallbackE8_NS_7IBinderE;
-    _ZTCN7android15BpShellCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android15BpShellCallbackE0_NS_11BpInterfaceINS_14IShellCallbackEEE;
-    _ZTCN7android15BpShellCallbackE0_NS_14IShellCallbackE;
-    _ZTCN7android15BpShellCallbackE8_NS_9BpRefBaseE;
-    _ZTCN7android15IResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android15IServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android16BnResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android16BnResultReceiverE0_NS_11BnInterfaceINS_15IResultReceiverEEE;
-    _ZTCN7android16BnResultReceiverE0_NS_15IResultReceiverE;
-    _ZTCN7android16BnResultReceiverE8_NS_7BBinderE;
-    _ZTCN7android16BnResultReceiverE8_NS_7IBinderE;
-    _ZTCN7android16BpResultReceiverE0_NS_10IInterfaceE;
-    _ZTCN7android16BpResultReceiverE0_NS_11BpInterfaceINS_15IResultReceiverEEE;
-    _ZTCN7android16BpResultReceiverE0_NS_15IResultReceiverE;
-    _ZTCN7android16BpResultReceiverE8_NS_9BpRefBaseE;
-    _ZTCN7android18ServiceManagerShimE0_NS_10IInterfaceE;
-    _ZTCN7android18ServiceManagerShimE0_NS_15IServiceManagerE;
-    _ZTCN7android2os15IClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os15IServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnClientCallbackE0_NS0_15IClientCallbackE;
-    _ZTCN7android2os16BnClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnClientCallbackE0_NS_11BnInterfaceINS0_15IClientCallbackEEE;
-    _ZTCN7android2os16BnClientCallbackE8_NS_7BBinderE;
-    _ZTCN7android2os16BnClientCallbackE8_NS_7IBinderE;
-    _ZTCN7android2os16BnServiceManagerE0_NS0_15IServiceManagerE;
-    _ZTCN7android2os16BnServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BnServiceManagerE0_NS_11BnInterfaceINS0_15IServiceManagerEEE;
-    _ZTCN7android2os16BnServiceManagerE8_NS_7BBinderE;
-    _ZTCN7android2os16BnServiceManagerE8_NS_7IBinderE;
-    _ZTCN7android2os16BpClientCallbackE0_NS0_15IClientCallbackE;
-    _ZTCN7android2os16BpClientCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BpClientCallbackE0_NS_11BpInterfaceINS0_15IClientCallbackEEE;
-    _ZTCN7android2os16BpClientCallbackE8_NS_9BpRefBaseE;
-    _ZTCN7android2os16BpServiceManagerE0_NS0_15IServiceManagerE;
-    _ZTCN7android2os16BpServiceManagerE0_NS_10IInterfaceE;
-    _ZTCN7android2os16BpServiceManagerE0_NS_11BpInterfaceINS0_15IServiceManagerEEE;
-    _ZTCN7android2os16BpServiceManagerE8_NS_9BpRefBaseE;
-    _ZTCN7android2os16IServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS0_16IServiceCallbackE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BnServiceCallbackE0_NS_11BnInterfaceINS0_16IServiceCallbackEEE;
-    _ZTCN7android2os17BnServiceCallbackE8_NS_7BBinderE;
-    _ZTCN7android2os17BnServiceCallbackE8_NS_7IBinderE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS0_16IServiceCallbackE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS_10IInterfaceE;
-    _ZTCN7android2os17BpServiceCallbackE0_NS_11BpInterfaceINS0_16IServiceCallbackEEE;
-    _ZTCN7android2os17BpServiceCallbackE8_NS_9BpRefBaseE;
-    _ZTCN7android7BBinderE0_NS_7IBinderE;
-    _ZTCN7android7content2pm21IPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS_11BnInterfaceINS1_21IPackageManagerNativeEEE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE8_NS_7BBinderE;
-    _ZTCN7android7content2pm22BnPackageManagerNativeE8_NS_7IBinderE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS_11BpInterfaceINS1_21IPackageManagerNativeEEE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE0_NS1_21IPackageManagerNativeE;
-    _ZTCN7android7content2pm22BpPackageManagerNativeE8_NS_9BpRefBaseE;
-    _ZTCN7android7content2pm22IPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS_11BnInterfaceINS1_22IPackageChangeObserverEEE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE8_NS_7BBinderE;
-    _ZTCN7android7content2pm23BnPackageChangeObserverE8_NS_7IBinderE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_10IInterfaceE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS_11BpInterfaceINS1_22IPackageChangeObserverEEE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE0_NS1_22IPackageChangeObserverE;
-    _ZTCN7android7content2pm23BpPackageChangeObserverE8_NS_9BpRefBaseE;
-    _ZTCN7android7IMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BnMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BnMemoryE0_NS_11BnInterfaceINS_7IMemoryEEE;
-    _ZTCN7android8BnMemoryE0_NS_7IMemoryE;
-    _ZTCN7android8BnMemoryE8_NS_7BBinderE;
-    _ZTCN7android8BnMemoryE8_NS_7IBinderE;
-    _ZTCN7android8BpBinderE0_NS_7IBinderE;
-    _ZTCN7android8BpMemoryE0_NS_10IInterfaceE;
-    _ZTCN7android8BpMemoryE0_NS_11BpInterfaceINS_7IMemoryEEE;
-    _ZTCN7android8BpMemoryE0_NS_7IMemoryE;
-    _ZTCN7android8BpMemoryE8_NS_9BpRefBaseE;
-    _ZTCN7android9HeapCacheE0_NS_7IBinder14DeathRecipientE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_13basic_istreamIcS2_EE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE0_NS_14basic_iostreamIcS2_EE;
-    _ZTCNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE16_NS_13basic_ostreamIcS2_EE;
-    _ZThn8_N7android10AllocationD0Ev;
-    _ZThn8_N7android10AllocationD1Ev;
-    _ZThn8_N7android10MemoryBaseD0Ev;
-    _ZThn8_N7android10MemoryBaseD1Ev;
-    _ZThn8_N7android12BnMemoryHeap10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn8_N7android12BnMemoryHeapD0Ev;
-    _ZThn8_N7android12BnMemoryHeapD1Ev;
-    _ZThn8_N7android12BpMemoryHeapD0Ev;
-    _ZThn8_N7android12BpMemoryHeapD1Ev;
-    _ZThn8_N7android15BnShellCallback10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn8_N7android16BnResultReceiver10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn8_N7android2os16BnClientCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn8_N7android2os16BnServiceManager10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn8_N7android2os17BnServiceCallback10onTransactEjRKNS_6ParcelEPS2_j;
-    _ZThn8_N7android7content2pm22BnPackageManagerNative10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZThn8_N7android7content2pm23BnPackageChangeObserver10onTransactEjRKNS_6ParcelEPS3_j;
-    _ZThn8_N7android8BnMemory10onTransactEjRKNS_6ParcelEPS1_j;
-    _ZThn8_N7android8BnMemoryD0Ev;
-    _ZThn8_N7android8BnMemoryD1Ev;
-    _ZThn8_N7android8BpMemoryD0Ev;
-    _ZThn8_N7android8BpMemoryD1Ev;
-    _ZTTN7android10AllocationE;
-    _ZTTN7android10IInterfaceE;
-    _ZTTN7android10MemoryBaseE;
-    _ZTTN7android10PoolThreadE;
-    _ZTTN7android10RpcSessionE;
-    _ZTTN7android11IMemoryHeapE;
-    _ZTTN7android12BnMemoryHeapE;
-    _ZTTN7android12BpMemoryHeapE;
-    _ZTTN7android12ProcessStateE;
-    _ZTTN7android14IShellCallbackE;
-    _ZTTN7android14MemoryHeapBaseE;
-    _ZTTN7android15BnShellCallbackE;
-    _ZTTN7android15BpShellCallbackE;
-    _ZTTN7android15IResultReceiverE;
-    _ZTTN7android15IServiceManagerE;
-    _ZTTN7android16BnResultReceiverE;
-    _ZTTN7android16BpResultReceiverE;
-    _ZTTN7android18ServiceManagerShimE;
-    _ZTTN7android2os15IClientCallbackE;
-    _ZTTN7android2os15IServiceManagerE;
-    _ZTTN7android2os16BnClientCallbackE;
-    _ZTTN7android2os16BnServiceManagerE;
-    _ZTTN7android2os16BpClientCallbackE;
-    _ZTTN7android2os16BpServiceManagerE;
-    _ZTTN7android2os16IServiceCallbackE;
-    _ZTTN7android2os17BnServiceCallbackE;
-    _ZTTN7android2os17BpServiceCallbackE;
-    _ZTTN7android7BBinderE;
-    _ZTTN7android7content2pm21IPackageManagerNativeE;
-    _ZTTN7android7content2pm22BnPackageManagerNativeE;
-    _ZTTN7android7content2pm22BpPackageManagerNativeE;
-    _ZTTN7android7content2pm22IPackageChangeObserverE;
-    _ZTTN7android7content2pm23BnPackageChangeObserverE;
-    _ZTTN7android7content2pm23BpPackageChangeObserverE;
-    _ZTTN7android7IBinderE;
-    _ZTTN7android7IMemoryE;
-    _ZTTN7android8BnMemoryE;
-    _ZTTN7android8BpBinderE;
-    _ZTTN7android8BpMemoryE;
-    _ZTTN7android9BpRefBaseE;
-    _ZTTN7android9HeapCacheE;
-    _ZTTN7android9RpcServerE;
-    _ZTTNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE;
-    _ZTv0_n24_N7android10AllocationD0Ev;
-    _ZTv0_n24_N7android10AllocationD1Ev;
-    _ZTv0_n24_N7android10IInterfaceD0Ev;
-    _ZTv0_n24_N7android10IInterfaceD1Ev;
-    _ZTv0_n24_N7android10MemoryBaseD0Ev;
-    _ZTv0_n24_N7android10MemoryBaseD1Ev;
-    _ZTv0_n24_N7android10RpcSessionD0Ev;
-    _ZTv0_n24_N7android10RpcSessionD1Ev;
-    _ZTv0_n24_N7android11IMemoryHeapD0Ev;
-    _ZTv0_n24_N7android11IMemoryHeapD1Ev;
-    _ZTv0_n24_N7android12BnMemoryHeapD0Ev;
-    _ZTv0_n24_N7android12BnMemoryHeapD1Ev;
-    _ZTv0_n24_N7android12BpMemoryHeapD0Ev;
-    _ZTv0_n24_N7android12BpMemoryHeapD1Ev;
-    _ZTv0_n24_N7android12ProcessStateD0Ev;
-    _ZTv0_n24_N7android12ProcessStateD1Ev;
-    _ZTv0_n24_N7android14IShellCallbackD0Ev;
-    _ZTv0_n24_N7android14IShellCallbackD1Ev;
-    _ZTv0_n24_N7android14MemoryHeapBaseD0Ev;
-    _ZTv0_n24_N7android14MemoryHeapBaseD1Ev;
-    _ZTv0_n24_N7android15IResultReceiverD0Ev;
-    _ZTv0_n24_N7android15IResultReceiverD1Ev;
-    _ZTv0_n24_N7android15IServiceManagerD0Ev;
-    _ZTv0_n24_N7android15IServiceManagerD1Ev;
-    _ZTv0_n24_N7android2os15IClientCallbackD0Ev;
-    _ZTv0_n24_N7android2os15IClientCallbackD1Ev;
-    _ZTv0_n24_N7android2os15IServiceManagerD0Ev;
-    _ZTv0_n24_N7android2os15IServiceManagerD1Ev;
-    _ZTv0_n24_N7android2os16IServiceCallbackD0Ev;
-    _ZTv0_n24_N7android2os16IServiceCallbackD1Ev;
-    _ZTv0_n24_N7android7BBinderD0Ev;
-    _ZTv0_n24_N7android7BBinderD1Ev;
-    _ZTv0_n24_N7android7content2pm21IPackageManagerNativeD0Ev;
-    _ZTv0_n24_N7android7content2pm21IPackageManagerNativeD1Ev;
-    _ZTv0_n24_N7android7content2pm22IPackageChangeObserverD0Ev;
-    _ZTv0_n24_N7android7content2pm22IPackageChangeObserverD1Ev;
-    _ZTv0_n24_N7android7IBinderD0Ev;
-    _ZTv0_n24_N7android7IBinderD1Ev;
-    _ZTv0_n24_N7android7IMemoryD0Ev;
-    _ZTv0_n24_N7android7IMemoryD1Ev;
-    _ZTv0_n24_N7android8BnMemoryD0Ev;
-    _ZTv0_n24_N7android8BnMemoryD1Ev;
-    _ZTv0_n24_N7android8BpBinderD0Ev;
-    _ZTv0_n24_N7android8BpBinderD1Ev;
-    _ZTv0_n24_N7android8BpMemoryD0Ev;
-    _ZTv0_n24_N7android8BpMemoryD1Ev;
-    _ZTv0_n24_N7android9BpRefBaseD0Ev;
-    _ZTv0_n24_N7android9BpRefBaseD1Ev;
-    _ZTv0_n24_N7android9HeapCacheD0Ev;
-    _ZTv0_n24_N7android9HeapCacheD1Ev;
-    _ZTv0_n24_N7android9RpcServerD0Ev;
-    _ZTv0_n24_N7android9RpcServerD1Ev;
-    _ZTv0_n32_N7android14MemoryHeapBaseD0Ev;
-    _ZTv0_n32_N7android14MemoryHeapBaseD1Ev;
-    _ZTv0_n32_N7android8BpBinder10onFirstRefEv;
-    _ZTv0_n32_N7android9BpRefBase10onFirstRefEv;
-    _ZTv0_n40_N7android8BpBinder15onLastStrongRefEPKv;
-    _ZTv0_n40_N7android9BpRefBase15onLastStrongRefEPKv;
-    _ZTv0_n48_N7android8BpBinder20onIncStrongAttemptedEjPKv;
-    _ZTv0_n48_N7android9BpRefBase20onIncStrongAttemptedEjPKv;
-    _ZTv0_n56_NK7android14MemoryHeapBase9getHeapIDEv;
-    _ZTv0_n64_NK7android14MemoryHeapBase7getBaseEv;
-    _ZTv0_n72_NK7android14MemoryHeapBase7getSizeEv;
-    _ZTv0_n80_NK7android14MemoryHeapBase8getFlagsEv;
-    _ZTv0_n88_NK7android14MemoryHeapBase9getOffsetEv;
-    _ZTVN7android10AllocationE;
-    _ZTVN7android10IInterfaceE;
-    _ZTVN7android10MemoryBaseE;
-    _ZTVN7android10PoolThreadE;
-    _ZTVN7android10RpcSession13RpcConnectionE;
-    _ZTVN7android10RpcSessionE;
-    _ZTVN7android10TextOutputE;
-    _ZTVN7android11IMemoryHeapE;
-    _ZTVN7android12BnMemoryHeapE;
-    _ZTVN7android12BpMemoryHeapE;
-    _ZTVN7android12FdTextOutputE;
-    _ZTVN7android12MemoryDealerE;
-    _ZTVN7android12ProcessStateE;
-    _ZTVN7android12SortedVectorINS_16key_value_pair_tINS_2wpINS_7IBinderEEENS_9HeapCache11heap_info_tEEEEE;
-    _ZTVN7android12SortedVectorINS_16key_value_pair_tIPKvNS_8BpBinder13ObjectManager7entry_tEEEEE;
-    _ZTVN7android13LogTextOutputE;
-    _ZTVN7android14IShellCallbackE;
-    _ZTVN7android14MemoryHeapBaseE;
-    _ZTVN7android15BnShellCallbackE;
-    _ZTVN7android15BpShellCallbackE;
-    _ZTVN7android15IResultReceiverE;
-    _ZTVN7android15IServiceManagerE;
-    _ZTVN7android16BnResultReceiverE;
-    _ZTVN7android16BpResultReceiverE;
-    _ZTVN7android17InetSocketAddressE;
-    _ZTVN7android17UnixSocketAddressE;
-    _ZTVN7android18BufferedTextOutput11BufferStateE;
-    _ZTVN7android18BufferedTextOutputE;
-    _ZTVN7android18ServiceManagerShimE;
-    _ZTVN7android18VsockSocketAddressE;
-    _ZTVN7android2os15IClientCallbackE;
-    _ZTVN7android2os15IServiceManagerE;
-    _ZTVN7android2os16BnClientCallbackE;
-    _ZTVN7android2os16BnServiceManagerE;
-    _ZTVN7android2os16BpClientCallbackE;
-    _ZTVN7android2os16BpServiceManagerE;
-    _ZTVN7android2os16IServiceCallbackE;
-    _ZTVN7android2os16ParcelableHolderE;
-    _ZTVN7android2os16ServiceDebugInfoE;
-    _ZTVN7android2os17BnServiceCallbackE;
-    _ZTVN7android2os17BpServiceCallbackE;
-    _ZTVN7android2os17PersistableBundleE;
-    _ZTVN7android2os20ParcelFileDescriptorE;
-    _ZTVN7android6VectorIiEE;
-    _ZTVN7android6VectorINS_12ProcessState12handle_entryEEE;
-    _ZTVN7android6VectorINS_2spINS_18BufferedTextOutput11BufferStateEEEEE;
-    _ZTVN7android6VectorINS_8BpBinder8ObituaryEEE;
-    _ZTVN7android6VectorINS_8String16EEE;
-    _ZTVN7android6VectorIPNS_7BBinderEEE;
-    _ZTVN7android6VectorIPNS_7RefBase12weakref_typeEEE;
-    _ZTVN7android6VectorIPNS_7RefBaseEEE;
-    _ZTVN7android7BBinderE;
-    _ZTVN7android7content2pm18PackageChangeEventE;
-    _ZTVN7android7content2pm21IPackageManagerNativeE;
-    _ZTVN7android7content2pm22BnPackageManagerNativeE;
-    _ZTVN7android7content2pm22BpPackageManagerNativeE;
-    _ZTVN7android7content2pm22IPackageChangeObserverE;
-    _ZTVN7android7content2pm23BnPackageChangeObserverE;
-    _ZTVN7android7content2pm23BpPackageChangeObserverE;
-    _ZTVN7android7IBinderE;
-    _ZTVN7android7IMemoryE;
-    _ZTVN7android8BnMemoryE;
-    _ZTVN7android8BpBinderE;
-    _ZTVN7android8BpMemoryE;
-    _ZTVN7android9BpRefBaseE;
-    _ZTVN7android9HeapCacheE;
-    _ZTVN7android9RpcServerE;
-    _ZTvn8_n32_N7android14MemoryHeapBaseD0Ev;
-    _ZTvn8_n32_N7android14MemoryHeapBaseD1Ev;
-  local:
-    *;
-};
diff --git a/libs/binder/libbinder.map b/libs/binder/libbinder.map
new file mode 100644
index 0000000..9ca14bc
--- /dev/null
+++ b/libs/binder/libbinder.map
@@ -0,0 +1,5 @@
+# b/190148312: Populate with correct list of ABI symbols
+LIBBINDER {
+  global:
+    *;
+};
diff --git a/libs/binder/libbinder_rpc_unstable.cpp b/libs/binder/libbinder_rpc_unstable.cpp
new file mode 100644
index 0000000..bf2b25b
--- /dev/null
+++ b/libs/binder/libbinder_rpc_unstable.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <android/binder_libbinder.h>
+#include <binder/RpcServer.h>
+#include <binder/RpcSession.h>
+#include <linux/vm_sockets.h>
+
+using android::OK;
+using android::RpcServer;
+using android::RpcSession;
+using android::status_t;
+using android::statusToString;
+using android::base::unique_fd;
+
+extern "C" {
+
+bool RunRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
+                             void* factoryContext, unsigned int port) {
+    auto server = RpcServer::make();
+    if (status_t status = server->setupVsockServer(port); status != OK) {
+        LOG(ERROR) << "Failed to set up vsock server with port " << port
+                   << " error: " << statusToString(status).c_str();
+        return false;
+    }
+    server->setPerSessionRootObject([=](const sockaddr* addr, socklen_t addrlen) {
+        LOG_ALWAYS_FATAL_IF(addr->sa_family != AF_VSOCK, "address is not a vsock");
+        LOG_ALWAYS_FATAL_IF(addrlen < sizeof(sockaddr_vm), "sockaddr is truncated");
+        const sockaddr_vm* vaddr = reinterpret_cast<const sockaddr_vm*>(addr);
+        return AIBinder_toPlatformBinder(factory(vaddr->svm_cid, factoryContext));
+    });
+
+    server->join();
+
+    // Shutdown any open sessions since server failed.
+    (void)server->shutdown();
+    return true;
+}
+
+bool RunRpcServerCallback(AIBinder* service, unsigned int port, void (*readyCallback)(void* param),
+                          void* param) {
+    auto server = RpcServer::make();
+    if (status_t status = server->setupVsockServer(port); status != OK) {
+        LOG(ERROR) << "Failed to set up vsock server with port " << port
+                   << " error: " << statusToString(status).c_str();
+        return false;
+    }
+    server->setRootObject(AIBinder_toPlatformBinder(service));
+
+    if (readyCallback) readyCallback(param);
+    server->join();
+
+    // Shutdown any open sessions since server failed.
+    (void)server->shutdown();
+    return true;
+}
+
+bool RunRpcServer(AIBinder* service, unsigned int port) {
+    return RunRpcServerCallback(service, port, nullptr, nullptr);
+}
+
+AIBinder* RpcClient(unsigned int cid, unsigned int port) {
+    auto session = RpcSession::make();
+    if (status_t status = session->setupVsockClient(cid, port); status != OK) {
+        LOG(ERROR) << "Failed to set up vsock client with CID " << cid << " and port " << port
+                   << " error: " << statusToString(status).c_str();
+        return nullptr;
+    }
+    return AIBinder_fromPlatformBinder(session->getRootObject());
+}
+
+AIBinder* RpcPreconnectedClient(int (*requestFd)(void* param), void* param) {
+    auto session = RpcSession::make();
+    auto request = [=] { return unique_fd{requestFd(param)}; };
+    if (status_t status = session->setupPreconnectedClient(unique_fd{}, request); status != OK) {
+        LOG(ERROR) << "Failed to set up vsock client. error: " << statusToString(status).c_str();
+        return nullptr;
+    }
+    return AIBinder_fromPlatformBinder(session->getRootObject());
+}
+}
diff --git a/libs/binder/libbinder_rpc_unstable.map.txt b/libs/binder/libbinder_rpc_unstable.map.txt
new file mode 100644
index 0000000..e856569
--- /dev/null
+++ b/libs/binder/libbinder_rpc_unstable.map.txt
@@ -0,0 +1,9 @@
+LIBBINDER_RPC_UNSTABLE_SHIM { # platform-only
+  global:
+    RunRpcServer;
+    RunRpcServerCallback;
+    RpcClient;
+    RpcPreconnectedClient;
+  local:
+    *;
+};
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index b03e24c..ee46fcb 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -54,6 +54,7 @@
 
     defaults: ["libbinder_ndk_host_user"],
     host_supported: true,
+    recovery_available: true,
 
     llndk: {
         symbol_file: "libbinder_ndk.map.txt",
@@ -117,6 +118,9 @@
             "30",
         ],
     },
+    sanitize: {
+        misc_undefined: ["integer"],
+    },
     tidy: true,
     tidy_flags: [
         // Only check our headers
@@ -152,6 +156,7 @@
     name: "libbinder_headers_platform_shared",
     export_include_dirs: ["include_cpp"],
     vendor_available: true,
+    recovery_available: true,
     host_supported: true,
     // TODO(b/153609531): remove when no longer needed.
     native_bridge_supported: true,
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 1dcb41b..6949c2c 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -47,7 +47,8 @@
 void clean(const void* /*id*/, void* /*obj*/, void* /*cookie*/){/* do nothing */};
 
 static void attach(const sp<IBinder>& binder) {
-    binder->attachObject(kId, kValue, nullptr /*cookie*/, clean);
+    // can only attach once
+    CHECK_EQ(nullptr, binder->attachObject(kId, kValue, nullptr /*cookie*/, clean));
 }
 static bool has(const sp<IBinder>& binder) {
     return binder != nullptr && binder->findObject(kId) == kValue;
@@ -57,7 +58,6 @@
 
 namespace ABpBinderTag {
 
-static std::mutex gLock;
 static const void* kId = "ABpBinder";
 struct Value {
     wp<ABpBinder> binder;
@@ -82,8 +82,8 @@
         const String16& currentDescriptor = mClazz->getInterfaceDescriptor();
         if (newDescriptor == currentDescriptor) {
             LOG(ERROR) << __func__ << ": Class descriptors '" << currentDescriptor
-                       << "' match during associateClass, but they are different class objects. "
-                          "Class descriptor collision?";
+                       << "' match during associateClass, but they are different class objects ("
+                       << clazz << " vs " << mClazz << "). Class descriptor collision?";
         } else {
             LOG(ERROR) << __func__
                        << ": Class cannot be associated on object which already has a class. "
@@ -104,6 +104,17 @@
     return {};
 }
 
+// b/175635923 libcxx causes "implicit-conversion" with a string with invalid char
+static std::string SanitizeString(const String16& str) {
+    std::string sanitized{String8(str)};
+    for (auto& c : sanitized) {
+        if (!isprint(c)) {
+            c = '?';
+        }
+    }
+    return sanitized;
+}
+
 bool AIBinder::associateClass(const AIBinder_Class* clazz) {
     if (clazz == nullptr) return false;
 
@@ -118,7 +129,7 @@
     if (descriptor != newDescriptor) {
         if (getBinder()->isBinderAlive()) {
             LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor
-                       << "' but descriptor is actually '" << descriptor << "'.";
+                       << "' but descriptor is actually '" << SanitizeString(descriptor) << "'.";
         } else {
             // b/155793159
             LOG(ERROR) << __func__ << ": Cannot associate class '" << newDescriptor
@@ -172,7 +183,7 @@
 status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply,
                               binder_flags_t flags) {
     if (isUserCommand(code)) {
-        if (!data.checkInterface(this)) {
+        if (getClass()->writeHeader && !data.checkInterface(this)) {
             return STATUS_BAD_TYPE;
         }
 
@@ -232,19 +243,16 @@
 ABpBinder::~ABpBinder() {}
 
 void ABpBinder::onLastStrongRef(const void* id) {
-    {
-        std::lock_guard<std::mutex> lock(ABpBinderTag::gLock);
-        // Since ABpBinder is OBJECT_LIFETIME_WEAK, we must remove this weak reference in order for
-        // the ABpBinder to be deleted. Since a strong reference to this ABpBinder object should no
-        // longer be able to exist at the time of this method call, there is no longer a need to
-        // recover it.
+    // Since ABpBinder is OBJECT_LIFETIME_WEAK, we must remove this weak reference in order for
+    // the ABpBinder to be deleted. Even though we have no more references on the ABpBinder
+    // (BpRefBase), the remote object may still exist (for instance, if we
+    // receive it from another process, before the ABpBinder is attached).
 
-        ABpBinderTag::Value* value =
-                static_cast<ABpBinderTag::Value*>(remote()->findObject(ABpBinderTag::kId));
-        if (value != nullptr) {
-            value->binder = nullptr;
-        }
-    }
+    ABpBinderTag::Value* value =
+            static_cast<ABpBinderTag::Value*>(remote()->findObject(ABpBinderTag::kId));
+    CHECK_NE(nullptr, value) << "ABpBinder must always be attached";
+
+    remote()->withLock([&]() { value->binder = nullptr; });
 
     BpRefBase::onLastStrongRef(id);
 }
@@ -259,21 +267,29 @@
 
     // The following code ensures that for a given binder object (remote or local), if it is not an
     // ABBinder then at most one ABpBinder object exists in a given process representing it.
-    std::lock_guard<std::mutex> lock(ABpBinderTag::gLock);
 
-    ABpBinderTag::Value* value =
-            static_cast<ABpBinderTag::Value*>(binder->findObject(ABpBinderTag::kId));
+    auto* value = static_cast<ABpBinderTag::Value*>(binder->findObject(ABpBinderTag::kId));
     if (value == nullptr) {
         value = new ABpBinderTag::Value;
-        binder->attachObject(ABpBinderTag::kId, static_cast<void*>(value), nullptr /*cookie*/,
-                             ABpBinderTag::clean);
+        auto oldValue = static_cast<ABpBinderTag::Value*>(
+                binder->attachObject(ABpBinderTag::kId, static_cast<void*>(value),
+                                     nullptr /*cookie*/, ABpBinderTag::clean));
+
+        // allocated by another thread
+        if (oldValue) {
+            delete value;
+            value = oldValue;
+        }
     }
 
-    sp<ABpBinder> ret = value->binder.promote();
-    if (ret == nullptr) {
-        ret = new ABpBinder(binder);
-        value->binder = ret;
-    }
+    sp<ABpBinder> ret;
+    binder->withLock([&]() {
+        ret = value->binder.promote();
+        if (ret == nullptr) {
+            ret = sp<ABpBinder>::make(binder);
+            value->binder = ret;
+        }
+    });
 
     return ret;
 }
@@ -349,6 +365,12 @@
     clazz->onDump = onDump;
 }
 
+void AIBinder_Class_disableInterfaceTokenHeader(AIBinder_Class* clazz) {
+    CHECK(clazz != nullptr) << "disableInterfaceTokenHeader requires non-null clazz";
+
+    clazz->writeHeader = false;
+}
+
 void AIBinder_Class_setHandleShellCommand(AIBinder_Class* clazz,
                                           AIBinder_handleShellCommand handleShellCommand) {
     CHECK(clazz != nullptr) << "setHandleShellCommand requires non-null clazz";
@@ -362,6 +384,12 @@
     return clazz->getInterfaceDescriptorUtf8();
 }
 
+AIBinder_DeathRecipient::TransferDeathRecipient::~TransferDeathRecipient() {
+    if (mOnUnlinked != nullptr) {
+        mOnUnlinked(mCookie);
+    }
+}
+
 void AIBinder_DeathRecipient::TransferDeathRecipient::binderDied(const wp<IBinder>& who) {
     CHECK(who == mWho) << who.unsafe_get() << "(" << who.get_refs() << ") vs " << mWho.unsafe_get()
                        << " (" << mWho.get_refs() << ")";
@@ -383,7 +411,7 @@
 }
 
 AIBinder_DeathRecipient::AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied)
-    : mOnDied(onDied) {
+    : mOnDied(onDied), mOnUnlinked(nullptr) {
     CHECK(onDied != nullptr);
 }
 
@@ -401,10 +429,12 @@
     std::lock_guard<std::mutex> l(mDeathRecipientsMutex);
 
     sp<TransferDeathRecipient> recipient =
-            new TransferDeathRecipient(binder, cookie, this, mOnDied);
+            new TransferDeathRecipient(binder, cookie, this, mOnDied, mOnUnlinked);
 
     status_t status = binder->linkToDeath(recipient, cookie, 0 /*flags*/);
     if (status != STATUS_OK) {
+        // When we failed to link, the destructor of TransferDeathRecipient runs here, which
+        // ensures that mOnUnlinked is called before we return with an error from this method.
         return PruneStatusT(status);
     }
 
@@ -437,6 +467,10 @@
     return STATUS_NAME_NOT_FOUND;
 }
 
+void AIBinder_DeathRecipient::setOnUnlinked(AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) {
+    mOnUnlinked = onUnlinked;
+}
+
 // start of C-API methods
 
 AIBinder* AIBinder_new(const AIBinder_Class* clazz, void* args) {
@@ -532,6 +566,10 @@
     return ::android::IPCThreadState::self()->getCallingPid();
 }
 
+bool AIBinder_isHandlingTransaction() {
+    return ::android::IPCThreadState::self()->getServingStackPointer() != nullptr;
+}
+
 void AIBinder_incStrong(AIBinder* binder) {
     if (binder == nullptr) {
         return;
@@ -601,7 +639,10 @@
     *in = new AParcel(binder);
     (*in)->get()->markForBinder(binder->getBinder());
 
-    status_t status = (*in)->get()->writeInterfaceToken(clazz->getInterfaceDescriptor());
+    status_t status = android::OK;
+    if (clazz->writeHeader) {
+        status = (*in)->get()->writeInterfaceToken(clazz->getInterfaceDescriptor());
+    }
     binder_status_t ret = PruneStatusT(status);
 
     if (ret != STATUS_OK) {
@@ -675,6 +716,15 @@
     return ret;
 }
 
+void AIBinder_DeathRecipient_setOnUnlinked(AIBinder_DeathRecipient* recipient,
+                                           AIBinder_DeathRecipient_onBinderUnlinked onUnlinked) {
+    if (recipient == nullptr) {
+        return;
+    }
+
+    recipient->setOnUnlinked(onUnlinked);
+}
+
 void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient* recipient) {
     if (recipient == nullptr) {
         return;
@@ -745,3 +795,7 @@
     AIBinder_incStrong(ndkBinder.get());
     return ndkBinder.get();
 }
+
+void AIBinder_setMinSchedulerPolicy(AIBinder* binder, int policy, int priority) {
+    binder->asABBinder()->setMinSchedulerPolicy(policy, priority);
+}
diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h
index 6824306..730e51b 100644
--- a/libs/binder/ndk/ibinder_internal.h
+++ b/libs/binder/ndk/ibinder_internal.h
@@ -105,6 +105,7 @@
     ABpBinder* asABpBinder() override { return this; }
 
    private:
+    friend android::sp<ABpBinder>;
     explicit ABpBinder(const ::android::sp<::android::IBinder>& binder);
 };
 
@@ -115,6 +116,9 @@
     const ::android::String16& getInterfaceDescriptor() const { return mWideInterfaceDescriptor; }
     const char* getInterfaceDescriptorUtf8() const { return mInterfaceDescriptor.c_str(); }
 
+    // whether a transaction header should be written
+    bool writeHeader = true;
+
     // required to be non-null, implemented for every class
     const AIBinder_Class_onCreate onCreate = nullptr;
     const AIBinder_Class_onDestroy onDestroy = nullptr;
@@ -144,8 +148,14 @@
     struct TransferDeathRecipient : ::android::IBinder::DeathRecipient {
         TransferDeathRecipient(const ::android::wp<::android::IBinder>& who, void* cookie,
                                const ::android::wp<AIBinder_DeathRecipient>& parentRecipient,
-                               const AIBinder_DeathRecipient_onBinderDied onDied)
-            : mWho(who), mCookie(cookie), mParentRecipient(parentRecipient), mOnDied(onDied) {}
+                               const AIBinder_DeathRecipient_onBinderDied onDied,
+                               const AIBinder_DeathRecipient_onBinderUnlinked onUnlinked)
+            : mWho(who),
+              mCookie(cookie),
+              mParentRecipient(parentRecipient),
+              mOnDied(onDied),
+              mOnUnlinked(onUnlinked) {}
+        ~TransferDeathRecipient();
 
         void binderDied(const ::android::wp<::android::IBinder>& who) override;
 
@@ -161,11 +171,13 @@
         // This is kept separately from AIBinder_DeathRecipient in case the death recipient is
         // deleted while the death notification is fired
         const AIBinder_DeathRecipient_onBinderDied mOnDied;
+        const AIBinder_DeathRecipient_onBinderUnlinked mOnUnlinked;
     };
 
     explicit AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied);
     binder_status_t linkToDeath(const ::android::sp<::android::IBinder>&, void* cookie);
     binder_status_t unlinkToDeath(const ::android::sp<::android::IBinder>& binder, void* cookie);
+    void setOnUnlinked(AIBinder_DeathRecipient_onBinderUnlinked onUnlinked);
 
    private:
     // When the user of this API deletes a Bp object but not the death recipient, the
@@ -176,4 +188,5 @@
     std::mutex mDeathRecipientsMutex;
     std::vector<::android::sp<TransferDeathRecipient>> mDeathRecipients;
     AIBinder_DeathRecipient_onBinderDied mOnDied;
+    AIBinder_DeathRecipient_onBinderUnlinked mOnUnlinked;
 };
diff --git a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
index 6c44726..5de64f8 100644
--- a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
@@ -55,6 +55,12 @@
         std::call_once(mFlagThis, [&]() {
             __assert(__FILE__, __LINE__, "SharedRefBase: no ref created during lifetime");
         });
+
+        if (ref() != nullptr) {
+            __assert(__FILE__, __LINE__,
+                     "SharedRefBase: destructed but still able to lock weak_ptr. Is this object "
+                     "double-owned?");
+        }
     }
 
     /**
diff --git a/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
index 83190aa..67623a6 100644
--- a/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_parcel_utils.h
@@ -27,15 +27,67 @@
 #pragma once
 
 #include <android/binder_auto_utils.h>
+#include <android/binder_interface_utils.h>
 #include <android/binder_internal_logging.h>
 #include <android/binder_parcel.h>
 
 #include <optional>
 #include <string>
+#include <type_traits>
 #include <vector>
 
 namespace ndk {
 
+namespace {
+template <typename Test, template <typename...> class Ref>
+struct is_specialization : std::false_type {};
+
+template <template <typename...> class Ref, typename... Args>
+struct is_specialization<Ref<Args...>, Ref> : std::true_type {};
+
+template <typename Test, template <typename...> class Ref>
+static inline constexpr bool is_specialization_v = is_specialization<Test, Ref>::value;
+
+// Get the first template type from a container, the T from MyClass<T, ...>.
+template <typename T>
+struct first_template_type {
+    using type = void;
+};
+
+template <template <typename...> class V, typename T, typename... Args>
+struct first_template_type<V<T, Args...>> {
+    using type = T;
+};
+
+template <typename T>
+using first_template_type_t = typename first_template_type<T>::type;
+
+// Tells if T represents NDK interface (shared_ptr<ICInterface-derived>)
+template <typename T>
+static inline constexpr bool is_interface_v = is_specialization_v<T, std::shared_ptr>&&
+        std::is_base_of_v<::ndk::ICInterface, first_template_type_t<T>>;
+
+// Tells if T represents NDK parcelable with readFromParcel/writeToParcel methods defined
+template <typename T, typename = void>
+struct is_parcelable : std::false_type {};
+
+template <typename T>
+struct is_parcelable<
+        T, std::void_t<decltype(std::declval<T>().readFromParcel(std::declval<const AParcel*>())),
+                       decltype(std::declval<T>().writeToParcel(std::declval<AParcel*>()))>>
+    : std::true_type {};
+
+template <typename T>
+static inline constexpr bool is_parcelable_v = is_parcelable<T>::value;
+
+// Tells if T represents nullable NDK parcelable (optional<parcelable> or unique_ptr<parcelable>)
+template <typename T>
+static inline constexpr bool is_nullable_parcelable_v = is_parcelable_v<first_template_type_t<T>> &&
+                                                        (is_specialization_v<T, std::optional> ||
+                                                         is_specialization_v<T, std::unique_ptr>);
+
+}  // namespace
+
 /**
  * This retrieves and allocates a vector to size 'length' and returns the underlying buffer.
  */
@@ -429,11 +481,19 @@
  */
 template <typename P>
 static inline binder_status_t AParcel_writeParcelable(AParcel* parcel, const P& p) {
-    binder_status_t status = AParcel_writeInt32(parcel, 1);  // non-null
-    if (status != STATUS_OK) {
-        return status;
+    if constexpr (is_interface_v<P>) {
+        if (!p) {
+            return STATUS_UNEXPECTED_NULL;
+        }
+        return first_template_type_t<P>::writeToParcel(parcel, p);
+    } else {
+        static_assert(is_parcelable_v<P>);
+        binder_status_t status = AParcel_writeInt32(parcel, 1);  // non-null
+        if (status != STATUS_OK) {
+            return status;
+        }
+        return p.writeToParcel(parcel);
     }
-    return p.writeToParcel(parcel);
 }
 
 /**
@@ -441,50 +501,81 @@
  */
 template <typename P>
 static inline binder_status_t AParcel_readParcelable(const AParcel* parcel, P* p) {
-    int32_t null;
-    binder_status_t status = AParcel_readInt32(parcel, &null);
-    if (status != STATUS_OK) {
+    if constexpr (is_interface_v<P>) {
+        binder_status_t status = first_template_type_t<P>::readFromParcel(parcel, p);
+        if (status == STATUS_OK) {
+            if (!*p) {
+                return STATUS_UNEXPECTED_NULL;
+            }
+        }
         return status;
+    } else {
+        static_assert(is_parcelable_v<P>);
+        int32_t null;
+        binder_status_t status = AParcel_readInt32(parcel, &null);
+        if (status != STATUS_OK) {
+            return status;
+        }
+        if (null == 0) {
+            return STATUS_UNEXPECTED_NULL;
+        }
+        return p->readFromParcel(parcel);
     }
-    if (null == 0) {
-        return STATUS_UNEXPECTED_NULL;
-    }
-    return p->readFromParcel(parcel);
 }
 
 /**
  * Convenience API for writing a nullable parcelable.
  */
 template <typename P>
-static inline binder_status_t AParcel_writeNullableParcelable(AParcel* parcel,
-                                                              const std::optional<P>& p) {
-    if (p == std::nullopt) {
-        return AParcel_writeInt32(parcel, 0);  // null
+static inline binder_status_t AParcel_writeNullableParcelable(AParcel* parcel, const P& p) {
+    if constexpr (is_interface_v<P>) {
+        return first_template_type_t<P>::writeToParcel(parcel, p);
+    } else {
+        static_assert(is_nullable_parcelable_v<P>);
+        if (!p) {
+            return AParcel_writeInt32(parcel, 0);  // null
+        }
+        binder_status_t status = AParcel_writeInt32(parcel, 1);  // non-null
+        if (status != STATUS_OK) {
+            return status;
+        }
+        return p->writeToParcel(parcel);
     }
-    binder_status_t status = AParcel_writeInt32(parcel, 1);  // non-null
-    if (status != STATUS_OK) {
-        return status;
-    }
-    return p->writeToParcel(parcel);
 }
 
 /**
  * Convenience API for reading a nullable parcelable.
  */
 template <typename P>
-static inline binder_status_t AParcel_readNullableParcelable(const AParcel* parcel,
-                                                             std::optional<P>* p) {
-    int32_t null;
-    binder_status_t status = AParcel_readInt32(parcel, &null);
-    if (status != STATUS_OK) {
-        return status;
+static inline binder_status_t AParcel_readNullableParcelable(const AParcel* parcel, P* p) {
+    if constexpr (is_interface_v<P>) {
+        return first_template_type_t<P>::readFromParcel(parcel, p);
+    } else if constexpr (is_specialization_v<P, std::optional>) {
+        int32_t null;
+        binder_status_t status = AParcel_readInt32(parcel, &null);
+        if (status != STATUS_OK) {
+            return status;
+        }
+        if (null == 0) {
+            *p = std::nullopt;
+            return STATUS_OK;
+        }
+        *p = std::optional<first_template_type_t<P>>(first_template_type_t<P>{});
+        return (*p)->readFromParcel(parcel);
+    } else {
+        static_assert(is_specialization_v<P, std::unique_ptr>);
+        int32_t null;
+        binder_status_t status = AParcel_readInt32(parcel, &null);
+        if (status != STATUS_OK) {
+            return status;
+        }
+        if (null == 0) {
+            p->reset();
+            return STATUS_OK;
+        }
+        *p = std::make_unique<first_template_type_t<P>>();
+        return (*p)->readFromParcel(parcel);
     }
-    if (null == 0) {
-        *p = std::nullopt;
-        return STATUS_OK;
-    }
-    *p = std::optional<P>(P{});
-    return (*p)->readFromParcel(parcel);
 }
 
 /**
@@ -508,6 +599,28 @@
 }
 
 /**
+ * Writes a parcelable object of type P inside a std::vector<P> at index 'index' to 'parcel'.
+ */
+template <typename P>
+binder_status_t AParcel_writeNullableStdVectorParcelableElement(AParcel* parcel,
+                                                                const void* vectorData,
+                                                                size_t index) {
+    const std::optional<std::vector<P>>* vector =
+            static_cast<const std::optional<std::vector<P>>*>(vectorData);
+    return AParcel_writeNullableParcelable(parcel, (*vector)->at(index));
+}
+
+/**
+ * Reads a parcelable object of type P inside a std::vector<P> at index 'index' from 'parcel'.
+ */
+template <typename P>
+binder_status_t AParcel_readNullableStdVectorParcelableElement(const AParcel* parcel,
+                                                               void* vectorData, size_t index) {
+    std::optional<std::vector<P>>* vector = static_cast<std::optional<std::vector<P>>*>(vectorData);
+    return AParcel_readNullableParcelable(parcel, &(*vector)->at(index));
+}
+
+/**
  * Writes a ScopedFileDescriptor object inside a std::vector<ScopedFileDescriptor> at index 'index'
  * to 'parcel'.
  */
@@ -516,11 +629,7 @@
         AParcel* parcel, const void* vectorData, size_t index) {
     const std::vector<ScopedFileDescriptor>* vector =
             static_cast<const std::vector<ScopedFileDescriptor>*>(vectorData);
-    int writeFd = vector->at(index).get();
-    if (writeFd < 0) {
-        return STATUS_UNEXPECTED_NULL;
-    }
-    return AParcel_writeParcelFileDescriptor(parcel, writeFd);
+    return AParcel_writeRequiredParcelFileDescriptor(parcel, vector->at(index));
 }
 
 /**
@@ -532,15 +641,79 @@
         const AParcel* parcel, void* vectorData, size_t index) {
     std::vector<ScopedFileDescriptor>* vector =
             static_cast<std::vector<ScopedFileDescriptor>*>(vectorData);
-    int readFd;
-    binder_status_t status = AParcel_readParcelFileDescriptor(parcel, &readFd);
-    if (status == STATUS_OK) {
-        if (readFd < 0) {
-            return STATUS_UNEXPECTED_NULL;
-        }
-        vector->at(index).set(readFd);
-    }
-    return status;
+    return AParcel_readRequiredParcelFileDescriptor(parcel, &vector->at(index));
+}
+
+/**
+ * Writes a ScopedFileDescriptor object inside a std::optional<std::vector<ScopedFileDescriptor>> at
+ * index 'index' to 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_writeNullableStdVectorParcelableElement<ScopedFileDescriptor>(
+        AParcel* parcel, const void* vectorData, size_t index) {
+    const std::optional<std::vector<ScopedFileDescriptor>>* vector =
+            static_cast<const std::optional<std::vector<ScopedFileDescriptor>>*>(vectorData);
+    return AParcel_writeNullableParcelFileDescriptor(parcel, (*vector)->at(index));
+}
+
+/**
+ * Reads a ScopedFileDescriptor object inside a std::optional<std::vector<ScopedFileDescriptor>> at
+ * index 'index' from 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_readNullableStdVectorParcelableElement<ScopedFileDescriptor>(
+        const AParcel* parcel, void* vectorData, size_t index) {
+    std::optional<std::vector<ScopedFileDescriptor>>* vector =
+            static_cast<std::optional<std::vector<ScopedFileDescriptor>>*>(vectorData);
+    return AParcel_readNullableParcelFileDescriptor(parcel, &(*vector)->at(index));
+}
+
+/**
+ * Writes an SpAIBinder object inside a std::vector<SpAIBinder> at index 'index'
+ * to 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_writeStdVectorParcelableElement<SpAIBinder>(AParcel* parcel,
+                                                                           const void* vectorData,
+                                                                           size_t index) {
+    const std::vector<SpAIBinder>* vector = static_cast<const std::vector<SpAIBinder>*>(vectorData);
+    return AParcel_writeRequiredStrongBinder(parcel, vector->at(index));
+}
+
+/**
+ * Reads an SpAIBinder object inside a std::vector<SpAIBinder> at index 'index'
+ * from 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_readStdVectorParcelableElement<SpAIBinder>(const AParcel* parcel,
+                                                                          void* vectorData,
+                                                                          size_t index) {
+    std::vector<SpAIBinder>* vector = static_cast<std::vector<SpAIBinder>*>(vectorData);
+    return AParcel_readRequiredStrongBinder(parcel, &vector->at(index));
+}
+
+/**
+ * Writes an SpAIBinder object inside a std::optional<std::vector<SpAIBinder>> at index 'index'
+ * to 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_writeNullableStdVectorParcelableElement<SpAIBinder>(
+        AParcel* parcel, const void* vectorData, size_t index) {
+    const std::optional<std::vector<SpAIBinder>>* vector =
+            static_cast<const std::optional<std::vector<SpAIBinder>>*>(vectorData);
+    return AParcel_writeNullableStrongBinder(parcel, (*vector)->at(index));
+}
+
+/**
+ * Reads an SpAIBinder object inside a std::optional<std::vector<SpAIBinder>> at index 'index'
+ * from 'parcel'.
+ */
+template <>
+inline binder_status_t AParcel_readNullableStdVectorParcelableElement<SpAIBinder>(
+        const AParcel* parcel, void* vectorData, size_t index) {
+    std::optional<std::vector<SpAIBinder>>* vector =
+            static_cast<std::optional<std::vector<SpAIBinder>>*>(vectorData);
+    return AParcel_readNullableStrongBinder(parcel, &(*vector)->at(index));
 }
 
 /**
@@ -563,6 +736,30 @@
                                        AParcel_readStdVectorParcelableElement<P>);
 }
 
+/**
+ * Convenience API for writing a std::optional<std::vector<P>>
+ */
+template <typename P>
+static inline binder_status_t AParcel_writeVector(AParcel* parcel,
+                                                  const std::optional<std::vector<P>>& vec) {
+    if (!vec) return AParcel_writeInt32(parcel, -1);
+    const void* vectorData = static_cast<const void*>(&vec);
+    return AParcel_writeParcelableArray(parcel, vectorData, static_cast<int32_t>(vec->size()),
+                                        AParcel_writeNullableStdVectorParcelableElement<P>);
+}
+
+/**
+ * Convenience API for reading a std::optional<std::vector<P>>
+ */
+template <typename P>
+static inline binder_status_t AParcel_readVector(const AParcel* parcel,
+                                                 std::optional<std::vector<P>>* vec) {
+    void* vectorData = static_cast<void*>(vec);
+    return AParcel_readParcelableArray(parcel, vectorData,
+                                       AParcel_nullableStdVectorExternalAllocator<P>,
+                                       AParcel_readNullableStdVectorParcelableElement<P>);
+}
+
 // @START
 /**
  * Writes a vector of int32_t to the next location in a non-null parcel.
@@ -910,6 +1107,9 @@
     if (err != STATUS_OK) return err;
     if (size < 0) return STATUS_UNEXPECTED_NULL;
 
+    // TODO(b/188215728): delegate to libbinder_ndk
+    if (size > 1000000) return STATUS_NO_MEMORY;
+
     vec->resize(static_cast<size_t>(size));
     return STATUS_OK;
 }
@@ -931,6 +1131,9 @@
         return STATUS_OK;
     }
 
+    // TODO(b/188215728): delegate to libbinder_ndk
+    if (size > 1000000) return STATUS_NO_MEMORY;
+
     *vec = std::optional<std::vector<T>>(std::vector<T>{});
     (*vec)->resize(static_cast<size_t>(size));
     return STATUS_OK;
diff --git a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
index 2277148..aa3b978 100644
--- a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
@@ -46,7 +46,7 @@
     AParcelableHolder() = delete;
     explicit AParcelableHolder(parcelable_stability_t stability)
         : mParcel(AParcel_create()), mStability(stability) {}
-
+    AParcelableHolder(AParcelableHolder&& other) = default;
     virtual ~AParcelableHolder() = default;
 
     binder_status_t writeToParcel(AParcel* parcel) const {
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 78f2d3a..565542b 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -219,6 +219,21 @@
 void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) __INTRODUCED_IN(29);
 
 /**
+ * This tells users of this class not to use a transaction header. By default, libbinder_ndk users
+ * read/write transaction headers implicitly (in the SDK, this must be manually written by
+ * android.os.Parcel#writeInterfaceToken, and it is read/checked with
+ * android.os.Parcel#enforceInterface). This method is provided in order to talk to legacy code
+ * which does not write an interface token. When this is disabled, type safety is reduced, so you
+ * must have a separate way of determining the binder you are talking to is the right type. Must
+ * be called before any instance of the class is created.
+ *
+ * Available since API level 33.
+ *
+ * \param clazz class to disable interface header on.
+ */
+void AIBinder_Class_disableInterfaceTokenHeader(AIBinder_Class* clazz) __INTRODUCED_IN(33);
+
+/**
  * Creates a new binder object of the appropriate class.
  *
  * Ownership of args is passed to this object. The lifecycle is implemented with AIBinder_incStrong
@@ -304,9 +319,9 @@
 /**
  * Registers for notifications that the associated binder is dead. The same death recipient may be
  * associated with multiple different binders. If the binder is local, then no death recipient will
- * be given (since if the local process dies, then no recipient will exist to recieve a
+ * be given (since if the local process dies, then no recipient will exist to receive a
  * transaction). The cookie is passed to recipient in the case that this binder dies and can be
- * null. The exact cookie must also be used to unlink this transaction (see AIBinder_linkToDeath).
+ * null. The exact cookie must also be used to unlink this transaction (see AIBinder_unlinkToDeath).
  * This function may return a binder transaction failure. The cookie can be used both for
  * identification and holding user data.
  *
@@ -333,6 +348,10 @@
  * If the binder dies, it will automatically unlink. If the binder is deleted, it will be
  * automatically unlinked.
  *
+ * Be aware that it is not safe to immediately deallocate the cookie when this call returns. If you
+ * need to clean up the cookie, you should do so in the onUnlinked callback, which can be set using
+ * AIBinder_DeathRecipient_setOnUnlinked.
+ *
  * Available since API level 29.
  *
  * \param binder the binder object to remove a previously linked death recipient from.
@@ -374,6 +393,14 @@
 pid_t AIBinder_getCallingPid() __INTRODUCED_IN(29);
 
 /**
+ * Determine whether the current thread is currently executing an incoming transaction.
+ *
+ * \return true if the current thread is currently executing an incoming transaction, and false
+ * otherwise.
+ */
+bool AIBinder_isHandlingTransaction() __INTRODUCED_IN(33);
+
+/**
  * This can only be called if a strong reference to this object already exists in process.
  *
  * Available since API level 29.
@@ -553,6 +580,22 @@
 typedef void (*AIBinder_DeathRecipient_onBinderDied)(void* cookie) __INTRODUCED_IN(29);
 
 /**
+ * This function is intended for cleaning up the data in the provided cookie, and it is executed
+ * when the DeathRecipient is unlinked. When the DeathRecipient is unlinked due to a death receipt,
+ * this method is called after the call to onBinderDied.
+ *
+ * This method is called once for each binder that is unlinked. Hence, if the same cookie is passed
+ * to multiple binders, then the caller is responsible for reference counting the cookie.
+ *
+ * See also AIBinder_linkToDeath/AIBinder_unlinkToDeath.
+ *
+ * Available since API level 33.
+ *
+ * \param cookie the cookie passed to AIBinder_linkToDeath.
+ */
+typedef void (*AIBinder_DeathRecipient_onBinderUnlinked)(void* cookie) __INTRODUCED_IN(33);
+
+/**
  * Creates a new binder death recipient. This can be attached to multiple different binder objects.
  *
  * Available since API level 29.
@@ -565,9 +608,47 @@
         AIBinder_DeathRecipient_onBinderDied onBinderDied) __INTRODUCED_IN(29);
 
 /**
+ * Set the callback to be called when this DeathRecipient is unlinked from a binder. The callback is
+ * called in the following situations:
+ *
+ *  1. If the binder died, shortly after the call to onBinderDied.
+ *  2. If the binder is explicitly unlinked with AIBinder_unlinkToDeath or
+ *     AIBinder_DeathRecipient_delete.
+ *  3. During or shortly after the AIBinder_linkToDeath call if it returns an error.
+ *
+ * It is guaranteed that the callback is called exactly once for each call to linkToDeath unless the
+ * process is aborted before the binder is unlinked.
+ *
+ * Be aware that when the binder is explicitly unlinked, it is not guaranteed that onUnlinked has
+ * been called before the call to AIBinder_unlinkToDeath or AIBinder_DeathRecipient_delete returns.
+ * For example, if the binder dies concurrently with a call to AIBinder_unlinkToDeath, the binder is
+ * not unlinked until after the death notification is delivered, even if AIBinder_unlinkToDeath
+ * returns before that happens.
+ *
+ * This method should be called before linking the DeathRecipient to a binder because the function
+ * pointer is cached. If you change it after linking to a binder, it is unspecified whether the old
+ * binder will call the old or new onUnlinked callback.
+ *
+ * The onUnlinked argument may be null. In this case, no notification is given when the binder is
+ * unlinked.
+ *
+ * Available since API level 33.
+ *
+ * \param recipient the DeathRecipient to set the onUnlinked callback for.
+ * \param onUnlinked the callback to call when a binder is unlinked from recipient.
+ */
+void AIBinder_DeathRecipient_setOnUnlinked(AIBinder_DeathRecipient* recipient,
+                                           AIBinder_DeathRecipient_onBinderUnlinked onUnlinked)
+        __INTRODUCED_IN(33);
+
+/**
  * Deletes a binder death recipient. It is not necessary to call AIBinder_unlinkToDeath before
  * calling this as these will all be automatically unlinked.
  *
+ * Be aware that it is not safe to immediately deallocate the cookie when this call returns. If you
+ * need to clean up the cookie, you should do so in the onUnlinked callback, which can be set using
+ * AIBinder_DeathRecipient_setOnUnlinked.
+ *
  * Available since API level 29.
  *
  * \param recipient the binder to delete (previously created with AIBinder_DeathRecipient_new).
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
index 527b151..8457581 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -1163,6 +1163,45 @@
  * \return A parcel which is not related to any IBinder objects.
  */
 AParcel* AParcel_create() __INTRODUCED_IN(31);
+
+/**
+ * Marshals the raw bytes of the Parcel to a buffer.
+ *
+ * Available since API level 33.
+ *
+ * The parcel must not contain any binders or file descriptors.
+ *
+ * The data you retrieve here must not be placed in any kind of persistent storage. (on local disk,
+ * across a network, etc). For that, you should use standard serialization or another kind of
+ * general serialization mechanism. The Parcel marshalled representation is highly optimized for
+ * local IPC, and as such does not attempt to maintain compatibility with data created in different
+ * versions of the platform.
+ *
+ * \param parcel The parcel of which to get the data.
+ * \param buffer The buffer to copy the raw bytes to.
+ * \param start The start position in the buffer to copy from.
+ * \param len The size of the data to copy, buffer size must be larger or equal to this.
+ *
+ * \return STATUS_OK on success, STATUS_INVALID_OPERATION if parcel contains binders or file
+ * descriptors. STATUS_BAD_VALUE if the buffer size is less than parcel size.
+ */
+binder_status_t AParcel_marshal(const AParcel* parcel, uint8_t* buffer, size_t start, size_t len)
+        __INTRODUCED_IN(33);
+
+/**
+ * Set the data in the parcel to the raw bytes from the buffer.
+ *
+ * Available since API level 33.
+ *
+ * \param parcel The parcel to set data.
+ * \param buffer The data buffer to set.
+ * \param len The size of the data to set.
+ *
+ * \return STATUS_OK on success.
+ */
+binder_status_t AParcel_unmarshal(AParcel* parcel, const uint8_t* buffer, size_t len)
+        __INTRODUCED_IN(33);
+
 __END_DECLS
 
 /** @} */
diff --git a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
index e315c79..b0217c4 100644
--- a/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
+++ b/libs/binder/ndk/include_platform/android/binder_ibinder_platform.h
@@ -55,4 +55,17 @@
  */
 __attribute__((weak, warn_unused_result)) const char* AIBinder_getCallingSid() __INTRODUCED_IN(31);
 
+/**
+ * Sets a minimum scheduler policy for all transactions coming into this
+ * AIBinder.
+ *
+ * This must be called before the object is sent to another process.
+ * Aborts on invalid values. Not thread safe.
+ *
+ * \param binder local server binder to set the policy for
+ * \param policy scheduler policy as defined in linux UAPI
+ * \param priority priority. [-20..19] for SCHED_NORMAL, [1..99] for RT
+ */
+void AIBinder_setMinSchedulerPolicy(AIBinder* binder, int policy, int priority) __INTRODUCED_IN(33);
+
 __END_DECLS
diff --git a/libs/binder/ndk/include_platform/android/binder_parcel_platform.h b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
index 6372449..b24094e 100644
--- a/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
+++ b/libs/binder/ndk/include_platform/android/binder_parcel_platform.h
@@ -33,7 +33,6 @@
 
 #endif
 
-#if !defined(__ANDROID_APEX__)
 /**
  * Data written to the parcel will be zero'd before being deleted or realloced.
  *
@@ -44,6 +43,5 @@
  * \param parcel The parcel to clear associated data from.
  */
 void AParcel_markSensitive(const AParcel* parcel);
-#endif
 
 __END_DECLS
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 7d4b82e..197c0a1 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -117,13 +117,13 @@
     ABinderProcess_setupPolling; # apex
     AIBinder_getCallingSid; # apex
     AIBinder_setRequestingSid; # apex
-    AParcel_markSensitive; # llndk
+    AParcel_markSensitive; # systemapi llndk
     AServiceManager_forEachDeclaredInstance; # apex llndk
-    AServiceManager_forceLazyServicesPersist; # llndk
+    AServiceManager_forceLazyServicesPersist; # apex llndk
     AServiceManager_isDeclared; # apex llndk
     AServiceManager_isUpdatableViaApex; # apex
     AServiceManager_reRegister; # llndk
-    AServiceManager_registerLazyService; # llndk
+    AServiceManager_registerLazyService; # apex llndk
     AServiceManager_setActiveServicesCallback; # llndk
     AServiceManager_tryUnregister; # llndk
     AServiceManager_waitForService; # apex llndk
@@ -141,6 +141,16 @@
     AParcel_reset;
 };
 
+LIBBINDER_NDK33 { # introduced=33
+  global:
+    AIBinder_Class_disableInterfaceTokenHeader;
+    AIBinder_DeathRecipient_setOnUnlinked;
+    AIBinder_isHandlingTransaction;
+    AIBinder_setMinSchedulerPolicy; # llndk
+    AParcel_marshal;
+    AParcel_unmarshal;
+};
+
 LIBBINDER_NDK_PLATFORM {
   global:
     AParcel_getAllowFds;
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index ec7c7d8..c320e8d 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -46,7 +46,8 @@
 template <typename T>
 using ArraySetter = void (*)(void* arrayData, size_t index, T value);
 
-binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray, int32_t length) {
+static binder_status_t WriteAndValidateArraySize(AParcel* parcel, bool isNullArray,
+                                                 int32_t length) {
     // only -1 can be used to represent a null array
     if (length < -1) return STATUS_BAD_VALUE;
 
@@ -61,12 +62,24 @@
 
     Parcel* rawParcel = parcel->get();
 
-    status_t status = rawParcel->writeInt32(static_cast<int32_t>(length));
+    status_t status = rawParcel->writeInt32(length);
     if (status != STATUS_OK) return PruneStatusT(status);
 
     return STATUS_OK;
 }
 
+static binder_status_t ReadAndValidateArraySize(const AParcel* parcel, int32_t* length) {
+    if (status_t status = parcel->get()->readInt32(length); status != STATUS_OK) {
+        return PruneStatusT(status);
+    }
+
+    if (*length < -1) return STATUS_BAD_VALUE;  // libbinder_ndk reserves these
+    if (*length <= 0) return STATUS_OK;         // null
+    if (static_cast<size_t>(*length) > parcel->get()->dataAvail()) return STATUS_NO_MEMORY;
+
+    return STATUS_OK;
+}
+
 template <typename T>
 binder_status_t WriteArray(AParcel* parcel, const T* array, int32_t length) {
     binder_status_t status = WriteAndValidateArraySize(parcel, array == nullptr, length);
@@ -111,10 +124,9 @@
     const Parcel* rawParcel = parcel->get();
 
     int32_t length;
-    status_t status = rawParcel->readInt32(&length);
-
-    if (status != STATUS_OK) return PruneStatusT(status);
-    if (length < -1) return STATUS_BAD_VALUE;
+    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
+        return status;
+    }
 
     T* array;
     if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
@@ -140,10 +152,9 @@
     const Parcel* rawParcel = parcel->get();
 
     int32_t length;
-    status_t status = rawParcel->readInt32(&length);
-
-    if (status != STATUS_OK) return PruneStatusT(status);
-    if (length < -1) return STATUS_BAD_VALUE;
+    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
+        return status;
+    }
 
     char16_t* array;
     if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
@@ -155,7 +166,7 @@
     if (__builtin_smul_overflow(sizeof(char16_t), length, &size)) return STATUS_NO_MEMORY;
 
     for (int32_t i = 0; i < length; i++) {
-        status = rawParcel->readChar(array + i);
+        status_t status = rawParcel->readChar(array + i);
 
         if (status != STATUS_OK) return PruneStatusT(status);
     }
@@ -189,10 +200,9 @@
     const Parcel* rawParcel = parcel->get();
 
     int32_t length;
-    status_t status = rawParcel->readInt32(&length);
-
-    if (status != STATUS_OK) return PruneStatusT(status);
-    if (length < -1) return STATUS_BAD_VALUE;
+    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
+        return status;
+    }
 
     if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
 
@@ -200,7 +210,7 @@
 
     for (int32_t i = 0; i < length; i++) {
         T readTarget;
-        status = (rawParcel->*read)(&readTarget);
+        status_t status = (rawParcel->*read)(&readTarget);
         if (status != STATUS_OK) return PruneStatusT(status);
 
         setter(arrayData, i, readTarget);
@@ -402,13 +412,10 @@
 binder_status_t AParcel_readStringArray(const AParcel* parcel, void* arrayData,
                                         AParcel_stringArrayAllocator allocator,
                                         AParcel_stringArrayElementAllocator elementAllocator) {
-    const Parcel* rawParcel = parcel->get();
-
     int32_t length;
-    status_t status = rawParcel->readInt32(&length);
-
-    if (status != STATUS_OK) return PruneStatusT(status);
-    if (length < -1) return STATUS_BAD_VALUE;
+    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
+        return status;
+    }
 
     if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
 
@@ -449,13 +456,10 @@
 binder_status_t AParcel_readParcelableArray(const AParcel* parcel, void* arrayData,
                                             AParcel_parcelableArrayAllocator allocator,
                                             AParcel_readParcelableElement elementReader) {
-    const Parcel* rawParcel = parcel->get();
-
     int32_t length;
-    status_t status = rawParcel->readInt32(&length);
-
-    if (status != STATUS_OK) return PruneStatusT(status);
-    if (length < -1) return STATUS_BAD_VALUE;
+    if (binder_status_t status = ReadAndValidateArraySize(parcel, &length); status != STATUS_OK) {
+        return status;
+    }
 
     if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
 
@@ -669,4 +673,32 @@
     return new AParcel(nullptr);
 }
 
+binder_status_t AParcel_marshal(const AParcel* parcel, uint8_t* buffer, size_t start, size_t len) {
+    if (parcel->get()->objectsCount()) {
+        return STATUS_INVALID_OPERATION;
+    }
+    int32_t dataSize = AParcel_getDataSize(parcel);
+    if (len > static_cast<size_t>(dataSize) || start > static_cast<size_t>(dataSize) - len) {
+        return STATUS_BAD_VALUE;
+    }
+    const uint8_t* internalBuffer = parcel->get()->data();
+    memcpy(buffer, internalBuffer + start, len);
+    return STATUS_OK;
+}
+
+binder_status_t AParcel_unmarshal(AParcel* parcel, const uint8_t* buffer, size_t len) {
+    status_t status = parcel->get()->setDataSize(len);
+    if (status != ::android::OK) {
+        return PruneStatusT(status);
+    }
+    parcel->get()->setDataPosition(0);
+
+    void* raw = parcel->get()->writeInplace(len);
+    if (raw == nullptr) {
+        return STATUS_NO_MEMORY;
+    }
+    memcpy(raw, buffer, len);
+    return STATUS_OK;
+}
+
 // @END
diff --git a/libs/binder/ndk/status.cpp b/libs/binder/ndk/status.cpp
index a8ae441..8ed91a5 100644
--- a/libs/binder/ndk/status.cpp
+++ b/libs/binder/ndk/status.cpp
@@ -20,6 +20,7 @@
 #include <android-base/logging.h>
 
 using ::android::status_t;
+using ::android::statusToString;
 using ::android::binder::Status;
 
 AStatus* AStatus_newOk() {
@@ -126,7 +127,7 @@
             return STATUS_UNKNOWN_ERROR;
 
         default:
-            LOG(WARNING) << __func__ << ": Unknown status_t (" << status
+            LOG(WARNING) << __func__ << ": Unknown status_t (" << statusToString(status)
                          << ") pruned into STATUS_UNKNOWN_ERROR";
             return STATUS_UNKNOWN_ERROR;
     }
diff --git a/libs/binder/ndk/tests/Android.bp b/libs/binder/ndk/tests/Android.bp
index ede4873..8ee396e 100644
--- a/libs/binder/ndk/tests/Android.bp
+++ b/libs/binder/ndk/tests/Android.bp
@@ -71,9 +71,12 @@
     srcs: ["libbinder_ndk_unit_test.cpp"],
     static_libs: [
         "IBinderNdkUnitTest-cpp",
-        "IBinderNdkUnitTest-ndk_platform",
+        "IBinderNdkUnitTest-ndk",
     ],
-    test_suites: ["general-tests", "vts"],
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
     require_root: true,
 }
 
@@ -85,8 +88,8 @@
     ],
     static_libs: [
         "IBinderVendorDoubleLoadTest-cpp",
-        "IBinderVendorDoubleLoadTest-ndk_platform",
-        "libbinder_aidl_test_stub-ndk_platform",
+        "IBinderVendorDoubleLoadTest-ndk",
+        "libbinder_aidl_test_stub-ndk",
     ],
     // critical that libbinder/libbinder_ndk are shared for VTS
     shared_libs: [
@@ -115,4 +118,12 @@
         "IBinderNdkUnitTest.aidl",
         "IEmpty.aidl",
     ],
+    backend: {
+        java: {
+            enabled: false,
+        },
+        ndk: {
+            apps_enabled: false,
+        },
+    },
 }
diff --git a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
index ecbd649..a626d39 100644
--- a/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
+++ b/libs/binder/ndk/tests/IBinderNdkUnitTest.aidl
@@ -21,6 +21,7 @@
 
 import IEmpty;
 
+@SensitiveData
 interface IBinderNdkUnitTest {
     int repeatInt(int a);
 
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 62db3cf..499f88e 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -39,6 +39,7 @@
 #include <condition_variable>
 #include <iostream>
 #include <mutex>
+#include <thread>
 #include "android/binder_ibinder.h"
 
 using namespace android;
@@ -223,6 +224,17 @@
     return true;
 }
 
+TEST(NdkBinder, DetectDoubleOwn) {
+    auto badService = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
+    EXPECT_DEATH(std::shared_ptr<MyBinderNdkUnitTest>(badService.get()),
+                 "Is this object double-owned?");
+}
+
+TEST(NdkBinder, DetectNoSharedRefBaseCreated) {
+    EXPECT_DEATH(std::make_shared<MyBinderNdkUnitTest>(),
+                 "SharedRefBase: no ref created during lifetime");
+}
+
 TEST(NdkBinder, GetServiceThatDoesntExist) {
     sp<IFoo> foo = IFoo::getService("asdfghkl;");
     EXPECT_EQ(nullptr, foo.get());
@@ -270,6 +282,27 @@
     EXPECT_EQ(2, out);
 }
 
+TEST(NdkBinder, GetTestServiceStressTest) {
+    // libbinder has some complicated logic to make sure only one instance of
+    // ABpBinder is associated with each binder.
+
+    constexpr size_t kNumThreads = 10;
+    constexpr size_t kNumCalls = 1000;
+    std::vector<std::thread> threads;
+
+    for (size_t i = 0; i < kNumThreads; i++) {
+        threads.push_back(std::thread([&]() {
+            for (size_t j = 0; j < kNumCalls; j++) {
+                auto binder =
+                        ndk::SpAIBinder(AServiceManager_checkService(IFoo::kSomeInstanceName));
+                EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
+            }
+        }));
+    }
+
+    for (auto& thread : threads) thread.join();
+}
+
 void defaultInstanceCounter(const char* instance, void* context) {
     if (strcmp(instance, "default") == 0) {
         ++*(size_t*)(context);
@@ -362,9 +395,16 @@
             << "Service failed to shut down.";
 }
 
+struct DeathRecipientCookie {
+    std::function<void(void)>*onDeath, *onUnlink;
+};
 void LambdaOnDeath(void* cookie) {
-    auto onDeath = static_cast<std::function<void(void)>*>(cookie);
-    (*onDeath)();
+    auto funcs = static_cast<DeathRecipientCookie*>(cookie);
+    (*funcs->onDeath)();
+};
+void LambdaOnUnlink(void* cookie) {
+    auto funcs = static_cast<DeathRecipientCookie*>(cookie);
+    (*funcs->onUnlink)();
 };
 TEST(NdkBinder, DeathRecipient) {
     using namespace std::chrono_literals;
@@ -376,26 +416,46 @@
 
     std::mutex deathMutex;
     std::condition_variable deathCv;
-    bool deathRecieved = false;
+    bool deathReceived = false;
 
     std::function<void(void)> onDeath = [&] {
         std::cerr << "Binder died (as requested)." << std::endl;
-        deathRecieved = true;
+        deathReceived = true;
         deathCv.notify_one();
     };
 
-    AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(LambdaOnDeath);
+    std::mutex unlinkMutex;
+    std::condition_variable unlinkCv;
+    bool unlinkReceived = false;
+    bool wasDeathReceivedFirst = false;
 
-    EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, static_cast<void*>(&onDeath)));
+    std::function<void(void)> onUnlink = [&] {
+        std::cerr << "Binder unlinked (as requested)." << std::endl;
+        wasDeathReceivedFirst = deathReceived;
+        unlinkReceived = true;
+        unlinkCv.notify_one();
+    };
+
+    DeathRecipientCookie cookie = {&onDeath, &onUnlink};
+
+    AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(LambdaOnDeath);
+    AIBinder_DeathRecipient_setOnUnlinked(recipient, LambdaOnUnlink);
+
+    EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, static_cast<void*>(&cookie)));
 
     // the binder driver should return this if the service dies during the transaction
     EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
 
     foo = nullptr;
 
-    std::unique_lock<std::mutex> lock(deathMutex);
-    EXPECT_TRUE(deathCv.wait_for(lock, 1s, [&] { return deathRecieved; }));
-    EXPECT_TRUE(deathRecieved);
+    std::unique_lock<std::mutex> lockDeath(deathMutex);
+    EXPECT_TRUE(deathCv.wait_for(lockDeath, 1s, [&] { return deathReceived; }));
+    EXPECT_TRUE(deathReceived);
+
+    std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
+    EXPECT_TRUE(deathCv.wait_for(lockUnlink, 1s, [&] { return unlinkReceived; }));
+    EXPECT_TRUE(unlinkReceived);
+    EXPECT_TRUE(wasDeathReceivedFirst);
 
     AIBinder_DeathRecipient_delete(recipient);
     AIBinder_decStrong(binder);
diff --git a/libs/binder/run_rpc_tests.sh b/libs/binder/run_rpc_tests.sh
new file mode 100755
index 0000000..7ba682d
--- /dev/null
+++ b/libs/binder/run_rpc_tests.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+
+set -ex
+
+if [ $# -eq 0 ]; then
+  :
+elif [ $# -eq 1 ] && [[ "$1" =~ ^host|device$ ]]; then
+  :
+else
+  echo "usage: $0 [device|host]"
+  false
+fi
+
+# Script maintained for RPC development, while it is active, to quickly run
+# tests. Generally, to match VTS/presubmit behavior, 'atest' should be used.
+
+function dtest () { adb shell /data/nativetest64/$1/$@; }
+function hbench () { $AT/out/host/linux-x86/benchmarktest/$1/$@; }
+function hfuzz () { time $ANDROID_HOST_OUT/fuzz/x86_64/$1/$@; }
+function htest () { time $ANDROID_BUILD_TOP/out/host/linux-x86/nativetest/$1/$@; }
+function pdtest () { adb wait-for-device && adb shell mkdir -p /data/nativetest64/$1 && adb push $OUT/data/nativetest64/$1/$1 /data/nativetest64/$1/$1 && dtest $@; }
+function dbench () { adb shell /data/benchmarktest64/$1/$@; }
+function pdbench () { adb wait-for-device && adb shell mkdir -p /data/benchmarktest64/$1 && adb push $OUT/data/benchmarktest64/$1/$1 /data/benchmarktest64/$1/$1 && dbench $@; }
+
+$ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode \
+  binderRpcTest \
+  binder_rpc_fuzzer \
+  binder_parcel_fuzzer \
+  binderLibTest \
+  binderRpcBenchmark
+
+if ! [ "$1" = "device" ]; then
+  htest binderRpcTest
+  hbench binderRpcBenchmark
+  hfuzz binder_rpc_fuzzer -max_total_time=30
+  hfuzz binder_parcel_fuzzer -max_total_time=30
+fi
+
+if ! [ "$1" = "host" ]; then
+  pdtest binderRpcTest
+  pdtest binderLibTest
+  pdbench binderRpcBenchmark
+fi
+
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index 49d3401..4561d6e 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -17,6 +17,29 @@
     rustlibs: [
         "liblibc",
         "libbinder_ndk_sys",
+        "libdowncast_rs",
+    ],
+    host_supported: true,
+    vendor_available: true,
+    target: {
+        darwin: {
+            enabled: false,
+        }
+    },
+    apex_available: [
+        "//apex_available:platform",
+        "com.android.compos",
+        "com.android.virt",
+    ],
+}
+
+rust_library {
+    name: "libbinder_tokio_rs",
+    crate_name: "binder_tokio",
+    srcs: ["binder_tokio/lib.rs"],
+    rustlibs: [
+        "libbinder_rs",
+        "libtokio",
     ],
     host_supported: true,
     target: {
@@ -26,6 +49,7 @@
     },
     apex_available: [
         "//apex_available:platform",
+        "com.android.compos",
         "com.android.virt",
     ],
 }
@@ -41,6 +65,7 @@
         "libbinder_ndk",
     ],
     host_supported: true,
+    vendor_available: true,
     target: {
         darwin: {
             enabled: false,
@@ -48,6 +73,7 @@
     },
     apex_available: [
         "//apex_available:platform",
+        "com.android.compos",
         "com.android.virt",
     ],
     lints: "none",
@@ -81,6 +107,7 @@
         "libbinder_ndk",
     ],
     host_supported: true,
+    vendor_available: true,
 
     // Currently necessary for host builds
     // TODO(b/31559095): bionic on host should define this
@@ -99,6 +126,22 @@
     },
     apex_available: [
         "//apex_available:platform",
+        "com.android.compos",
+        "com.android.virt",
+    ],
+}
+
+// TODO(b/184872979): remove once the Rust API is created.
+rust_bindgen {
+    name: "libbinder_rpc_unstable_bindgen",
+    wrapper_src: ":libbinder_rpc_unstable_header",
+    crate_name: "binder_rpc_unstable_bindgen",
+    source_stem: "bindings",
+    shared_libs: [
+        "libutils",
+    ],
+    apex_available: [
+        "com.android.compos",
         "com.android.virt",
     ],
 }
@@ -115,5 +158,26 @@
     rustlibs: [
         "liblibc",
         "libbinder_ndk_sys",
+        "libdowncast_rs",
     ],
 }
+
+rust_test {
+    name: "libbinder_ndk_bindgen_test",
+    srcs: [":libbinder_ndk_bindgen"],
+    crate_name: "binder_ndk_bindgen",
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    clippy_lints: "none",
+    lints: "none",
+}
+
+rust_test {
+    name: "libbinder_rpc_unstable_bindgen_test",
+    srcs: [":libbinder_rpc_unstable_bindgen"],
+    crate_name: "binder_rpc_unstable_bindgen",
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    clippy_lints: "none",
+    lints: "none",
+}
diff --git a/libs/binder/rust/binder_tokio/lib.rs b/libs/binder/rust/binder_tokio/lib.rs
new file mode 100644
index 0000000..64833b6
--- /dev/null
+++ b/libs/binder/rust/binder_tokio/lib.rs
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+//! This crate lets you use the Tokio `spawn_blocking` pool with AIDL in async
+//! Rust code.
+//!
+//! This crate works by defining a type [`Tokio`], which you can use as the
+//! generic parameter in the async version of the trait generated by the AIDL
+//! compiler.
+//! ```text
+//! use binder_tokio::Tokio;
+//!
+//! binder::get_interface::<dyn SomeAsyncInterface<Tokio>>("...").
+//! ```
+//!
+//! [`Tokio`]: crate::Tokio
+
+use binder::public_api::{BinderAsyncPool, BoxFuture, Strong};
+use binder::{FromIBinder, StatusCode};
+use std::future::Future;
+
+/// Retrieve an existing service for a particular interface, sleeping for a few
+/// seconds if it doesn't yet exist.
+pub async fn get_interface<T: FromIBinder + ?Sized + 'static>(name: &str) -> Result<Strong<T>, StatusCode> {
+    let name = name.to_string();
+    let res = tokio::task::spawn_blocking(move || {
+        binder::public_api::get_interface::<T>(&name)
+    }).await;
+
+    // The `is_panic` branch is not actually reachable in Android as we compile
+    // with `panic = abort`.
+    match res {
+        Ok(Ok(service)) => Ok(service),
+        Ok(Err(err)) => Err(err),
+        Err(e) if e.is_panic() => std::panic::resume_unwind(e.into_panic()),
+        Err(e) if e.is_cancelled() => Err(StatusCode::FAILED_TRANSACTION),
+        Err(_) => Err(StatusCode::UNKNOWN_ERROR),
+    }
+}
+
+/// Retrieve an existing service for a particular interface, or start it if it
+/// is configured as a dynamic service and isn't yet started.
+pub async fn wait_for_interface<T: FromIBinder + ?Sized + 'static>(name: &str) -> Result<Strong<T>, StatusCode> {
+    let name = name.to_string();
+    let res = tokio::task::spawn_blocking(move || {
+        binder::public_api::wait_for_interface::<T>(&name)
+    }).await;
+
+    // The `is_panic` branch is not actually reachable in Android as we compile
+    // with `panic = abort`.
+    match res {
+        Ok(Ok(service)) => Ok(service),
+        Ok(Err(err)) => Err(err),
+        Err(e) if e.is_panic() => std::panic::resume_unwind(e.into_panic()),
+        Err(e) if e.is_cancelled() => Err(StatusCode::FAILED_TRANSACTION),
+        Err(_) => Err(StatusCode::UNKNOWN_ERROR),
+    }
+}
+
+/// Use the Tokio `spawn_blocking` pool with AIDL.
+pub enum Tokio {}
+
+impl BinderAsyncPool for Tokio {
+    fn spawn<'a, F1, F2, Fut, A, B, E>(spawn_me: F1, after_spawn: F2) -> BoxFuture<'a, Result<B, E>>
+    where
+        F1: FnOnce() -> A,
+        F2: FnOnce(A) -> Fut,
+        Fut: Future<Output = Result<B, E>>,
+        F1: Send + 'static,
+        F2: Send + 'a,
+        Fut: Send + 'a,
+        A: Send + 'static,
+        B: Send + 'a,
+        E: From<crate::StatusCode>,
+    {
+        let handle = tokio::task::spawn_blocking(spawn_me);
+        Box::pin(async move {
+            // The `is_panic` branch is not actually reachable in Android as we compile
+            // with `panic = abort`.
+            match handle.await {
+                Ok(res) => after_spawn(res).await,
+                Err(e) if e.is_panic() => std::panic::resume_unwind(e.into_panic()),
+                Err(e) if e.is_cancelled() => Err(StatusCode::FAILED_TRANSACTION.into()),
+                Err(_) => Err(StatusCode::UNKNOWN_ERROR.into()),
+            }
+        })
+    }
+}
+
+
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 695a83e..d09ac83 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -17,14 +17,16 @@
 //! Trait definitions for binder objects
 
 use crate::error::{status_t, Result, StatusCode};
-use crate::parcel::Parcel;
+use crate::parcel::{Parcel, BorrowedParcel};
 use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder};
 use crate::sys;
 
 use std::borrow::Borrow;
 use std::cmp::Ordering;
+use std::convert::TryFrom;
 use std::ffi::{c_void, CStr, CString};
 use std::fmt;
+use std::fs::File;
 use std::marker::PhantomData;
 use std::ops::Deref;
 use std::os::raw::c_char;
@@ -49,11 +51,19 @@
 /// interfaces) must implement this trait.
 ///
 /// This is equivalent `IInterface` in C++.
-pub trait Interface: Send {
+pub trait Interface: Send + Sync {
     /// Convert this binder object into a generic [`SpIBinder`] reference.
     fn as_binder(&self) -> SpIBinder {
         panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
     }
+
+    /// Dump transaction handler for this Binder object.
+    ///
+    /// This handler is a no-op by default and should be implemented for each
+    /// Binder service struct that wishes to respond to dump transactions.
+    fn dump(&self, _file: &File, _args: &[&CStr]) -> Result<()> {
+        Ok(())
+    }
 }
 
 /// Interface stability promise
@@ -61,6 +71,7 @@
 /// An interface can promise to be a stable vendor interface ([`Vintf`]), or
 /// makes no stability guarantees ([`Local`]). [`Local`] is
 /// currently the default stability.
+#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
 pub enum Stability {
     /// Default stability, visible to other modules in the same compilation
     /// context (e.g. modules on system.img)
@@ -76,6 +87,28 @@
     }
 }
 
+impl From<Stability> for i32 {
+    fn from(stability: Stability) -> i32 {
+        use Stability::*;
+        match stability {
+            Local => 0,
+            Vintf => 1,
+        }
+    }
+}
+
+impl TryFrom<i32> for Stability {
+    type Error = StatusCode;
+    fn try_from(stability: i32) -> Result<Stability> {
+        use Stability::*;
+        match stability {
+            0 => Ok(Local),
+            1 => Ok(Vintf),
+            _ => Err(StatusCode::BAD_VALUE)
+        }
+    }
+}
+
 /// A local service that can be remotable via Binder.
 ///
 /// An object that implement this interface made be made into a Binder service
@@ -96,7 +129,11 @@
     /// Handle and reply to a request to invoke a transaction on this object.
     ///
     /// `reply` may be [`None`] if the sender does not expect a reply.
-    fn on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>;
+    fn on_transact(&self, code: TransactionCode, data: &BorrowedParcel<'_>, reply: &mut BorrowedParcel<'_>) -> Result<()>;
+
+    /// Handle a request to invoke the dump transaction on this
+    /// object.
+    fn on_dump(&self, file: &File, args: &[&CStr]) -> Result<()>;
 
     /// Retrieve the class of this remote object.
     ///
@@ -130,6 +167,7 @@
     fn ping_binder(&mut self) -> Result<()>;
 
     /// Indicate that the service intends to receive caller security contexts.
+    #[cfg(not(android_vndk))]
     fn set_requesting_sid(&mut self, enable: bool);
 
     /// Dump this object to the given file handle
@@ -139,20 +177,46 @@
     /// available.
     fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
 
+    /// Create a Parcel that can be used with `submit_transact`.
+    fn prepare_transact(&self) -> Result<Parcel>;
+
     /// Perform a generic operation with the object.
     ///
+    /// The provided [`Parcel`] must have been created by a call to
+    /// `prepare_transact` on the same binder.
+    ///
+    /// # Arguments
+    ///
+    /// * `code` - Transaction code for the operation.
+    /// * `data` - [`Parcel`] with input data.
+    /// * `flags` - Transaction flags, e.g. marking the transaction as
+    ///   asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY)).
+    fn submit_transact(
+        &self,
+        code: TransactionCode,
+        data: Parcel,
+        flags: TransactionFlags,
+    ) -> Result<Parcel>;
+
+    /// Perform a generic operation with the object. This is a convenience
+    /// method that internally calls `prepare_transact` followed by
+    /// `submit_transact.
+    ///
     /// # Arguments
     /// * `code` - Transaction code for the operation
-    /// * `data` - [`Parcel`] with input data
-    /// * `reply` - Optional [`Parcel`] for reply data
     /// * `flags` - Transaction flags, e.g. marking the transaction as
     ///   asynchronous ([`FLAG_ONEWAY`](FLAG_ONEWAY))
-    fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
+    /// * `input_callback` A callback for building the `Parcel`.
+    fn transact<F: FnOnce(BorrowedParcel<'_>) -> Result<()>>(
         &self,
         code: TransactionCode,
         flags: TransactionFlags,
         input_callback: F,
-    ) -> Result<Parcel>;
+    ) -> Result<Parcel> {
+        let mut parcel = self.prepare_transact()?;
+        input_callback(parcel.borrowed())?;
+        self.submit_transact(code, parcel, flags)
+    }
 }
 
 /// Interface of binder local or remote objects.
@@ -218,7 +282,7 @@
             if class.is_null() {
                 panic!("Expected non-null class pointer from AIBinder_Class_define!");
             }
-            sys::AIBinder_Class_setOnDump(class, None);
+            sys::AIBinder_Class_setOnDump(class, Some(I::on_dump));
             sys::AIBinder_Class_setHandleShellCommand(class, None);
             class
         };
@@ -412,8 +476,8 @@
 ///     fn on_transact(
 ///         &self,
 ///         code: TransactionCode,
-///         data: &Parcel,
-///         reply: &mut Parcel,
+///         data: &BorrowedParcel,
+///         reply: &mut BorrowedParcel,
 ///     ) -> Result<()> {
 ///         // ...
 ///     }
@@ -492,6 +556,16 @@
     /// returned by `on_create` for this class. This function takes ownership of
     /// the provided pointer and destroys it.
     unsafe extern "C" fn on_destroy(object: *mut c_void);
+
+    /// Called to handle the `dump` transaction.
+    ///
+    /// # Safety
+    ///
+    /// Must be called with a non-null, valid pointer to a local `AIBinder` that
+    /// contains a `T` pointer in its user data. fd should be a non-owned file
+    /// descriptor, and args must be an array of null-terminated string
+    /// poiinters with length num_args.
+    unsafe extern "C" fn on_dump(binder: *mut sys::AIBinder, fd: i32, args: *mut *const c_char, num_args: u32) -> status_t;
 }
 
 /// Interface for transforming a generic SpIBinder into a specific remote
@@ -562,6 +636,7 @@
 pub struct BinderFeatures {
     /// Indicates that the service intends to receive caller security contexts. This must be true
     /// for `ThreadState::with_calling_sid` to work.
+    #[cfg(not(android_vndk))]
     pub set_requesting_sid: bool,
     // Ensure that clients include a ..BinderFeatures::default() to preserve backwards compatibility
     // when new fields are added. #[non_exhaustive] doesn't work because it prevents struct
@@ -582,13 +657,13 @@
 /// have the following type:
 ///
 /// ```
-/// # use binder::{Interface, TransactionCode, Parcel};
+/// # use binder::{Interface, TransactionCode, BorrowedParcel};
 /// # trait Placeholder {
 /// fn on_transact(
 ///     service: &dyn Interface,
 ///     code: TransactionCode,
-///     data: &Parcel,
-///     reply: &mut Parcel,
+///     data: &BorrowedParcel,
+///     reply: &mut BorrowedParcel,
 /// ) -> binder::Result<()>;
 /// # }
 /// ```
@@ -603,7 +678,7 @@
 /// using the provided function, `on_transact`.
 ///
 /// ```
-/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel};
+/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, BorrowedParcel};
 ///
 /// pub trait IServiceManager: Interface {
 ///     // remote methods...
@@ -619,8 +694,8 @@
 /// fn on_transact(
 ///     service: &dyn IServiceManager,
 ///     code: TransactionCode,
-///     data: &Parcel,
-///     reply: &mut Parcel,
+///     data: &BorrowedParcel,
+///     reply: &mut BorrowedParcel,
 /// ) -> binder::Result<()> {
 ///     // ...
 ///     Ok(())
@@ -640,12 +715,14 @@
         $interface:path[$descriptor:expr] {
             native: $native:ident($on_transact:path),
             proxy: $proxy:ident,
+            $(async: $async_interface:ident,)?
         }
     } => {
         $crate::declare_binder_interface! {
             $interface[$descriptor] {
                 native: $native($on_transact),
                 proxy: $proxy {},
+                $(async: $async_interface,)?
                 stability: $crate::Stability::default(),
             }
         }
@@ -655,6 +732,7 @@
         $interface:path[$descriptor:expr] {
             native: $native:ident($on_transact:path),
             proxy: $proxy:ident,
+            $(async: $async_interface:ident,)?
             stability: $stability:expr,
         }
     } => {
@@ -662,6 +740,7 @@
             $interface[$descriptor] {
                 native: $native($on_transact),
                 proxy: $proxy {},
+                $(async: $async_interface,)?
                 stability: $stability,
             }
         }
@@ -673,6 +752,7 @@
             proxy: $proxy:ident {
                 $($fname:ident: $fty:ty = $finit:expr),*
             },
+            $(async: $async_interface:ident,)?
         }
     } => {
         $crate::declare_binder_interface! {
@@ -681,6 +761,7 @@
                 proxy: $proxy {
                     $($fname: $fty = $finit),*
                 },
+                $(async: $async_interface,)?
                 stability: $crate::Stability::default(),
             }
         }
@@ -692,6 +773,7 @@
             proxy: $proxy:ident {
                 $($fname:ident: $fty:ty = $finit:expr),*
             },
+            $(async: $async_interface:ident,)?
             stability: $stability:expr,
         }
     } => {
@@ -703,6 +785,7 @@
                 proxy: $proxy {
                     $($fname: $fty = $finit),*
                 },
+                $(async: $async_interface,)?
                 stability: $stability,
             }
         }
@@ -718,6 +801,8 @@
                 $($fname:ident: $fty:ty = $finit:expr),*
             },
 
+            $( async: $async_interface:ident, )?
+
             stability: $stability:expr,
         }
     } => {
@@ -754,6 +839,7 @@
             /// Create a new binder service.
             pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T, features: $crate::BinderFeatures) -> $crate::Strong<dyn $interface> {
                 let mut binder = $crate::Binder::new_with_stability($native(Box::new(inner)), $stability);
+                #[cfg(not(android_vndk))]
                 $crate::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
                 $crate::Strong::new(Box::new(binder))
             }
@@ -764,7 +850,7 @@
                 $descriptor
             }
 
-            fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
+            fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::BorrowedParcel<'_>, reply: &mut $crate::BorrowedParcel<'_>) -> $crate::Result<()> {
                 match $on_transact(&*self.0, code, data, reply) {
                     // The C++ backend converts UNEXPECTED_NULL into an exception
                     Err($crate::StatusCode::UNEXPECTED_NULL) => {
@@ -778,6 +864,10 @@
                 }
             }
 
+            fn on_dump(&self, file: &std::fs::File, args: &[&std::ffi::CStr]) -> $crate::Result<()> {
+                self.0.dump(file, args)
+            }
+
             fn get_class() -> $crate::InterfaceClass {
                 static CLASS_INIT: std::sync::Once = std::sync::Once::new();
                 static mut CLASS: Option<$crate::InterfaceClass> = None;
@@ -835,19 +925,19 @@
         where
             dyn $interface: $crate::Interface
         {
-            fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+            fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
                 let binder = $crate::Interface::as_binder(self);
                 parcel.write(&binder)
             }
         }
 
         impl $crate::parcel::SerializeOption for dyn $interface + '_ {
-            fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+            fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
                 parcel.write(&this.map($crate::Interface::as_binder))
             }
         }
 
-        impl std::fmt::Debug for dyn $interface {
+        impl std::fmt::Debug for dyn $interface + '_ {
             fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                 f.pad(stringify!($interface))
             }
@@ -861,6 +951,73 @@
                     .expect(concat!("Error cloning interface ", stringify!($interface)))
             }
         }
+
+        $(
+        // Async interface trait implementations.
+        impl<P: $crate::BinderAsyncPool> $crate::FromIBinder for dyn $async_interface<P> {
+            fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $async_interface<P>>> {
+                use $crate::AssociateClass;
+
+                let existing_class = ibinder.get_class();
+                if let Some(class) = existing_class {
+                    if class != <$native as $crate::Remotable>::get_class() &&
+                        class.get_descriptor() == <$native as $crate::Remotable>::get_descriptor()
+                    {
+                        // The binder object's descriptor string matches what we
+                        // expect. We still need to treat this local or already
+                        // associated object as remote, because we can't cast it
+                        // into a Rust service object without a matching class
+                        // pointer.
+                        return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
+                    }
+                }
+
+                if ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
+                    let service: $crate::Result<$crate::Binder<$native>> =
+                        std::convert::TryFrom::try_from(ibinder.clone());
+                    if let Ok(service) = service {
+                        // We were able to associate with our expected class and
+                        // the service is local.
+                        todo!()
+                        //return Ok($crate::Strong::new(Box::new(service)));
+                    } else {
+                        // Service is remote
+                        return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
+                    }
+                }
+
+                Err($crate::StatusCode::BAD_TYPE.into())
+            }
+        }
+
+        impl<P: $crate::BinderAsyncPool> $crate::parcel::Serialize for dyn $async_interface<P> + '_ {
+            fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
+                let binder = $crate::Interface::as_binder(self);
+                parcel.write(&binder)
+            }
+        }
+
+        impl<P: $crate::BinderAsyncPool> $crate::parcel::SerializeOption for dyn $async_interface<P> + '_ {
+            fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
+                parcel.write(&this.map($crate::Interface::as_binder))
+            }
+        }
+
+        impl<P: $crate::BinderAsyncPool> std::fmt::Debug for dyn $async_interface<P> + '_ {
+            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+                f.pad(stringify!($async_interface))
+            }
+        }
+
+        /// Convert a &dyn $async_interface to Strong<dyn $async_interface>
+        impl<P: $crate::BinderAsyncPool> std::borrow::ToOwned for dyn $async_interface<P> {
+            type Owned = $crate::Strong<dyn $async_interface<P>>;
+            fn to_owned(&self) -> Self::Owned {
+                self.as_binder().into_interface()
+                    .expect(concat!("Error cloning interface ", stringify!($async_interface)))
+            }
+        }
+        )?
     };
 }
 
@@ -870,7 +1027,7 @@
 #[macro_export]
 macro_rules! declare_binder_enum {
     {
-        $enum:ident : $backing:ty {
+        $enum:ident : [$backing:ty; $size:expr] {
             $( $name:ident = $value:expr, )*
         }
     } => {
@@ -878,29 +1035,34 @@
         pub struct $enum(pub $backing);
         impl $enum {
             $( pub const $name: Self = Self($value); )*
+
+            #[inline(always)]
+            pub const fn enum_values() -> [Self; $size] {
+                [$(Self::$name),*]
+            }
         }
 
         impl $crate::parcel::Serialize for $enum {
-            fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+            fn serialize(&self, parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
                 parcel.write(&self.0)
             }
         }
 
         impl $crate::parcel::SerializeArray for $enum {
-            fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+            fn serialize_array(slice: &[Self], parcel: &mut $crate::parcel::BorrowedParcel<'_>) -> $crate::Result<()> {
                 let v: Vec<$backing> = slice.iter().map(|x| x.0).collect();
                 <$backing as binder::parcel::SerializeArray>::serialize_array(&v[..], parcel)
             }
         }
 
         impl $crate::parcel::Deserialize for $enum {
-            fn deserialize(parcel: &$crate::parcel::Parcel) -> $crate::Result<Self> {
+            fn deserialize(parcel: &$crate::parcel::BorrowedParcel<'_>) -> $crate::Result<Self> {
                 parcel.read().map(Self)
             }
         }
 
         impl $crate::parcel::DeserializeArray for $enum {
-            fn deserialize_array(parcel: &$crate::parcel::Parcel) -> $crate::Result<Option<Vec<Self>>> {
+            fn deserialize_array(parcel: &$crate::parcel::BorrowedParcel<'_>) -> $crate::Result<Option<Vec<Self>>> {
                 let v: Option<Vec<$backing>> =
                     <$backing as binder::parcel::DeserializeArray>::deserialize_array(parcel)?;
                 Ok(v.map(|v| v.into_iter().map(Self).collect()))
diff --git a/libs/binder/rust/src/binder_async.rs b/libs/binder/rust/src/binder_async.rs
new file mode 100644
index 0000000..214c0b5
--- /dev/null
+++ b/libs/binder/rust/src/binder_async.rs
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use std::future::Future;
+use std::pin::Pin;
+
+/// A type alias for a pinned, boxed future that lets you write shorter code without littering it
+/// with Pin and Send bounds.
+pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
+
+/// A thread pool for running binder transactions.
+pub trait BinderAsyncPool {
+    /// This function should conceptually behave like this:
+    ///
+    /// ```text
+    /// let result = spawn_thread(|| spawn_me()).await;
+    /// return after_spawn(result).await;
+    /// ```
+    ///
+    /// If the spawning fails for some reason, the method may also skip the `after_spawn` closure
+    /// and immediately return an error.
+    ///
+    /// The only difference between different implementations should be which
+    /// `spawn_thread` method is used. For Tokio, it would be `tokio::task::spawn_blocking`.
+    ///
+    /// This method has the design it has because the only way to define a trait that
+    /// allows the return type of the spawn to be chosen by the caller is to return a
+    /// boxed `Future` trait object, and including `after_spawn` in the trait function
+    /// allows the caller to avoid double-boxing if they want to do anything to the value
+    /// returned from the spawned thread.
+    fn spawn<'a, F1, F2, Fut, A, B, E>(spawn_me: F1, after_spawn: F2) -> BoxFuture<'a, Result<B, E>>
+    where
+        F1: FnOnce() -> A,
+        F2: FnOnce(A) -> Fut,
+        Fut: Future<Output = Result<B, E>>,
+        F1: Send + 'static,
+        F2: Send + 'a,
+        Fut: Send + 'a,
+        A: Send + 'static,
+        B: Send + 'a,
+        E: From<crate::StatusCode>;
+}
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index 2694cba..cce55c0 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -50,8 +50,8 @@
 //! fn on_transact(
 //!     service: &dyn ITest,
 //!     code: TransactionCode,
-//!     _data: &Parcel,
-//!     reply: &mut Parcel,
+//!     _data: &BorrowedParcel,
+//!     reply: &mut BorrowedParcel,
 //! ) -> binder::Result<()> {
 //!     match code {
 //!         SpIBinder::FIRST_CALL_TRANSACTION => {
@@ -98,6 +98,7 @@
 
 #[macro_use]
 mod binder;
+mod binder_async;
 mod error;
 mod native;
 mod state;
@@ -111,21 +112,32 @@
     Stability, Strong, TransactionCode, TransactionFlags, Weak, FIRST_CALL_TRANSACTION,
     FLAG_CLEAR_BUF, FLAG_ONEWAY, FLAG_PRIVATE_LOCAL, LAST_CALL_TRANSACTION,
 };
+pub use crate::binder_async::{BoxFuture, BinderAsyncPool};
 pub use error::{status_t, ExceptionCode, Result, Status, StatusCode};
-pub use native::add_service;
-pub use native::Binder;
-pub use parcel::Parcel;
-pub use proxy::{get_interface, get_service};
+pub use native::{add_service, force_lazy_services_persist, register_lazy_service, Binder};
+pub use parcel::{BorrowedParcel, Parcel};
+pub use proxy::{get_interface, get_service, wait_for_interface, wait_for_service};
 pub use proxy::{AssociateClass, DeathRecipient, Proxy, SpIBinder, WpIBinder};
 pub use state::{ProcessState, ThreadState};
 
+/// Unstable, in-development API that only allowlisted clients are allowed to use.
+pub mod unstable_api {
+    pub use crate::binder::AsNative;
+    pub use crate::proxy::unstable_api::new_spibinder;
+    pub use crate::sys::AIBinder;
+}
+
 /// The public API usable outside AIDL-generated interface crates.
 pub mod public_api {
-    pub use super::parcel::ParcelFileDescriptor;
-    pub use super::{add_service, get_interface};
+    pub use super::parcel::{ParcelFileDescriptor, ParcelableHolder};
     pub use super::{
-        BinderFeatures, DeathRecipient, ExceptionCode, IBinder, Interface, ProcessState, SpIBinder,
-        Status, StatusCode, Strong, ThreadState, Weak, WpIBinder,
+        add_service, force_lazy_services_persist, get_interface, register_lazy_service,
+        wait_for_interface,
+    };
+    pub use super::{
+        BinderAsyncPool, BinderFeatures, BoxFuture, DeathRecipient, ExceptionCode, IBinder,
+        Interface, ProcessState, SpIBinder, Status, StatusCode, Strong, ThreadState, Weak,
+        WpIBinder,
     };
 
     /// Binder result containing a [`Status`] on error.
diff --git a/libs/binder/rust/src/native.rs b/libs/binder/rust/src/native.rs
index 3920129..e183ea3 100644
--- a/libs/binder/rust/src/native.rs
+++ b/libs/binder/rust/src/native.rs
@@ -14,16 +14,22 @@
  * limitations under the License.
  */
 
-use crate::binder::{AsNative, Interface, InterfaceClassMethods, Remotable, Stability, TransactionCode};
+use crate::binder::{
+    AsNative, Interface, InterfaceClassMethods, Remotable, Stability, TransactionCode,
+};
 use crate::error::{status_result, status_t, Result, StatusCode};
-use crate::parcel::{Parcel, Serialize};
+use crate::parcel::{BorrowedParcel, Serialize};
 use crate::proxy::SpIBinder;
 use crate::sys;
 
 use std::convert::TryFrom;
-use std::ffi::{c_void, CString};
+use std::ffi::{c_void, CStr, CString};
+use std::fs::File;
 use std::mem::ManuallyDrop;
 use std::ops::Deref;
+use std::os::raw::c_char;
+use std::os::unix::io::FromRawFd;
+use std::slice;
 
 /// Rust wrapper around Binder remotable objects.
 ///
@@ -47,6 +53,25 @@
 /// to how `Box<T>` is `Send` if `T` is `Send`.
 unsafe impl<T: Remotable> Send for Binder<T> {}
 
+/// # Safety
+///
+/// A `Binder<T>` is a pair of unique owning pointers to two values:
+///   * a C++ ABBinder which is thread-safe, i.e. `Send + Sync`
+///   * a Rust object which implements `Remotable`; this trait requires `Send + Sync`
+///
+/// `ABBinder` contains an immutable `mUserData` pointer, which is actually a
+/// pointer to a boxed `T: Remotable`, which is `Sync`. `ABBinder` also contains
+/// a mutable pointer to its class, but mutation of this field is controlled by
+/// a mutex and it is only allowed to be set once, therefore we can concurrently
+/// access this field safely. `ABBinder` inherits from `BBinder`, which is also
+/// thread-safe. Thus `ABBinder` is thread-safe.
+///
+/// Both pointers are unique (never escape the `Binder<T>` object and are not copied)
+/// so we can essentially treat `Binder<T>` as a box-like containing the two objects;
+/// the box-like object inherits `Sync` from the two inner values, similarly
+/// to how `Box<T>` is `Sync` if `T` is `Sync`.
+unsafe impl<T: Remotable> Sync for Binder<T> {}
+
 impl<T: Remotable> Binder<T> {
     /// Create a new Binder remotable object with default stability
     ///
@@ -136,8 +161,8 @@
     ///        # fn on_transact(
     ///        #     service: &dyn IBar,
     ///        #     code: TransactionCode,
-    ///        #     data: &Parcel,
-    ///        #     reply: &mut Parcel,
+    ///        #     data: &BorrowedParcel,
+    ///        #     reply: &mut BorrowedParcel,
     ///        # ) -> binder::Result<()> {
     ///        #     Ok(())
     ///        # }
@@ -187,7 +212,7 @@
 
     /// Mark this binder object with local stability, which is vendor if we are
     /// building for the VNDK and system otherwise.
-    #[cfg(vendor_ndk)]
+    #[cfg(any(vendor_ndk, android_vndk))]
     fn mark_local_stability(&mut self) {
         unsafe {
             // Safety: Self always contains a valid `AIBinder` pointer, so
@@ -198,7 +223,7 @@
 
     /// Mark this binder object with local stability, which is vendor if we are
     /// building for the VNDK and system otherwise.
-    #[cfg(not(vendor_ndk))]
+    #[cfg(not(any(vendor_ndk, android_vndk)))]
     fn mark_local_stability(&mut self) {
         unsafe {
             // Safety: Self always contains a valid `AIBinder` pointer, so
@@ -252,8 +277,8 @@
         reply: *mut sys::AParcel,
     ) -> status_t {
         let res = {
-            let mut reply = Parcel::borrowed(reply).unwrap();
-            let data = Parcel::borrowed(data as *mut sys::AParcel).unwrap();
+            let mut reply = BorrowedParcel::from_raw(reply).unwrap();
+            let data = BorrowedParcel::from_raw(data as *mut sys::AParcel).unwrap();
             let object = sys::AIBinder_getUserData(binder);
             let binder: &T = &*(object as *const T);
             binder.on_transact(code, &data, &mut reply)
@@ -289,6 +314,42 @@
         // object created by Box.
         args
     }
+
+    /// Called to handle the `dump` transaction.
+    ///
+    /// # Safety
+    ///
+    /// Must be called with a non-null, valid pointer to a local `AIBinder` that
+    /// contains a `T` pointer in its user data. fd should be a non-owned file
+    /// descriptor, and args must be an array of null-terminated string
+    /// poiinters with length num_args.
+    unsafe extern "C" fn on_dump(
+        binder: *mut sys::AIBinder,
+        fd: i32,
+        args: *mut *const c_char,
+        num_args: u32,
+    ) -> status_t {
+        if fd < 0 {
+            return StatusCode::UNEXPECTED_NULL as status_t;
+        }
+        // We don't own this file, so we need to be careful not to drop it.
+        let file = ManuallyDrop::new(File::from_raw_fd(fd));
+
+        if args.is_null() {
+            return StatusCode::UNEXPECTED_NULL as status_t;
+        }
+        let args = slice::from_raw_parts(args, num_args as usize);
+        let args: Vec<_> = args.iter().map(|s| CStr::from_ptr(*s)).collect();
+
+        let object = sys::AIBinder_getUserData(binder);
+        let binder: &T = &*(object as *const T);
+        let res = binder.on_dump(&file, &args);
+
+        match res {
+            Ok(()) => 0,
+            Err(e) => e as status_t,
+        }
+    }
 }
 
 impl<T: Remotable> Drop for Binder<T> {
@@ -323,7 +384,7 @@
 }
 
 impl<B: Remotable> Serialize for Binder<B> {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         parcel.write_binder(Some(&self.as_binder()))
     }
 }
@@ -380,6 +441,8 @@
 ///
 /// Registers the given binder object with the given identifier. If successful,
 /// this service can then be retrieved using that identifier.
+///
+/// This function will panic if the identifier contains a 0 byte (NUL).
 pub fn add_service(identifier: &str, mut binder: SpIBinder) -> Result<()> {
     let instance = CString::new(identifier).unwrap();
     let status = unsafe {
@@ -393,6 +456,43 @@
     status_result(status)
 }
 
+/// Register a dynamic service via the LazyServiceRegistrar.
+///
+/// Registers the given binder object with the given identifier. If successful,
+/// this service can then be retrieved using that identifier. The service process
+/// will be shut down once all registered services are no longer in use.
+///
+/// If any service in the process is registered as lazy, all should be, otherwise
+/// the process may be shut down while a service is in use.
+///
+/// This function will panic if the identifier contains a 0 byte (NUL).
+pub fn register_lazy_service(identifier: &str, mut binder: SpIBinder) -> Result<()> {
+    let instance = CString::new(identifier).unwrap();
+    let status = unsafe {
+        // Safety: `AServiceManager_registerLazyService` expects valid `AIBinder` and C
+        // string pointers. Caller retains ownership of both
+        // pointers. `AServiceManager_registerLazyService` creates a new strong reference
+        // and copies the string, so both pointers need only be valid until the
+        // call returns.
+
+        sys::AServiceManager_registerLazyService(binder.as_native_mut(), instance.as_ptr())
+    };
+    status_result(status)
+}
+
+/// Prevent a process which registers lazy services from being shut down even when none
+/// of the services is in use.
+///
+/// If persist is true then shut down will be blocked until this function is called again with
+/// persist false. If this is to be the initial state, call this function before calling
+/// register_lazy_service.
+pub fn force_lazy_services_persist(persist: bool) {
+    unsafe {
+        // Safety: No borrowing or transfer of ownership occurs here.
+        sys::AServiceManager_forceLazyServicesPersist(persist)
+    }
+}
+
 /// Tests often create a base BBinder instance; so allowing the unit
 /// type to be remotable translates nicely to Binder::new(()).
 impl Remotable for () {
@@ -403,12 +503,16 @@
     fn on_transact(
         &self,
         _code: TransactionCode,
-        _data: &Parcel,
-        _reply: &mut Parcel,
+        _data: &BorrowedParcel<'_>,
+        _reply: &mut BorrowedParcel<'_>,
     ) -> Result<()> {
         Ok(())
     }
 
+    fn on_dump(&self, _file: &File, _args: &[&CStr]) -> Result<()> {
+        Ok(())
+    }
+
     binder_fn_get_class!(Binder::<Self>);
 }
 
diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs
index 6c34824..206b90c 100644
--- a/libs/binder/rust/src/parcel.rs
+++ b/libs/binder/rust/src/parcel.rs
@@ -21,18 +21,22 @@
 use crate::proxy::SpIBinder;
 use crate::sys;
 
-use std::cell::RefCell;
 use std::convert::TryInto;
+use std::marker::PhantomData;
 use std::mem::ManuallyDrop;
-use std::ptr;
+use std::ptr::{self, NonNull};
+use std::fmt;
 
 mod file_descriptor;
 mod parcelable;
+mod parcelable_holder;
 
 pub use self::file_descriptor::ParcelFileDescriptor;
 pub use self::parcelable::{
     Deserialize, DeserializeArray, DeserializeOption, Serialize, SerializeArray, SerializeOption,
+    Parcelable, NON_NULL_PARCELABLE_FLAG, NULL_PARCELABLE_FLAG,
 };
+pub use self::parcelable_holder::{ParcelableHolder, ParcelableMetadata};
 
 /// Container for a message (data and object references) that can be sent
 /// through Binder.
@@ -41,40 +45,42 @@
 /// other side of the IPC, and references to live Binder objects that will
 /// result in the other side receiving a proxy Binder connected with the
 /// original Binder in the Parcel.
-pub enum Parcel {
-    /// Owned parcel pointer
-    Owned(*mut sys::AParcel),
-    /// Borrowed parcel pointer (will not be destroyed on drop)
-    Borrowed(*mut sys::AParcel),
+///
+/// This type represents a parcel that is owned by Rust code.
+#[repr(transparent)]
+pub struct Parcel {
+    ptr: NonNull<sys::AParcel>,
 }
 
 /// # Safety
 ///
-/// The `Parcel` constructors guarantee that a `Parcel` object will always
-/// contain a valid pointer to an `AParcel`.
-unsafe impl AsNative<sys::AParcel> for Parcel {
-    fn as_native(&self) -> *const sys::AParcel {
-        match *self {
-            Self::Owned(x) | Self::Borrowed(x) => x,
-        }
-    }
+/// This type guarantees that it owns the AParcel and that all access to
+/// the AParcel happens through the Parcel, so it is ok to send across
+/// threads.
+unsafe impl Send for Parcel {}
 
-    fn as_native_mut(&mut self) -> *mut sys::AParcel {
-        match *self {
-            Self::Owned(x) | Self::Borrowed(x) => x,
-        }
-    }
+/// Container for a message (data and object references) that can be sent
+/// through Binder.
+///
+/// This object is a borrowed variant of [`Parcel`]. It is a separate type from
+/// `&mut Parcel` because it is not valid to `mem::swap` two parcels.
+#[repr(transparent)]
+pub struct BorrowedParcel<'a> {
+    ptr: NonNull<sys::AParcel>,
+    _lifetime: PhantomData<&'a mut Parcel>,
 }
 
 impl Parcel {
-    /// Create a borrowed reference to a parcel object from a raw pointer.
-    ///
-    /// # Safety
-    ///
-    /// This constructor is safe if the raw pointer parameter is either null
-    /// (resulting in `None`), or a valid pointer to an `AParcel` object.
-    pub(crate) unsafe fn borrowed(ptr: *mut sys::AParcel) -> Option<Parcel> {
-        ptr.as_mut().map(|ptr| Self::Borrowed(ptr))
+    /// Create a new empty `Parcel`.
+    pub fn new() -> Parcel {
+        let ptr = unsafe {
+            // Safety: If `AParcel_create` succeeds, it always returns
+            // a valid pointer. If it fails, the process will crash.
+            sys::AParcel_create()
+        };
+        Self {
+            ptr: NonNull::new(ptr).expect("AParcel_create returned null pointer")
+        }
     }
 
     /// Create an owned reference to a parcel object from a raw pointer.
@@ -85,21 +91,129 @@
     /// (resulting in `None`), or a valid pointer to an `AParcel` object. The
     /// parcel object must be owned by the caller prior to this call, as this
     /// constructor takes ownership of the parcel and will destroy it on drop.
-    pub(crate) unsafe fn owned(ptr: *mut sys::AParcel) -> Option<Parcel> {
-        ptr.as_mut().map(|ptr| Self::Owned(ptr))
+    ///
+    /// Additionally, the caller must guarantee that it is valid to take
+    /// ownership of the AParcel object. All future access to the AParcel
+    /// must happen through this `Parcel`.
+    ///
+    /// Because `Parcel` implements `Send`, the pointer must never point to any
+    /// thread-local data, e.g., a variable on the stack, either directly or
+    /// indirectly.
+    pub unsafe fn from_raw(ptr: *mut sys::AParcel) -> Option<Parcel> {
+        NonNull::new(ptr).map(|ptr| Self { ptr })
     }
 
-    /// Consume the parcel, transferring ownership to the caller if the parcel
-    /// was owned.
-    pub(crate) fn into_raw(mut self) -> *mut sys::AParcel {
-        let ptr = self.as_native_mut();
+    /// Consume the parcel, transferring ownership to the caller.
+    pub(crate) fn into_raw(self) -> *mut sys::AParcel {
+        let ptr = self.ptr.as_ptr();
         let _ = ManuallyDrop::new(self);
         ptr
     }
+
+    /// Get a borrowed view into the contents of this `Parcel`.
+    pub fn borrowed(&mut self) -> BorrowedParcel<'_> {
+        // Safety: The raw pointer is a valid pointer to an AParcel, and the
+        // lifetime of the returned `BorrowedParcel` is tied to `self`, so the
+        // borrow checker will ensure that the `AParcel` can only be accessed
+        // via the `BorrowParcel` until it goes out of scope.
+        BorrowedParcel {
+            ptr: self.ptr,
+            _lifetime: PhantomData,
+        }
+    }
+
+    /// Get an immutable borrowed view into the contents of this `Parcel`.
+    pub fn borrowed_ref(&self) -> &BorrowedParcel<'_> {
+        // Safety: Parcel and BorrowedParcel are both represented in the same
+        // way as a NonNull<sys::AParcel> due to their use of repr(transparent),
+        // so casting references as done here is valid.
+        unsafe {
+            &*(self as *const Parcel as *const BorrowedParcel<'_>)
+        }
+    }
+}
+
+impl Default for Parcel {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl Clone for Parcel {
+    fn clone(&self) -> Self {
+        let mut new_parcel = Self::new();
+        new_parcel
+            .borrowed()
+            .append_all_from(self.borrowed_ref())
+            .expect("Failed to append from Parcel");
+        new_parcel
+    }
+}
+
+impl<'a> BorrowedParcel<'a> {
+    /// Create a borrowed reference to a parcel object from a raw pointer.
+    ///
+    /// # Safety
+    ///
+    /// This constructor is safe if the raw pointer parameter is either null
+    /// (resulting in `None`), or a valid pointer to an `AParcel` object.
+    ///
+    /// Since the raw pointer is not restricted by any lifetime, the lifetime on
+    /// the returned `BorrowedParcel` object can be chosen arbitrarily by the
+    /// caller. The caller must ensure it is valid to mutably borrow the AParcel
+    /// for the duration of the lifetime that the caller chooses. Note that
+    /// since this is a mutable borrow, it must have exclusive access to the
+    /// AParcel for the duration of the borrow.
+    pub unsafe fn from_raw(ptr: *mut sys::AParcel) -> Option<BorrowedParcel<'a>> {
+        Some(Self {
+            ptr: NonNull::new(ptr)?,
+            _lifetime: PhantomData,
+        })
+    }
+
+    /// Get a sub-reference to this reference to the parcel.
+    pub fn reborrow(&mut self) -> BorrowedParcel<'_> {
+        // Safety: The raw pointer is a valid pointer to an AParcel, and the
+        // lifetime of the returned `BorrowedParcel` is tied to `self`, so the
+        // borrow checker will ensure that the `AParcel` can only be accessed
+        // via the `BorrowParcel` until it goes out of scope.
+        BorrowedParcel {
+            ptr: self.ptr,
+            _lifetime: PhantomData,
+        }
+    }
+}
+
+/// # Safety
+///
+/// The `Parcel` constructors guarantee that a `Parcel` object will always
+/// contain a valid pointer to an `AParcel`.
+unsafe impl AsNative<sys::AParcel> for Parcel {
+    fn as_native(&self) -> *const sys::AParcel {
+        self.ptr.as_ptr()
+    }
+
+    fn as_native_mut(&mut self) -> *mut sys::AParcel {
+        self.ptr.as_ptr()
+    }
+}
+
+/// # Safety
+///
+/// The `BorrowedParcel` constructors guarantee that a `BorrowedParcel` object
+/// will always contain a valid pointer to an `AParcel`.
+unsafe impl<'a> AsNative<sys::AParcel> for BorrowedParcel<'a> {
+    fn as_native(&self) -> *const sys::AParcel {
+        self.ptr.as_ptr()
+    }
+
+    fn as_native_mut(&mut self) -> *mut sys::AParcel {
+        self.ptr.as_ptr()
+    }
 }
 
 // Data serialization methods
-impl Parcel {
+impl<'a> BorrowedParcel<'a> {
     /// Data written to parcelable is zero'd before being deleted or reallocated.
     pub fn mark_sensitive(&mut self) {
         unsafe {
@@ -108,12 +222,12 @@
         }
     }
 
-    /// Write a type that implements [`Serialize`] to the `Parcel`.
+    /// Write a type that implements [`Serialize`] to the parcel.
     pub fn write<S: Serialize + ?Sized>(&mut self, parcelable: &S) -> Result<()> {
         parcelable.serialize(self)
     }
 
-    /// Writes the length of a slice to the `Parcel`.
+    /// Writes the length of a slice to the parcel.
     ///
     /// This is used in AIDL-generated client side code to indicate the
     /// allocated space for an output array parameter.
@@ -126,7 +240,7 @@
         }
     }
 
-    /// Perform a series of writes to the `Parcel`, prepended with the length
+    /// Perform a series of writes to the parcel, prepended with the length
     /// (in bytes) of the written data.
     ///
     /// The length `0i32` will be written to the parcel first, followed by the
@@ -140,7 +254,7 @@
     ///
     /// ```
     /// # use binder::{Binder, Interface, Parcel};
-    /// # let mut parcel = Parcel::Owned(std::ptr::null_mut());
+    /// # let mut parcel = Parcel::new();
     /// parcel.sized_write(|subparcel| {
     ///     subparcel.write(&1u32)?;
     ///     subparcel.write(&2u32)?;
@@ -154,14 +268,14 @@
     /// [16i32, 1u32, 2u32, 3u32]
     /// ```
     pub fn sized_write<F>(&mut self, f: F) -> Result<()>
-    where for<'a>
-        F: Fn(&'a WritableSubParcel<'a>) -> Result<()>
+    where
+        for<'b> F: FnOnce(&'b mut WritableSubParcel<'b>) -> Result<()>
     {
         let start = self.get_data_position();
         self.write(&0i32)?;
         {
-            let subparcel = WritableSubParcel(RefCell::new(self));
-            f(&subparcel)?;
+            let mut subparcel = WritableSubParcel(self.reborrow());
+            f(&mut subparcel)?;
         }
         let end = self.get_data_position();
         unsafe {
@@ -178,17 +292,23 @@
     /// Returns the current position in the parcel data.
     pub fn get_data_position(&self) -> i32 {
         unsafe {
-            // Safety: `Parcel` always contains a valid pointer to an `AParcel`,
-            // and this call is otherwise safe.
+            // Safety: `BorrowedParcel` always contains a valid pointer to an
+            // `AParcel`, and this call is otherwise safe.
             sys::AParcel_getDataPosition(self.as_native())
         }
     }
 
+    /// Returns the total size of the parcel.
+    pub fn get_data_size(&self) -> i32 {
+        unsafe {
+            // Safety: `BorrowedParcel` always contains a valid pointer to an
+            // `AParcel`, and this call is otherwise safe.
+            sys::AParcel_getDataSize(self.as_native())
+        }
+    }
+
     /// Move the current read/write position in the parcel.
     ///
-    /// The new position must be a position previously returned by
-    /// `self.get_data_position()`.
-    ///
     /// # Safety
     ///
     /// This method is safe if `pos` is less than the current size of the parcel
@@ -199,28 +319,213 @@
     pub unsafe fn set_data_position(&self, pos: i32) -> Result<()> {
         status_result(sys::AParcel_setDataPosition(self.as_native(), pos))
     }
+
+    /// Append a subset of another parcel.
+    ///
+    /// This appends `size` bytes of data from `other` starting at offset
+    /// `start` to the current parcel, or returns an error if not possible.
+    pub fn append_from(&mut self, other: &impl AsNative<sys::AParcel>, start: i32, size: i32) -> Result<()> {
+        let status = unsafe {
+            // Safety: `Parcel::appendFrom` from C++ checks that `start`
+            // and `size` are in bounds, and returns an error otherwise.
+            // Both `self` and `other` always contain valid pointers.
+            sys::AParcel_appendFrom(
+                other.as_native(),
+                self.as_native_mut(),
+                start,
+                size,
+            )
+        };
+        status_result(status)
+    }
+
+    /// Append the contents of another parcel.
+    pub fn append_all_from(&mut self, other: &impl AsNative<sys::AParcel>) -> Result<()> {
+        // Safety: `BorrowedParcel` always contains a valid pointer to an
+        // `AParcel`, and this call is otherwise safe.
+        let size = unsafe { sys::AParcel_getDataSize(other.as_native()) };
+        self.append_from(other, 0, size)
+    }
 }
 
-/// A segment of a writable parcel, used for [`Parcel::sized_write`].
-pub struct WritableSubParcel<'a>(RefCell<&'a mut Parcel>);
+/// A segment of a writable parcel, used for [`BorrowedParcel::sized_write`].
+pub struct WritableSubParcel<'a>(BorrowedParcel<'a>);
 
 impl<'a> WritableSubParcel<'a> {
     /// Write a type that implements [`Serialize`] to the sub-parcel.
-    pub fn write<S: Serialize + ?Sized>(&self, parcelable: &S) -> Result<()> {
-        parcelable.serialize(&mut *self.0.borrow_mut())
+    pub fn write<S: Serialize + ?Sized>(&mut self, parcelable: &S) -> Result<()> {
+        parcelable.serialize(&mut self.0)
+    }
+}
+
+impl Parcel {
+    /// Data written to parcelable is zero'd before being deleted or reallocated.
+    pub fn mark_sensitive(&mut self) {
+        self.borrowed().mark_sensitive()
+    }
+
+    /// Write a type that implements [`Serialize`] to the parcel.
+    pub fn write<S: Serialize + ?Sized>(&mut self, parcelable: &S) -> Result<()> {
+        self.borrowed().write(parcelable)
+    }
+
+    /// Writes the length of a slice to the parcel.
+    ///
+    /// This is used in AIDL-generated client side code to indicate the
+    /// allocated space for an output array parameter.
+    pub fn write_slice_size<T>(&mut self, slice: Option<&[T]>) -> Result<()> {
+        self.borrowed().write_slice_size(slice)
+    }
+
+    /// Perform a series of writes to the parcel, prepended with the length
+    /// (in bytes) of the written data.
+    ///
+    /// The length `0i32` will be written to the parcel first, followed by the
+    /// writes performed by the callback. The initial length will then be
+    /// updated to the length of all data written by the callback, plus the
+    /// size of the length elemement itself (4 bytes).
+    ///
+    /// # Examples
+    ///
+    /// After the following call:
+    ///
+    /// ```
+    /// # use binder::{Binder, Interface, Parcel};
+    /// # let mut parcel = Parcel::new();
+    /// parcel.sized_write(|subparcel| {
+    ///     subparcel.write(&1u32)?;
+    ///     subparcel.write(&2u32)?;
+    ///     subparcel.write(&3u32)
+    /// });
+    /// ```
+    ///
+    /// `parcel` will contain the following:
+    ///
+    /// ```ignore
+    /// [16i32, 1u32, 2u32, 3u32]
+    /// ```
+    pub fn sized_write<F>(&mut self, f: F) -> Result<()>
+    where
+        for<'b> F: FnOnce(&'b mut WritableSubParcel<'b>) -> Result<()>
+    {
+        self.borrowed().sized_write(f)
+    }
+
+    /// Returns the current position in the parcel data.
+    pub fn get_data_position(&self) -> i32 {
+        self.borrowed_ref().get_data_position()
+    }
+
+    /// Returns the total size of the parcel.
+    pub fn get_data_size(&self) -> i32 {
+        self.borrowed_ref().get_data_size()
+    }
+
+    /// Move the current read/write position in the parcel.
+    ///
+    /// # Safety
+    ///
+    /// This method is safe if `pos` is less than the current size of the parcel
+    /// data buffer. Otherwise, we are relying on correct bounds checking in the
+    /// Parcel C++ code on every subsequent read or write to this parcel. If all
+    /// accesses are bounds checked, this call is still safe, but we can't rely
+    /// on that.
+    pub unsafe fn set_data_position(&self, pos: i32) -> Result<()> {
+        self.borrowed_ref().set_data_position(pos)
+    }
+
+    /// Append a subset of another parcel.
+    ///
+    /// This appends `size` bytes of data from `other` starting at offset
+    /// `start` to the current parcel, or returns an error if not possible.
+    pub fn append_from(&mut self, other: &impl AsNative<sys::AParcel>, start: i32, size: i32) -> Result<()> {
+        self.borrowed().append_from(other, start, size)
+    }
+
+    /// Append the contents of another parcel.
+    pub fn append_all_from(&mut self, other: &impl AsNative<sys::AParcel>) -> Result<()> {
+        self.borrowed().append_all_from(other)
     }
 }
 
 // Data deserialization methods
-impl Parcel {
-    /// Attempt to read a type that implements [`Deserialize`] from this
-    /// `Parcel`.
+impl<'a> BorrowedParcel<'a> {
+    /// Attempt to read a type that implements [`Deserialize`] from this parcel.
     pub fn read<D: Deserialize>(&self) -> Result<D> {
         D::deserialize(self)
     }
 
-    /// Read a vector size from the `Parcel` and resize the given output vector
-    /// to be correctly sized for that amount of data.
+    /// Attempt to read a type that implements [`Deserialize`] from this parcel
+    /// onto an existing value. This operation will overwrite the old value
+    /// partially or completely, depending on how much data is available.
+    pub fn read_onto<D: Deserialize>(&self, x: &mut D) -> Result<()> {
+        x.deserialize_from(self)
+    }
+
+    /// Safely read a sized parcelable.
+    ///
+    /// Read the size of a parcelable, compute the end position
+    /// of that parcelable, then build a sized readable sub-parcel
+    /// and call a closure with the sub-parcel as its parameter.
+    /// The closure can keep reading data from the sub-parcel
+    /// until it runs out of input data. The closure is responsible
+    /// for calling [`ReadableSubParcel::has_more_data`] to check for
+    /// more data before every read, at least until Rust generators
+    /// are stabilized.
+    /// After the closure returns, skip to the end of the current
+    /// parcelable regardless of how much the closure has read.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// let mut parcelable = Default::default();
+    /// parcel.sized_read(|subparcel| {
+    ///     if subparcel.has_more_data() {
+    ///         parcelable.a = subparcel.read()?;
+    ///     }
+    ///     if subparcel.has_more_data() {
+    ///         parcelable.b = subparcel.read()?;
+    ///     }
+    ///     Ok(())
+    /// });
+    /// ```
+    ///
+    pub fn sized_read<F>(&self, f: F) -> Result<()>
+    where
+        for<'b> F: FnOnce(ReadableSubParcel<'b>) -> Result<()>
+    {
+        let start = self.get_data_position();
+        let parcelable_size: i32 = self.read()?;
+        if parcelable_size < 0 {
+            return Err(StatusCode::BAD_VALUE);
+        }
+
+        let end = start.checked_add(parcelable_size)
+            .ok_or(StatusCode::BAD_VALUE)?;
+        if end > self.get_data_size() {
+            return Err(StatusCode::NOT_ENOUGH_DATA);
+        }
+
+        let subparcel = ReadableSubParcel {
+            parcel: BorrowedParcel {
+                ptr: self.ptr,
+                _lifetime: PhantomData,
+            },
+            end_position: end,
+        };
+        f(subparcel)?;
+
+        // Advance the data position to the actual end,
+        // in case the closure read less data than was available
+        unsafe {
+            self.set_data_position(end)?;
+        }
+
+        Ok(())
+    }
+
+    /// Read a vector size from the parcel and resize the given output vector to
+    /// be correctly sized for that amount of data.
     ///
     /// This method is used in AIDL-generated server side code for methods that
     /// take a mutable slice reference parameter.
@@ -238,7 +543,7 @@
         Ok(())
     }
 
-    /// Read a vector size from the `Parcel` and either create a correctly sized
+    /// Read a vector size from the parcel and either create a correctly sized
     /// vector for that amount of data or set the output parameter to None if
     /// the vector should be null.
     ///
@@ -264,11 +569,103 @@
     }
 }
 
-// Internal APIs
+/// A segment of a readable parcel, used for [`Parcel::sized_read`].
+pub struct ReadableSubParcel<'a> {
+    parcel: BorrowedParcel<'a>,
+    end_position: i32,
+}
+
+impl<'a> ReadableSubParcel<'a> {
+    /// Read a type that implements [`Deserialize`] from the sub-parcel.
+    pub fn read<D: Deserialize>(&self) -> Result<D> {
+        // The caller should have checked this,
+        // but it can't hurt to double-check
+        assert!(self.has_more_data());
+        D::deserialize(&self.parcel)
+    }
+
+    /// Check if the sub-parcel has more data to read
+    pub fn has_more_data(&self) -> bool {
+        self.parcel.get_data_position() < self.end_position
+    }
+}
+
 impl Parcel {
+    /// Attempt to read a type that implements [`Deserialize`] from this parcel.
+    pub fn read<D: Deserialize>(&self) -> Result<D> {
+        self.borrowed_ref().read()
+    }
+
+    /// Attempt to read a type that implements [`Deserialize`] from this parcel
+    /// onto an existing value. This operation will overwrite the old value
+    /// partially or completely, depending on how much data is available.
+    pub fn read_onto<D: Deserialize>(&self, x: &mut D) -> Result<()> {
+        self.borrowed_ref().read_onto(x)
+    }
+
+    /// Safely read a sized parcelable.
+    ///
+    /// Read the size of a parcelable, compute the end position
+    /// of that parcelable, then build a sized readable sub-parcel
+    /// and call a closure with the sub-parcel as its parameter.
+    /// The closure can keep reading data from the sub-parcel
+    /// until it runs out of input data. The closure is responsible
+    /// for calling [`ReadableSubParcel::has_more_data`] to check for
+    /// more data before every read, at least until Rust generators
+    /// are stabilized.
+    /// After the closure returns, skip to the end of the current
+    /// parcelable regardless of how much the closure has read.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// let mut parcelable = Default::default();
+    /// parcel.sized_read(|subparcel| {
+    ///     if subparcel.has_more_data() {
+    ///         parcelable.a = subparcel.read()?;
+    ///     }
+    ///     if subparcel.has_more_data() {
+    ///         parcelable.b = subparcel.read()?;
+    ///     }
+    ///     Ok(())
+    /// });
+    /// ```
+    ///
+    pub fn sized_read<F>(&self, f: F) -> Result<()>
+    where
+        for<'b> F: FnOnce(ReadableSubParcel<'b>) -> Result<()>
+    {
+        self.borrowed_ref().sized_read(f)
+    }
+
+    /// Read a vector size from the parcel and resize the given output vector to
+    /// be correctly sized for that amount of data.
+    ///
+    /// This method is used in AIDL-generated server side code for methods that
+    /// take a mutable slice reference parameter.
+    pub fn resize_out_vec<D: Default + Deserialize>(&self, out_vec: &mut Vec<D>) -> Result<()> {
+        self.borrowed_ref().resize_out_vec(out_vec)
+    }
+
+    /// Read a vector size from the parcel and either create a correctly sized
+    /// vector for that amount of data or set the output parameter to None if
+    /// the vector should be null.
+    ///
+    /// This method is used in AIDL-generated server side code for methods that
+    /// take a mutable slice reference parameter.
+    pub fn resize_nullable_out_vec<D: Default + Deserialize>(
+        &self,
+        out_vec: &mut Option<Vec<D>>,
+    ) -> Result<()> {
+        self.borrowed_ref().resize_nullable_out_vec(out_vec)
+    }
+}
+
+// Internal APIs
+impl<'a> BorrowedParcel<'a> {
     pub(crate) fn write_binder(&mut self, binder: Option<&SpIBinder>) -> Result<()> {
         unsafe {
-            // Safety: `Parcel` always contains a valid pointer to an
+            // Safety: `BorrowedParcel` always contains a valid pointer to an
             // `AParcel`. `AsNative` for `Option<SpIBinder`> will either return
             // null or a valid pointer to an `AIBinder`, both of which are
             // valid, safe inputs to `AParcel_writeStrongBinder`.
@@ -288,7 +685,7 @@
     pub(crate) fn read_binder(&self) -> Result<Option<SpIBinder>> {
         let mut binder = ptr::null_mut();
         let status = unsafe {
-            // Safety: `Parcel` always contains a valid pointer to an
+            // Safety: `BorrowedParcel` always contains a valid pointer to an
             // `AParcel`. We pass a valid, mutable out pointer to the `binder`
             // parameter. After this call, `binder` will be either null or a
             // valid pointer to an `AIBinder` owned by the caller.
@@ -308,54 +705,32 @@
 impl Drop for Parcel {
     fn drop(&mut self) {
         // Run the C++ Parcel complete object destructor
-        if let Self::Owned(ptr) = *self {
-            unsafe {
-                // Safety: `Parcel` always contains a valid pointer to an
-                // `AParcel`. If we own the parcel, we can safely delete it
-                // here.
-                sys::AParcel_delete(ptr)
-            }
+        unsafe {
+            // Safety: `Parcel` always contains a valid pointer to an
+            // `AParcel`. Since we own the parcel, we can safely delete it
+            // here.
+            sys::AParcel_delete(self.ptr.as_ptr())
         }
     }
 }
 
-#[cfg(test)]
-impl Parcel {
-    /// Create a new parcel tied to a bogus binder. TESTING ONLY!
-    ///
-    /// This can only be used for testing! All real parcel operations must be
-    /// done in the callback to [`IBinder::transact`] or in
-    /// [`Remotable::on_transact`] using the parcels provided to these methods.
-    pub(crate) fn new_for_test(binder: &mut SpIBinder) -> Result<Self> {
-        let mut input = ptr::null_mut();
-        let status = unsafe {
-            // Safety: `SpIBinder` guarantees that `binder` always contains a
-            // valid pointer to an `AIBinder`. We pass a valid, mutable out
-            // pointer to receive a newly constructed parcel. When successful
-            // this function assigns a new pointer to an `AParcel` to `input`
-            // and transfers ownership of this pointer to the caller. Thus,
-            // after this call, `input` will either be null or point to a valid,
-            // owned `AParcel`.
-            sys::AIBinder_prepareTransaction(binder.as_native_mut(), &mut input)
-        };
-        status_result(status)?;
-        unsafe {
-            // Safety: `input` is either null or a valid, owned pointer to an
-            // `AParcel`, so is valid to safe to
-            // `Parcel::owned`. `Parcel::owned` takes ownership of the parcel
-            // pointer.
-            Parcel::owned(input).ok_or(StatusCode::UNEXPECTED_NULL)
-        }
+impl fmt::Debug for Parcel {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Parcel")
+            .finish()
+    }
+}
+
+impl<'a> fmt::Debug for BorrowedParcel<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("BorrowedParcel")
+            .finish()
     }
 }
 
 #[test]
 fn test_read_write() {
-    use crate::binder::Interface;
-    use crate::native::Binder;
-
-    let mut service = Binder::new(()).as_binder();
-    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
+    let mut parcel = Parcel::new();
     let start = parcel.get_data_position();
 
     assert_eq!(parcel.read::<bool>(), Err(StatusCode::NOT_ENOUGH_DATA));
@@ -370,7 +745,7 @@
     assert_eq!(parcel.read::<Option<String>>(), Ok(None));
     assert_eq!(parcel.read::<String>(), Err(StatusCode::UNEXPECTED_NULL));
 
-    assert_eq!(parcel.read_binder().err(), Some(StatusCode::BAD_TYPE));
+    assert_eq!(parcel.borrowed_ref().read_binder().err(), Some(StatusCode::BAD_TYPE));
 
     parcel.write(&1i32).unwrap();
 
@@ -385,11 +760,7 @@
 #[test]
 #[allow(clippy::float_cmp)]
 fn test_read_data() {
-    use crate::binder::Interface;
-    use crate::native::Binder;
-
-    let mut service = Binder::new(()).as_binder();
-    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
+    let mut parcel = Parcel::new();
     let str_start = parcel.get_data_position();
 
     parcel.write(&b"Hello, Binder!\0"[..]).unwrap();
@@ -400,7 +771,7 @@
     assert_eq!(parcel.read::<i32>().unwrap(), 15);
     let start = parcel.get_data_position();
 
-    assert_eq!(parcel.read::<bool>().unwrap(), true);
+    assert!(parcel.read::<bool>().unwrap());
 
     unsafe {
         assert!(parcel.set_data_position(start).is_ok());
@@ -464,11 +835,7 @@
 
 #[test]
 fn test_utf8_utf16_conversions() {
-    use crate::binder::Interface;
-    use crate::native::Binder;
-
-    let mut service = Binder::new(()).as_binder();
-    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
+    let mut parcel = Parcel::new();
     let start = parcel.get_data_position();
 
     assert!(parcel.write("Hello, Binder!").is_ok());
@@ -528,11 +895,7 @@
 
 #[test]
 fn test_sized_write() {
-    use crate::binder::Interface;
-    use crate::native::Binder;
-
-    let mut service = Binder::new(()).as_binder();
-    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
+    let mut parcel = Parcel::new();
     let start = parcel.get_data_position();
 
     let arr = [1i32, 2i32, 3i32];
@@ -560,3 +923,43 @@
         &arr,
     );
 }
+
+#[test]
+fn test_append_from() {
+    let mut parcel1 = Parcel::new();
+    parcel1.write(&42i32).expect("Could not perform write");
+
+    let mut parcel2 = Parcel::new();
+    assert_eq!(Ok(()), parcel2.append_all_from(&parcel1));
+    assert_eq!(4, parcel2.get_data_size());
+    assert_eq!(Ok(()), parcel2.append_all_from(&parcel1));
+    assert_eq!(8, parcel2.get_data_size());
+    unsafe {
+        parcel2.set_data_position(0).unwrap();
+    }
+    assert_eq!(Ok(42), parcel2.read::<i32>());
+    assert_eq!(Ok(42), parcel2.read::<i32>());
+
+    let mut parcel2 = Parcel::new();
+    assert_eq!(Ok(()), parcel2.append_from(&parcel1, 0, 2));
+    assert_eq!(Ok(()), parcel2.append_from(&parcel1, 2, 2));
+    assert_eq!(4, parcel2.get_data_size());
+    unsafe {
+        parcel2.set_data_position(0).unwrap();
+    }
+    assert_eq!(Ok(42), parcel2.read::<i32>());
+
+    let mut parcel2 = Parcel::new();
+    assert_eq!(Ok(()), parcel2.append_from(&parcel1, 0, 2));
+    assert_eq!(2, parcel2.get_data_size());
+    unsafe {
+        parcel2.set_data_position(0).unwrap();
+    }
+    assert_eq!(Err(StatusCode::NOT_ENOUGH_DATA), parcel2.read::<i32>());
+
+    let mut parcel2 = Parcel::new();
+    assert_eq!(Err(StatusCode::BAD_VALUE), parcel2.append_from(&parcel1, 4, 2));
+    assert_eq!(Err(StatusCode::BAD_VALUE), parcel2.append_from(&parcel1, 2, 4));
+    assert_eq!(Err(StatusCode::BAD_VALUE), parcel2.append_from(&parcel1, -1, 4));
+    assert_eq!(Err(StatusCode::BAD_VALUE), parcel2.append_from(&parcel1, 2, -1));
+}
diff --git a/libs/binder/rust/src/parcel/file_descriptor.rs b/libs/binder/rust/src/parcel/file_descriptor.rs
index 20e9178..b0dea94 100644
--- a/libs/binder/rust/src/parcel/file_descriptor.rs
+++ b/libs/binder/rust/src/parcel/file_descriptor.rs
@@ -15,7 +15,7 @@
  */
 
 use super::{
-    Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize, SerializeArray,
+    Deserialize, DeserializeArray, DeserializeOption, BorrowedParcel, Serialize, SerializeArray,
     SerializeOption,
 };
 use crate::binder::AsNative;
@@ -23,7 +23,7 @@
 use crate::sys;
 
 use std::fs::File;
-use std::os::unix::io::{AsRawFd, FromRawFd};
+use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
 
 /// Rust version of the Java class android.os.ParcelFileDescriptor
 #[derive(Debug)]
@@ -48,8 +48,20 @@
     }
 }
 
+impl AsRawFd for ParcelFileDescriptor {
+    fn as_raw_fd(&self) -> RawFd {
+        self.0.as_raw_fd()
+    }
+}
+
+impl IntoRawFd for ParcelFileDescriptor {
+    fn into_raw_fd(self) -> RawFd {
+        self.0.into_raw_fd()
+    }
+}
+
 impl Serialize for ParcelFileDescriptor {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         let fd = self.0.as_raw_fd();
         let status = unsafe {
             // Safety: `Parcel` always contains a valid pointer to an
@@ -66,7 +78,7 @@
 impl SerializeArray for ParcelFileDescriptor {}
 
 impl SerializeOption for ParcelFileDescriptor {
-    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+    fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         if let Some(f) = this {
             f.serialize(parcel)
         } else {
@@ -82,10 +94,8 @@
     }
 }
 
-impl SerializeArray for Option<ParcelFileDescriptor> {}
-
 impl DeserializeOption for ParcelFileDescriptor {
-    fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+    fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<Self>> {
         let mut fd = -1i32;
         unsafe {
             // Safety: `Parcel` always contains a valid pointer to an
@@ -114,10 +124,8 @@
     }
 }
 
-impl DeserializeArray for Option<ParcelFileDescriptor> {}
-
 impl Deserialize for ParcelFileDescriptor {
-    fn deserialize(parcel: &Parcel) -> Result<Self> {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
         Deserialize::deserialize(parcel)
             .transpose()
             .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
index f57788b..9007cba 100644
--- a/libs/binder/rust/src/parcel/parcelable.rs
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -14,31 +14,62 @@
  * limitations under the License.
  */
 
-use crate::binder::{AsNative, FromIBinder, Strong};
+use crate::binder::{AsNative, FromIBinder, Stability, Strong};
 use crate::error::{status_result, status_t, Result, Status, StatusCode};
-use crate::parcel::Parcel;
+use crate::parcel::BorrowedParcel;
 use crate::proxy::SpIBinder;
 use crate::sys;
 
-use std::convert::TryInto;
+use std::convert::{TryFrom, TryInto};
 use std::ffi::c_void;
 use std::os::raw::{c_char, c_ulong};
-use std::mem::{self, MaybeUninit};
+use std::mem::{self, MaybeUninit, ManuallyDrop};
 use std::ptr;
 use std::slice;
 
+/// Super-trait for Binder parcelables.
+///
+/// This trait is equivalent `android::Parcelable` in C++,
+/// and defines a common interface that all parcelables need
+/// to implement.
+pub trait Parcelable {
+    /// Internal serialization function for parcelables.
+    ///
+    /// This method is mainly for internal use.
+    /// `Serialize::serialize` and its variants are generally
+    /// preferred over this function, since the former also
+    /// prepend a header.
+    fn write_to_parcel(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()>;
+
+    /// Internal deserialization function for parcelables.
+    ///
+    /// This method is mainly for internal use.
+    /// `Deserialize::deserialize` and its variants are generally
+    /// preferred over this function, since the former also
+    /// parse the additional header.
+    fn read_from_parcel(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()>;
+}
+
 /// A struct whose instances can be written to a [`Parcel`].
 // Might be able to hook this up as a serde backend in the future?
 pub trait Serialize {
     /// Serialize this instance into the given [`Parcel`].
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()>;
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()>;
 }
 
 /// A struct whose instances can be restored from a [`Parcel`].
 // Might be able to hook this up as a serde backend in the future?
 pub trait Deserialize: Sized {
     /// Deserialize an instance from the given [`Parcel`].
-    fn deserialize(parcel: &Parcel) -> Result<Self>;
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self>;
+
+    /// Deserialize an instance from the given [`Parcel`] onto the
+    /// current object. This operation will overwrite the old value
+    /// partially or completely, depending on how much data is available.
+    fn deserialize_from(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()> {
+        *self = Self::deserialize(parcel)?;
+        Ok(())
+    }
 }
 
 /// Helper trait for types that can be serialized as arrays.
@@ -49,8 +80,8 @@
 // We want the default implementation for most types, but an override for
 // a few special ones like `readByteArray` for `u8`.
 pub trait SerializeArray: Serialize + Sized {
-    /// Serialize an array of this type into the given [`Parcel`].
-    fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+    /// Serialize an array of this type into the given parcel.
+    fn serialize_array(slice: &[Self], parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         let res = unsafe {
             // Safety: Safe FFI, slice will always be a safe pointer to pass.
             sys::AParcel_writeParcelableArray(
@@ -80,7 +111,7 @@
 
     let slice: &[T] = slice::from_raw_parts(array.cast(), index+1);
 
-    let mut parcel = match Parcel::borrowed(parcel) {
+    let mut parcel = match BorrowedParcel::from_raw(parcel) {
         None => return StatusCode::UNEXPECTED_NULL as status_t,
         Some(p) => p,
     };
@@ -95,8 +126,8 @@
 /// Defaults to calling Deserialize::deserialize() manually for every element,
 /// but can be overridden for custom implementations like `readByteArray`.
 pub trait DeserializeArray: Deserialize {
-    /// Deserialize an array of type from the given [`Parcel`].
-    fn deserialize_array(parcel: &Parcel) -> Result<Option<Vec<Self>>> {
+    /// Deserialize an array of type from the given parcel.
+    fn deserialize_array(parcel: &BorrowedParcel<'_>) -> Result<Option<Vec<Self>>> {
         let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
         let res = unsafe {
             // Safety: Safe FFI, vec is the correct opaque type expected by
@@ -142,7 +173,7 @@
         None => return StatusCode::BAD_INDEX as status_t,
     };
 
-    let parcel = match Parcel::borrowed(parcel as *mut _) {
+    let parcel = match BorrowedParcel::from_raw(parcel as *mut _) {
         None => return StatusCode::UNEXPECTED_NULL as status_t,
         Some(p) => p,
     };
@@ -154,6 +185,18 @@
     StatusCode::OK as status_t
 }
 
+/// Flag that specifies that the following parcelable is present.
+///
+/// This is the Rust equivalent of `Parcel::kNonNullParcelableFlag`
+/// from `include/binder/Parcel.h` in C++.
+pub const NON_NULL_PARCELABLE_FLAG: i32 = 1;
+
+/// Flag that specifies that the following parcelable is absent.
+///
+/// This is the Rust equivalent of `Parcel::kNullParcelableFlag`
+/// from `include/binder/Parcel.h` in C++.
+pub const NULL_PARCELABLE_FLAG: i32 = 0;
+
 /// Helper trait for types that can be nullable when serialized.
 // We really need this trait instead of implementing `Serialize for Option<T>`
 // because of the Rust orphan rule which prevents us from doing
@@ -162,28 +205,36 @@
 // We also use it to provide a default implementation for AIDL-generated
 // parcelables.
 pub trait SerializeOption: Serialize {
-    /// Serialize an Option of this type into the given [`Parcel`].
-    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+    /// Serialize an Option of this type into the given parcel.
+    fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         if let Some(inner) = this {
-            parcel.write(&1i32)?;
+            parcel.write(&NON_NULL_PARCELABLE_FLAG)?;
             parcel.write(inner)
         } else {
-            parcel.write(&0i32)
+            parcel.write(&NULL_PARCELABLE_FLAG)
         }
     }
 }
 
 /// Helper trait for types that can be nullable when deserialized.
 pub trait DeserializeOption: Deserialize {
-    /// Deserialize an Option of this type from the given [`Parcel`].
-    fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+    /// Deserialize an Option of this type from the given parcel.
+    fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<Self>> {
         let null: i32 = parcel.read()?;
-        if null == 0 {
+        if null == NULL_PARCELABLE_FLAG {
             Ok(None)
         } else {
             parcel.read().map(Some)
         }
     }
+
+    /// Deserialize an Option of this type from the given parcel onto the
+    /// current object. This operation will overwrite the current value
+    /// partially or completely, depending on how much data is available.
+    fn deserialize_option_from(this: &mut Option<Self>, parcel: &BorrowedParcel<'_>) -> Result<()> {
+        *this = Self::deserialize_option(parcel)?;
+        Ok(())
+    }
 }
 
 /// Callback to allocate a vector for parcel array read functions.
@@ -246,10 +297,23 @@
     };
 }
 
+/// Safety: All elements in the vector must be properly initialized.
+unsafe fn vec_assume_init<T>(vec: Vec<MaybeUninit<T>>) -> Vec<T> {
+    // We can convert from Vec<MaybeUninit<T>> to Vec<T> because MaybeUninit<T>
+    // has the same alignment and size as T, so the pointer to the vector
+    // allocation will be compatible.
+    let mut vec = ManuallyDrop::new(vec);
+    Vec::from_raw_parts(
+        vec.as_mut_ptr().cast(),
+        vec.len(),
+        vec.capacity(),
+    )
+}
+
 macro_rules! impl_parcelable {
     {Serialize, $ty:ty, $write_fn:path} => {
         impl Serialize for $ty {
-            fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+            fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
                 unsafe {
                     // Safety: `Parcel` always contains a valid pointer to an
                     // `AParcel`, and any `$ty` literal value is safe to pass to
@@ -262,7 +326,7 @@
 
     {Deserialize, $ty:ty, $read_fn:path} => {
         impl Deserialize for $ty {
-            fn deserialize(parcel: &Parcel) -> Result<Self> {
+            fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
                 let mut val = Self::default();
                 unsafe {
                     // Safety: `Parcel` always contains a valid pointer to an
@@ -278,7 +342,7 @@
 
     {SerializeArray, $ty:ty, $write_array_fn:path} => {
         impl SerializeArray for $ty {
-            fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+            fn serialize_array(slice: &[Self], parcel: &mut BorrowedParcel<'_>) -> Result<()> {
                 let status = unsafe {
                     // Safety: `Parcel` always contains a valid pointer to an
                     // `AParcel`. If the slice is > 0 length, `slice.as_ptr()`
@@ -302,7 +366,7 @@
 
     {DeserializeArray, $ty:ty, $read_array_fn:path} => {
         impl DeserializeArray for $ty {
-            fn deserialize_array(parcel: &Parcel) -> Result<Option<Vec<Self>>> {
+            fn deserialize_array(parcel: &BorrowedParcel<'_>) -> Result<Option<Vec<Self>>> {
                 let mut vec: Option<Vec<MaybeUninit<Self>>> = None;
                 let status = unsafe {
                     // Safety: `Parcel` always contains a valid pointer to an
@@ -320,11 +384,8 @@
                     // Safety: We are assuming that the NDK correctly
                     // initialized every element of the vector by now, so we
                     // know that all the MaybeUninits are now properly
-                    // initialized. We can transmute from Vec<MaybeUninit<T>> to
-                    // Vec<T> because MaybeUninit<T> has the same alignment and
-                    // size as T, so the pointer to the vector allocation will
-                    // be compatible.
-                    mem::transmute(vec)
+                    // initialized.
+                    vec.map(|vec| vec_assume_init(vec))
                 };
                 Ok(vec)
             }
@@ -332,6 +393,9 @@
     };
 }
 
+impl<T: DeserializeOption> DeserializeArray for Option<T> {}
+impl<T: SerializeOption> SerializeArray for Option<T> {}
+
 parcelable_primitives! {
     impl Serialize for bool = sys::AParcel_writeBool;
     impl Deserialize for bool = sys::AParcel_readBool;
@@ -389,19 +453,19 @@
 impl DeserializeArray for bool {}
 
 impl Serialize for u8 {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         (*self as i8).serialize(parcel)
     }
 }
 
 impl Deserialize for u8 {
-    fn deserialize(parcel: &Parcel) -> Result<Self> {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
         i8::deserialize(parcel).map(|v| v as u8)
     }
 }
 
 impl SerializeArray for u8 {
-    fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+    fn serialize_array(slice: &[Self], parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         let status = unsafe {
             // Safety: `Parcel` always contains a valid pointer to an
             // `AParcel`. If the slice is > 0 length, `slice.as_ptr()` will be a
@@ -420,19 +484,19 @@
 }
 
 impl Serialize for i16 {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         (*self as u16).serialize(parcel)
     }
 }
 
 impl Deserialize for i16 {
-    fn deserialize(parcel: &Parcel) -> Result<Self> {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
         u16::deserialize(parcel).map(|v| v as i16)
     }
 }
 
 impl SerializeArray for i16 {
-    fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+    fn serialize_array(slice: &[Self], parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         let status = unsafe {
             // Safety: `Parcel` always contains a valid pointer to an
             // `AParcel`. If the slice is > 0 length, `slice.as_ptr()` will be a
@@ -451,7 +515,7 @@
 }
 
 impl SerializeOption for str {
-    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+    fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         match this {
             None => unsafe {
                 // Safety: `Parcel` always contains a valid pointer to an
@@ -486,10 +550,8 @@
     }
 }
 
-impl SerializeArray for Option<&str> {}
-
 impl Serialize for str {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         Some(self).serialize(parcel)
     }
 }
@@ -497,7 +559,7 @@
 impl SerializeArray for &str {}
 
 impl Serialize for String {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         Some(self.as_str()).serialize(parcel)
     }
 }
@@ -505,15 +567,13 @@
 impl SerializeArray for String {}
 
 impl SerializeOption for String {
-    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+    fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         SerializeOption::serialize_option(this.map(String::as_str), parcel)
     }
 }
 
-impl SerializeArray for Option<String> {}
-
 impl Deserialize for Option<String> {
-    fn deserialize(parcel: &Parcel) -> Result<Self> {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
         let mut vec: Option<Vec<u8>> = None;
         let status = unsafe {
             // Safety: `Parcel` always contains a valid pointer to an `AParcel`.
@@ -541,7 +601,7 @@
 impl DeserializeArray for Option<String> {}
 
 impl Deserialize for String {
-    fn deserialize(parcel: &Parcel) -> Result<Self> {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
         Deserialize::deserialize(parcel)
             .transpose()
             .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
@@ -551,19 +611,19 @@
 impl DeserializeArray for String {}
 
 impl<T: SerializeArray> Serialize for [T] {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         SerializeArray::serialize_array(self, parcel)
     }
 }
 
 impl<T: SerializeArray> Serialize for Vec<T> {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         SerializeArray::serialize_array(&self[..], parcel)
     }
 }
 
 impl<T: SerializeArray> SerializeOption for [T] {
-    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+    fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         if let Some(v) = this {
             SerializeArray::serialize_array(v, parcel)
         } else {
@@ -573,13 +633,13 @@
 }
 
 impl<T: SerializeArray> SerializeOption for Vec<T> {
-    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+    fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         SerializeOption::serialize_option(this.map(Vec::as_slice), parcel)
     }
 }
 
 impl<T: DeserializeArray> Deserialize for Vec<T> {
-    fn deserialize(parcel: &Parcel) -> Result<Self> {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
         DeserializeArray::deserialize_array(parcel)
             .transpose()
             .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
@@ -587,13 +647,25 @@
 }
 
 impl<T: DeserializeArray> DeserializeOption for Vec<T> {
-    fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+    fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<Self>> {
         DeserializeArray::deserialize_array(parcel)
     }
 }
 
+impl Serialize for Stability {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
+        i32::from(*self).serialize(parcel)
+    }
+}
+
+impl Deserialize for Stability {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
+        i32::deserialize(parcel).and_then(Stability::try_from)
+    }
+}
+
 impl Serialize for Status {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         unsafe {
             // Safety: `Parcel` always contains a valid pointer to an `AParcel`
             // and `Status` always contains a valid pointer to an `AStatus`, so
@@ -608,7 +680,7 @@
 }
 
 impl Deserialize for Status {
-    fn deserialize(parcel: &Parcel) -> Result<Self> {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
         let mut status_ptr = ptr::null_mut();
         let ret_status = unsafe {
             // Safety: `Parcel` always contains a valid pointer to an
@@ -629,361 +701,491 @@
 }
 
 impl<T: Serialize + FromIBinder + ?Sized> Serialize for Strong<T> {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         Serialize::serialize(&**self, parcel)
     }
 }
 
 impl<T: SerializeOption + FromIBinder + ?Sized> SerializeOption for Strong<T> {
-    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+    fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         SerializeOption::serialize_option(this.map(|b| &**b), parcel)
     }
 }
 
+impl<T: Serialize + FromIBinder + ?Sized> SerializeArray for Strong<T> {}
+
 impl<T: FromIBinder + ?Sized> Deserialize for Strong<T> {
-    fn deserialize(parcel: &Parcel) -> Result<Self> {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
         let ibinder: SpIBinder = parcel.read()?;
         FromIBinder::try_from(ibinder)
     }
 }
 
 impl<T: FromIBinder + ?Sized> DeserializeOption for Strong<T> {
-    fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+    fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<Self>> {
         let ibinder: Option<SpIBinder> = parcel.read()?;
         ibinder.map(FromIBinder::try_from).transpose()
     }
 }
 
+impl<T: FromIBinder + ?Sized> DeserializeArray for Strong<T> {}
+
 // We need these to support Option<&T> for all T
 impl<T: Serialize + ?Sized> Serialize for &T {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         Serialize::serialize(*self, parcel)
     }
 }
 
 impl<T: SerializeOption + ?Sized> SerializeOption for &T {
-    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+    fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         SerializeOption::serialize_option(this.copied(), parcel)
     }
 }
 
 impl<T: SerializeOption> Serialize for Option<T> {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         SerializeOption::serialize_option(self.as_ref(), parcel)
     }
 }
 
 impl<T: DeserializeOption> Deserialize for Option<T> {
-    fn deserialize(parcel: &Parcel) -> Result<Self> {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
         DeserializeOption::deserialize_option(parcel)
     }
+
+    fn deserialize_from(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()> {
+        DeserializeOption::deserialize_option_from(self, parcel)
+    }
 }
 
-#[test]
-fn test_custom_parcelable() {
-    use crate::binder::Interface;
-    use crate::native::Binder;
-    let mut service = Binder::new(()).as_binder();
+/// Implement `Serialize` trait and friends for a parcelable
+///
+/// This is an internal macro used by the AIDL compiler to implement
+/// `Serialize`, `SerializeArray` and `SerializeOption` for
+/// structured parcelables. The target type must implement the
+/// `Parcelable` trait.
+/// ```
+#[macro_export]
+macro_rules! impl_serialize_for_parcelable {
+    ($parcelable:ident) => {
+        impl $crate::parcel::Serialize for $parcelable {
+            fn serialize(
+                &self,
+                parcel: &mut $crate::parcel::BorrowedParcel<'_>,
+            ) -> $crate::Result<()> {
+                <Self as $crate::parcel::SerializeOption>::serialize_option(
+                    Some(self),
+                    parcel,
+                )
+            }
+        }
 
-    struct Custom(u32, bool, String, Vec<String>);
+        impl $crate::parcel::SerializeArray for $parcelable {}
 
-    impl Serialize for Custom {
-        fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
-            self.0.serialize(parcel)?;
-            self.1.serialize(parcel)?;
-            self.2.serialize(parcel)?;
-            self.3.serialize(parcel)
+        impl $crate::parcel::SerializeOption for $parcelable {
+            fn serialize_option(
+                this: Option<&Self>,
+                parcel: &mut $crate::parcel::BorrowedParcel<'_>,
+            ) -> $crate::Result<()> {
+                if let Some(this) = this {
+                    use $crate::parcel::Parcelable;
+                    parcel.write(&$crate::parcel::NON_NULL_PARCELABLE_FLAG)?;
+                    this.write_to_parcel(parcel)
+                } else {
+                    parcel.write(&$crate::parcel::NULL_PARCELABLE_FLAG)
+                }
+            }
         }
     }
-
-    impl Deserialize for Custom {
-        fn deserialize(parcel: &Parcel) -> Result<Self> {
-            Ok(Custom(
-                parcel.read()?,
-                parcel.read()?,
-                parcel.read()?,
-                parcel.read::<Option<Vec<String>>>()?.unwrap(),
-            ))
-        }
-    }
-
-    let string8 = "Custom Parcelable".to_string();
-
-    let s1 = "str1".to_string();
-    let s2 = "str2".to_string();
-    let s3 = "str3".to_string();
-
-    let strs = vec![s1, s2, s3];
-
-    let custom = Custom(123_456_789, true, string8, strs);
-
-    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
-    let start = parcel.get_data_position();
-
-    assert!(custom.serialize(&mut parcel).is_ok());
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let custom2 = Custom::deserialize(&parcel).unwrap();
-
-    assert_eq!(custom2.0, 123_456_789);
-    assert!(custom2.1);
-    assert_eq!(custom2.2, custom.2);
-    assert_eq!(custom2.3, custom.3);
 }
 
-#[test]
-#[allow(clippy::excessive_precision)]
-fn test_slice_parcelables() {
-    use crate::binder::Interface;
-    use crate::native::Binder;
-    let mut service = Binder::new(()).as_binder();
+/// Implement `Deserialize` trait and friends for a parcelable
+///
+/// This is an internal macro used by the AIDL compiler to implement
+/// `Deserialize`, `DeserializeArray` and `DeserializeOption` for
+/// structured parcelables. The target type must implement the
+/// `Parcelable` trait.
+#[macro_export]
+macro_rules! impl_deserialize_for_parcelable {
+    ($parcelable:ident) => {
+        impl $crate::parcel::Deserialize for $parcelable {
+            fn deserialize(
+                parcel: &$crate::parcel::BorrowedParcel<'_>,
+            ) -> $crate::Result<Self> {
+                $crate::parcel::DeserializeOption::deserialize_option(parcel)
+                    .transpose()
+                    .unwrap_or(Err($crate::StatusCode::UNEXPECTED_NULL))
+            }
+            fn deserialize_from(
+                &mut self,
+                parcel: &$crate::parcel::BorrowedParcel<'_>,
+            ) -> $crate::Result<()> {
+                let status: i32 = parcel.read()?;
+                if status == $crate::parcel::NULL_PARCELABLE_FLAG {
+                    Err($crate::StatusCode::UNEXPECTED_NULL)
+                } else {
+                    use $crate::parcel::Parcelable;
+                    self.read_from_parcel(parcel)
+                }
+            }
+        }
 
-    let bools = [true, false, false, true];
+        impl $crate::parcel::DeserializeArray for $parcelable {}
 
-    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
-    let start = parcel.get_data_position();
+        impl $crate::parcel::DeserializeOption for $parcelable {
+            fn deserialize_option(
+                parcel: &$crate::parcel::BorrowedParcel<'_>,
+            ) -> $crate::Result<Option<Self>> {
+                let mut result = None;
+                Self::deserialize_option_from(&mut result, parcel)?;
+                Ok(result)
+            }
+            fn deserialize_option_from(
+                this: &mut Option<Self>,
+                parcel: &$crate::parcel::BorrowedParcel<'_>,
+            ) -> $crate::Result<()> {
+                let status: i32 = parcel.read()?;
+                if status == $crate::parcel::NULL_PARCELABLE_FLAG {
+                    *this = None;
+                    Ok(())
+                } else {
+                    use $crate::parcel::Parcelable;
+                    this.get_or_insert_with(Self::default)
+                        .read_from_parcel(parcel)
+                }
+            }
+        }
+    }
+}
 
-    assert!(bools.serialize(&mut parcel).is_ok());
+impl<T: Serialize> Serialize for Box<T> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
+        Serialize::serialize(&**self, parcel)
+    }
+}
 
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
+impl<T: Deserialize> Deserialize for Box<T> {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
+        Deserialize::deserialize(parcel).map(Box::new)
+    }
+}
+
+impl<T: SerializeOption> SerializeOption for Box<T> {
+    fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
+        SerializeOption::serialize_option(this.map(|inner| &**inner), parcel)
+    }
+}
+
+impl<T: DeserializeOption> DeserializeOption for Box<T> {
+    fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<Self>> {
+        DeserializeOption::deserialize_option(parcel).map(|t| t.map(Box::new))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::Parcel;
+    use super::*;
+
+    #[test]
+    fn test_custom_parcelable() {
+        struct Custom(u32, bool, String, Vec<String>);
+
+        impl Serialize for Custom {
+            fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
+                self.0.serialize(parcel)?;
+                self.1.serialize(parcel)?;
+                self.2.serialize(parcel)?;
+                self.3.serialize(parcel)
+            }
+        }
+
+        impl Deserialize for Custom {
+            fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<Self> {
+                Ok(Custom(
+                        parcel.read()?,
+                        parcel.read()?,
+                        parcel.read()?,
+                        parcel.read::<Option<Vec<String>>>()?.unwrap(),
+                        ))
+            }
+        }
+
+        let string8 = "Custom Parcelable".to_string();
+
+        let s1 = "str1".to_string();
+        let s2 = "str2".to_string();
+        let s3 = "str3".to_string();
+
+        let strs = vec![s1, s2, s3];
+
+        let custom = Custom(123_456_789, true, string8, strs);
+
+        let mut parcel = Parcel::new();
+        let start = parcel.get_data_position();
+
+        assert!(custom.serialize(&mut parcel.borrowed()).is_ok());
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let custom2 = Custom::deserialize(parcel.borrowed_ref()).unwrap();
+
+        assert_eq!(custom2.0, 123_456_789);
+        assert!(custom2.1);
+        assert_eq!(custom2.2, custom.2);
+        assert_eq!(custom2.3, custom.3);
     }
 
-    assert_eq!(parcel.read::<u32>().unwrap(), 4);
-    assert_eq!(parcel.read::<u32>().unwrap(), 1);
-    assert_eq!(parcel.read::<u32>().unwrap(), 0);
-    assert_eq!(parcel.read::<u32>().unwrap(), 0);
-    assert_eq!(parcel.read::<u32>().unwrap(), 1);
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
+    #[test]
+    #[allow(clippy::excessive_precision)]
+    fn test_slice_parcelables() {
+        let bools = [true, false, false, true];
+
+        let mut parcel = Parcel::new();
+        let start = parcel.get_data_position();
+
+        assert!(bools.serialize(&mut parcel.borrowed()).is_ok());
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        assert_eq!(parcel.read::<u32>().unwrap(), 4);
+        assert_eq!(parcel.read::<u32>().unwrap(), 1);
+        assert_eq!(parcel.read::<u32>().unwrap(), 0);
+        assert_eq!(parcel.read::<u32>().unwrap(), 0);
+        assert_eq!(parcel.read::<u32>().unwrap(), 1);
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<bool>::deserialize(parcel.borrowed_ref()).unwrap();
+
+        assert_eq!(vec, [true, false, false, true]);
+
+        let u8s = [101u8, 255, 42, 117];
+
+        let mut parcel = Parcel::new();
+        let start = parcel.get_data_position();
+
+        assert!(parcel.write(&u8s[..]).is_ok());
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+        assert_eq!(parcel.read::<u32>().unwrap(), 0x752aff65); // bytes
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<u8>::deserialize(parcel.borrowed_ref()).unwrap();
+        assert_eq!(vec, [101, 255, 42, 117]);
+
+        let i8s = [-128i8, 127, 42, -117];
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        assert!(parcel.write(&i8s[..]).is_ok());
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+        assert_eq!(parcel.read::<u32>().unwrap(), 0x8b2a7f80); // bytes
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<u8>::deserialize(parcel.borrowed_ref()).unwrap();
+        assert_eq!(vec, [-128i8 as u8, 127, 42, -117i8 as u8]);
+
+        let u16s = [u16::max_value(), 12_345, 42, 117];
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+        assert!(u16s.serialize(&mut parcel.borrowed()).is_ok());
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+        assert_eq!(parcel.read::<u32>().unwrap(), 0xffff); // u16::max_value()
+        assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
+        assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+        assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<u16>::deserialize(parcel.borrowed_ref()).unwrap();
+
+        assert_eq!(vec, [u16::max_value(), 12_345, 42, 117]);
+
+        let i16s = [i16::max_value(), i16::min_value(), 42, -117];
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+        assert!(i16s.serialize(&mut parcel.borrowed()).is_ok());
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+        assert_eq!(parcel.read::<u32>().unwrap(), 0x7fff); // i16::max_value()
+        assert_eq!(parcel.read::<u32>().unwrap(), 0x8000); // i16::min_value()
+        assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+        assert_eq!(parcel.read::<u32>().unwrap(), 0xff8b); // -117
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<i16>::deserialize(parcel.borrowed_ref()).unwrap();
+
+        assert_eq!(vec, [i16::max_value(), i16::min_value(), 42, -117]);
+
+        let u32s = [u32::max_value(), 12_345, 42, 117];
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+        assert!(u32s.serialize(&mut parcel.borrowed()).is_ok());
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+        assert_eq!(parcel.read::<u32>().unwrap(), 0xffffffff); // u32::max_value()
+        assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
+        assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+        assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<u32>::deserialize(parcel.borrowed_ref()).unwrap();
+
+        assert_eq!(vec, [u32::max_value(), 12_345, 42, 117]);
+
+        let i32s = [i32::max_value(), i32::min_value(), 42, -117];
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+        assert!(i32s.serialize(&mut parcel.borrowed()).is_ok());
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+        assert_eq!(parcel.read::<u32>().unwrap(), 0x7fffffff); // i32::max_value()
+        assert_eq!(parcel.read::<u32>().unwrap(), 0x80000000); // i32::min_value()
+        assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+        assert_eq!(parcel.read::<u32>().unwrap(), 0xffffff8b); // -117
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<i32>::deserialize(parcel.borrowed_ref()).unwrap();
+
+        assert_eq!(vec, [i32::max_value(), i32::min_value(), 42, -117]);
+
+        let u64s = [u64::max_value(), 12_345, 42, 117];
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+        assert!(u64s.serialize(&mut parcel.borrowed()).is_ok());
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<u64>::deserialize(parcel.borrowed_ref()).unwrap();
+
+        assert_eq!(vec, [u64::max_value(), 12_345, 42, 117]);
+
+        let i64s = [i64::max_value(), i64::min_value(), 42, -117];
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+        assert!(i64s.serialize(&mut parcel.borrowed()).is_ok());
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<i64>::deserialize(parcel.borrowed_ref()).unwrap();
+
+        assert_eq!(vec, [i64::max_value(), i64::min_value(), 42, -117]);
+
+        let f32s = [
+            std::f32::NAN,
+            std::f32::INFINITY,
+            1.23456789,
+            std::f32::EPSILON,
+        ];
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+        assert!(f32s.serialize(&mut parcel.borrowed()).is_ok());
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<f32>::deserialize(parcel.borrowed_ref()).unwrap();
+
+        // NAN != NAN so we can't use it in the assert_eq:
+        assert!(vec[0].is_nan());
+        assert_eq!(vec[1..], f32s[1..]);
+
+        let f64s = [
+            std::f64::NAN,
+            std::f64::INFINITY,
+            1.234567890123456789,
+            std::f64::EPSILON,
+        ];
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+        assert!(f64s.serialize(&mut parcel.borrowed()).is_ok());
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<f64>::deserialize(parcel.borrowed_ref()).unwrap();
+
+        // NAN != NAN so we can't use it in the assert_eq:
+        assert!(vec[0].is_nan());
+        assert_eq!(vec[1..], f64s[1..]);
+
+        let s1 = "Hello, Binder!";
+        let s2 = "This is a utf8 string.";
+        let s3 = "Some more text here.";
+        let s4 = "Embedded nulls \0 \0";
+
+        let strs = [s1, s2, s3, s4];
+
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+        assert!(strs.serialize(&mut parcel.borrowed()).is_ok());
+        unsafe {
+            assert!(parcel.set_data_position(start).is_ok());
+        }
+
+        let vec = Vec::<String>::deserialize(parcel.borrowed_ref()).unwrap();
+
+        assert_eq!(vec, strs);
     }
-
-    let vec = Vec::<bool>::deserialize(&parcel).unwrap();
-
-    assert_eq!(vec, [true, false, false, true]);
-
-    let u8s = [101u8, 255, 42, 117];
-
-    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
-    let start = parcel.get_data_position();
-
-    assert!(parcel.write(&u8s[..]).is_ok());
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
-    assert_eq!(parcel.read::<u32>().unwrap(), 0x752aff65); // bytes
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let vec = Vec::<u8>::deserialize(&parcel).unwrap();
-    assert_eq!(vec, [101, 255, 42, 117]);
-
-    let i8s = [-128i8, 127, 42, -117];
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    assert!(parcel.write(&i8s[..]).is_ok());
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
-    assert_eq!(parcel.read::<u32>().unwrap(), 0x8b2a7f80); // bytes
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let vec = Vec::<u8>::deserialize(&parcel).unwrap();
-    assert_eq!(vec, [-128i8 as u8, 127, 42, -117i8 as u8]);
-
-    let u16s = [u16::max_value(), 12_345, 42, 117];
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-    assert!(u16s.serialize(&mut parcel).is_ok());
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
-    assert_eq!(parcel.read::<u32>().unwrap(), 0xffff); // u16::max_value()
-    assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
-    assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
-    assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let vec = Vec::<u16>::deserialize(&parcel).unwrap();
-
-    assert_eq!(vec, [u16::max_value(), 12_345, 42, 117]);
-
-    let i16s = [i16::max_value(), i16::min_value(), 42, -117];
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-    assert!(i16s.serialize(&mut parcel).is_ok());
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
-    assert_eq!(parcel.read::<u32>().unwrap(), 0x7fff); // i16::max_value()
-    assert_eq!(parcel.read::<u32>().unwrap(), 0x8000); // i16::min_value()
-    assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
-    assert_eq!(parcel.read::<u32>().unwrap(), 0xff8b); // -117
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let vec = Vec::<i16>::deserialize(&parcel).unwrap();
-
-    assert_eq!(vec, [i16::max_value(), i16::min_value(), 42, -117]);
-
-    let u32s = [u32::max_value(), 12_345, 42, 117];
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-    assert!(u32s.serialize(&mut parcel).is_ok());
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
-    assert_eq!(parcel.read::<u32>().unwrap(), 0xffffffff); // u32::max_value()
-    assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
-    assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
-    assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let vec = Vec::<u32>::deserialize(&parcel).unwrap();
-
-    assert_eq!(vec, [u32::max_value(), 12_345, 42, 117]);
-
-    let i32s = [i32::max_value(), i32::min_value(), 42, -117];
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-    assert!(i32s.serialize(&mut parcel).is_ok());
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
-    assert_eq!(parcel.read::<u32>().unwrap(), 0x7fffffff); // i32::max_value()
-    assert_eq!(parcel.read::<u32>().unwrap(), 0x80000000); // i32::min_value()
-    assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
-    assert_eq!(parcel.read::<u32>().unwrap(), 0xffffff8b); // -117
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let vec = Vec::<i32>::deserialize(&parcel).unwrap();
-
-    assert_eq!(vec, [i32::max_value(), i32::min_value(), 42, -117]);
-
-    let u64s = [u64::max_value(), 12_345, 42, 117];
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-    assert!(u64s.serialize(&mut parcel).is_ok());
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let vec = Vec::<u64>::deserialize(&parcel).unwrap();
-
-    assert_eq!(vec, [u64::max_value(), 12_345, 42, 117]);
-
-    let i64s = [i64::max_value(), i64::min_value(), 42, -117];
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-    assert!(i64s.serialize(&mut parcel).is_ok());
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let vec = Vec::<i64>::deserialize(&parcel).unwrap();
-
-    assert_eq!(vec, [i64::max_value(), i64::min_value(), 42, -117]);
-
-    let f32s = [
-        std::f32::NAN,
-        std::f32::INFINITY,
-        1.23456789,
-        std::f32::EPSILON,
-    ];
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-    assert!(f32s.serialize(&mut parcel).is_ok());
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let vec = Vec::<f32>::deserialize(&parcel).unwrap();
-
-    // NAN != NAN so we can't use it in the assert_eq:
-    assert!(vec[0].is_nan());
-    assert_eq!(vec[1..], f32s[1..]);
-
-    let f64s = [
-        std::f64::NAN,
-        std::f64::INFINITY,
-        1.234567890123456789,
-        std::f64::EPSILON,
-    ];
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-    assert!(f64s.serialize(&mut parcel).is_ok());
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let vec = Vec::<f64>::deserialize(&parcel).unwrap();
-
-    // NAN != NAN so we can't use it in the assert_eq:
-    assert!(vec[0].is_nan());
-    assert_eq!(vec[1..], f64s[1..]);
-
-    let s1 = "Hello, Binder!";
-    let s2 = "This is a utf8 string.";
-    let s3 = "Some more text here.";
-    let s4 = "Embedded nulls \0 \0";
-
-    let strs = [s1, s2, s3, s4];
-
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-    assert!(strs.serialize(&mut parcel).is_ok());
-    unsafe {
-        assert!(parcel.set_data_position(start).is_ok());
-    }
-
-    let vec = Vec::<String>::deserialize(&parcel).unwrap();
-
-    assert_eq!(vec, strs);
 }
diff --git a/libs/binder/rust/src/parcel/parcelable_holder.rs b/libs/binder/rust/src/parcel/parcelable_holder.rs
new file mode 100644
index 0000000..b4282b2
--- /dev/null
+++ b/libs/binder/rust/src/parcel/parcelable_holder.rs
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use crate::binder::Stability;
+use crate::error::{Result, StatusCode};
+use crate::parcel::{Parcel, BorrowedParcel, Parcelable};
+use crate::{impl_deserialize_for_parcelable, impl_serialize_for_parcelable};
+
+use downcast_rs::{impl_downcast, DowncastSync};
+use std::any::Any;
+use std::sync::{Arc, Mutex};
+
+/// Metadata that `ParcelableHolder` needs for all parcelables.
+///
+/// The compiler auto-generates implementations of this trait
+/// for AIDL parcelables.
+pub trait ParcelableMetadata {
+    /// The Binder parcelable descriptor string.
+    ///
+    /// This string is a unique identifier for a Binder parcelable.
+    fn get_descriptor() -> &'static str;
+
+    /// The Binder parcelable stability.
+    fn get_stability(&self) -> Stability {
+        Stability::Local
+    }
+}
+
+trait AnyParcelable: DowncastSync + Parcelable + std::fmt::Debug {}
+impl_downcast!(sync AnyParcelable);
+impl<T> AnyParcelable for T where T: DowncastSync + Parcelable + std::fmt::Debug {}
+
+#[derive(Debug, Clone)]
+enum ParcelableHolderData {
+    Empty,
+    Parcelable {
+        parcelable: Arc<dyn AnyParcelable>,
+        name: String,
+    },
+    Parcel(Parcel),
+}
+
+impl Default for ParcelableHolderData {
+    fn default() -> Self {
+        ParcelableHolderData::Empty
+    }
+}
+
+/// A container that can hold any arbitrary `Parcelable`.
+///
+/// This type is currently used for AIDL parcelable fields.
+///
+/// `ParcelableHolder` is currently not thread-safe (neither
+/// `Send` nor `Sync`), mainly because it internally contains
+/// a `Parcel` which in turn is not thread-safe.
+#[derive(Debug, Default)]
+pub struct ParcelableHolder {
+    // This is a `Mutex` because of `get_parcelable`
+    // which takes `&self` for consistency with C++.
+    // We could make `get_parcelable` take a `&mut self`
+    // and get rid of the `Mutex` here for a performance
+    // improvement, but then callers would require a mutable
+    // `ParcelableHolder` even for that getter method.
+    data: Mutex<ParcelableHolderData>,
+    stability: Stability,
+}
+
+impl ParcelableHolder {
+    /// Construct a new `ParcelableHolder` with the given stability.
+    pub fn new(stability: Stability) -> Self {
+        Self {
+            data: Mutex::new(ParcelableHolderData::Empty),
+            stability,
+        }
+    }
+
+    /// Reset the contents of this `ParcelableHolder`.
+    ///
+    /// Note that this method does not reset the stability,
+    /// only the contents.
+    pub fn reset(&mut self) {
+        *self.data.get_mut().unwrap() = ParcelableHolderData::Empty;
+        // We could also clear stability here, but C++ doesn't
+    }
+
+    /// Set the parcelable contained in this `ParcelableHolder`.
+    pub fn set_parcelable<T>(&mut self, p: Arc<T>) -> Result<()>
+    where
+        T: Any + Parcelable + ParcelableMetadata + std::fmt::Debug + Send + Sync,
+    {
+        if self.stability > p.get_stability() {
+            return Err(StatusCode::BAD_VALUE);
+        }
+
+        *self.data.get_mut().unwrap() = ParcelableHolderData::Parcelable {
+            parcelable: p,
+            name: T::get_descriptor().into(),
+        };
+
+        Ok(())
+    }
+
+    /// Retrieve the parcelable stored in this `ParcelableHolder`.
+    ///
+    /// This method attempts to retrieve the parcelable inside
+    /// the current object as a parcelable of type `T`.
+    /// The object is validated against `T` by checking that
+    /// its parcelable descriptor matches the one returned
+    /// by `T::get_descriptor()`.
+    ///
+    /// Returns one of the following:
+    /// * `Err(_)` in case of error
+    /// * `Ok(None)` if the holder is empty or the descriptor does not match
+    /// * `Ok(Some(_))` if the object holds a parcelable of type `T`
+    ///   with the correct descriptor
+    pub fn get_parcelable<T>(&self) -> Result<Option<Arc<T>>>
+    where
+        T: Any + Parcelable + ParcelableMetadata + Default + std::fmt::Debug + Send + Sync,
+    {
+        let parcelable_desc = T::get_descriptor();
+        let mut data = self.data.lock().unwrap();
+        match *data {
+            ParcelableHolderData::Empty => Ok(None),
+            ParcelableHolderData::Parcelable {
+                ref parcelable,
+                ref name,
+            } => {
+                if name != parcelable_desc {
+                    return Err(StatusCode::BAD_VALUE);
+                }
+
+                match Arc::clone(parcelable).downcast_arc::<T>() {
+                    Err(_) => Err(StatusCode::BAD_VALUE),
+                    Ok(x) => Ok(Some(x)),
+                }
+            }
+            ParcelableHolderData::Parcel(ref mut parcel) => {
+                unsafe {
+                    // Safety: 0 should always be a valid position.
+                    parcel.set_data_position(0)?;
+                }
+
+                let name: String = parcel.read()?;
+                if name != parcelable_desc {
+                    return Ok(None);
+                }
+
+                let mut parcelable = T::default();
+                parcelable.read_from_parcel(parcel.borrowed_ref())?;
+
+                let parcelable = Arc::new(parcelable);
+                let result = Arc::clone(&parcelable);
+                *data = ParcelableHolderData::Parcelable { parcelable, name };
+
+                Ok(Some(result))
+            }
+        }
+    }
+
+    /// Return the stability value of this object.
+    pub fn get_stability(&self) -> Stability {
+        self.stability
+    }
+}
+
+impl_serialize_for_parcelable!(ParcelableHolder);
+impl_deserialize_for_parcelable!(ParcelableHolder);
+
+impl Parcelable for ParcelableHolder {
+    fn write_to_parcel(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
+        parcel.write(&self.stability)?;
+
+        let mut data = self.data.lock().unwrap();
+        match *data {
+            ParcelableHolderData::Empty => parcel.write(&0i32),
+            ParcelableHolderData::Parcelable {
+                ref parcelable,
+                ref name,
+            } => {
+                let length_start = parcel.get_data_position();
+                parcel.write(&0i32)?;
+
+                let data_start = parcel.get_data_position();
+                parcel.write(name)?;
+                parcelable.write_to_parcel(parcel)?;
+
+                let end = parcel.get_data_position();
+                unsafe {
+                    // Safety: we got the position from `get_data_position`.
+                    parcel.set_data_position(length_start)?;
+                }
+
+                assert!(end >= data_start);
+                parcel.write(&(end - data_start))?;
+                unsafe {
+                    // Safety: we got the position from `get_data_position`.
+                    parcel.set_data_position(end)?;
+                }
+
+                Ok(())
+            }
+            ParcelableHolderData::Parcel(ref mut p) => {
+                parcel.write(&p.get_data_size())?;
+                parcel.append_all_from(&*p)
+            }
+        }
+    }
+
+    fn read_from_parcel(&mut self, parcel: &BorrowedParcel<'_>) -> Result<()> {
+        self.stability = parcel.read()?;
+
+        let data_size: i32 = parcel.read()?;
+        if data_size < 0 {
+            // C++ returns BAD_VALUE here,
+            // while Java returns ILLEGAL_ARGUMENT
+            return Err(StatusCode::BAD_VALUE);
+        }
+        if data_size == 0 {
+            *self.data.get_mut().unwrap() = ParcelableHolderData::Empty;
+            return Ok(());
+        }
+
+        // TODO: C++ ParcelableHolder accepts sizes up to SIZE_MAX here, but we
+        // only go up to i32::MAX because that's what our API uses everywhere
+        let data_start = parcel.get_data_position();
+        let data_end = data_start
+            .checked_add(data_size)
+            .ok_or(StatusCode::BAD_VALUE)?;
+
+        let mut new_parcel = Parcel::new();
+        new_parcel.append_from(parcel, data_start, data_size)?;
+        *self.data.get_mut().unwrap() = ParcelableHolderData::Parcel(new_parcel);
+
+        unsafe {
+            // Safety: `append_from` checks if `data_size` overflows
+            // `parcel` and returns `BAD_VALUE` if that happens. We also
+            // explicitly check for negative and zero `data_size` above,
+            // so `data_end` is guaranteed to be greater than `data_start`.
+            parcel.set_data_position(data_end)?;
+        }
+
+        Ok(())
+    }
+}
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index 52036f5..760d862 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -22,8 +22,7 @@
 };
 use crate::error::{status_result, Result, StatusCode};
 use crate::parcel::{
-    Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize, SerializeArray,
-    SerializeOption,
+    Parcel, BorrowedParcel, Deserialize, DeserializeArray, DeserializeOption, Serialize, SerializeArray, SerializeOption,
 };
 use crate::sys;
 
@@ -31,14 +30,16 @@
 use std::convert::TryInto;
 use std::ffi::{c_void, CString};
 use std::fmt;
+use std::mem;
 use std::os::unix::io::AsRawFd;
 use std::ptr;
+use std::sync::Arc;
 
 /// A strong reference to a Binder remote object.
 ///
 /// This struct encapsulates the generic C++ `sp<IBinder>` class. This wrapper
 /// is untyped; typed interface access is implemented by the AIDL compiler.
-pub struct SpIBinder(*mut sys::AIBinder);
+pub struct SpIBinder(ptr::NonNull<sys::AIBinder>);
 
 impl fmt::Debug for SpIBinder {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -48,9 +49,14 @@
 
 /// # Safety
 ///
-/// An `SpIBinder` is a handle to a C++ IBinder, which is thread-safe
+/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
 unsafe impl Send for SpIBinder {}
 
+/// # Safety
+///
+/// An `SpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe
+unsafe impl Sync for SpIBinder {}
+
 impl SpIBinder {
     /// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer.
     ///
@@ -69,7 +75,7 @@
     /// to an `AIBinder`, which will remain valid for the entire lifetime of the
     /// `SpIBinder` (we keep a strong reference, and only decrement on drop).
     pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> {
-        ptr.as_mut().map(|p| Self(p))
+        ptr::NonNull::new(ptr).map(Self)
     }
 
     /// Extract a raw `AIBinder` pointer from this wrapper.
@@ -83,7 +89,7 @@
     /// The SpIBinder object retains ownership of the AIBinder and the caller
     /// should not attempt to free the returned pointer.
     pub unsafe fn as_raw(&self) -> *mut sys::AIBinder {
-        self.0
+        self.0.as_ptr()
     }
 
     /// Return true if this binder object is hosted in a different process than
@@ -125,6 +131,21 @@
     }
 }
 
+pub mod unstable_api {
+    use super::{sys, SpIBinder};
+
+    /// A temporary API to allow the client to create a `SpIBinder` from a `sys::AIBinder`. This is
+    /// needed to bridge RPC binder, which doesn't have Rust API yet.
+    /// TODO(b/184872979): remove once the Rust API is created.
+    ///
+    /// # Safety
+    ///
+    /// See `SpIBinder::from_raw`.
+    pub unsafe fn new_spibinder(ptr: *mut sys::AIBinder) -> Option<SpIBinder> {
+        SpIBinder::from_raw(ptr)
+    }
+}
+
 /// An object that can be associate with an [`InterfaceClass`].
 pub trait AssociateClass {
     /// Check if this object is a valid object for the given interface class
@@ -156,13 +177,13 @@
             // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
             // this pointer is always safe to pass to `AIBinder_lt` (null is
             // also safe to pass to this function, but we should never do that).
-            sys::AIBinder_lt(self.0, other.0)
+            sys::AIBinder_lt(self.0.as_ptr(), other.0.as_ptr())
         };
         let greater_than = unsafe {
             // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
             // this pointer is always safe to pass to `AIBinder_lt` (null is
             // also safe to pass to this function, but we should never do that).
-            sys::AIBinder_lt(other.0, self.0)
+            sys::AIBinder_lt(other.0.as_ptr(), self.0.as_ptr())
         };
         if !less_than && !greater_than {
             Ordering::Equal
@@ -182,7 +203,7 @@
 
 impl PartialEq for SpIBinder {
     fn eq(&self, other: &Self) -> bool {
-        ptr::eq(self.0, other.0)
+        ptr::eq(self.0.as_ptr(), other.0.as_ptr())
     }
 }
 
@@ -194,7 +215,7 @@
             // Safety: Cloning a strong reference must increment the reference
             // count. We are guaranteed by the `SpIBinder` constructor
             // invariants that `self.0` is always a valid `AIBinder` pointer.
-            sys::AIBinder_incStrong(self.0);
+            sys::AIBinder_incStrong(self.0.as_ptr());
         }
         Self(self.0)
     }
@@ -213,13 +234,7 @@
 }
 
 impl<T: AsNative<sys::AIBinder>> IBinderInternal for T {
-    /// Perform a binder transaction
-    fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
-        &self,
-        code: TransactionCode,
-        flags: TransactionFlags,
-        input_callback: F,
-    ) -> Result<Parcel> {
+    fn prepare_transact(&self) -> Result<Parcel> {
         let mut input = ptr::null_mut();
         let status = unsafe {
             // Safety: `SpIBinder` guarantees that `self` always contains a
@@ -232,14 +247,23 @@
             // pointer, or null.
             sys::AIBinder_prepareTransaction(self.as_native() as *mut sys::AIBinder, &mut input)
         };
+
         status_result(status)?;
-        let mut input = unsafe {
+
+        unsafe {
             // Safety: At this point, `input` is either a valid, owned `AParcel`
-            // pointer, or null. `Parcel::owned` safely handles both cases,
+            // pointer, or null. `OwnedParcel::from_raw` safely handles both cases,
             // taking ownership of the parcel.
-            Parcel::owned(input).ok_or(StatusCode::UNEXPECTED_NULL)?
-        };
-        input_callback(&mut input)?;
+            Parcel::from_raw(input).ok_or(StatusCode::UNEXPECTED_NULL)
+        }
+    }
+
+    fn submit_transact(
+        &self,
+        code: TransactionCode,
+        data: Parcel,
+        flags: TransactionFlags,
+    ) -> Result<Parcel> {
         let mut reply = ptr::null_mut();
         let status = unsafe {
             // Safety: `SpIBinder` guarantees that `self` always contains a
@@ -255,13 +279,13 @@
             // only providing `on_transact` with an immutable reference to
             // `self`.
             //
-            // This call takes ownership of the `input` parcel pointer, and
+            // This call takes ownership of the `data` parcel pointer, and
             // passes ownership of the `reply` out parameter to its caller. It
             // does not affect ownership of the `binder` parameter.
             sys::AIBinder_transact(
                 self.as_native() as *mut sys::AIBinder,
                 code,
-                &mut input.into_raw(),
+                &mut data.into_raw(),
                 &mut reply,
                 flags,
             )
@@ -273,9 +297,8 @@
             // after the call to `AIBinder_transact` above, so we can
             // construct a `Parcel` out of it. `AIBinder_transact` passes
             // ownership of the `reply` parcel to Rust, so we need to
-            // construct an owned variant. `Parcel::owned` takes ownership
-            // of the parcel pointer.
-            Parcel::owned(reply).ok_or(StatusCode::UNEXPECTED_NULL)
+            // construct an owned variant.
+            Parcel::from_raw(reply).ok_or(StatusCode::UNEXPECTED_NULL)
         }
     }
 
@@ -300,6 +323,7 @@
         status_result(status)
     }
 
+    #[cfg(not(android_vndk))]
     fn set_requesting_sid(&mut self, enable: bool) {
         unsafe { sys::AIBinder_setRequestingSid(self.as_native_mut(), enable) };
     }
@@ -358,13 +382,17 @@
             // Safety: `SpIBinder` guarantees that `self` always contains a
             // valid pointer to an `AIBinder`. `recipient` can always be
             // converted into a valid pointer to an
-            // `AIBinder_DeathRecipient`. Any value is safe to pass as the
-            // cookie, although we depend on this value being set by
-            // `get_cookie` when the death recipient callback is called.
+            // `AIBinder_DeathRecipient`.
+            //
+            // The cookie is also the correct pointer, and by calling new_cookie,
+            // we have created a new ref-count to the cookie, which linkToDeath
+            // takes ownership of. Once the DeathRecipient is unlinked for any
+            // reason (including if this call fails), the onUnlinked callback
+            // will consume that ref-count.
             sys::AIBinder_linkToDeath(
                 self.as_native_mut(),
                 recipient.as_native_mut(),
-                recipient.get_cookie(),
+                recipient.new_cookie(),
             )
         })
     }
@@ -387,22 +415,21 @@
 }
 
 impl Serialize for SpIBinder {
-    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+    fn serialize(&self, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         parcel.write_binder(Some(self))
     }
 }
 
 impl SerializeOption for SpIBinder {
-    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+    fn serialize_option(this: Option<&Self>, parcel: &mut BorrowedParcel<'_>) -> Result<()> {
         parcel.write_binder(this)
     }
 }
 
 impl SerializeArray for SpIBinder {}
-impl SerializeArray for Option<&SpIBinder> {}
 
 impl Deserialize for SpIBinder {
-    fn deserialize(parcel: &Parcel) -> Result<SpIBinder> {
+    fn deserialize(parcel: &BorrowedParcel<'_>) -> Result<SpIBinder> {
         parcel
             .read_binder()
             .transpose()
@@ -411,19 +438,18 @@
 }
 
 impl DeserializeOption for SpIBinder {
-    fn deserialize_option(parcel: &Parcel) -> Result<Option<SpIBinder>> {
+    fn deserialize_option(parcel: &BorrowedParcel<'_>) -> Result<Option<SpIBinder>> {
         parcel.read_binder()
     }
 }
 
 impl DeserializeArray for SpIBinder {}
-impl DeserializeArray for Option<SpIBinder> {}
 
 /// A weak reference to a Binder remote object.
 ///
 /// This struct encapsulates the generic C++ `wp<IBinder>` class. This wrapper
 /// is untyped; typed interface access is implemented by the AIDL compiler.
-pub struct WpIBinder(*mut sys::AIBinder_Weak);
+pub struct WpIBinder(ptr::NonNull<sys::AIBinder_Weak>);
 
 impl fmt::Debug for WpIBinder {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -433,9 +459,14 @@
 
 /// # Safety
 ///
-/// A `WpIBinder` is a handle to a C++ IBinder, which is thread-safe.
+/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
 unsafe impl Send for WpIBinder {}
 
+/// # Safety
+///
+/// A `WpIBinder` is an immutable handle to a C++ IBinder, which is thread-safe.
+unsafe impl Sync for WpIBinder {}
+
 impl WpIBinder {
     /// Create a new weak reference from an object that can be converted into a
     /// raw `AIBinder` pointer.
@@ -445,8 +476,7 @@
             // valid pointer to an `AIBinder`.
             sys::AIBinder_Weak_new(binder.as_native_mut())
         };
-        assert!(!ptr.is_null());
-        Self(ptr)
+        Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_new"))
     }
 
     /// Promote this weak reference to a strong reference to the binder object.
@@ -456,7 +486,7 @@
             // can pass this pointer to `AIBinder_Weak_promote`. Returns either
             // null or an AIBinder owned by the caller, both of which are valid
             // to pass to `SpIBinder::from_raw`.
-            let ptr = sys::AIBinder_Weak_promote(self.0);
+            let ptr = sys::AIBinder_Weak_promote(self.0.as_ptr());
             SpIBinder::from_raw(ptr)
         }
     }
@@ -471,13 +501,9 @@
             //
             // We get ownership of the returned pointer, so can construct a new
             // WpIBinder object from it.
-            sys::AIBinder_Weak_clone(self.0)
+            sys::AIBinder_Weak_clone(self.0.as_ptr())
         };
-        assert!(
-            !ptr.is_null(),
-            "Unexpected null pointer from AIBinder_Weak_clone"
-        );
-        Self(ptr)
+        Self(ptr::NonNull::new(ptr).expect("Unexpected null pointer from AIBinder_Weak_clone"))
     }
 }
 
@@ -488,14 +514,14 @@
             // so this pointer is always safe to pass to `AIBinder_Weak_lt`
             // (null is also safe to pass to this function, but we should never
             // do that).
-            sys::AIBinder_Weak_lt(self.0, other.0)
+            sys::AIBinder_Weak_lt(self.0.as_ptr(), other.0.as_ptr())
         };
         let greater_than = unsafe {
             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
             // so this pointer is always safe to pass to `AIBinder_Weak_lt`
             // (null is also safe to pass to this function, but we should never
             // do that).
-            sys::AIBinder_Weak_lt(other.0, self.0)
+            sys::AIBinder_Weak_lt(other.0.as_ptr(), self.0.as_ptr())
         };
         if !less_than && !greater_than {
             Ordering::Equal
@@ -526,16 +552,26 @@
         unsafe {
             // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer, so we
             // know this pointer is safe to pass to `AIBinder_Weak_delete` here.
-            sys::AIBinder_Weak_delete(self.0);
+            sys::AIBinder_Weak_delete(self.0.as_ptr());
         }
     }
 }
 
 /// Rust wrapper around DeathRecipient objects.
+///
+/// The cookie in this struct represents an Arc<F> for the owned callback.
+/// This struct owns a ref-count of it, and so does every binder that we
+/// have been linked with.
 #[repr(C)]
 pub struct DeathRecipient {
     recipient: *mut sys::AIBinder_DeathRecipient,
-    callback: Box<dyn Fn() + Send + 'static>,
+    cookie: *mut c_void,
+    vtable: &'static DeathRecipientVtable,
+}
+
+struct DeathRecipientVtable {
+    cookie_incr_refcount: unsafe extern "C" fn(*mut c_void),
+    cookie_decr_refcount: unsafe extern "C" fn(*mut c_void),
 }
 
 impl DeathRecipient {
@@ -543,9 +579,9 @@
     /// associated object dies.
     pub fn new<F>(callback: F) -> DeathRecipient
     where
-        F: Fn() + Send + 'static,
+        F: Fn() + Send + Sync + 'static,
     {
-        let callback = Box::new(callback);
+        let callback: *const F = Arc::into_raw(Arc::new(callback));
         let recipient = unsafe {
             // Safety: The function pointer is a valid death recipient callback.
             //
@@ -554,34 +590,85 @@
             // no longer needed.
             sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>))
         };
+        unsafe {
+            // Safety: The function pointer is a valid onUnlinked callback.
+            //
+            // All uses of linkToDeath in this file correctly increment the
+            // ref-count that this onUnlinked callback will decrement.
+            sys::AIBinder_DeathRecipient_setOnUnlinked(recipient, Some(Self::cookie_decr_refcount::<F>));
+        }
         DeathRecipient {
             recipient,
-            callback,
+            cookie: callback as *mut c_void,
+            vtable: &DeathRecipientVtable {
+                cookie_incr_refcount: Self::cookie_incr_refcount::<F>,
+                cookie_decr_refcount: Self::cookie_decr_refcount::<F>,
+            },
         }
     }
 
+    /// Increment the ref-count for the cookie and return it.
+    ///
+    /// # Safety
+    ///
+    /// The caller must handle the returned ref-count correctly.
+    unsafe fn new_cookie(&self) -> *mut c_void {
+        (self.vtable.cookie_incr_refcount)(self.cookie);
+
+        // Return a raw pointer with ownership of a ref-count
+        self.cookie
+    }
+
     /// Get the opaque cookie that identifies this death recipient.
     ///
     /// This cookie will be used to link and unlink this death recipient to a
     /// binder object and will be passed to the `binder_died` callback as an
     /// opaque userdata pointer.
     fn get_cookie(&self) -> *mut c_void {
-        &*self.callback as *const _ as *mut c_void
+        self.cookie
     }
 
     /// Callback invoked from C++ when the binder object dies.
     ///
     /// # Safety
     ///
-    /// The `cookie` parameter must have been created with the `get_cookie`
-    /// method of this object.
+    /// The `cookie` parameter must be the cookie for an Arc<F> and
+    /// the caller must hold a ref-count to it.
     unsafe extern "C" fn binder_died<F>(cookie: *mut c_void)
     where
-        F: Fn() + Send + 'static,
+        F: Fn() + Send + Sync + 'static,
     {
-        let callback = (cookie as *mut F).as_ref().unwrap();
+        let callback = (cookie as *const F).as_ref().unwrap();
         callback();
     }
+
+    /// Callback that decrements the ref-count.
+    /// This is invoked from C++ when a binder is unlinked.
+    ///
+    /// # Safety
+    ///
+    /// The `cookie` parameter must be the cookie for an Arc<F> and
+    /// the owner must give up a ref-count to it.
+    unsafe extern "C" fn cookie_decr_refcount<F>(cookie: *mut c_void)
+    where
+        F: Fn() + Send + Sync + 'static,
+    {
+        drop(Arc::from_raw(cookie as *const F));
+    }
+
+    /// Callback that increments the ref-count.
+    ///
+    /// # Safety
+    ///
+    /// The `cookie` parameter must be the cookie for an Arc<F> and
+    /// the owner must handle the created ref-count properly.
+    unsafe extern "C" fn cookie_incr_refcount<F>(cookie: *mut c_void)
+    where
+        F: Fn() + Send + Sync + 'static,
+    {
+        let arc = mem::ManuallyDrop::new(Arc::from_raw(cookie as *const F));
+        mem::forget(Arc::clone(&arc));
+    }
 }
 
 /// # Safety
@@ -607,6 +694,12 @@
             // `AIBinder_DeathRecipient_new` when `self` was created. This
             // delete method can only be called once when `self` is dropped.
             sys::AIBinder_DeathRecipient_delete(self.recipient);
+
+            // Safety: We own a ref-count to the cookie, and so does every
+            // linked binder. This call gives up our ref-count. The linked
+            // binders should already have given up their ref-count, or should
+            // do so shortly.
+            (self.vtable.cookie_decr_refcount)(self.cookie)
         }
     }
 }
@@ -653,6 +746,18 @@
     }
 }
 
+/// Retrieve an existing service, or start it if it is configured as a dynamic
+/// service and isn't yet started.
+pub fn wait_for_service(name: &str) -> Option<SpIBinder> {
+    let name = CString::new(name).ok()?;
+    unsafe {
+        // Safety: `AServiceManager_waitforService` returns either a null
+        // pointer or a valid pointer to an owned `AIBinder`. Either of these
+        // values is safe to pass to `SpIBinder::from_raw`.
+        SpIBinder::from_raw(sys::AServiceManager_waitForService(name.as_ptr()))
+    }
+}
+
 /// Retrieve an existing service for a particular interface, blocking for a few
 /// seconds if it doesn't yet exist.
 pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
@@ -663,16 +768,26 @@
     }
 }
 
+/// Retrieve an existing service for a particular interface, or start it if it
+/// is configured as a dynamic service and isn't yet started.
+pub fn wait_for_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
+    let service = wait_for_service(name);
+    match service {
+        Some(service) => FromIBinder::try_from(service),
+        None => Err(StatusCode::NAME_NOT_FOUND),
+    }
+}
+
 /// # Safety
 ///
 /// `SpIBinder` guarantees that `binder` always contains a valid pointer to an
 /// `AIBinder`, so we can trivially extract this pointer here.
 unsafe impl AsNative<sys::AIBinder> for SpIBinder {
     fn as_native(&self) -> *const sys::AIBinder {
-        self.0
+        self.0.as_ptr()
     }
 
     fn as_native_mut(&mut self) -> *mut sys::AIBinder {
-        self.0
+        self.0.as_ptr()
     }
 }
diff --git a/libs/binder/rust/src/state.rs b/libs/binder/rust/src/state.rs
index 0e05f10..0aef744 100644
--- a/libs/binder/rust/src/state.rs
+++ b/libs/binder/rust/src/state.rs
@@ -99,6 +99,17 @@
         }
     }
 
+    /// Determine whether the current thread is currently executing an incoming transaction.
+    ///
+    /// \return true if the current thread is currently executing an incoming transaction, and false
+    /// otherwise.
+    pub fn is_handling_transaction() -> bool {
+        unsafe {
+            // Safety: Safe FFI
+            sys::AIBinder_isHandlingTransaction()
+        }
+    }
+
     /// This function makes the client's security context available to the
     /// service calling this function. This can be used for access control.
     /// It does not suffer from the TOCTOU issues of get_calling_pid.
diff --git a/libs/binder/rust/tests/Android.bp b/libs/binder/rust/tests/Android.bp
index 607860f..2d1175b 100644
--- a/libs/binder/rust/tests/Android.bp
+++ b/libs/binder/rust/tests/Android.bp
@@ -13,6 +13,8 @@
     rustlibs: [
         "libbinder_rs",
         "libselinux_bindgen",
+        "libbinder_tokio_rs",
+        "libtokio",
     ],
     shared_libs: [
         "libselinux",
@@ -50,7 +52,7 @@
         "libbinder_ndk",
     ],
     static_libs: [
-        "IBinderRustNdkInteropTest-ndk_platform",
+        "IBinderRustNdkInteropTest-ndk",
         "libbinder_ndk_rust_interop",
     ],
     test_suites: ["general-tests"],
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index 0332007..1fd2ead 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -17,12 +17,15 @@
 //! Rust Binder crate integration tests
 
 use binder::declare_binder_interface;
-use binder::parcel::Parcel;
+use binder::parcel::BorrowedParcel;
 use binder::{
     Binder, BinderFeatures, IBinderInternal, Interface, StatusCode, ThreadState, TransactionCode,
     FIRST_CALL_TRANSACTION,
 };
 use std::convert::{TryFrom, TryInto};
+use std::ffi::CStr;
+use std::fs::File;
+use std::sync::Mutex;
 
 /// Name of service runner.
 ///
@@ -50,13 +53,11 @@
     let extension_name = args.next();
 
     {
-        let mut service = Binder::new(BnTest(Box::new(TestService {
-            s: service_name.clone(),
-        })));
+        let mut service = Binder::new(BnTest(Box::new(TestService::new(&service_name))));
         service.set_requesting_sid(true);
         if let Some(extension_name) = extension_name {
             let extension =
-                BnTest::new_binder(TestService { s: extension_name }, BinderFeatures::default());
+                BnTest::new_binder(TestService::new(&extension_name), BinderFeatures::default());
             service
                 .set_extension(&mut extension.as_binder())
                 .expect("Could not add extension");
@@ -80,14 +81,24 @@
     ));
 }
 
-#[derive(Clone)]
 struct TestService {
     s: String,
+    dump_args: Mutex<Vec<String>>,
+}
+
+impl TestService {
+    fn new(s: &str) -> Self {
+        Self {
+            s: s.to_string(),
+            dump_args: Mutex::new(Vec::new()),
+        }
+    }
 }
 
 #[repr(u32)]
 enum TestTransactionCode {
     Test = FIRST_CALL_TRANSACTION,
+    GetDumpArgs,
     GetSelinuxContext,
 }
 
@@ -97,6 +108,7 @@
     fn try_from(c: u32) -> Result<Self, Self::Error> {
         match c {
             _ if c == TestTransactionCode::Test as u32 => Ok(TestTransactionCode::Test),
+            _ if c == TestTransactionCode::GetDumpArgs as u32 => Ok(TestTransactionCode::GetDumpArgs),
             _ if c == TestTransactionCode::GetSelinuxContext as u32 => {
                 Ok(TestTransactionCode::GetSelinuxContext)
             }
@@ -105,13 +117,24 @@
     }
 }
 
-impl Interface for TestService {}
+impl Interface for TestService {
+    fn dump(&self, _file: &File, args: &[&CStr]) -> binder::Result<()> {
+        let mut dump_args = self.dump_args.lock().unwrap();
+        dump_args.extend(args.iter().map(|s| s.to_str().unwrap().to_owned()));
+        Ok(())
+    }
+}
 
 impl ITest for TestService {
     fn test(&self) -> binder::Result<String> {
         Ok(self.s.clone())
     }
 
+    fn get_dump_args(&self) -> binder::Result<Vec<String>> {
+        let args = self.dump_args.lock().unwrap().clone();
+        Ok(args)
+    }
+
     fn get_selinux_context(&self) -> binder::Result<String> {
         let sid =
             ThreadState::with_calling_sid(|sid| sid.map(|s| s.to_string_lossy().into_owned()));
@@ -124,27 +147,44 @@
     /// Returns a test string
     fn test(&self) -> binder::Result<String>;
 
+    /// Return the arguments sent via dump
+    fn get_dump_args(&self) -> binder::Result<Vec<String>>;
+
     /// Returns the caller's SELinux context
     fn get_selinux_context(&self) -> binder::Result<String>;
 }
 
+/// Async trivial testing binder interface
+pub trait IATest<P>: Interface {
+    /// Returns a test string
+    fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>>;
+
+    /// Return the arguments sent via dump
+    fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>>;
+
+    /// Returns the caller's SELinux context
+    fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>>;
+}
+
 declare_binder_interface! {
     ITest["android.os.ITest"] {
         native: BnTest(on_transact),
         proxy: BpTest {
             x: i32 = 100
         },
+        async: IATest,
     }
 }
 
 fn on_transact(
     service: &dyn ITest,
     code: TransactionCode,
-    _data: &Parcel,
-    reply: &mut Parcel,
+    _data: &BorrowedParcel<'_>,
+    reply: &mut BorrowedParcel<'_>,
 ) -> binder::Result<()> {
     match code.try_into()? {
         TestTransactionCode::Test => reply.write(&service.test()?),
+        TestTransactionCode::GetDumpArgs => reply.write(&service.get_dump_args()?),
         TestTransactionCode::GetSelinuxContext => reply.write(&service.get_selinux_context()?),
     }
 }
@@ -157,6 +197,13 @@
         reply.read()
     }
 
+    fn get_dump_args(&self) -> binder::Result<Vec<String>> {
+        let reply =
+            self.binder
+                .transact(TestTransactionCode::GetDumpArgs as TransactionCode, 0, |_| Ok(()))?;
+        reply.read()
+    }
+
     fn get_selinux_context(&self) -> binder::Result<String> {
         let reply = self.binder.transact(
             TestTransactionCode::GetSelinuxContext as TransactionCode,
@@ -167,16 +214,63 @@
     }
 }
 
+impl<P: binder::BinderAsyncPool> IATest<P> for BpTest {
+    fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
+        let binder = self.binder.clone();
+        P::spawn(
+            move || binder.transact(TestTransactionCode::Test as TransactionCode, 0, |_| Ok(())),
+            |reply| async move { reply?.read() }
+        )
+    }
+
+    fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>> {
+        let binder = self.binder.clone();
+        P::spawn(
+            move || binder.transact(TestTransactionCode::GetDumpArgs as TransactionCode, 0, |_| Ok(())),
+            |reply| async move { reply?.read() }
+        )
+    }
+
+    fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
+        let binder = self.binder.clone();
+        P::spawn(
+            move || binder.transact(TestTransactionCode::GetSelinuxContext as TransactionCode, 0, |_| Ok(())),
+            |reply| async move { reply?.read() }
+        )
+    }
+}
+
 impl ITest for Binder<BnTest> {
     fn test(&self) -> binder::Result<String> {
         self.0.test()
     }
 
+    fn get_dump_args(&self) -> binder::Result<Vec<String>> {
+        self.0.get_dump_args()
+    }
+
     fn get_selinux_context(&self) -> binder::Result<String> {
         self.0.get_selinux_context()
     }
 }
 
+impl<P: binder::BinderAsyncPool> IATest<P> for Binder<BnTest> {
+    fn test(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
+        let res = self.0.test();
+        Box::pin(async move { res })
+    }
+
+    fn get_dump_args(&self) -> binder::BoxFuture<'static, binder::Result<Vec<String>>> {
+        let res = self.0.get_dump_args();
+        Box::pin(async move { res })
+    }
+
+    fn get_selinux_context(&self) -> binder::BoxFuture<'static, binder::Result<String>> {
+        let res = self.0.get_selinux_context();
+        Box::pin(async move { res })
+    }
+}
+
 /// Trivial testing binder interface
 pub trait ITestSameDescriptor: Interface {}
 
@@ -190,8 +284,8 @@
 fn on_transact_same_descriptor(
     _service: &dyn ITestSameDescriptor,
     _code: TransactionCode,
-    _data: &Parcel,
-    _reply: &mut Parcel,
+    _data: &BorrowedParcel<'_>,
+    _reply: &mut BorrowedParcel<'_>,
 ) -> binder::Result<()> {
     Ok(())
 }
@@ -217,7 +311,9 @@
         SpIBinder, StatusCode, Strong,
     };
 
-    use super::{BnTest, ITest, ITestSameDescriptor, TestService, RUST_SERVICE_BINARY};
+    use binder_tokio::Tokio;
+
+    use super::{BnTest, ITest, IATest, ITestSameDescriptor, TestService, RUST_SERVICE_BINARY};
 
     pub struct ScopedServiceProcess(Child);
 
@@ -265,12 +361,65 @@
             binder::get_interface::<dyn ITest>("this_service_does_not_exist").err(),
             Some(StatusCode::NAME_NOT_FOUND)
         );
+        assert_eq!(
+            binder::get_interface::<dyn IATest<Tokio>>("this_service_does_not_exist").err(),
+            Some(StatusCode::NAME_NOT_FOUND)
+        );
 
         // The service manager service isn't an ITest, so this must fail.
         assert_eq!(
             binder::get_interface::<dyn ITest>("manager").err(),
             Some(StatusCode::BAD_TYPE)
         );
+        assert_eq!(
+            binder::get_interface::<dyn IATest<Tokio>>("manager").err(),
+            Some(StatusCode::BAD_TYPE)
+        );
+    }
+
+    #[tokio::test]
+    async fn check_services_async() {
+        let mut sm = binder::get_service("manager").expect("Did not get manager binder service");
+        assert!(sm.is_binder_alive());
+        assert!(sm.ping_binder().is_ok());
+
+        assert!(binder::get_service("this_service_does_not_exist").is_none());
+        assert_eq!(
+            binder_tokio::get_interface::<dyn ITest>("this_service_does_not_exist").await.err(),
+            Some(StatusCode::NAME_NOT_FOUND)
+        );
+        assert_eq!(
+            binder_tokio::get_interface::<dyn IATest<Tokio>>("this_service_does_not_exist").await.err(),
+            Some(StatusCode::NAME_NOT_FOUND)
+        );
+
+        // The service manager service isn't an ITest, so this must fail.
+        assert_eq!(
+            binder_tokio::get_interface::<dyn ITest>("manager").await.err(),
+            Some(StatusCode::BAD_TYPE)
+        );
+        assert_eq!(
+            binder_tokio::get_interface::<dyn IATest<Tokio>>("manager").await.err(),
+            Some(StatusCode::BAD_TYPE)
+        );
+    }
+
+    #[test]
+    fn check_wait_for_service() {
+        let mut sm =
+            binder::wait_for_service("manager").expect("Did not get manager binder service");
+        assert!(sm.is_binder_alive());
+        assert!(sm.ping_binder().is_ok());
+
+        // The service manager service isn't an ITest, so this must fail.
+        assert_eq!(
+            binder::wait_for_interface::<dyn ITest>("manager").err(),
+            Some(StatusCode::BAD_TYPE)
+        );
+        assert_eq!(
+            binder::wait_for_interface::<dyn IATest<Tokio>>("manager").err(),
+            Some(StatusCode::BAD_TYPE)
+        );
     }
 
     #[test]
@@ -282,33 +431,120 @@
         assert_eq!(test_client.test().unwrap(), "trivial_client_test");
     }
 
+    #[tokio::test]
+    async fn trivial_client_async() {
+        let service_name = "trivial_client_test";
+        let _process = ScopedServiceProcess::new(service_name);
+        let test_client: Strong<dyn IATest<Tokio>> =
+            binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service");
+        assert_eq!(test_client.test().await.unwrap(), "trivial_client_test");
+    }
+
+    #[test]
+    fn wait_for_trivial_client() {
+        let service_name = "wait_for_trivial_client_test";
+        let _process = ScopedServiceProcess::new(service_name);
+        let test_client: Strong<dyn ITest> =
+            binder::wait_for_interface(service_name).expect("Did not get manager binder service");
+        assert_eq!(test_client.test().unwrap(), "wait_for_trivial_client_test");
+    }
+
+    #[tokio::test]
+    async fn wait_for_trivial_client_async() {
+        let service_name = "wait_for_trivial_client_test";
+        let _process = ScopedServiceProcess::new(service_name);
+        let test_client: Strong<dyn IATest<Tokio>> =
+            binder_tokio::wait_for_interface(service_name).await.expect("Did not get manager binder service");
+        assert_eq!(test_client.test().await.unwrap(), "wait_for_trivial_client_test");
+    }
+
+    fn get_expected_selinux_context() -> &'static str {
+        unsafe {
+            let mut out_ptr = ptr::null_mut();
+            assert_eq!(selinux_sys::getcon(&mut out_ptr), 0);
+            assert!(!out_ptr.is_null());
+            CStr::from_ptr(out_ptr)
+                .to_str()
+                .expect("context was invalid UTF-8")
+        }
+    }
+
     #[test]
     fn get_selinux_context() {
         let service_name = "get_selinux_context";
         let _process = ScopedServiceProcess::new(service_name);
         let test_client: Strong<dyn ITest> =
             binder::get_interface(service_name).expect("Did not get manager binder service");
-        let expected_context = unsafe {
-            let mut out_ptr = ptr::null_mut();
-            assert_eq!(selinux_sys::getcon(&mut out_ptr), 0);
-            assert!(!out_ptr.is_null());
-            CStr::from_ptr(out_ptr)
-        };
         assert_eq!(
             test_client.get_selinux_context().unwrap(),
-            expected_context
-                .to_str()
-                .expect("context was invalid UTF-8"),
+            get_expected_selinux_context()
         );
     }
 
-    fn register_death_notification(binder: &mut SpIBinder) -> (Arc<AtomicBool>, DeathRecipient) {
+    #[tokio::test]
+    async fn get_selinux_context_async() {
+        let service_name = "get_selinux_context";
+        let _process = ScopedServiceProcess::new(service_name);
+        let test_client: Strong<dyn IATest<Tokio>> =
+            binder_tokio::get_interface(service_name).await.expect("Did not get manager binder service");
+        assert_eq!(
+            test_client.get_selinux_context().await.unwrap(),
+            get_expected_selinux_context()
+        );
+    }
+
+    struct Bools {
+        binder_died: Arc<AtomicBool>,
+        binder_dealloc: Arc<AtomicBool>,
+    }
+
+    impl Bools {
+        fn is_dead(&self) -> bool {
+            self.binder_died.load(Ordering::Relaxed)
+        }
+        fn assert_died(&self) {
+            assert!(
+                self.is_dead(),
+                "Did not receive death notification"
+            );
+        }
+        fn assert_dropped(&self) {
+            assert!(
+                self.binder_dealloc.load(Ordering::Relaxed),
+                "Did not dealloc death notification"
+            );
+        }
+        fn assert_not_dropped(&self) {
+            assert!(
+                !self.binder_dealloc.load(Ordering::Relaxed),
+                "Dealloc death notification too early"
+            );
+        }
+    }
+
+    fn register_death_notification(binder: &mut SpIBinder) -> (Bools, DeathRecipient) {
         let binder_died = Arc::new(AtomicBool::new(false));
+        let binder_dealloc = Arc::new(AtomicBool::new(false));
+
+        struct SetOnDrop {
+            binder_dealloc: Arc<AtomicBool>,
+        }
+        impl Drop for SetOnDrop {
+            fn drop(&mut self) {
+                self.binder_dealloc.store(true, Ordering::Relaxed);
+            }
+        }
 
         let mut death_recipient = {
             let flag = binder_died.clone();
+            let set_on_drop = SetOnDrop {
+                binder_dealloc: binder_dealloc.clone(),
+            };
             DeathRecipient::new(move || {
                 flag.store(true, Ordering::Relaxed);
+                // Force the closure to take ownership of set_on_drop. When the closure is
+                // dropped, the destructor of `set_on_drop` will run.
+                let _ = &set_on_drop;
             })
         };
 
@@ -316,7 +552,12 @@
             .link_to_death(&mut death_recipient)
             .expect("link_to_death failed");
 
-        (binder_died, death_recipient)
+        let bools = Bools {
+            binder_died,
+            binder_dealloc,
+        };
+
+        (bools, death_recipient)
     }
 
     /// Killing a remote service should unregister the service and trigger
@@ -329,7 +570,7 @@
         let service_process = ScopedServiceProcess::new(service_name);
         let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
 
-        let (binder_died, _recipient) = register_death_notification(&mut remote);
+        let (bools, recipient) = register_death_notification(&mut remote);
 
         drop(service_process);
         remote
@@ -339,10 +580,12 @@
         // Pause to ensure any death notifications get delivered
         thread::sleep(Duration::from_secs(1));
 
-        assert!(
-            binder_died.load(Ordering::Relaxed),
-            "Did not receive death notification"
-        );
+        bools.assert_died();
+        bools.assert_not_dropped();
+
+        drop(recipient);
+
+        bools.assert_dropped();
     }
 
     /// Test unregistering death notifications.
@@ -354,7 +597,7 @@
         let service_process = ScopedServiceProcess::new(service_name);
         let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
 
-        let (binder_died, mut recipient) = register_death_notification(&mut remote);
+        let (bools, mut recipient) = register_death_notification(&mut remote);
 
         remote
             .unlink_to_death(&mut recipient)
@@ -369,9 +612,13 @@
         thread::sleep(Duration::from_secs(1));
 
         assert!(
-            !binder_died.load(Ordering::Relaxed),
+            !bools.is_dead(),
             "Received unexpected death notification after unlinking",
         );
+
+        bools.assert_not_dropped();
+        drop(recipient);
+        bools.assert_dropped();
     }
 
     /// Dropping a remote handle should unregister any death notifications.
@@ -383,7 +630,7 @@
         let service_process = ScopedServiceProcess::new(service_name);
         let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
 
-        let (binder_died, _recipient) = register_death_notification(&mut remote);
+        let (bools, recipient) = register_death_notification(&mut remote);
 
         // This should automatically unregister our death notification.
         drop(remote);
@@ -396,9 +643,13 @@
         // We dropped the remote handle, so we should not receive the death
         // notification when the remote process dies here.
         assert!(
-            !binder_died.load(Ordering::Relaxed),
+            !bools.is_dead(),
             "Received unexpected death notification after dropping remote handle"
         );
+
+        bools.assert_not_dropped();
+        drop(recipient);
+        bools.assert_dropped();
     }
 
     /// Test IBinder interface methods not exercised elsewhere.
@@ -409,18 +660,22 @@
         {
             let _process = ScopedServiceProcess::new(service_name);
 
-            let mut remote = binder::get_service(service_name);
+            let test_client: Strong<dyn ITest> =
+                binder::get_interface(service_name)
+                .expect("Did not get test binder service");
+            let mut remote = test_client.as_binder();
             assert!(remote.is_binder_alive());
             remote.ping_binder().expect("Could not ping remote service");
 
-            // We're not testing the output of dump here, as that's really a
-            // property of the C++ implementation. There is the risk that the
-            // method just does nothing, but we don't want to depend on any
-            // particular output from the underlying library.
+            let dump_args = ["dump", "args", "for", "testing"];
+
             let null_out = File::open("/dev/null").expect("Could not open /dev/null");
             remote
-                .dump(&null_out, &[])
+                .dump(&null_out, &dump_args)
                 .expect("Could not dump remote service");
+
+            let remote_args = test_client.get_dump_args().expect("Could not fetched dumped args");
+            assert_eq!(dump_args, remote_args[..], "Remote args don't match call to dump");
         }
 
         // get/set_extensions is tested in test_extensions()
@@ -481,9 +736,7 @@
     /// rust_ndk_interop.rs
     #[test]
     fn associate_existing_class() {
-        let service = Binder::new(BnTest(Box::new(TestService {
-            s: "testing_service".to_string(),
-        })));
+        let service = Binder::new(BnTest(Box::new(TestService::new("testing_service"))));
 
         // This should succeed although we will have to treat the service as
         // remote.
@@ -497,9 +750,7 @@
     fn reassociate_rust_binder() {
         let service_name = "testing_service";
         let service_ibinder = BnTest::new_binder(
-            TestService {
-                s: service_name.to_string(),
-            },
+            TestService::new(service_name),
             BinderFeatures::default(),
         )
         .as_binder();
@@ -515,9 +766,7 @@
     fn weak_binder_upgrade() {
         let service_name = "testing_service";
         let service = BnTest::new_binder(
-            TestService {
-                s: service_name.to_string(),
-            },
+            TestService::new(service_name),
             BinderFeatures::default(),
         );
 
@@ -533,9 +782,7 @@
         let service_name = "testing_service";
         let weak = {
             let service = BnTest::new_binder(
-                TestService {
-                    s: service_name.to_string(),
-                },
+                TestService::new(service_name),
                 BinderFeatures::default(),
             );
 
@@ -549,9 +796,7 @@
     fn weak_binder_clone() {
         let service_name = "testing_service";
         let service = BnTest::new_binder(
-            TestService {
-                s: service_name.to_string(),
-            },
+            TestService::new(service_name),
             BinderFeatures::default(),
         );
 
@@ -570,15 +815,11 @@
     #[allow(clippy::eq_op)]
     fn binder_ord() {
         let service1 = BnTest::new_binder(
-            TestService {
-                s: "testing_service1".to_string(),
-            },
+            TestService::new("testing_service1"),
             BinderFeatures::default(),
         );
         let service2 = BnTest::new_binder(
-            TestService {
-                s: "testing_service2".to_string(),
-            },
+            TestService::new("testing_service2"),
             BinderFeatures::default(),
         );
 
@@ -586,4 +827,27 @@
         assert!(!(service1 > service1));
         assert_eq!(service1 < service2, !(service2 < service1));
     }
+
+    #[test]
+    fn binder_parcel_mixup() {
+        let service1 = BnTest::new_binder(
+            TestService::new("testing_service1"),
+            BinderFeatures::default(),
+        );
+        let service2 = BnTest::new_binder(
+            TestService::new("testing_service2"),
+            BinderFeatures::default(),
+        );
+
+        let service1 = service1.as_binder();
+        let service2 = service2.as_binder();
+
+        let parcel = service1.prepare_transact().unwrap();
+        let res = service2.submit_transact(super::TestTransactionCode::Test as binder::TransactionCode, parcel, 0);
+
+        match res {
+            Ok(_) => panic!("submit_transact should fail"),
+            Err(err) => assert_eq!(err, binder::StatusCode::BAD_VALUE),
+        }
+    }
 }
diff --git a/libs/binder/rust/tests/ndk_rust_interop.rs b/libs/binder/rust/tests/ndk_rust_interop.rs
index 4702e45..415ede1 100644
--- a/libs/binder/rust/tests/ndk_rust_interop.rs
+++ b/libs/binder/rust/tests/ndk_rust_interop.rs
@@ -90,7 +90,7 @@
 pub unsafe extern "C" fn rust_start_service(service_name: *const c_char) -> c_int {
     let service_name = CStr::from_ptr(service_name).to_str().unwrap();
     let service = BnBinderRustNdkInteropTest::new_binder(Service, BinderFeatures::default());
-    match binder::add_service(&service_name, service.as_binder()) {
+    match binder::add_service(service_name, service.as_binder()) {
         Ok(_) => StatusCode::OK as c_int,
         Err(e) => e as c_int,
     }
diff --git a/libs/binder/rust/tests/serialization.rs b/libs/binder/rust/tests/serialization.rs
index 66ba846..1fc761e 100644
--- a/libs/binder/rust/tests/serialization.rs
+++ b/libs/binder/rust/tests/serialization.rs
@@ -20,7 +20,7 @@
 use binder::declare_binder_interface;
 use binder::parcel::ParcelFileDescriptor;
 use binder::{
-    Binder, BinderFeatures, ExceptionCode, Interface, Parcel, Result, SpIBinder, Status,
+    Binder, BinderFeatures, BorrowedParcel, ExceptionCode, Interface, Result, SpIBinder, Status,
     StatusCode, TransactionCode,
 };
 
@@ -111,8 +111,8 @@
 fn on_transact(
     _service: &dyn ReadParcelTest,
     code: TransactionCode,
-    parcel: &Parcel,
-    reply: &mut Parcel,
+    parcel: &BorrowedParcel<'_>,
+    reply: &mut BorrowedParcel<'_>,
 ) -> Result<()> {
     match code {
         bindings::Transaction_TEST_BOOL => {
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
new file mode 100644
index 0000000..777f3c9
--- /dev/null
+++ b/libs/binder/servicedispatcher.cpp
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sysexits.h>
+#include <unistd.h>
+
+#include <iostream>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android/debug/BnAdbCallback.h>
+#include <android/debug/IAdbManager.h>
+#include <android/os/BnServiceManager.h>
+#include <android/os/IServiceManager.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <binder/RpcServer.h>
+
+using android::BBinder;
+using android::defaultServiceManager;
+using android::OK;
+using android::RpcServer;
+using android::sp;
+using android::status_t;
+using android::statusToString;
+using android::String16;
+using android::base::Basename;
+using android::base::GetBoolProperty;
+using android::base::InitLogging;
+using android::base::LogdLogger;
+using android::base::LogId;
+using android::base::LogSeverity;
+using android::base::StdioLogger;
+using android::base::StringPrintf;
+using std::string_view_literals::operator""sv;
+
+namespace {
+
+const char* kLocalInetAddress = "127.0.0.1";
+using ServiceRetriever = decltype(&android::IServiceManager::checkService);
+using android::debug::IAdbManager;
+
+int Usage(const char* program) {
+    auto basename = Basename(program);
+    auto format = R"(dispatch calls to RPC service.
+Usage:
+  %s [-g] <service_name>
+    <service_name>: the service to connect to.
+  %s [-g] manager
+    Runs an RPC-friendly service that redirects calls to servicemanager.
+
+  -g: use getService() instead of checkService().
+
+  If successful, writes port number and a new line character to stdout, and
+  blocks until killed.
+  Otherwise, writes error message to stderr and exits with non-zero code.
+)";
+    LOG(ERROR) << StringPrintf(format, basename.c_str(), basename.c_str());
+    return EX_USAGE;
+}
+
+int Dispatch(const char* name, const ServiceRetriever& serviceRetriever) {
+    auto sm = defaultServiceManager();
+    if (nullptr == sm) {
+        LOG(ERROR) << "No servicemanager";
+        return EX_SOFTWARE;
+    }
+    auto binder = std::invoke(serviceRetriever, defaultServiceManager(), String16(name));
+    if (nullptr == binder) {
+        LOG(ERROR) << "No service \"" << name << "\"";
+        return EX_SOFTWARE;
+    }
+    auto rpcServer = RpcServer::make();
+    if (nullptr == rpcServer) {
+        LOG(ERROR) << "Cannot create RpcServer";
+        return EX_SOFTWARE;
+    }
+    unsigned int port;
+    if (status_t status = rpcServer->setupInetServer(kLocalInetAddress, 0, &port); status != OK) {
+        LOG(ERROR) << "setupInetServer failed: " << statusToString(status);
+        return EX_SOFTWARE;
+    }
+    auto socket = rpcServer->releaseServer();
+    auto keepAliveBinder = sp<BBinder>::make();
+    auto status = binder->setRpcClientDebug(std::move(socket), keepAliveBinder);
+    if (status != OK) {
+        LOG(ERROR) << "setRpcClientDebug failed with " << statusToString(status);
+        return EX_SOFTWARE;
+    }
+    LOG(INFO) << "Finish setting up RPC on service " << name << " on port " << port;
+
+    std::cout << port << std::endl;
+
+    TEMP_FAILURE_RETRY(pause());
+
+    PLOG(FATAL) << "TEMP_FAILURE_RETRY(pause()) exits; this should not happen!";
+    __builtin_unreachable();
+}
+
+// Wrapper that wraps a BpServiceManager as a BnServiceManager.
+class ServiceManagerProxyToNative : public android::os::BnServiceManager {
+public:
+    ServiceManagerProxyToNative(const sp<android::os::IServiceManager>& impl) : mImpl(impl) {}
+    android::binder::Status getService(const std::string&,
+                                       android::sp<android::IBinder>*) override {
+        // We can't send BpBinder for regular binder over RPC.
+        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+    }
+    android::binder::Status checkService(const std::string&,
+                                         android::sp<android::IBinder>*) override {
+        // We can't send BpBinder for regular binder over RPC.
+        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+    }
+    android::binder::Status addService(const std::string&, const android::sp<android::IBinder>&,
+                                       bool, int32_t) override {
+        // We can't send BpBinder for RPC over regular binder.
+        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+    }
+    android::binder::Status listServices(int32_t dumpPriority,
+                                         std::vector<std::string>* _aidl_return) override {
+        return mImpl->listServices(dumpPriority, _aidl_return);
+    }
+    android::binder::Status registerForNotifications(
+            const std::string&, const android::sp<android::os::IServiceCallback>&) override {
+        // We can't send BpBinder for RPC over regular binder.
+        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+    }
+    android::binder::Status unregisterForNotifications(
+            const std::string&, const android::sp<android::os::IServiceCallback>&) override {
+        // We can't send BpBinder for RPC over regular binder.
+        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+    }
+    android::binder::Status isDeclared(const std::string& name, bool* _aidl_return) override {
+        return mImpl->isDeclared(name, _aidl_return);
+    }
+    android::binder::Status getDeclaredInstances(const std::string& iface,
+                                                 std::vector<std::string>* _aidl_return) override {
+        return mImpl->getDeclaredInstances(iface, _aidl_return);
+    }
+    android::binder::Status updatableViaApex(const std::string& name,
+                                             std::optional<std::string>* _aidl_return) override {
+        return mImpl->updatableViaApex(name, _aidl_return);
+    }
+    android::binder::Status getConnectionInfo(
+            const std::string& name,
+            std::optional<android::os::ConnectionInfo>* _aidl_return) override {
+        return mImpl->getConnectionInfo(name, _aidl_return);
+    }
+    android::binder::Status registerClientCallback(
+            const std::string&, const android::sp<android::IBinder>&,
+            const android::sp<android::os::IClientCallback>&) override {
+        // We can't send BpBinder for RPC over regular binder.
+        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+    }
+    android::binder::Status tryUnregisterService(const std::string&,
+                                                 const android::sp<android::IBinder>&) override {
+        // We can't send BpBinder for RPC over regular binder.
+        return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+    }
+    android::binder::Status getServiceDebugInfo(
+            std::vector<android::os::ServiceDebugInfo>* _aidl_return) override {
+        return mImpl->getServiceDebugInfo(_aidl_return);
+    }
+
+private:
+    sp<android::os::IServiceManager> mImpl;
+};
+
+// Workaround for b/191059588.
+// TODO(b/191059588): Once we can run RpcServer on single-threaded services,
+//   `servicedispatcher manager` should call Dispatch("manager") directly.
+int wrapServiceManager(const ServiceRetriever& serviceRetriever) {
+    auto sm = defaultServiceManager();
+    if (nullptr == sm) {
+        LOG(ERROR) << "No servicemanager";
+        return EX_SOFTWARE;
+    }
+    auto service = std::invoke(serviceRetriever, defaultServiceManager(), String16("manager"));
+    if (nullptr == service) {
+        LOG(ERROR) << "No service called `manager`";
+        return EX_SOFTWARE;
+    }
+    auto interface = android::os::IServiceManager::asInterface(service);
+    if (nullptr == interface) {
+        LOG(ERROR) << "Cannot cast service called `manager` to IServiceManager";
+        return EX_SOFTWARE;
+    }
+
+    // Work around restriction that doesn't allow us to send proxy over RPC.
+    interface = sp<ServiceManagerProxyToNative>::make(interface);
+    service = ServiceManagerProxyToNative::asBinder(interface);
+
+    auto rpcServer = RpcServer::make();
+    rpcServer->setRootObject(service);
+    unsigned int port;
+    if (status_t status = rpcServer->setupInetServer(kLocalInetAddress, 0, &port); status != OK) {
+        LOG(ERROR) << "Unable to set up inet server: " << statusToString(status);
+        return EX_SOFTWARE;
+    }
+    LOG(INFO) << "Finish wrapping servicemanager with RPC on port " << port;
+    std::cout << port << std::endl;
+    rpcServer->join();
+
+    LOG(FATAL) << "Wrapped servicemanager exits; this should not happen!";
+    __builtin_unreachable();
+}
+
+class AdbCallback : public android::debug::BnAdbCallback {
+public:
+    android::binder::Status onDebuggingChanged(bool enabled,
+                                               android::debug::AdbTransportType) override {
+        if (!enabled) {
+            LOG(ERROR) << "ADB debugging disabled, exiting.";
+            exit(EX_SOFTWARE);
+        }
+        return android::binder::Status::ok();
+    }
+};
+
+void exitOnAdbDebuggingDisabled() {
+    auto adb = android::waitForService<IAdbManager>(String16("adb"));
+    CHECK(adb != nullptr) << "Unable to retrieve service adb";
+    auto status = adb->registerCallback(sp<AdbCallback>::make());
+    CHECK(status.isOk()) << "Unable to call IAdbManager::registerCallback: " << status;
+}
+
+// Log to logd. For warning and more severe messages, also log to stderr.
+class ServiceDispatcherLogger {
+public:
+    void operator()(LogId id, LogSeverity severity, const char* tag, const char* file,
+                    unsigned int line, const char* message) {
+        mLogdLogger(id, severity, tag, file, line, message);
+        if (severity >= LogSeverity::WARNING) {
+            std::cout << std::flush;
+            std::cerr << Basename(getprogname()) << ": " << message << std::endl;
+        }
+    }
+
+private:
+    LogdLogger mLogdLogger{};
+};
+
+} // namespace
+
+int main(int argc, char* argv[]) {
+    InitLogging(argv, ServiceDispatcherLogger());
+
+    if (!GetBoolProperty("ro.debuggable", false)) {
+        LOG(ERROR) << "servicedispatcher is only allowed on debuggable builds.";
+        return EX_NOPERM;
+    }
+    LOG(WARNING) << "WARNING: servicedispatcher is debug only. Use with caution.";
+
+    int opt;
+    ServiceRetriever serviceRetriever = &android::IServiceManager::checkService;
+    while (-1 != (opt = getopt(argc, argv, "g"))) {
+        switch (opt) {
+            case 'g': {
+                serviceRetriever = &android::IServiceManager::getService;
+            } break;
+            default: {
+                return Usage(argv[0]);
+            }
+        }
+    }
+
+    android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    android::ProcessState::self()->startThreadPool();
+    exitOnAdbDebuggingDisabled();
+
+    if (optind + 1 != argc) return Usage(argv[0]);
+    auto name = argv[optind];
+
+    if (name == "manager"sv) {
+        return wrapServiceManager(serviceRetriever);
+    }
+    return Dispatch(name, serviceRetriever);
+}
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index d584897..86da588 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -60,7 +60,9 @@
     defaults: ["binder_test_defaults"],
     srcs: ["binderLibTest.cpp"],
     shared_libs: [
+        "libbase",
         "libbinder",
+        "liblog",
         "libutils",
     ],
     static_libs: [
@@ -75,16 +77,17 @@
 
 // unit test only, which can run on host and doesn't use /dev/binder
 cc_test {
-    name: "binderParcelTest",
+    name: "binderUnitTest",
     host_supported: true,
     target: {
         darwin: {
             enabled: false,
         },
     },
-    srcs: ["binderParcelTest.cpp"],
+    srcs: ["binderParcelUnitTest.cpp", "binderBinderUnitTest.cpp"],
     shared_libs: [
         "libbinder",
+        "libcutils",
         "libutils",
     ],
     test_suites: ["general-tests"],
@@ -101,7 +104,9 @@
 
     srcs: ["binderLibTest.cpp"],
     shared_libs: [
+        "libbase",
         "libbinder",
+        "liblog",
         "libutils",
     ],
     static_libs: [
@@ -116,8 +121,12 @@
     host_supported: true,
     unstable: true,
     srcs: [
+        "BinderRpcTestClientInfo.aidl",
+        "BinderRpcTestServerInfo.aidl",
+        "IBinderRpcCallback.aidl",
         "IBinderRpcSession.aidl",
         "IBinderRpcTest.aidl",
+        "ParcelableCertificateData.aidl",
     ],
     backend: {
         java: {
@@ -126,6 +135,37 @@
     },
 }
 
+cc_library_static {
+    name: "libbinder_tls_test_utils",
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    defaults: [
+        "binder_test_defaults",
+        "libbinder_tls_shared_deps",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbase",
+        "liblog",
+    ],
+    static_libs: [
+        "libbinder_tls_static",
+    ],
+    srcs: [
+        "RpcTlsTestUtils.cpp",
+    ],
+    export_include_dirs: [
+        "include_tls_test_utils",
+    ],
+    visibility: [
+        ":__subpackages__",
+    ],
+}
+
 cc_test {
     name: "binderRpcTest",
     host_supported: true,
@@ -133,10 +173,14 @@
         darwin: {
             enabled: false,
         },
+        android: {
+            test_suites: ["vts"],
+        },
     },
     defaults: [
         "binder_test_defaults",
         "libbinder_ndk_host_user",
+        "libbinder_tls_shared_deps",
     ],
 
     srcs: [
@@ -151,19 +195,52 @@
         "liblog",
     ],
     static_libs: [
+        "libbinder_tls_static",
+        "libbinder_tls_test_utils",
         "binderRpcTestIface-cpp",
-        "binderRpcTestIface-ndk_platform",
+        "binderRpcTestIface-ndk",
     ],
+    test_suites: ["general-tests"],
     require_root: true,
-    // Prevent the unit test target from running on sc-dev as it's not ready.
-    test_options: {
-        unit_test: false,
+}
+
+cc_test {
+    name: "RpcTlsUtilsTest",
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+        android: {
+            test_suites: ["vts"],
+        },
     },
+    defaults: [
+        "binder_test_defaults",
+        "libbinder_tls_shared_deps",
+    ],
+    srcs: [
+        "RpcTlsUtilsTest.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbase",
+        "libutils",
+        "liblog",
+    ],
+    static_libs: [
+        "libbinder_tls_test_utils",
+        "libbinder_tls_static",
+    ],
+    test_suites: ["general-tests", "device-tests"],
 }
 
 cc_benchmark {
     name: "binderRpcBenchmark",
-    defaults: ["binder_test_defaults"],
+    defaults: [
+        "binder_test_defaults",
+        "libbinder_tls_shared_deps",
+    ],
     host_supported: true,
     target: {
         darwin: {
@@ -180,6 +257,37 @@
         "liblog",
         "libutils",
     ],
+    static_libs: [
+        "libbinder_tls_test_utils",
+        "libbinder_tls_static",
+    ],
+}
+
+cc_test {
+    name: "binderRpcWireProtocolTest",
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+        android: {
+            test_suites: ["vts"],
+        },
+    },
+    defaults: [
+        "binder_test_defaults",
+    ],
+    srcs: [
+        "binderRpcWireProtocolTest.cpp",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libbase",
+        "libutils",
+        "libcutils",
+        "liblog",
+    ],
+    test_suites: ["general-tests"],
 }
 
 cc_test {
@@ -291,7 +399,7 @@
     ],
     static_libs: [
         "binderStabilityTestIface-cpp",
-        "binderStabilityTestIface-ndk_platform",
+        "binderStabilityTestIface-ndk",
     ],
 
     test_suites: ["device-tests", "vts"],
@@ -324,3 +432,68 @@
         "libutils",
     ],
 }
+
+cc_test_host {
+    name: "binderUtilsHostTest",
+    defaults: ["binder_test_defaults"],
+    srcs: ["binderUtilsHostTest.cpp"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+    ],
+    static_libs: [
+        "libgmock",
+    ],
+    test_suites: ["general-tests"],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
+cc_test_host {
+    name: "binderHostDeviceTest",
+    defaults: ["binder_test_defaults"],
+    srcs: ["binderHostDeviceTest.cpp"],
+    test_config: "binderHostDeviceTest.xml",
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "liblog",
+        "libutils",
+    ],
+    static_libs: [
+        "libgmock",
+    ],
+    target_required: [
+        "binderHostDeviceTestService",
+    ],
+    test_suites: ["general-tests"],
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    test_options: {
+        unit_test: false,
+    },
+}
+
+cc_test {
+    name: "binderHostDeviceTestService",
+    // The binary is named differently from the module so that PushFilePreparer pushes the binary
+    // directly, not the test module directory.
+    stem: "binderHostDeviceTest-service",
+    defaults: ["binder_test_defaults"],
+    gtest: false,
+    auto_gen_config: false,
+    srcs: ["binderHostDeviceTestService.cpp"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "liblog",
+        "libutils",
+    ],
+    test_suites: ["general-tests"],
+}
diff --git a/libs/binder/tests/BinderRpcTestClientInfo.aidl b/libs/binder/tests/BinderRpcTestClientInfo.aidl
new file mode 100644
index 0000000..b4baebc
--- /dev/null
+++ b/libs/binder/tests/BinderRpcTestClientInfo.aidl
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+import ParcelableCertificateData;
+
+parcelable BinderRpcTestClientInfo {
+    ParcelableCertificateData[] certs;
+}
diff --git a/libs/binder/tests/BinderRpcTestServerInfo.aidl b/libs/binder/tests/BinderRpcTestServerInfo.aidl
new file mode 100644
index 0000000..00dc0bc
--- /dev/null
+++ b/libs/binder/tests/BinderRpcTestServerInfo.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+import ParcelableCertificateData;
+
+parcelable BinderRpcTestServerInfo {
+    long port;
+    ParcelableCertificateData cert;
+}
diff --git a/libs/binder/tests/IBinderRpcBenchmark.aidl b/libs/binder/tests/IBinderRpcBenchmark.aidl
index 1457422..2baf680 100644
--- a/libs/binder/tests/IBinderRpcBenchmark.aidl
+++ b/libs/binder/tests/IBinderRpcBenchmark.aidl
@@ -17,4 +17,5 @@
 interface IBinderRpcBenchmark {
     @utf8InCpp String repeatString(@utf8InCpp String str);
     IBinder repeatBinder(IBinder binder);
+    byte[] repeatBytes(in byte[] bytes);
 }
diff --git a/libs/binder/tests/IBinderRpcCallback.aidl b/libs/binder/tests/IBinderRpcCallback.aidl
new file mode 100644
index 0000000..0336961
--- /dev/null
+++ b/libs/binder/tests/IBinderRpcCallback.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+interface IBinderRpcCallback {
+    void sendCallback(@utf8InCpp String str);
+    oneway void sendOnewayCallback(@utf8InCpp String str);
+}
diff --git a/libs/binder/tests/IBinderRpcTest.aidl b/libs/binder/tests/IBinderRpcTest.aidl
index ef4198d..fdd02a4 100644
--- a/libs/binder/tests/IBinderRpcTest.aidl
+++ b/libs/binder/tests/IBinderRpcTest.aidl
@@ -18,6 +18,9 @@
     oneway void sendString(@utf8InCpp String str);
     @utf8InCpp String doubleString(@utf8InCpp String str);
 
+    // get the port that a client used to connect to this object
+    int getClientPort();
+
     // number of known RPC binders to process, RpcState::countBinders by session
     int[] countBinders();
 
@@ -54,5 +57,11 @@
     void sleepMs(int ms);
     oneway void sleepMsAsync(int ms);
 
+    void doCallback(IBinderRpcCallback callback, boolean isOneway, boolean delayed, @utf8InCpp String value);
+    oneway void doCallbackAsync(IBinderRpcCallback callback, boolean isOneway, boolean delayed, @utf8InCpp String value);
+
     void die(boolean cleanup);
+    void scheduleShutdown();
+
+    void useKernelBinderCallingId();
 }
diff --git a/libs/binder/tests/ParcelableCertificateData.aidl b/libs/binder/tests/ParcelableCertificateData.aidl
new file mode 100644
index 0000000..38c382e
--- /dev/null
+++ b/libs/binder/tests/ParcelableCertificateData.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+parcelable ParcelableCertificateData {
+    byte[] data;
+}
diff --git a/libs/binder/tests/RpcTlsTestUtils.cpp b/libs/binder/tests/RpcTlsTestUtils.cpp
new file mode 100644
index 0000000..6119313
--- /dev/null
+++ b/libs/binder/tests/RpcTlsTestUtils.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "RpcTlsTestUtils"
+#include <log/log.h>
+
+#include <binder/RpcTlsTestUtils.h>
+
+#include <binder/RpcTlsUtils.h>
+
+#include "../Utils.h" // for TEST_AND_RETURN
+
+namespace android {
+
+bssl::UniquePtr<EVP_PKEY> makeKeyPairForSelfSignedCert() {
+    bssl::UniquePtr<EC_KEY> ec_key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+    if (ec_key == nullptr || !EC_KEY_generate_key(ec_key.get())) {
+        ALOGE("Failed to generate key pair.");
+        return nullptr;
+    }
+    bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
+    // Use set1 instead of assign to avoid leaking ec_key when assign fails. set1 increments
+    // the refcount of the ec_key, so it is okay to release it at the end of this function.
+    if (pkey == nullptr || !EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get())) {
+        ALOGE("Failed to assign key pair.");
+        return nullptr;
+    }
+    return pkey;
+}
+
+bssl::UniquePtr<X509> makeSelfSignedCert(EVP_PKEY* pkey, const uint32_t validSeconds) {
+    bssl::UniquePtr<X509> x509(X509_new());
+    bssl::UniquePtr<BIGNUM> serial(BN_new());
+    bssl::UniquePtr<BIGNUM> serialLimit(BN_new());
+    TEST_AND_RETURN(nullptr, BN_lshift(serialLimit.get(), BN_value_one(), 128));
+    TEST_AND_RETURN(nullptr, BN_rand_range(serial.get(), serialLimit.get()));
+    TEST_AND_RETURN(nullptr, BN_to_ASN1_INTEGER(serial.get(), X509_get_serialNumber(x509.get())));
+    TEST_AND_RETURN(nullptr, X509_gmtime_adj(X509_getm_notBefore(x509.get()), 0));
+    TEST_AND_RETURN(nullptr, X509_gmtime_adj(X509_getm_notAfter(x509.get()), validSeconds));
+
+    X509_NAME* subject = X509_get_subject_name(x509.get());
+    TEST_AND_RETURN(nullptr,
+                    X509_NAME_add_entry_by_txt(subject, "O", MBSTRING_ASC,
+                                               reinterpret_cast<const uint8_t*>("Android"), -1, -1,
+                                               0));
+    TEST_AND_RETURN(nullptr,
+                    X509_NAME_add_entry_by_txt(subject, "CN", MBSTRING_ASC,
+                                               reinterpret_cast<const uint8_t*>("BinderRPC"), -1,
+                                               -1, 0));
+    TEST_AND_RETURN(nullptr, X509_set_issuer_name(x509.get(), subject));
+
+    TEST_AND_RETURN(nullptr, X509_set_pubkey(x509.get(), pkey));
+    TEST_AND_RETURN(nullptr, X509_sign(x509.get(), pkey, EVP_sha256()));
+    return x509;
+}
+
+status_t RpcAuthSelfSigned::configure(SSL_CTX* ctx) {
+    auto pkey = makeKeyPairForSelfSignedCert();
+    TEST_AND_RETURN(UNKNOWN_ERROR, pkey != nullptr);
+    auto cert = makeSelfSignedCert(pkey.get(), mValidSeconds);
+    TEST_AND_RETURN(UNKNOWN_ERROR, cert != nullptr);
+    TEST_AND_RETURN(INVALID_OPERATION, SSL_CTX_use_PrivateKey(ctx, pkey.get()));
+    TEST_AND_RETURN(INVALID_OPERATION, SSL_CTX_use_certificate(ctx, cert.get()));
+    return OK;
+}
+
+status_t RpcAuthPreSigned::configure(SSL_CTX* ctx) {
+    if (!SSL_CTX_use_PrivateKey(ctx, mPkey.get())) {
+        return INVALID_OPERATION;
+    }
+    if (!SSL_CTX_use_certificate(ctx, mCert.get())) {
+        return INVALID_OPERATION;
+    }
+    return OK;
+}
+
+status_t RpcCertificateVerifierSimple::verify(const SSL* ssl, uint8_t* outAlert) {
+    const char* logPrefix = SSL_is_server(ssl) ? "Server" : "Client";
+    bssl::UniquePtr<X509> peerCert(SSL_get_peer_certificate(ssl)); // Does not set error queue
+    LOG_ALWAYS_FATAL_IF(peerCert == nullptr,
+                        "%s: libssl should not ask to verify non-existing cert", logPrefix);
+
+    std::lock_guard<std::mutex> lock(mMutex);
+    for (const auto& trustedCert : mTrustedPeerCertificates) {
+        if (0 == X509_cmp(trustedCert.get(), peerCert.get())) {
+            return OK;
+        }
+    }
+    *outAlert = SSL_AD_CERTIFICATE_UNKNOWN;
+    return PERMISSION_DENIED;
+}
+
+status_t RpcCertificateVerifierSimple::addTrustedPeerCertificate(RpcCertificateFormat format,
+                                                                 const std::vector<uint8_t>& cert) {
+    bssl::UniquePtr<X509> x509 = deserializeCertificate(cert, format);
+    if (x509 == nullptr) {
+        ALOGE("Certificate is not in the proper format %s", PrintToString(format).c_str());
+        return BAD_VALUE;
+    }
+    std::lock_guard<std::mutex> lock(mMutex);
+    mTrustedPeerCertificates.push_back(std::move(x509));
+    return OK;
+}
+
+} // namespace android
diff --git a/libs/binder/tests/RpcTlsUtilsTest.cpp b/libs/binder/tests/RpcTlsUtilsTest.cpp
new file mode 100644
index 0000000..530606c
--- /dev/null
+++ b/libs/binder/tests/RpcTlsUtilsTest.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/RpcTlsTestUtils.h>
+#include <binder/RpcTlsUtils.h>
+#include <gtest/gtest.h>
+
+namespace android {
+
+std::string toDebugString(EVP_PKEY* pkey) {
+    bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
+    int res = EVP_PKEY_print_public(bio.get(), pkey, 2, nullptr);
+    std::string buf = "\nEVP_PKEY_print_public -> " + std::to_string(res) + "\n";
+    if (BIO_write(bio.get(), buf.data(), buf.length()) <= 0) return {};
+    res = EVP_PKEY_print_private(bio.get(), pkey, 2, nullptr);
+    buf = "\nEVP_PKEY_print_private -> " + std::to_string(res);
+    if (BIO_write(bio.get(), buf.data(), buf.length()) <= 0) return {};
+    const uint8_t* data;
+    size_t len;
+    if (!BIO_mem_contents(bio.get(), &data, &len)) return {};
+    return std::string(reinterpret_cast<const char*>(data), len);
+}
+
+class RpcTlsUtilsKeyTest : public testing::TestWithParam<RpcKeyFormat> {
+public:
+    static inline std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
+        return PrintToString(info.param);
+    }
+};
+
+TEST_P(RpcTlsUtilsKeyTest, Test) {
+    auto pkey = makeKeyPairForSelfSignedCert();
+    ASSERT_NE(nullptr, pkey);
+    auto pkeyData = serializeUnencryptedPrivatekey(pkey.get(), GetParam());
+    auto deserializedPkey = deserializeUnencryptedPrivatekey(pkeyData, GetParam());
+    ASSERT_NE(nullptr, deserializedPkey);
+    EXPECT_EQ(1, EVP_PKEY_cmp(pkey.get(), deserializedPkey.get()))
+            << "expected: " << toDebugString(pkey.get())
+            << "\nactual: " << toDebugString(deserializedPkey.get());
+}
+
+INSTANTIATE_TEST_CASE_P(RpcTlsUtilsTest, RpcTlsUtilsKeyTest,
+                        testing::Values(RpcKeyFormat::PEM, RpcKeyFormat::DER),
+                        RpcTlsUtilsKeyTest::PrintParamInfo);
+
+class RpcTlsUtilsCertTest : public testing::TestWithParam<RpcCertificateFormat> {
+public:
+    static inline std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
+        return PrintToString(info.param);
+    }
+};
+
+TEST_P(RpcTlsUtilsCertTest, Test) {
+    auto pkey = makeKeyPairForSelfSignedCert();
+    ASSERT_NE(nullptr, pkey);
+    // Make certificate from the original key in memory
+    auto cert = makeSelfSignedCert(pkey.get(), kCertValidSeconds);
+    ASSERT_NE(nullptr, cert);
+    auto certData = serializeCertificate(cert.get(), GetParam());
+    auto deserializedCert = deserializeCertificate(certData, GetParam());
+    ASSERT_NE(nullptr, deserializedCert);
+    EXPECT_EQ(0, X509_cmp(cert.get(), deserializedCert.get()));
+}
+
+INSTANTIATE_TEST_CASE_P(RpcTlsUtilsTest, RpcTlsUtilsCertTest,
+                        testing::Values(RpcCertificateFormat::PEM, RpcCertificateFormat::DER),
+                        RpcTlsUtilsCertTest::PrintParamInfo);
+
+class RpcTlsUtilsKeyAndCertTest
+      : public testing::TestWithParam<std::tuple<RpcKeyFormat, RpcCertificateFormat>> {
+public:
+    static inline std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
+        auto [keyFormat, certificateFormat] = info.param;
+        return "key_" + PrintToString(keyFormat) + "_cert_" + PrintToString(certificateFormat);
+    }
+};
+
+TEST_P(RpcTlsUtilsKeyAndCertTest, TestCertFromDeserializedKey) {
+    auto [keyFormat, certificateFormat] = GetParam();
+    auto pkey = makeKeyPairForSelfSignedCert();
+    ASSERT_NE(nullptr, pkey);
+    auto pkeyData = serializeUnencryptedPrivatekey(pkey.get(), keyFormat);
+    auto deserializedPkey = deserializeUnencryptedPrivatekey(pkeyData, keyFormat);
+    ASSERT_NE(nullptr, deserializedPkey);
+
+    // Make certificate from deserialized key loaded from bytes
+    auto cert = makeSelfSignedCert(deserializedPkey.get(), kCertValidSeconds);
+    ASSERT_NE(nullptr, cert);
+    auto certData = serializeCertificate(cert.get(), certificateFormat);
+    auto deserializedCert = deserializeCertificate(certData, certificateFormat);
+    ASSERT_NE(nullptr, deserializedCert);
+    EXPECT_EQ(0, X509_cmp(cert.get(), deserializedCert.get()));
+}
+
+INSTANTIATE_TEST_CASE_P(RpcTlsUtilsTest, RpcTlsUtilsKeyAndCertTest,
+                        testing::Combine(testing::Values(RpcKeyFormat::PEM, RpcKeyFormat::DER),
+                                         testing::Values(RpcCertificateFormat::PEM,
+                                                         RpcCertificateFormat::DER)),
+                        RpcTlsUtilsKeyAndCertTest::PrintParamInfo);
+
+} // namespace android
diff --git a/libs/binder/tests/binderBinderUnitTest.cpp b/libs/binder/tests/binderBinderUnitTest.cpp
new file mode 100644
index 0000000..1be0c59
--- /dev/null
+++ b/libs/binder/tests/binderBinderUnitTest.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/Binder.h>
+#include <binder/IBinder.h>
+#include <gtest/gtest.h>
+
+using android::BBinder;
+using android::OK;
+using android::sp;
+
+const void* kObjectId1 = reinterpret_cast<const void*>(1);
+const void* kObjectId2 = reinterpret_cast<const void*>(2);
+void* kObject1 = reinterpret_cast<void*>(101);
+void* kObject2 = reinterpret_cast<void*>(102);
+void* kObject3 = reinterpret_cast<void*>(103);
+
+TEST(Binder, AttachObject) {
+    auto binder = sp<BBinder>::make();
+    EXPECT_EQ(nullptr, binder->attachObject(kObjectId1, kObject1, nullptr, nullptr));
+    EXPECT_EQ(nullptr, binder->attachObject(kObjectId2, kObject2, nullptr, nullptr));
+    EXPECT_EQ(kObject1, binder->attachObject(kObjectId1, kObject3, nullptr, nullptr));
+}
+
+TEST(Binder, DetachObject) {
+    auto binder = sp<BBinder>::make();
+    EXPECT_EQ(nullptr, binder->attachObject(kObjectId1, kObject1, nullptr, nullptr));
+    EXPECT_EQ(kObject1, binder->detachObject(kObjectId1));
+    EXPECT_EQ(nullptr, binder->attachObject(kObjectId1, kObject2, nullptr, nullptr));
+}
diff --git a/libs/binder/tests/binderClearBufTest.cpp b/libs/binder/tests/binderClearBufTest.cpp
index 2d30c8d..307151c 100644
--- a/libs/binder/tests/binderClearBufTest.cpp
+++ b/libs/binder/tests/binderClearBufTest.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <android-base/hex.h>
 #include <android-base/logging.h>
 #include <binder/Binder.h>
 #include <binder/IBinder.h>
@@ -30,22 +31,6 @@
 
 const String16 kServerName = String16("binderClearBuf");
 
-std::string hexString(const void* bytes, size_t len) {
-    if (bytes == nullptr) return "<null>";
-
-    const uint8_t* bytes8 = static_cast<const uint8_t*>(bytes);
-    char chars[] = "0123456789abcdef";
-    std::string result;
-    result.resize(len * 2);
-
-    for (size_t i = 0; i < len; i++) {
-        result[2 * i] = chars[bytes8[i] >> 4];
-        result[2 * i + 1] = chars[bytes8[i] & 0xf];
-    }
-
-    return result;
-}
-
 class FooBar : public BBinder {
  public:
     enum {
@@ -83,7 +68,7 @@
             lastReply = reply.data();
             lastReplySize = reply.dataSize();
         }
-        *outBuffer = hexString(lastReply, lastReplySize);
+        *outBuffer = android::base::HexString(lastReply, lastReplySize);
         return result;
     }
 };
diff --git a/libs/binder/tests/binderHostDeviceTest.cpp b/libs/binder/tests/binderHostDeviceTest.cpp
new file mode 100644
index 0000000..464da60
--- /dev/null
+++ b/libs/binder/tests/binderHostDeviceTest.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+// Integration test for servicedispatcher + adb forward. Requires ADB.
+
+#include <stdlib.h>
+
+#include <vector>
+
+#include <android-base/parsebool.h>
+#include <android-base/result-gmock.h>
+#include <android-base/strings.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <binder/IServiceManager.h>
+#include <binder/RpcSession.h>
+
+#include "../UtilsHost.h"
+
+using ::android::setDefaultServiceManager;
+using ::android::base::EndsWith;
+using ::android::base::Join;
+using ::android::base::ParseBool;
+using ::android::base::ParseBoolResult;
+using ::android::base::Split;
+using ::android::base::StartsWith;
+using ::android::base::StringReplace;
+using ::android::base::Trim;
+using ::android::base::testing::Ok;
+using ::std::chrono_literals::operator""ms;
+using ::std::string_literals::operator""s;
+using ::testing::AllOf;
+using ::testing::Contains;
+using ::testing::ContainsRegex;
+using ::testing::ExplainMatchResult;
+using ::testing::InitGoogleMock;
+
+namespace android {
+
+namespace {
+
+constexpr const char* kServiceBinary = "/data/local/tmp/binderHostDeviceTest-service";
+constexpr const char* kServiceName = "binderHostDeviceTestService";
+constexpr const char* kDescriptor = "android.binderHostDeviceTestService";
+
+// e.g. EXPECT_THAT(expr, StatusEq(OK)) << "additional message";
+MATCHER_P(StatusEq, expected, (negation ? "not " : "") + statusToString(expected)) {
+    *result_listener << statusToString(arg);
+    return expected == arg;
+}
+
+void initHostRpcServiceManagerOnce() {
+    static std::once_flag gSmOnce;
+    std::call_once(gSmOnce, [] {
+        setDefaultServiceManager(createRpcDelegateServiceManager({.maxOutgoingThreads = 1}));
+    });
+}
+
+// Test for host service manager.
+class HostDeviceTest : public ::testing::Test {
+public:
+    void SetUp() override {
+        auto debuggableResult = execute(Split("adb shell getprop ro.debuggable", " "), nullptr);
+        ASSERT_THAT(debuggableResult, Ok());
+        ASSERT_EQ(0, debuggableResult->exitCode) << *debuggableResult;
+        auto debuggableBool = ParseBool(Trim(debuggableResult->stdoutStr));
+        ASSERT_NE(ParseBoolResult::kError, debuggableBool) << Trim(debuggableResult->stdoutStr);
+        if (debuggableBool == ParseBoolResult::kFalse) {
+            GTEST_SKIP() << "ro.debuggable=" << Trim(debuggableResult->stdoutStr);
+        }
+
+        auto lsResult = execute(Split("adb shell which servicedispatcher", " "), nullptr);
+        ASSERT_THAT(lsResult, Ok());
+        if (lsResult->exitCode != 0) {
+            GTEST_SKIP() << "b/182914638: until feature is fully enabled, skip test on devices "
+                            "without servicedispatcher";
+        }
+
+        initHostRpcServiceManagerOnce();
+        ASSERT_NE(nullptr, defaultServiceManager()) << "No defaultServiceManager() over RPC";
+
+        auto service = execute({"adb", "shell", kServiceBinary, kServiceName, kDescriptor},
+                               &CommandResult::stdoutEndsWithNewLine);
+        ASSERT_THAT(service, Ok());
+        ASSERT_EQ(std::nullopt, service->exitCode) << *service;
+        mService = std::move(*service);
+    }
+    void TearDown() override { mService.reset(); }
+
+    [[nodiscard]] static sp<IBinder> get(unsigned int hostPort) {
+        auto rpcSession = RpcSession::make();
+        if (status_t status = rpcSession->setupInetClient("127.0.0.1", hostPort); status != OK) {
+            ADD_FAILURE() << "Failed to setupInetClient on " << hostPort << ": "
+                          << statusToString(status);
+            return nullptr;
+        }
+        return rpcSession->getRootObject();
+    }
+
+private:
+    std::optional<CommandResult> mService;
+};
+
+TEST_F(HostDeviceTest, List) {
+    auto sm = defaultServiceManager();
+
+    auto services = sm->listServices();
+    ASSERT_THAT(services, Contains(String16(kServiceName)));
+}
+
+TEST_F(HostDeviceTest, CheckService) {
+    auto sm = defaultServiceManager();
+
+    auto rpcBinder = sm->checkService(String16(kServiceName));
+    ASSERT_NE(nullptr, rpcBinder);
+
+    EXPECT_THAT(rpcBinder->pingBinder(), StatusEq(OK));
+    EXPECT_EQ(String16(kDescriptor), rpcBinder->getInterfaceDescriptor());
+}
+
+TEST_F(HostDeviceTest, GetService) {
+    auto sm = defaultServiceManager();
+
+    auto rpcBinder = sm->getService(String16(kServiceName));
+    ASSERT_NE(nullptr, rpcBinder);
+
+    EXPECT_THAT(rpcBinder->pingBinder(), StatusEq(OK));
+    EXPECT_EQ(String16(kDescriptor), rpcBinder->getInterfaceDescriptor());
+}
+
+TEST_F(HostDeviceTest, WaitForService) {
+    auto sm = defaultServiceManager();
+
+    auto rpcBinder = sm->waitForService(String16(kServiceName));
+    ASSERT_NE(nullptr, rpcBinder);
+
+    EXPECT_THAT(rpcBinder->pingBinder(), StatusEq(OK));
+    EXPECT_EQ(String16(kDescriptor), rpcBinder->getInterfaceDescriptor());
+}
+
+TEST_F(HostDeviceTest, TenClients) {
+    auto sm = defaultServiceManager();
+
+    auto threadFn = [&] {
+        auto rpcBinder = sm->checkService(String16(kServiceName));
+        ASSERT_NE(nullptr, rpcBinder);
+
+        EXPECT_THAT(rpcBinder->pingBinder(), StatusEq(OK));
+        EXPECT_EQ(String16(kDescriptor), rpcBinder->getInterfaceDescriptor());
+    };
+
+    std::vector<std::thread> threads;
+    for (size_t i = 0; i < 10; ++i) threads.emplace_back(threadFn);
+    for (auto& thread : threads) thread.join();
+}
+
+} // namespace
+
+} // namespace android
diff --git a/libs/binder/tests/binderHostDeviceTest.xml b/libs/binder/tests/binderHostDeviceTest.xml
new file mode 100644
index 0000000..250ed3a
--- /dev/null
+++ b/libs/binder/tests/binderHostDeviceTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<configuration description="Runs binderHostDeviceTest.">
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push-file" key="binderHostDeviceTest-service"
+                value="/data/local/tmp/binderHostDeviceTest-service"/>
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.binary.ExecutableHostTest">
+        <option name="binary" value="binderHostDeviceTest"/>
+    </test>
+</configuration>
diff --git a/libs/binder/tests/binderHostDeviceTestService.cpp b/libs/binder/tests/binderHostDeviceTestService.cpp
new file mode 100644
index 0000000..6ddd2e7
--- /dev/null
+++ b/libs/binder/tests/binderHostDeviceTestService.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sysexits.h>
+
+#include <android-base/logging.h>
+#include <binder/IBinder.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+namespace {
+class Service : public android::BBinder {
+public:
+    Service(std::string_view descriptor) : mDescriptor(descriptor.data(), descriptor.size()) {}
+    const android::String16& getInterfaceDescriptor() const override { return mDescriptor; }
+
+private:
+    android::String16 mDescriptor;
+};
+} // namespace
+
+int main(int argc, char** argv) {
+    if (argc != 3) {
+        std::cerr << "usage: " << argv[0] << " <service-name> <interface-descriptor>" << std::endl;
+        return EX_USAGE;
+    }
+    auto name = argv[1];
+    auto descriptor = argv[2];
+
+    auto sm = android::defaultServiceManager();
+    CHECK(sm != nullptr);
+    auto service = android::sp<Service>::make(descriptor);
+    auto status = sm->addService(android::String16(name), service);
+    CHECK_EQ(android::OK, status) << android::statusToString(status);
+    std::cout << "running..." << std::endl;
+    android::ProcessState::self()->startThreadPool();
+    android::IPCThreadState::self()->joinThreadPool();
+    LOG(ERROR) << "joinThreadPool exits";
+    return EX_SOFTWARE;
+}
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 6cb7e7f..63a4b2c 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -15,25 +15,36 @@
  */
 
 #include <errno.h>
-#include <fcntl.h>
-#include <fstream>
 #include <poll.h>
 #include <pthread.h>
 #include <stdio.h>
 #include <stdlib.h>
+
+#include <chrono>
+#include <fstream>
 #include <thread>
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
+#include <android-base/properties.h>
+#include <android-base/result-gmock.h>
+#include <android-base/result.h>
+#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
 #include <binder/Binder.h>
+#include <binder/BpBinder.h>
 #include <binder/IBinder.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
+#include <binder/RpcServer.h>
+#include <binder/RpcSession.h>
 
 #include <linux/sched.h>
 #include <sys/epoll.h>
 #include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 
 #include "../binder_module.h"
 #include "binderAbiHelper.h"
@@ -41,7 +52,13 @@
 #define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
 
 using namespace android;
+using namespace std::string_literals;
+using namespace std::chrono_literals;
+using android::base::testing::HasValue;
+using android::base::testing::Ok;
+using testing::ExplainMatchResult;
 using testing::Not;
+using testing::WithParamInterface;
 
 // e.g. EXPECT_THAT(expr, StatusEq(OK)) << "additional message";
 MATCHER_P(StatusEq, expected, (negation ? "not " : "") + statusToString(expected)) {
@@ -72,6 +89,7 @@
     BINDER_LIB_TEST_REGISTER_SERVER,
     BINDER_LIB_TEST_ADD_SERVER,
     BINDER_LIB_TEST_ADD_POLL_SERVER,
+    BINDER_LIB_TEST_USE_CALLING_GUARD_TRANSACTION,
     BINDER_LIB_TEST_CALL_BACK,
     BINDER_LIB_TEST_CALL_BACK_VERIFY_BUF,
     BINDER_LIB_TEST_DELAYED_CALL_BACK,
@@ -156,6 +174,20 @@
     return pid;
 }
 
+android::base::Result<int32_t> GetId(sp<IBinder> service) {
+    using android::base::Error;
+    Parcel data, reply;
+    data.markForBinder(service);
+    const char *prefix = data.isForRpc() ? "On RPC server, " : "On binder server, ";
+    status_t status = service->transact(BINDER_LIB_TEST_GET_ID_TRANSACTION, data, &reply);
+    if (status != OK)
+        return Error(status) << prefix << "transact(GET_ID): " << statusToString(status);
+    int32_t result = 0;
+    status = reply.readInt32(&result);
+    if (status != OK) return Error(status) << prefix << "readInt32: " << statusToString(status);
+    return result;
+}
+
 class BinderLibTestEnv : public ::testing::Environment {
     public:
         BinderLibTestEnv() {}
@@ -404,6 +436,19 @@
         };
 };
 
+TEST_F(BinderLibTest, CannotUseBinderAfterFork) {
+    // EXPECT_DEATH works by forking the process
+    EXPECT_DEATH({ ProcessState::self(); }, "libbinder ProcessState can not be used after fork");
+}
+
+TEST_F(BinderLibTest, WasParceled) {
+    auto binder = sp<BBinder>::make();
+    EXPECT_FALSE(binder->wasParceled());
+    Parcel data;
+    data.writeStrongBinder(binder);
+    EXPECT_TRUE(binder->wasParceled());
+}
+
 TEST_F(BinderLibTest, NopTransaction) {
     Parcel data, reply;
     EXPECT_THAT(m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply),
@@ -451,7 +496,7 @@
     EXPECT_EQ(NO_ERROR, IPCThreadState::self()->freeze(pid, true, 1000));
     EXPECT_EQ(FAILED_TRANSACTION, m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply));
 
-    bool sync_received, async_received;
+    uint32_t sync_received, async_received;
 
     EXPECT_EQ(NO_ERROR, IPCThreadState::self()->getProcessFreezeInfo(pid, &sync_received,
                 &async_received));
@@ -459,15 +504,7 @@
     EXPECT_EQ(sync_received, 1);
     EXPECT_EQ(async_received, 0);
 
-    uint32_t sync_received2, async_received2;
-
-    EXPECT_EQ(NO_ERROR, IPCThreadState::self()->getProcessFreezeInfo(pid, &sync_received2,
-                &async_received2));
-
-    EXPECT_EQ(sync_received2, 1);
-    EXPECT_EQ(async_received2, 0);
-
-    EXPECT_EQ(NO_ERROR, IPCThreadState::self()->freeze(pid, 0, 0));
+    EXPECT_EQ(NO_ERROR, IPCThreadState::self()->freeze(pid, false, 0));
     EXPECT_EQ(NO_ERROR, m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply));
 }
 
@@ -482,12 +519,7 @@
 }
 
 TEST_F(BinderLibTest, GetId) {
-    int32_t id;
-    Parcel data, reply;
-    EXPECT_THAT(m_server->transact(BINDER_LIB_TEST_GET_ID_TRANSACTION, data, &reply),
-                StatusEq(NO_ERROR));
-    EXPECT_THAT(reply.readInt32(&id), StatusEq(NO_ERROR));
-    EXPECT_EQ(0, id);
+    EXPECT_THAT(GetId(m_server), HasValue(0));
 }
 
 TEST_F(BinderLibTest, PtrSize) {
@@ -610,6 +642,13 @@
     EXPECT_THAT(callBack->getResult(), StatusEq(NO_ERROR));
 }
 
+TEST_F(BinderLibTest, BinderCallContextGuard) {
+    sp<IBinder> binder = addServer();
+    Parcel data, reply;
+    EXPECT_THAT(binder->transact(BINDER_LIB_TEST_USE_CALLING_GUARD_TRANSACTION, data, &reply),
+                StatusEq(DEAD_OBJECT));
+}
+
 TEST_F(BinderLibTest, AddServer)
 {
     sp<IBinder> server = addServer();
@@ -1181,39 +1220,115 @@
     EXPECT_THAT(server->transact(BINDER_LIB_TEST_CAN_GET_SID, data, nullptr), StatusEq(OK));
 }
 
-class BinderLibTestService : public BBinder
-{
-    public:
-        explicit BinderLibTestService(int32_t id)
-            : m_id(id)
-            , m_nextServerId(id + 1)
-            , m_serverStartRequested(false)
-            , m_callback(nullptr)
-        {
-            pthread_mutex_init(&m_serverWaitMutex, nullptr);
-            pthread_cond_init(&m_serverWaitCond, nullptr);
+class BinderLibRpcTestBase : public BinderLibTest {
+public:
+    void SetUp() override {
+        if (!base::GetBoolProperty("ro.debuggable", false)) {
+            GTEST_SKIP() << "Binder RPC is only enabled on debuggable builds, skipping test on "
+                            "non-debuggable builds.";
         }
-        ~BinderLibTestService()
-        {
-            exit(EXIT_SUCCESS);
-        }
+        BinderLibTest::SetUp();
+    }
 
-        void processPendingCall() {
-            if (m_callback != nullptr) {
-                Parcel data;
-                data.writeInt32(NO_ERROR);
-                m_callback->transact(BINDER_LIB_TEST_CALL_BACK, data, nullptr, TF_ONE_WAY);
-                m_callback = nullptr;
-            }
+    std::tuple<android::base::unique_fd, unsigned int> CreateSocket() {
+        auto rpcServer = RpcServer::make();
+        EXPECT_NE(nullptr, rpcServer);
+        if (rpcServer == nullptr) return {};
+        unsigned int port;
+        if (status_t status = rpcServer->setupInetServer("127.0.0.1", 0, &port); status != OK) {
+            ADD_FAILURE() << "setupInetServer failed" << statusToString(status);
+            return {};
         }
+        return {rpcServer->releaseServer(), port};
+    }
+};
 
-        virtual status_t onTransact(uint32_t code,
-                                    const Parcel& data, Parcel* reply,
-                                    uint32_t flags = 0) {
-            if (getuid() != (uid_t)IPCThreadState::self()->getCallingUid()) {
-                return PERMISSION_DENIED;
-            }
-            switch (code) {
+class BinderLibRpcTest : public BinderLibRpcTestBase {};
+
+TEST_F(BinderLibRpcTest, SetRpcClientDebug) {
+    auto binder = addServer();
+    ASSERT_TRUE(binder != nullptr);
+    auto [socket, port] = CreateSocket();
+    ASSERT_TRUE(socket.ok());
+    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), sp<BBinder>::make()), StatusEq(OK));
+}
+
+// Tests for multiple RpcServer's on the same binder object.
+TEST_F(BinderLibRpcTest, SetRpcClientDebugTwice) {
+    auto binder = addServer();
+    ASSERT_TRUE(binder != nullptr);
+
+    auto [socket1, port1] = CreateSocket();
+    ASSERT_TRUE(socket1.ok());
+    auto keepAliveBinder1 = sp<BBinder>::make();
+    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket1), keepAliveBinder1), StatusEq(OK));
+
+    auto [socket2, port2] = CreateSocket();
+    ASSERT_TRUE(socket2.ok());
+    auto keepAliveBinder2 = sp<BBinder>::make();
+    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket2), keepAliveBinder2), StatusEq(OK));
+}
+
+// Negative tests for RPC APIs on IBinder. Call should fail in the same way on both remote and
+// local binders.
+class BinderLibRpcTestP : public BinderLibRpcTestBase, public WithParamInterface<bool> {
+public:
+    sp<IBinder> GetService() {
+        return GetParam() ? sp<IBinder>(addServer()) : sp<IBinder>(sp<BBinder>::make());
+    }
+    static std::string ParamToString(const testing::TestParamInfo<ParamType> &info) {
+        return info.param ? "remote" : "local";
+    }
+};
+
+TEST_P(BinderLibRpcTestP, SetRpcClientDebugNoFd) {
+    auto binder = GetService();
+    ASSERT_TRUE(binder != nullptr);
+    EXPECT_THAT(binder->setRpcClientDebug(android::base::unique_fd(), sp<BBinder>::make()),
+                StatusEq(BAD_VALUE));
+}
+
+TEST_P(BinderLibRpcTestP, SetRpcClientDebugNoKeepAliveBinder) {
+    auto binder = GetService();
+    ASSERT_TRUE(binder != nullptr);
+    auto [socket, port] = CreateSocket();
+    ASSERT_TRUE(socket.ok());
+    EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), nullptr), StatusEq(UNEXPECTED_NULL));
+}
+INSTANTIATE_TEST_CASE_P(BinderLibTest, BinderLibRpcTestP, testing::Bool(),
+                        BinderLibRpcTestP::ParamToString);
+
+class BinderLibTestService : public BBinder {
+public:
+    explicit BinderLibTestService(int32_t id, bool exitOnDestroy = true)
+          : m_id(id),
+            m_nextServerId(id + 1),
+            m_serverStartRequested(false),
+            m_callback(nullptr),
+            m_exitOnDestroy(exitOnDestroy) {
+        pthread_mutex_init(&m_serverWaitMutex, nullptr);
+        pthread_cond_init(&m_serverWaitCond, nullptr);
+    }
+    ~BinderLibTestService() {
+        if (m_exitOnDestroy) exit(EXIT_SUCCESS);
+    }
+
+    void processPendingCall() {
+        if (m_callback != nullptr) {
+            Parcel data;
+            data.writeInt32(NO_ERROR);
+            m_callback->transact(BINDER_LIB_TEST_CALL_BACK, data, nullptr, TF_ONE_WAY);
+            m_callback = nullptr;
+        }
+    }
+
+    virtual status_t onTransact(uint32_t code, const Parcel &data, Parcel *reply,
+                                uint32_t flags = 0) {
+        // TODO(b/182914638): also checks getCallingUid() for RPC
+        if (!data.isForRpc() && getuid() != (uid_t)IPCThreadState::self()->getCallingUid()) {
+            return PERMISSION_DENIED;
+        }
+        switch (code) {
             case BINDER_LIB_TEST_REGISTER_SERVER: {
                 int32_t id;
                 sp<IBinder> binder;
@@ -1223,8 +1338,7 @@
                     return BAD_VALUE;
                 }
 
-                if (m_id != 0)
-                    return INVALID_OPERATION;
+                if (m_id != 0) return INVALID_OPERATION;
 
                 pthread_mutex_lock(&m_serverWaitMutex);
                 if (m_serverStartRequested) {
@@ -1278,6 +1392,21 @@
                 pthread_mutex_unlock(&m_serverWaitMutex);
                 return ret;
             }
+            case BINDER_LIB_TEST_USE_CALLING_GUARD_TRANSACTION: {
+                IPCThreadState::SpGuard spGuard{
+                        .address = __builtin_frame_address(0),
+                        .context = "GuardInBinderTransaction",
+                };
+                const IPCThreadState::SpGuard *origGuard =
+                        IPCThreadState::self()->pushGetCallingSpGuard(&spGuard);
+
+                // if the guard works, this should abort
+                (void)IPCThreadState::self()->getCallingPid();
+
+                IPCThreadState::self()->restoreGetCallingSpGuard(origGuard);
+                return NO_ERROR;
+            }
+
             case BINDER_LIB_TEST_GETPID:
                 reply->writeInt32(getpid());
                 return NO_ERROR;
@@ -1394,8 +1523,7 @@
                     return BAD_VALUE;
                 }
                 ret = target->linkToDeath(testDeathRecipient);
-                if (ret == NO_ERROR)
-                    ret = testDeathRecipient->waitEvent(5);
+                if (ret == NO_ERROR) ret = testDeathRecipient->waitEvent(5);
                 data2.writeInt32(ret);
                 callback->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
                 return NO_ERROR;
@@ -1419,8 +1547,7 @@
                     return BAD_VALUE;
                 }
                 ret = write(fd, buf, size);
-                if (ret != size)
-                    return UNKNOWN_ERROR;
+                if (ret != size) return UNKNOWN_ERROR;
                 return NO_ERROR;
             }
             case BINDER_LIB_TEST_WRITE_PARCEL_FILE_DESCRIPTOR_TRANSACTION: {
@@ -1475,8 +1602,7 @@
             case BINDER_LIB_TEST_ECHO_VECTOR: {
                 std::vector<uint64_t> vector;
                 auto err = data.readUint64Vector(&vector);
-                if (err != NO_ERROR)
-                    return err;
+                if (err != NO_ERROR) return err;
                 reply->writeUint64Vector(vector);
                 return NO_ERROR;
             }
@@ -1488,23 +1614,33 @@
             }
             default:
                 return UNKNOWN_TRANSACTION;
-            };
-        }
-    private:
-        int32_t m_id;
-        int32_t m_nextServerId;
-        pthread_mutex_t m_serverWaitMutex;
-        pthread_cond_t m_serverWaitCond;
-        bool m_serverStartRequested;
-        sp<IBinder> m_serverStarted;
-        sp<IBinder> m_strongRef;
-        sp<IBinder> m_callback;
+        };
+    }
+
+private:
+    int32_t m_id;
+    int32_t m_nextServerId;
+    pthread_mutex_t m_serverWaitMutex;
+    pthread_cond_t m_serverWaitCond;
+    bool m_serverStartRequested;
+    sp<IBinder> m_serverStarted;
+    sp<IBinder> m_strongRef;
+    sp<IBinder> m_callback;
+    bool m_exitOnDestroy;
 };
 
 int run_server(int index, int readypipefd, bool usePoll)
 {
     binderLibTestServiceName += String16(binderserversuffix);
 
+    // Testing to make sure that calls that we are serving can use getCallin*
+    // even though we don't here.
+    IPCThreadState::SpGuard spGuard{
+            .address = __builtin_frame_address(0),
+            .context = "main server thread",
+    };
+    (void)IPCThreadState::self()->pushGetCallingSpGuard(&spGuard);
+
     status_t ret;
     sp<IServiceManager> sm = defaultServiceManager();
     BinderLibTestService* testServicePtr;
diff --git a/libs/binder/tests/binderParcelTest.cpp b/libs/binder/tests/binderParcelUnitTest.cpp
similarity index 91%
rename from libs/binder/tests/binderParcelTest.cpp
rename to libs/binder/tests/binderParcelUnitTest.cpp
index 841d47b..4950b23 100644
--- a/libs/binder/tests/binderParcelTest.cpp
+++ b/libs/binder/tests/binderParcelUnitTest.cpp
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-#include <binder/Parcel.h>
 #include <binder/IPCThreadState.h>
+#include <binder/Parcel.h>
+#include <cutils/ashmem.h>
 #include <gtest/gtest.h>
 
 using android::IPCThreadState;
@@ -146,3 +147,18 @@
 TEST_READ_WRITE_INVERSE(int8_t, Byte, {-1, 0, 1});
 TEST_READ_WRITE_INVERSE(String8, String8, {String8(), String8("a"), String8("asdf")});
 TEST_READ_WRITE_INVERSE(String16, String16, {String16(), String16("a"), String16("asdf")});
+
+TEST(Parcel, GetOpenAshmemSize) {
+    constexpr size_t kSize = 1024;
+    constexpr size_t kCount = 3;
+
+    Parcel p;
+
+    for (size_t i = 0; i < kCount; i++) {
+        int fd = ashmem_create_region("test-getOpenAshmemSize", kSize);
+        ASSERT_GE(fd, 0);
+        ASSERT_EQ(OK, p.writeFileDescriptor(fd, true /* take ownership */));
+
+        ASSERT_EQ((kSize * (i + 1)), p.getOpenAshmemSize());
+    }
+}
diff --git a/libs/binder/tests/binderRpcBenchmark.cpp b/libs/binder/tests/binderRpcBenchmark.cpp
index a457e67..52ba9b0 100644
--- a/libs/binder/tests/binderRpcBenchmark.cpp
+++ b/libs/binder/tests/binderRpcBenchmark.cpp
@@ -18,21 +18,47 @@
 #include <android-base/logging.h>
 #include <benchmark/benchmark.h>
 #include <binder/Binder.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <binder/RpcCertificateFormat.h>
+#include <binder/RpcCertificateVerifier.h>
 #include <binder/RpcServer.h>
 #include <binder/RpcSession.h>
+#include <binder/RpcTlsTestUtils.h>
+#include <binder/RpcTlsUtils.h>
+#include <binder/RpcTransportRaw.h>
+#include <binder/RpcTransportTls.h>
+#include <openssl/ssl.h>
 
 #include <thread>
 
+#include <signal.h>
+#include <sys/prctl.h>
 #include <sys/types.h>
 #include <unistd.h>
 
 using android::BBinder;
+using android::defaultServiceManager;
 using android::IBinder;
 using android::interface_cast;
+using android::IPCThreadState;
+using android::IServiceManager;
 using android::OK;
+using android::ProcessState;
+using android::RpcAuthPreSigned;
+using android::RpcCertificateFormat;
+using android::RpcCertificateVerifier;
+using android::RpcCertificateVerifierNoOp;
 using android::RpcServer;
 using android::RpcSession;
+using android::RpcTransportCtxFactory;
+using android::RpcTransportCtxFactoryRaw;
+using android::RpcTransportCtxFactoryTls;
 using android::sp;
+using android::status_t;
+using android::statusToString;
+using android::String16;
 using android::binder::Status;
 
 class MyBinderRpcBenchmark : public BnBinderRpcBenchmark {
@@ -40,34 +66,79 @@
         *out = str;
         return Status::ok();
     }
-    Status repeatBinder(const sp<IBinder>& str, sp<IBinder>* out) override {
-        *out = str;
+    Status repeatBinder(const sp<IBinder>& binder, sp<IBinder>* out) override {
+        *out = binder;
+        return Status::ok();
+    }
+    Status repeatBytes(const std::vector<uint8_t>& bytes, std::vector<uint8_t>* out) override {
+        *out = bytes;
         return Status::ok();
     }
 };
 
-static sp<RpcSession> gSession = RpcSession::make();
+enum Transport {
+    KERNEL,
+    RPC,
+    RPC_TLS,
+};
 
-void BM_getRootObject(benchmark::State& state) {
-    while (state.KeepRunning()) {
-        CHECK(gSession->getRootObject() != nullptr);
+static const std::initializer_list<int64_t> kTransportList = {
+#ifdef __BIONIC__
+        Transport::KERNEL,
+#endif
+        Transport::RPC,
+        Transport::RPC_TLS,
+};
+
+std::unique_ptr<RpcTransportCtxFactory> makeFactoryTls() {
+    auto pkey = android::makeKeyPairForSelfSignedCert();
+    CHECK_NE(pkey.get(), nullptr);
+    auto cert = android::makeSelfSignedCert(pkey.get(), android::kCertValidSeconds);
+    CHECK_NE(cert.get(), nullptr);
+
+    auto verifier = std::make_shared<RpcCertificateVerifierNoOp>(OK);
+    auto auth = std::make_unique<RpcAuthPreSigned>(std::move(pkey), std::move(cert));
+    return RpcTransportCtxFactoryTls::make(verifier, std::move(auth));
+}
+
+static sp<RpcSession> gSession = RpcSession::make();
+// Certificate validation happens during handshake and does not affect the result of benchmarks.
+// Skip certificate validation to simplify the setup process.
+static sp<RpcSession> gSessionTls = RpcSession::make(makeFactoryTls());
+#ifdef __BIONIC__
+static const String16 kKernelBinderInstance = String16(u"binderRpcBenchmark-control");
+static sp<IBinder> gKernelBinder;
+#endif
+
+static sp<IBinder> getBinderForOptions(benchmark::State& state) {
+    Transport transport = static_cast<Transport>(state.range(0));
+    switch (transport) {
+#ifdef __BIONIC__
+        case KERNEL:
+            return gKernelBinder;
+#endif
+        case RPC:
+            return gSession->getRootObject();
+        case RPC_TLS:
+            return gSessionTls->getRootObject();
+        default:
+            LOG(FATAL) << "Unknown transport value: " << transport;
+            return nullptr;
     }
 }
-BENCHMARK(BM_getRootObject);
 
 void BM_pingTransaction(benchmark::State& state) {
-    sp<IBinder> binder = gSession->getRootObject();
-    CHECK(binder != nullptr);
+    sp<IBinder> binder = getBinderForOptions(state);
 
     while (state.KeepRunning()) {
         CHECK_EQ(OK, binder->pingBinder());
     }
 }
-BENCHMARK(BM_pingTransaction);
+BENCHMARK(BM_pingTransaction)->ArgsProduct({kTransportList});
 
-void BM_repeatString(benchmark::State& state) {
-    sp<IBinder> binder = gSession->getRootObject();
-    CHECK(binder != nullptr);
+void BM_repeatTwoPageString(benchmark::State& state) {
+    sp<IBinder> binder = getBinderForOptions(state);
+
     sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
     CHECK(iface != nullptr);
 
@@ -92,10 +163,30 @@
         CHECK(ret.isOk()) << ret;
     }
 }
-BENCHMARK(BM_repeatString);
+BENCHMARK(BM_repeatTwoPageString)->ArgsProduct({kTransportList});
+
+void BM_throughputForTransportAndBytes(benchmark::State& state) {
+    sp<IBinder> binder = getBinderForOptions(state);
+    sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
+    CHECK(iface != nullptr);
+
+    std::vector<uint8_t> bytes = std::vector<uint8_t>(state.range(1));
+    for (size_t i = 0; i < bytes.size(); i++) {
+        bytes[i] = i % 256;
+    }
+
+    while (state.KeepRunning()) {
+        std::vector<uint8_t> out;
+        Status ret = iface->repeatBytes(bytes, &out);
+        CHECK(ret.isOk()) << ret;
+    }
+}
+BENCHMARK(BM_throughputForTransportAndBytes)
+        ->ArgsProduct({kTransportList,
+                       {64, 1024, 2048, 4096, 8182, 16364, 32728, 65535, 65536, 65537}});
 
 void BM_repeatBinder(benchmark::State& state) {
-    sp<IBinder> binder = gSession->getRootObject();
+    sp<IBinder> binder = getBinderForOptions(state);
     CHECK(binder != nullptr);
     sp<IBinderRpcBenchmark> iface = interface_cast<IBinderRpcBenchmark>(binder);
     CHECK(iface != nullptr);
@@ -109,29 +200,65 @@
         CHECK(ret.isOk()) << ret;
     }
 }
-BENCHMARK(BM_repeatBinder);
+BENCHMARK(BM_repeatBinder)->ArgsProduct({kTransportList});
+
+void forkRpcServer(const char* addr, const sp<RpcServer>& server) {
+    if (0 == fork()) {
+        prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
+        server->setRootObject(sp<MyBinderRpcBenchmark>::make());
+        CHECK_EQ(OK, server->setupUnixDomainServer(addr));
+        server->join();
+        exit(1);
+    }
+}
+
+void setupClient(const sp<RpcSession>& session, const char* addr) {
+    status_t status;
+    for (size_t tries = 0; tries < 5; tries++) {
+        usleep(10000);
+        status = session->setupUnixDomainClient(addr);
+        if (status == OK) break;
+    }
+    CHECK_EQ(status, OK) << "Could not connect: " << addr << ": " << statusToString(status).c_str();
+}
 
 int main(int argc, char** argv) {
     ::benchmark::Initialize(&argc, argv);
     if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
 
-    std::string addr = std::string(getenv("TMPDIR") ?: "/tmp") + "/binderRpcBenchmark";
-    (void)unlink(addr.c_str());
+    std::cerr << "Tests suffixes:" << std::endl;
+    std::cerr << "\t.../" << Transport::KERNEL << " is KERNEL" << std::endl;
+    std::cerr << "\t.../" << Transport::RPC << " is RPC" << std::endl;
+    std::cerr << "\t.../" << Transport::RPC_TLS << " is RPC with TLS" << std::endl;
 
-    std::thread([addr]() {
-        sp<RpcServer> server = RpcServer::make();
-        server->setRootObject(sp<MyBinderRpcBenchmark>::make());
-        server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
-        CHECK(server->setupUnixDomainServer(addr.c_str()));
-        server->join();
-    }).detach();
-
-    for (size_t tries = 0; tries < 5; tries++) {
-        usleep(10000);
-        if (gSession->setupUnixDomainClient(addr.c_str())) goto success;
+#ifdef __BIONIC__
+    if (0 == fork()) {
+        prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
+        CHECK_EQ(OK,
+                 defaultServiceManager()->addService(kKernelBinderInstance,
+                                                     sp<MyBinderRpcBenchmark>::make()));
+        IPCThreadState::self()->joinThreadPool();
+        exit(1);
     }
-    LOG(FATAL) << "Could not connect.";
-success:
+
+    ProcessState::self()->setThreadPoolMaxThreadCount(1);
+    ProcessState::self()->startThreadPool();
+
+    gKernelBinder = defaultServiceManager()->waitForService(kKernelBinderInstance);
+    CHECK_NE(nullptr, gKernelBinder.get());
+#endif
+
+    std::string tmp = getenv("TMPDIR") ?: "/tmp";
+
+    std::string addr = tmp + "/binderRpcBenchmark";
+    (void)unlink(addr.c_str());
+    forkRpcServer(addr.c_str(), RpcServer::make(RpcTransportCtxFactoryRaw::make()));
+    setupClient(gSession, addr.c_str());
+
+    std::string tlsAddr = tmp + "/binderRpcTlsBenchmark";
+    (void)unlink(tlsAddr.c_str());
+    forkRpcServer(tlsAddr.c_str(), RpcServer::make(makeFactoryTls()));
+    setupClient(gSessionTls, tlsAddr.c_str());
 
     ::benchmark::RunSpecifiedBenchmarks();
     return 0;
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index a96deb5..5a96b78 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -14,34 +14,84 @@
  * limitations under the License.
  */
 
+#include <BinderRpcTestClientInfo.h>
+#include <BinderRpcTestServerInfo.h>
+#include <BnBinderRpcCallback.h>
 #include <BnBinderRpcSession.h>
 #include <BnBinderRpcTest.h>
 #include <aidl/IBinderRpcTest.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/properties.h>
 #include <android/binder_auto_utils.h>
 #include <android/binder_libbinder.h>
 #include <binder/Binder.h>
 #include <binder/BpBinder.h>
+#include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 #include <binder/RpcServer.h>
 #include <binder/RpcSession.h>
+#include <binder/RpcTlsTestUtils.h>
+#include <binder/RpcTlsUtils.h>
+#include <binder/RpcTransport.h>
+#include <binder/RpcTransportRaw.h>
+#include <binder/RpcTransportTls.h>
 #include <gtest/gtest.h>
 
 #include <chrono>
 #include <cstdlib>
 #include <iostream>
 #include <thread>
+#include <type_traits>
 
+#include <poll.h>
 #include <sys/prctl.h>
 #include <unistd.h>
 
-#include "../RpcState.h"   // for debugging
-#include "../vm_sockets.h" // for VMADDR_*
+#include "../FdTrigger.h"
+#include "../RpcSocketAddress.h" // for testing preconnected clients
+#include "../RpcState.h"         // for debugging
+#include "../vm_sockets.h"       // for VMADDR_*
+
+using namespace std::chrono_literals;
+using namespace std::placeholders;
+using testing::AssertionFailure;
+using testing::AssertionResult;
+using testing::AssertionSuccess;
 
 namespace android {
 
+static_assert(RPC_WIRE_PROTOCOL_VERSION + 1 == RPC_WIRE_PROTOCOL_VERSION_NEXT ||
+              RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
+const char* kLocalInetAddress = "127.0.0.1";
+
+enum class RpcSecurity { RAW, TLS };
+
+static inline std::vector<RpcSecurity> RpcSecurityValues() {
+    return {RpcSecurity::RAW, RpcSecurity::TLS};
+}
+
+static inline std::unique_ptr<RpcTransportCtxFactory> newFactory(
+        RpcSecurity rpcSecurity, std::shared_ptr<RpcCertificateVerifier> verifier = nullptr,
+        std::unique_ptr<RpcAuth> auth = nullptr) {
+    switch (rpcSecurity) {
+        case RpcSecurity::RAW:
+            return RpcTransportCtxFactoryRaw::make();
+        case RpcSecurity::TLS: {
+            if (verifier == nullptr) {
+                verifier = std::make_shared<RpcCertificateVerifierSimple>();
+            }
+            if (auth == nullptr) {
+                auth = std::make_unique<RpcAuthSelfSigned>();
+            }
+            return RpcTransportCtxFactoryTls::make(std::move(verifier), std::move(auth));
+        }
+        default:
+            LOG_ALWAYS_FATAL("Unknown RpcSecurity %d", rpcSecurity);
+    }
+}
+
 TEST(BinderRpcParcel, EntireParcelFormatted) {
     Parcel p;
     p.writeInt32(3);
@@ -49,19 +99,38 @@
     EXPECT_DEATH(p.markForBinder(sp<BBinder>::make()), "");
 }
 
-TEST(BinderRpc, SetExternalServer) {
+class BinderRpcSimple : public ::testing::TestWithParam<RpcSecurity> {
+public:
+    static std::string PrintTestParam(const ::testing::TestParamInfo<ParamType>& info) {
+        return newFactory(info.param)->toCString();
+    }
+};
+
+TEST_P(BinderRpcSimple, SetExternalServerTest) {
     base::unique_fd sink(TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR)));
     int sinkFd = sink.get();
-    auto server = RpcServer::make();
-    server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
+    auto server = RpcServer::make(newFactory(GetParam()));
     ASSERT_FALSE(server->hasServer());
-    ASSERT_TRUE(server->setupExternalServer(std::move(sink)));
+    ASSERT_EQ(OK, server->setupExternalServer(std::move(sink)));
     ASSERT_TRUE(server->hasServer());
     base::unique_fd retrieved = server->releaseServer();
     ASSERT_FALSE(server->hasServer());
     ASSERT_EQ(sinkFd, retrieved.get());
 }
 
+TEST(BinderRpc, CannotUseNextWireVersion) {
+    auto session = RpcSession::make();
+    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT));
+    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT + 1));
+    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT + 2));
+    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT + 15));
+}
+
+TEST(BinderRpc, CanUseExperimentalWireVersion) {
+    auto session = RpcSession::make();
+    EXPECT_TRUE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL));
+}
+
 using android::binder::Status;
 
 #define EXPECT_OK(status)                 \
@@ -86,9 +155,26 @@
 };
 std::atomic<int32_t> MyBinderRpcSession::gNum;
 
+class MyBinderRpcCallback : public BnBinderRpcCallback {
+    Status sendCallback(const std::string& value) {
+        std::unique_lock _l(mMutex);
+        mValues.push_back(value);
+        _l.unlock();
+        mCv.notify_one();
+        return Status::ok();
+    }
+    Status sendOnewayCallback(const std::string& value) { return sendCallback(value); }
+
+public:
+    std::mutex mMutex;
+    std::condition_variable mCv;
+    std::vector<std::string> mValues;
+};
+
 class MyBinderRpcTest : public BnBinderRpcTest {
 public:
     wp<RpcServer> server;
+    int port = 0;
 
     Status sendString(const std::string& str) override {
         (void)str;
@@ -98,6 +184,10 @@
         *strstr = str + str;
         return Status::ok();
     }
+    Status getClientPort(int* out) override {
+        *out = port;
+        return Status::ok();
+    }
     Status countBinders(std::vector<int32_t>* out) override {
         sp<RpcServer> spServer = server.promote();
         if (spServer == nullptr) {
@@ -106,11 +196,6 @@
         out->clear();
         for (auto session : spServer->listSessions()) {
             size_t count = session->state()->countBinders();
-            if (count != 1) {
-                // this is called when there is only one binder held remaining,
-                // so to aid debugging
-                session->state()->dump();
-            }
             out->push_back(count);
         }
         return Status::ok();
@@ -184,6 +269,33 @@
         return sleepMs(ms);
     }
 
+    Status doCallback(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
+                      const std::string& value) override {
+        if (callback == nullptr) {
+            return Status::fromExceptionCode(Status::EX_NULL_POINTER);
+        }
+
+        if (delayed) {
+            std::thread([=]() {
+                ALOGE("Executing delayed callback: '%s'", value.c_str());
+                Status status = doCallback(callback, oneway, false, value);
+                ALOGE("Delayed callback status: '%s'", status.toString8().c_str());
+            }).detach();
+            return Status::ok();
+        }
+
+        if (oneway) {
+            return callback->sendOnewayCallback(value);
+        }
+
+        return callback->sendCallback(value);
+    }
+
+    Status doCallbackAsync(const sp<IBinderRpcCallback>& callback, bool oneway, bool delayed,
+                           const std::string& value) override {
+        return doCallback(callback, oneway, delayed, value);
+    }
+
     Status die(bool cleanup) override {
         if (cleanup) {
             exit(1);
@@ -191,50 +303,73 @@
             _exit(1);
         }
     }
+
+    Status scheduleShutdown() override {
+        sp<RpcServer> strongServer = server.promote();
+        if (strongServer == nullptr) {
+            return Status::fromExceptionCode(Status::EX_NULL_POINTER);
+        }
+        std::thread([=] {
+            LOG_ALWAYS_FATAL_IF(!strongServer->shutdown(), "Could not shutdown");
+        }).detach();
+        return Status::ok();
+    }
+
+    Status useKernelBinderCallingId() override {
+        // this is WRONG! It does not make sense when using RPC binder, and
+        // because it is SO wrong, and so much code calls this, it should abort!
+
+        (void)IPCThreadState::self()->getCallingPid();
+        return Status::ok();
+    }
 };
 sp<IBinder> MyBinderRpcTest::mHeldBinder;
 
-class Pipe {
-public:
-    Pipe() { CHECK(android::base::Pipe(&mRead, &mWrite)); }
-    Pipe(Pipe&&) = default;
-    android::base::borrowed_fd readEnd() { return mRead; }
-    android::base::borrowed_fd writeEnd() { return mWrite; }
-
-private:
-    android::base::unique_fd mRead;
-    android::base::unique_fd mWrite;
-};
-
 class Process {
 public:
     Process(Process&&) = default;
-    Process(const std::function<void(Pipe*)>& f) {
+    Process(const std::function<void(android::base::borrowed_fd /* writeEnd */,
+                                     android::base::borrowed_fd /* readEnd */)>& f) {
+        android::base::unique_fd childWriteEnd;
+        android::base::unique_fd childReadEnd;
+        CHECK(android::base::Pipe(&mReadEnd, &childWriteEnd)) << strerror(errno);
+        CHECK(android::base::Pipe(&childReadEnd, &mWriteEnd)) << strerror(errno);
         if (0 == (mPid = fork())) {
             // racey: assume parent doesn't crash before this is set
             prctl(PR_SET_PDEATHSIG, SIGHUP);
 
-            f(&mPipe);
+            f(childWriteEnd, childReadEnd);
+
+            exit(0);
         }
     }
     ~Process() {
         if (mPid != 0) {
-            kill(mPid, SIGKILL);
+            waitpid(mPid, nullptr, 0);
         }
     }
-    Pipe* getPipe() { return &mPipe; }
+    android::base::borrowed_fd readEnd() { return mReadEnd; }
+    android::base::borrowed_fd writeEnd() { return mWriteEnd; }
 
 private:
     pid_t mPid = 0;
-    Pipe mPipe;
+    android::base::unique_fd mReadEnd;
+    android::base::unique_fd mWriteEnd;
 };
 
 static std::string allocateSocketAddress() {
     static size_t id = 0;
     std::string temp = getenv("TMPDIR") ?: "/tmp";
-    return temp + "/binderRpcTest_" + std::to_string(id++);
+    auto ret = temp + "/binderRpcTest_" + std::to_string(id++);
+    unlink(ret.c_str());
+    return ret;
 };
 
+static unsigned int allocateVsockPort() {
+    static unsigned int vsockPort = 3456;
+    return vsockPort++;
+}
+
 struct ProcessSession {
     // reference to process hosting a socket server
     Process host;
@@ -280,11 +415,14 @@
     sp<IBinderRpcTest> rootIface;
 
     // whether session should be invalidated by end of run
-    bool expectInvalid = false;
+    bool expectAlreadyShutdown = false;
 
     BinderRpcTestProcessSession(BinderRpcTestProcessSession&&) = default;
     ~BinderRpcTestProcessSession() {
-        if (!expectInvalid) {
+        EXPECT_NE(nullptr, rootIface);
+        if (rootIface == nullptr) return;
+
+        if (!expectAlreadyShutdown) {
             std::vector<int32_t> remoteCounts;
             // calling over any sessions counts across all sessions
             EXPECT_OK(rootIface->countBinders(&remoteCounts));
@@ -292,6 +430,12 @@
             for (auto remoteCount : remoteCounts) {
                 EXPECT_EQ(remoteCount, 1);
             }
+
+            // even though it is on another thread, shutdown races with
+            // the transaction reply being written
+            if (auto status = rootIface->scheduleShutdown(); !status.isOk()) {
+                EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status;
+            }
         }
 
         rootIface = nullptr;
@@ -300,12 +444,15 @@
 };
 
 enum class SocketType {
+    PRECONNECTED,
     UNIX,
     VSOCK,
     INET,
 };
-static inline std::string PrintSocketType(const testing::TestParamInfo<SocketType>& info) {
-    switch (info.param) {
+static inline std::string PrintToString(SocketType socketType) {
+    switch (socketType) {
+        case SocketType::PRECONNECTED:
+            return "preconnected_uds";
         case SocketType::UNIX:
             return "unix_domain_socket";
         case SocketType::VSOCK:
@@ -317,40 +464,100 @@
             return "";
     }
 }
-class BinderRpc : public ::testing::TestWithParam<SocketType> {
+
+static base::unique_fd connectTo(const RpcSocketAddress& addr) {
+    base::unique_fd serverFd(
+            TEMP_FAILURE_RETRY(socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0)));
+    int savedErrno = errno;
+    CHECK(serverFd.ok()) << "Could not create socket " << addr.toString() << ": "
+                         << strerror(savedErrno);
+
+    if (0 != TEMP_FAILURE_RETRY(connect(serverFd.get(), addr.addr(), addr.addrSize()))) {
+        int savedErrno = errno;
+        LOG(FATAL) << "Could not connect to socket " << addr.toString() << ": "
+                   << strerror(savedErrno);
+    }
+    return serverFd;
+}
+
+class BinderRpc : public ::testing::TestWithParam<std::tuple<SocketType, RpcSecurity>> {
 public:
+    struct Options {
+        size_t numThreads = 1;
+        size_t numSessions = 1;
+        size_t numIncomingConnections = 0;
+        size_t numOutgoingConnections = SIZE_MAX;
+    };
+
+    static inline std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
+        auto [type, security] = info.param;
+        return PrintToString(type) + "_" + newFactory(security)->toCString();
+    }
+
+    static inline void writeString(android::base::borrowed_fd fd, std::string_view str) {
+        uint64_t length = str.length();
+        CHECK(android::base::WriteFully(fd, &length, sizeof(length)));
+        CHECK(android::base::WriteFully(fd, str.data(), str.length()));
+    }
+
+    static inline std::string readString(android::base::borrowed_fd fd) {
+        uint64_t length;
+        CHECK(android::base::ReadFully(fd, &length, sizeof(length)));
+        std::string ret(length, '\0');
+        CHECK(android::base::ReadFully(fd, ret.data(), length));
+        return ret;
+    }
+
+    static inline void writeToFd(android::base::borrowed_fd fd, const Parcelable& parcelable) {
+        Parcel parcel;
+        CHECK_EQ(OK, parcelable.writeToParcel(&parcel));
+        writeString(fd,
+                    std::string(reinterpret_cast<const char*>(parcel.data()), parcel.dataSize()));
+    }
+
+    template <typename T>
+    static inline T readFromFd(android::base::borrowed_fd fd) {
+        std::string data = readString(fd);
+        Parcel parcel;
+        CHECK_EQ(OK, parcel.setData(reinterpret_cast<const uint8_t*>(data.data()), data.size()));
+        T object;
+        CHECK_EQ(OK, object.readFromParcel(&parcel));
+        return object;
+    }
+
     // This creates a new process serving an interface on a certain number of
     // threads.
     ProcessSession createRpcTestSocketServerProcess(
-            size_t numThreads, size_t numSessions,
-            const std::function<void(const sp<RpcServer>&)>& configure) {
-        CHECK_GE(numSessions, 1) << "Must have at least one session to a server";
+            const Options& options, const std::function<void(const sp<RpcServer>&)>& configure) {
+        CHECK_GE(options.numSessions, 1) << "Must have at least one session to a server";
 
-        SocketType socketType = GetParam();
+        SocketType socketType = std::get<0>(GetParam());
+        RpcSecurity rpcSecurity = std::get<1>(GetParam());
 
+        unsigned int vsockPort = allocateVsockPort();
         std::string addr = allocateSocketAddress();
-        unlink(addr.c_str());
-        static unsigned int vsockPort = 3456;
-        vsockPort++;
 
         auto ret = ProcessSession{
-                .host = Process([&](Pipe* pipe) {
-                    sp<RpcServer> server = RpcServer::make();
+                .host = Process([&](android::base::borrowed_fd writeEnd,
+                                    android::base::borrowed_fd readEnd) {
+                    auto certVerifier = std::make_shared<RpcCertificateVerifierSimple>();
+                    sp<RpcServer> server = RpcServer::make(newFactory(rpcSecurity, certVerifier));
 
-                    server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
-                    server->setMaxThreads(numThreads);
+                    server->setMaxThreads(options.numThreads);
 
                     unsigned int outPort = 0;
 
                     switch (socketType) {
+                        case SocketType::PRECONNECTED:
+                            [[fallthrough]];
                         case SocketType::UNIX:
-                            CHECK(server->setupUnixDomainServer(addr.c_str())) << addr;
+                            CHECK_EQ(OK, server->setupUnixDomainServer(addr.c_str())) << addr;
                             break;
                         case SocketType::VSOCK:
-                            CHECK(server->setupVsockServer(vsockPort));
+                            CHECK_EQ(OK, server->setupVsockServer(vsockPort));
                             break;
                         case SocketType::INET: {
-                            CHECK(server->setupInetServer(0, &outPort));
+                            CHECK_EQ(OK, server->setupInetServer(kLocalInetAddress, 0, &outPort));
                             CHECK_NE(0, outPort);
                             break;
                         }
@@ -358,53 +565,123 @@
                             LOG_ALWAYS_FATAL("Unknown socket type");
                     }
 
-                    CHECK(android::base::WriteFully(pipe->writeEnd(), &outPort, sizeof(outPort)));
+                    BinderRpcTestServerInfo serverInfo;
+                    serverInfo.port = static_cast<int64_t>(outPort);
+                    serverInfo.cert.data = server->getCertificate(RpcCertificateFormat::PEM);
+                    writeToFd(writeEnd, serverInfo);
+                    auto clientInfo = readFromFd<BinderRpcTestClientInfo>(readEnd);
+
+                    if (rpcSecurity == RpcSecurity::TLS) {
+                        for (const auto& clientCert : clientInfo.certs) {
+                            CHECK_EQ(OK,
+                                     certVerifier
+                                             ->addTrustedPeerCertificate(RpcCertificateFormat::PEM,
+                                                                         clientCert.data));
+                        }
+                    }
 
                     configure(server);
 
                     server->join();
+
+                    // Another thread calls shutdown. Wait for it to complete.
+                    (void)server->shutdown();
                 }),
         };
 
-        // always read socket, so that we have waited for the server to start
-        unsigned int outPort = 0;
-        CHECK(android::base::ReadFully(ret.host.getPipe()->readEnd(), &outPort, sizeof(outPort)));
-        if (socketType == SocketType::INET) {
-            CHECK_NE(0, outPort);
+        std::vector<sp<RpcSession>> sessions;
+        auto certVerifier = std::make_shared<RpcCertificateVerifierSimple>();
+        for (size_t i = 0; i < options.numSessions; i++) {
+            sessions.emplace_back(RpcSession::make(newFactory(rpcSecurity, certVerifier)));
         }
 
-        for (size_t i = 0; i < numSessions; i++) {
-            sp<RpcSession> session = RpcSession::make();
+        auto serverInfo = readFromFd<BinderRpcTestServerInfo>(ret.host.readEnd());
+        BinderRpcTestClientInfo clientInfo;
+        for (const auto& session : sessions) {
+            auto& parcelableCert = clientInfo.certs.emplace_back();
+            parcelableCert.data = session->getCertificate(RpcCertificateFormat::PEM);
+        }
+        writeToFd(ret.host.writeEnd(), clientInfo);
+
+        CHECK_LE(serverInfo.port, std::numeric_limits<unsigned int>::max());
+        if (socketType == SocketType::INET) {
+            CHECK_NE(0, serverInfo.port);
+        }
+
+        if (rpcSecurity == RpcSecurity::TLS) {
+            const auto& serverCert = serverInfo.cert.data;
+            CHECK_EQ(OK,
+                     certVerifier->addTrustedPeerCertificate(RpcCertificateFormat::PEM,
+                                                             serverCert));
+        }
+
+        status_t status;
+
+        for (const auto& session : sessions) {
+            session->setMaxIncomingThreads(options.numIncomingConnections);
+            session->setMaxOutgoingThreads(options.numOutgoingConnections);
+
             switch (socketType) {
+                case SocketType::PRECONNECTED:
+                    status = session->setupPreconnectedClient({}, [=]() {
+                        return connectTo(UnixSocketAddress(addr.c_str()));
+                    });
+                    break;
                 case SocketType::UNIX:
-                    if (session->setupUnixDomainClient(addr.c_str())) goto success;
+                    status = session->setupUnixDomainClient(addr.c_str());
                     break;
                 case SocketType::VSOCK:
-                    if (session->setupVsockClient(VMADDR_CID_LOCAL, vsockPort)) goto success;
+                    status = session->setupVsockClient(VMADDR_CID_LOCAL, vsockPort);
                     break;
                 case SocketType::INET:
-                    if (session->setupInetClient("127.0.0.1", outPort)) goto success;
+                    status = session->setupInetClient("127.0.0.1", serverInfo.port);
                     break;
                 default:
                     LOG_ALWAYS_FATAL("Unknown socket type");
             }
-            LOG_ALWAYS_FATAL("Could not connect");
-        success:
+            CHECK_EQ(status, OK) << "Could not connect: " << statusToString(status);
             ret.sessions.push_back({session, session->getRootObject()});
         }
         return ret;
     }
 
-    BinderRpcTestProcessSession createRpcTestSocketServerProcess(size_t numThreads,
-                                                                 size_t numSessions = 1) {
+    BinderRpcTestProcessSession createRpcTestSocketServerProcess(const Options& options) {
         BinderRpcTestProcessSession ret{
-                .proc = createRpcTestSocketServerProcess(numThreads, numSessions,
-                                                         [&](const sp<RpcServer>& server) {
-                                                             sp<MyBinderRpcTest> service =
-                                                                     new MyBinderRpcTest;
-                                                             server->setRootObject(service);
-                                                             service->server = server;
-                                                         }),
+                .proc = createRpcTestSocketServerProcess(
+                        options,
+                        [&](const sp<RpcServer>& server) {
+                            server->setPerSessionRootObject([&](const sockaddr* addr,
+                                                                socklen_t len) {
+                                sp<MyBinderRpcTest> service = sp<MyBinderRpcTest>::make();
+                                switch (addr->sa_family) {
+                                    case AF_UNIX:
+                                        // nothing to save
+                                        break;
+                                    case AF_VSOCK:
+                                        CHECK_EQ(len, sizeof(sockaddr_vm));
+                                        service->port = reinterpret_cast<const sockaddr_vm*>(addr)
+                                                                ->svm_port;
+                                        break;
+                                    case AF_INET:
+                                        CHECK_EQ(len, sizeof(sockaddr_in));
+                                        service->port =
+                                                ntohs(reinterpret_cast<const sockaddr_in*>(addr)
+                                                              ->sin_port);
+                                        break;
+                                    case AF_INET6:
+                                        CHECK_EQ(len, sizeof(sockaddr_in));
+                                        service->port =
+                                                ntohs(reinterpret_cast<const sockaddr_in6*>(addr)
+                                                              ->sin6_port);
+                                        break;
+                                    default:
+                                        LOG_ALWAYS_FATAL("Unrecognized address family %d",
+                                                         addr->sa_family);
+                                }
+                                service->server = server;
+                                return service;
+                            });
+                        }),
         };
 
         ret.rootBinder = ret.proc.sessions.at(0).root;
@@ -412,59 +689,82 @@
 
         return ret;
     }
+
+    void testThreadPoolOverSaturated(sp<IBinderRpcTest> iface, size_t numCalls,
+                                     size_t sleepMs = 500);
 };
 
-TEST_P(BinderRpc, RootObjectIsNull) {
-    auto proc = createRpcTestSocketServerProcess(1, 1, [](const sp<RpcServer>& server) {
-        // this is the default, but to be explicit
-        server->setRootObject(nullptr);
-    });
-
-    EXPECT_EQ(nullptr, proc.sessions.at(0).root);
-}
-
 TEST_P(BinderRpc, Ping) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
     ASSERT_NE(proc.rootBinder, nullptr);
     EXPECT_EQ(OK, proc.rootBinder->pingBinder());
 }
 
 TEST_P(BinderRpc, GetInterfaceDescriptor) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
     ASSERT_NE(proc.rootBinder, nullptr);
     EXPECT_EQ(IBinderRpcTest::descriptor, proc.rootBinder->getInterfaceDescriptor());
 }
 
 TEST_P(BinderRpc, MultipleSessions) {
-    auto proc = createRpcTestSocketServerProcess(1 /*threads*/, 5 /*sessions*/);
+    auto proc = createRpcTestSocketServerProcess({.numThreads = 1, .numSessions = 5});
     for (auto session : proc.proc.sessions) {
         ASSERT_NE(nullptr, session.root);
         EXPECT_EQ(OK, session.root->pingBinder());
     }
 }
 
+TEST_P(BinderRpc, SeparateRootObject) {
+    SocketType type = std::get<0>(GetParam());
+    if (type == SocketType::PRECONNECTED || type == SocketType::UNIX) {
+        // we can't get port numbers for unix sockets
+        return;
+    }
+
+    auto proc = createRpcTestSocketServerProcess({.numSessions = 2});
+
+    int port1 = 0;
+    EXPECT_OK(proc.rootIface->getClientPort(&port1));
+
+    sp<IBinderRpcTest> rootIface2 = interface_cast<IBinderRpcTest>(proc.proc.sessions.at(1).root);
+    int port2;
+    EXPECT_OK(rootIface2->getClientPort(&port2));
+
+    // we should have a different IBinderRpcTest object created for each
+    // session, because we use setPerSessionRootObject
+    EXPECT_NE(port1, port2);
+}
+
 TEST_P(BinderRpc, TransactionsMustBeMarkedRpc) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
     Parcel data;
     Parcel reply;
     EXPECT_EQ(BAD_TYPE, proc.rootBinder->transact(IBinder::PING_TRANSACTION, data, &reply, 0));
 }
 
 TEST_P(BinderRpc, AppendSeparateFormats) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc1 = createRpcTestSocketServerProcess({});
+    auto proc2 = createRpcTestSocketServerProcess({});
+
+    Parcel pRaw;
 
     Parcel p1;
-    p1.markForBinder(proc.rootBinder);
+    p1.markForBinder(proc1.rootBinder);
     p1.writeInt32(3);
 
+    EXPECT_EQ(BAD_TYPE, p1.appendFrom(&pRaw, 0, p1.dataSize()));
+    EXPECT_EQ(BAD_TYPE, pRaw.appendFrom(&p1, 0, p1.dataSize()));
+
     Parcel p2;
+    p2.markForBinder(proc2.rootBinder);
+    p2.writeInt32(7);
 
     EXPECT_EQ(BAD_TYPE, p1.appendFrom(&p2, 0, p2.dataSize()));
     EXPECT_EQ(BAD_TYPE, p2.appendFrom(&p1, 0, p1.dataSize()));
 }
 
 TEST_P(BinderRpc, UnknownTransaction) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
     Parcel data;
     data.markForBinder(proc.rootBinder);
     Parcel reply;
@@ -472,19 +772,19 @@
 }
 
 TEST_P(BinderRpc, SendSomethingOneway) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
     EXPECT_OK(proc.rootIface->sendString("asdf"));
 }
 
 TEST_P(BinderRpc, SendAndGetResultBack) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
     std::string doubled;
     EXPECT_OK(proc.rootIface->doubleString("cool ", &doubled));
     EXPECT_EQ("cool cool ", doubled);
 }
 
 TEST_P(BinderRpc, SendAndGetResultBackBig) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
     std::string single = std::string(1024, 'a');
     std::string doubled;
     EXPECT_OK(proc.rootIface->doubleString(single, &doubled));
@@ -492,7 +792,7 @@
 }
 
 TEST_P(BinderRpc, CallMeBack) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     int32_t pingResult;
     EXPECT_OK(proc.rootIface->pingMe(new MyBinderRpcSession("foo"), &pingResult));
@@ -502,7 +802,7 @@
 }
 
 TEST_P(BinderRpc, RepeatBinder) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     sp<IBinder> inBinder = new MyBinderRpcSession("foo");
     sp<IBinder> outBinder;
@@ -524,7 +824,7 @@
 }
 
 TEST_P(BinderRpc, RepeatTheirBinder) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     sp<IBinderRpcSession> session;
     EXPECT_OK(proc.rootIface->openSession("aoeu", &session));
@@ -548,7 +848,7 @@
 }
 
 TEST_P(BinderRpc, RepeatBinderNull) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     sp<IBinder> outBinder;
     EXPECT_OK(proc.rootIface->repeatBinder(nullptr, &outBinder));
@@ -556,7 +856,7 @@
 }
 
 TEST_P(BinderRpc, HoldBinder) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     IBinder* ptr = nullptr;
     {
@@ -582,8 +882,8 @@
 // aren't supported.
 
 TEST_P(BinderRpc, CannotMixBindersBetweenUnrelatedSocketSessions) {
-    auto proc1 = createRpcTestSocketServerProcess(1);
-    auto proc2 = createRpcTestSocketServerProcess(1);
+    auto proc1 = createRpcTestSocketServerProcess({});
+    auto proc2 = createRpcTestSocketServerProcess({});
 
     sp<IBinder> outBinder;
     EXPECT_EQ(INVALID_OPERATION,
@@ -591,7 +891,7 @@
 }
 
 TEST_P(BinderRpc, CannotMixBindersBetweenTwoSessionsToTheSameServer) {
-    auto proc = createRpcTestSocketServerProcess(1 /*threads*/, 2 /*sessions*/);
+    auto proc = createRpcTestSocketServerProcess({.numThreads = 1, .numSessions = 2});
 
     sp<IBinder> outBinder;
     EXPECT_EQ(INVALID_OPERATION,
@@ -600,7 +900,7 @@
 }
 
 TEST_P(BinderRpc, CannotSendRegularBinderOverSocketBinder) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     sp<IBinder> someRealBinder = IInterface::asBinder(defaultServiceManager());
     sp<IBinder> outBinder;
@@ -609,7 +909,7 @@
 }
 
 TEST_P(BinderRpc, CannotSendSocketBinderOverRegularBinder) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     // for historical reasons, IServiceManager interface only returns the
     // exception code
@@ -620,7 +920,7 @@
 // END TESTS FOR LIMITATIONS OF SOCKET BINDER
 
 TEST_P(BinderRpc, RepeatRootObject) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     sp<IBinder> outBinder;
     EXPECT_OK(proc.rootIface->repeatBinder(proc.rootBinder, &outBinder));
@@ -628,7 +928,7 @@
 }
 
 TEST_P(BinderRpc, NestedTransactions) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     auto nastyNester = sp<MyBinderRpcTest>::make();
     EXPECT_OK(proc.rootIface->nestMe(nastyNester, 10));
@@ -639,7 +939,7 @@
 }
 
 TEST_P(BinderRpc, SameBinderEquality) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     sp<IBinder> a;
     EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&a));
@@ -651,7 +951,7 @@
 }
 
 TEST_P(BinderRpc, SameBinderEqualityWeak) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     sp<IBinder> a;
     EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&a));
@@ -683,7 +983,7 @@
     } while (false)
 
 TEST_P(BinderRpc, SingleSession) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     sp<IBinderRpcSession> session;
     EXPECT_OK(proc.rootIface->openSession("aoeu", &session));
@@ -697,7 +997,7 @@
 }
 
 TEST_P(BinderRpc, ManySessions) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     std::vector<sp<IBinderRpcSession>> sessions;
 
@@ -733,7 +1033,7 @@
 TEST_P(BinderRpc, ThreadPoolGreaterThanEqualRequested) {
     constexpr size_t kNumThreads = 10;
 
-    auto proc = createRpcTestSocketServerProcess(kNumThreads);
+    auto proc = createRpcTestSocketServerProcess({.numThreads = kNumThreads});
 
     EXPECT_OK(proc.rootIface->lock());
 
@@ -762,28 +1062,39 @@
     for (auto& t : ts) t.join();
 }
 
-TEST_P(BinderRpc, ThreadPoolOverSaturated) {
-    constexpr size_t kNumThreads = 10;
-    constexpr size_t kNumCalls = kNumThreads + 3;
-    constexpr size_t kSleepMs = 500;
-
-    auto proc = createRpcTestSocketServerProcess(kNumThreads);
-
+void BinderRpc::testThreadPoolOverSaturated(sp<IBinderRpcTest> iface, size_t numCalls,
+                                            size_t sleepMs) {
     size_t epochMsBefore = epochMillis();
 
     std::vector<std::thread> ts;
-    for (size_t i = 0; i < kNumCalls; i++) {
-        ts.push_back(std::thread([&] { proc.rootIface->sleepMs(kSleepMs); }));
+    for (size_t i = 0; i < numCalls; i++) {
+        ts.push_back(std::thread([&] { iface->sleepMs(sleepMs); }));
     }
 
     for (auto& t : ts) t.join();
 
     size_t epochMsAfter = epochMillis();
 
-    EXPECT_GE(epochMsAfter, epochMsBefore + 2 * kSleepMs);
+    EXPECT_GE(epochMsAfter, epochMsBefore + 2 * sleepMs);
 
     // Potential flake, but make sure calls are handled in parallel.
-    EXPECT_LE(epochMsAfter, epochMsBefore + 3 * kSleepMs);
+    EXPECT_LE(epochMsAfter, epochMsBefore + 3 * sleepMs);
+}
+
+TEST_P(BinderRpc, ThreadPoolOverSaturated) {
+    constexpr size_t kNumThreads = 10;
+    constexpr size_t kNumCalls = kNumThreads + 3;
+    auto proc = createRpcTestSocketServerProcess({.numThreads = kNumThreads});
+    testThreadPoolOverSaturated(proc.rootIface, kNumCalls);
+}
+
+TEST_P(BinderRpc, ThreadPoolLimitOutgoing) {
+    constexpr size_t kNumThreads = 20;
+    constexpr size_t kNumOutgoingConnections = 10;
+    constexpr size_t kNumCalls = kNumOutgoingConnections + 3;
+    auto proc = createRpcTestSocketServerProcess(
+            {.numThreads = kNumThreads, .numOutgoingConnections = kNumOutgoingConnections});
+    testThreadPoolOverSaturated(proc.rootIface, kNumCalls);
 }
 
 TEST_P(BinderRpc, ThreadingStressTest) {
@@ -791,7 +1102,7 @@
     constexpr size_t kNumServerThreads = 10;
     constexpr size_t kNumCalls = 100;
 
-    auto proc = createRpcTestSocketServerProcess(kNumServerThreads);
+    auto proc = createRpcTestSocketServerProcess({.numThreads = kNumServerThreads});
 
     std::vector<std::thread> threads;
     for (size_t i = 0; i < kNumClientThreads; i++) {
@@ -807,12 +1118,20 @@
     for (auto& t : threads) t.join();
 }
 
+static void saturateThreadPool(size_t threadCount, const sp<IBinderRpcTest>& iface) {
+    std::vector<std::thread> threads;
+    for (size_t i = 0; i < threadCount; i++) {
+        threads.push_back(std::thread([&] { EXPECT_OK(iface->sleepMs(500)); }));
+    }
+    for (auto& t : threads) t.join();
+}
+
 TEST_P(BinderRpc, OnewayStressTest) {
     constexpr size_t kNumClientThreads = 10;
     constexpr size_t kNumServerThreads = 10;
-    constexpr size_t kNumCalls = 100;
+    constexpr size_t kNumCalls = 1000;
 
-    auto proc = createRpcTestSocketServerProcess(kNumServerThreads);
+    auto proc = createRpcTestSocketServerProcess({.numThreads = kNumServerThreads});
 
     std::vector<std::thread> threads;
     for (size_t i = 0; i < kNumClientThreads; i++) {
@@ -820,21 +1139,19 @@
             for (size_t j = 0; j < kNumCalls; j++) {
                 EXPECT_OK(proc.rootIface->sendString("a"));
             }
-
-            // check threads are not stuck
-            EXPECT_OK(proc.rootIface->sleepMs(250));
         }));
     }
 
     for (auto& t : threads) t.join();
+
+    saturateThreadPool(kNumServerThreads, proc.rootIface);
 }
 
 TEST_P(BinderRpc, OnewayCallDoesNotWait) {
     constexpr size_t kReallyLongTimeMs = 100;
     constexpr size_t kSleepMs = kReallyLongTimeMs * 5;
 
-    // more than one thread, just so this doesn't deadlock
-    auto proc = createRpcTestSocketServerProcess(2);
+    auto proc = createRpcTestSocketServerProcess({});
 
     size_t epochMsBefore = epochMillis();
 
@@ -850,27 +1167,126 @@
     constexpr size_t kSleepMs = 50;
 
     // make sure calls to the same object happen on the same thread
-    auto proc = createRpcTestSocketServerProcess(1 + kNumExtraServerThreads);
+    auto proc = createRpcTestSocketServerProcess({.numThreads = 1 + kNumExtraServerThreads});
 
     EXPECT_OK(proc.rootIface->lock());
 
-    for (size_t i = 0; i < kNumSleeps; i++) {
-        // these should be processed serially
+    size_t epochMsBefore = epochMillis();
+
+    // all these *Async commands should be queued on the server sequentially,
+    // even though there are multiple threads.
+    for (size_t i = 0; i + 1 < kNumSleeps; i++) {
         proc.rootIface->sleepMsAsync(kSleepMs);
     }
-    // should also be processesed serially
     EXPECT_OK(proc.rootIface->unlockInMsAsync(kSleepMs));
 
-    size_t epochMsBefore = epochMillis();
+    // this can only return once the final async call has unlocked
     EXPECT_OK(proc.rootIface->lockUnlock());
+
     size_t epochMsAfter = epochMillis();
 
     EXPECT_GT(epochMsAfter, epochMsBefore + kSleepMs * kNumSleeps);
+
+    saturateThreadPool(1 + kNumExtraServerThreads, proc.rootIface);
+}
+
+TEST_P(BinderRpc, OnewayCallExhaustion) {
+    constexpr size_t kNumClients = 2;
+    constexpr size_t kTooLongMs = 1000;
+
+    auto proc = createRpcTestSocketServerProcess({.numThreads = kNumClients, .numSessions = 2});
+
+    // Build up oneway calls on the second session to make sure it terminates
+    // and shuts down. The first session should be unaffected (proc destructor
+    // checks the first session).
+    auto iface = interface_cast<IBinderRpcTest>(proc.proc.sessions.at(1).root);
+
+    std::vector<std::thread> threads;
+    for (size_t i = 0; i < kNumClients; i++) {
+        // one of these threads will get stuck queueing a transaction once the
+        // socket fills up, the other will be able to fill up transactions on
+        // this object
+        threads.push_back(std::thread([&] {
+            while (iface->sleepMsAsync(kTooLongMs).isOk()) {
+            }
+        }));
+    }
+    for (auto& t : threads) t.join();
+
+    Status status = iface->sleepMsAsync(kTooLongMs);
+    EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status;
+
+    // now that it has died, wait for the remote session to shutdown
+    std::vector<int32_t> remoteCounts;
+    do {
+        EXPECT_OK(proc.rootIface->countBinders(&remoteCounts));
+    } while (remoteCounts.size() == kNumClients);
+
+    // the second session should be shutdown in the other process by the time we
+    // are able to join above (it'll only be hung up once it finishes processing
+    // any pending commands). We need to erase this session from the record
+    // here, so that the destructor for our session won't check that this
+    // session is valid, but we still want it to test the other session.
+    proc.proc.sessions.erase(proc.proc.sessions.begin() + 1);
+}
+
+TEST_P(BinderRpc, Callbacks) {
+    const static std::string kTestString = "good afternoon!";
+
+    for (bool callIsOneway : {true, false}) {
+        for (bool callbackIsOneway : {true, false}) {
+            for (bool delayed : {true, false}) {
+                auto proc = createRpcTestSocketServerProcess(
+                        {.numThreads = 1, .numSessions = 1, .numIncomingConnections = 1});
+                auto cb = sp<MyBinderRpcCallback>::make();
+
+                if (callIsOneway) {
+                    EXPECT_OK(proc.rootIface->doCallbackAsync(cb, callbackIsOneway, delayed,
+                                                              kTestString));
+                } else {
+                    EXPECT_OK(
+                            proc.rootIface->doCallback(cb, callbackIsOneway, delayed, kTestString));
+                }
+
+                using std::literals::chrono_literals::operator""s;
+                std::unique_lock<std::mutex> _l(cb->mMutex);
+                cb->mCv.wait_for(_l, 1s, [&] { return !cb->mValues.empty(); });
+
+                EXPECT_EQ(cb->mValues.size(), 1)
+                        << "callIsOneway: " << callIsOneway
+                        << " callbackIsOneway: " << callbackIsOneway << " delayed: " << delayed;
+                if (cb->mValues.empty()) continue;
+                EXPECT_EQ(cb->mValues.at(0), kTestString)
+                        << "callIsOneway: " << callIsOneway
+                        << " callbackIsOneway: " << callbackIsOneway << " delayed: " << delayed;
+
+                // since we are severing the connection, we need to go ahead and
+                // tell the server to shutdown and exit so that waitpid won't hang
+                if (auto status = proc.rootIface->scheduleShutdown(); !status.isOk()) {
+                    EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status;
+                }
+
+                // since this session has an incoming connection w/ a threadpool, we
+                // need to manually shut it down
+                EXPECT_TRUE(proc.proc.sessions.at(0).session->shutdownAndWait(true));
+
+                proc.expectAlreadyShutdown = true;
+            }
+        }
+    }
+}
+
+TEST_P(BinderRpc, OnewayCallbackWithNoThread) {
+    auto proc = createRpcTestSocketServerProcess({});
+    auto cb = sp<MyBinderRpcCallback>::make();
+
+    Status status = proc.rootIface->doCallback(cb, true /*oneway*/, false /*delayed*/, "anything");
+    EXPECT_EQ(WOULD_BLOCK, status.transactionError());
 }
 
 TEST_P(BinderRpc, Die) {
     for (bool doDeathCleanup : {true, false}) {
-        auto proc = createRpcTestSocketServerProcess(1);
+        auto proc = createRpcTestSocketServerProcess({});
 
         // make sure there is some state during crash
         // 1. we hold their binder
@@ -883,12 +1299,34 @@
         EXPECT_EQ(DEAD_OBJECT, proc.rootIface->die(doDeathCleanup).transactionError())
                 << "Do death cleanup: " << doDeathCleanup;
 
-        proc.expectInvalid = true;
+        proc.expectAlreadyShutdown = true;
     }
 }
 
+TEST_P(BinderRpc, UseKernelBinderCallingId) {
+    bool okToFork = ProcessState::selfOrNull() == nullptr;
+
+    auto proc = createRpcTestSocketServerProcess({});
+
+    // If this process has used ProcessState already, then the forked process
+    // cannot use it at all. If this process hasn't used it (depending on the
+    // order tests are run), then the forked process can use it, and we'll only
+    // catch the invalid usage the second time. Such is the burden of global
+    // state!
+    if (okToFork) {
+        // we can't allocate IPCThreadState so actually the first time should
+        // succeed :(
+        EXPECT_OK(proc.rootIface->useKernelBinderCallingId());
+    }
+
+    // second time! we catch the error :)
+    EXPECT_EQ(DEAD_OBJECT, proc.rootIface->useKernelBinderCallingId().transactionError());
+
+    proc.expectAlreadyShutdown = true;
+}
+
 TEST_P(BinderRpc, WorksWithLibbinderNdkPing) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     ndk::SpAIBinder binder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(proc.rootBinder));
     ASSERT_NE(binder, nullptr);
@@ -897,7 +1335,7 @@
 }
 
 TEST_P(BinderRpc, WorksWithLibbinderNdkUserTransaction) {
-    auto proc = createRpcTestSocketServerProcess(1);
+    auto proc = createRpcTestSocketServerProcess({});
 
     ndk::SpAIBinder binder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(proc.rootBinder));
     ASSERT_NE(binder, nullptr);
@@ -925,24 +1363,62 @@
     ssize_t beforeFds = countFds();
     ASSERT_GE(beforeFds, 0);
     {
-        auto proc = createRpcTestSocketServerProcess(10);
+        auto proc = createRpcTestSocketServerProcess({.numThreads = 10});
         ASSERT_EQ(OK, proc.rootBinder->pingBinder());
     }
     ASSERT_EQ(beforeFds, countFds()) << (system("ls -l /proc/self/fd/"), "fd leak?");
 }
 
-INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
-                        ::testing::ValuesIn({
-                                SocketType::UNIX,
-// TODO(b/185269356): working on host
-#ifdef __BIONIC__
-                                SocketType::VSOCK,
-#endif
-                                SocketType::INET,
-                        }),
-                        PrintSocketType);
+TEST_P(BinderRpc, AidlDelegatorTest) {
+    auto proc = createRpcTestSocketServerProcess({});
+    auto myDelegator = sp<IBinderRpcTestDelegator>::make(proc.rootIface);
+    ASSERT_NE(nullptr, myDelegator);
 
-class BinderRpcServerRootObject : public ::testing::TestWithParam<std::tuple<bool, bool>> {};
+    std::string doubled;
+    EXPECT_OK(myDelegator->doubleString("cool ", &doubled));
+    EXPECT_EQ("cool cool ", doubled);
+}
+
+static bool testSupportVsockLoopback() {
+    // We don't need to enable TLS to know if vsock is supported.
+    unsigned int vsockPort = allocateVsockPort();
+    sp<RpcServer> server = RpcServer::make(RpcTransportCtxFactoryRaw::make());
+    if (status_t status = server->setupVsockServer(vsockPort); status != OK) {
+        if (status == -EAFNOSUPPORT) {
+            return false;
+        }
+        LOG_ALWAYS_FATAL("Could not setup vsock server: %s", statusToString(status).c_str());
+    }
+    server->start();
+
+    sp<RpcSession> session = RpcSession::make(RpcTransportCtxFactoryRaw::make());
+    status_t status = session->setupVsockClient(VMADDR_CID_LOCAL, vsockPort);
+    while (!server->shutdown()) usleep(10000);
+    ALOGE("Detected vsock loopback supported: %s", statusToString(status).c_str());
+    return status == OK;
+}
+
+static std::vector<SocketType> testSocketTypes(bool hasPreconnected = true) {
+    std::vector<SocketType> ret = {SocketType::UNIX, SocketType::INET};
+
+    if (hasPreconnected) ret.push_back(SocketType::PRECONNECTED);
+
+    static bool hasVsockLoopback = testSupportVsockLoopback();
+
+    if (hasVsockLoopback) {
+        ret.push_back(SocketType::VSOCK);
+    }
+
+    return ret;
+}
+
+INSTANTIATE_TEST_CASE_P(PerSocket, BinderRpc,
+                        ::testing::Combine(::testing::ValuesIn(testSocketTypes()),
+                                           ::testing::ValuesIn(RpcSecurityValues())),
+                        BinderRpc::PrintParamInfo);
+
+class BinderRpcServerRootObject
+      : public ::testing::TestWithParam<std::tuple<bool, bool, RpcSecurity>> {};
 
 TEST_P(BinderRpcServerRootObject, WeakRootObject) {
     using SetFn = std::function<void(RpcServer*, sp<IBinder>)>;
@@ -950,8 +1426,8 @@
         return isStrong ? SetFn(&RpcServer::setRootObject) : SetFn(&RpcServer::setRootObjectWeak);
     };
 
-    auto server = RpcServer::make();
-    auto [isStrong1, isStrong2] = GetParam();
+    auto [isStrong1, isStrong2, rpcSecurity] = GetParam();
+    auto server = RpcServer::make(newFactory(rpcSecurity));
     auto binder1 = sp<BBinder>::make();
     IBinder* binderRaw1 = binder1.get();
     setRootObject(isStrong1)(server.get(), binder1);
@@ -968,12 +1444,581 @@
 }
 
 INSTANTIATE_TEST_CASE_P(BinderRpc, BinderRpcServerRootObject,
-                        ::testing::Combine(::testing::Bool(), ::testing::Bool()));
+                        ::testing::Combine(::testing::Bool(), ::testing::Bool(),
+                                           ::testing::ValuesIn(RpcSecurityValues())));
+
+class OneOffSignal {
+public:
+    // If notify() was previously called, or is called within |duration|, return true; else false.
+    template <typename R, typename P>
+    bool wait(std::chrono::duration<R, P> duration) {
+        std::unique_lock<std::mutex> lock(mMutex);
+        return mCv.wait_for(lock, duration, [this] { return mValue; });
+    }
+    void notify() {
+        std::unique_lock<std::mutex> lock(mMutex);
+        mValue = true;
+        lock.unlock();
+        mCv.notify_all();
+    }
+
+private:
+    std::mutex mMutex;
+    std::condition_variable mCv;
+    bool mValue = false;
+};
+
+TEST_P(BinderRpcSimple, Shutdown) {
+    auto addr = allocateSocketAddress();
+    auto server = RpcServer::make(newFactory(GetParam()));
+    ASSERT_EQ(OK, server->setupUnixDomainServer(addr.c_str()));
+    auto joinEnds = std::make_shared<OneOffSignal>();
+
+    // If things are broken and the thread never stops, don't block other tests. Because the thread
+    // may run after the test finishes, it must not access the stack memory of the test. Hence,
+    // shared pointers are passed.
+    std::thread([server, joinEnds] {
+        server->join();
+        joinEnds->notify();
+    }).detach();
+
+    bool shutdown = false;
+    for (int i = 0; i < 10 && !shutdown; i++) {
+        usleep(300 * 1000); // 300ms; total 3s
+        if (server->shutdown()) shutdown = true;
+    }
+    ASSERT_TRUE(shutdown) << "server->shutdown() never returns true";
+
+    ASSERT_TRUE(joinEnds->wait(2s))
+            << "After server->shutdown() returns true, join() did not stop after 2s";
+}
+
+TEST(BinderRpc, Java) {
+#if !defined(__ANDROID__)
+    GTEST_SKIP() << "This test is only run on Android. Though it can technically run on host on"
+                    "createRpcDelegateServiceManager() with a device attached, such test belongs "
+                    "to binderHostDeviceTest. Hence, just disable this test on host.";
+#endif // !__ANDROID__
+    sp<IServiceManager> sm = defaultServiceManager();
+    ASSERT_NE(nullptr, sm);
+    // Any Java service with non-empty getInterfaceDescriptor() would do.
+    // Let's pick batteryproperties.
+    auto binder = sm->checkService(String16("batteryproperties"));
+    ASSERT_NE(nullptr, binder);
+    auto descriptor = binder->getInterfaceDescriptor();
+    ASSERT_GE(descriptor.size(), 0);
+    ASSERT_EQ(OK, binder->pingBinder());
+
+    auto rpcServer = RpcServer::make();
+    unsigned int port;
+    ASSERT_EQ(OK, rpcServer->setupInetServer(kLocalInetAddress, 0, &port));
+    auto socket = rpcServer->releaseServer();
+
+    auto keepAlive = sp<BBinder>::make();
+    auto setRpcClientDebugStatus = binder->setRpcClientDebug(std::move(socket), keepAlive);
+
+    if (!android::base::GetBoolProperty("ro.debuggable", false)) {
+        ASSERT_EQ(INVALID_OPERATION, setRpcClientDebugStatus)
+                << "setRpcClientDebug should return INVALID_OPERATION on non-debuggable builds, "
+                   "but get "
+                << statusToString(setRpcClientDebugStatus);
+        GTEST_SKIP();
+    }
+
+    ASSERT_EQ(OK, setRpcClientDebugStatus);
+
+    auto rpcSession = RpcSession::make();
+    ASSERT_EQ(OK, rpcSession->setupInetClient("127.0.0.1", port));
+    auto rpcBinder = rpcSession->getRootObject();
+    ASSERT_NE(nullptr, rpcBinder);
+
+    ASSERT_EQ(OK, rpcBinder->pingBinder());
+
+    ASSERT_EQ(descriptor, rpcBinder->getInterfaceDescriptor())
+            << "getInterfaceDescriptor should not crash system_server";
+    ASSERT_EQ(OK, rpcBinder->pingBinder());
+}
+
+INSTANTIATE_TEST_CASE_P(BinderRpc, BinderRpcSimple, ::testing::ValuesIn(RpcSecurityValues()),
+                        BinderRpcSimple::PrintTestParam);
+
+class RpcTransportTestUtils {
+public:
+    using Param = std::tuple<SocketType, RpcSecurity, std::optional<RpcCertificateFormat>>;
+    using ConnectToServer = std::function<base::unique_fd()>;
+
+    // A server that handles client socket connections.
+    class Server {
+    public:
+        explicit Server() {}
+        Server(Server&&) = default;
+        ~Server() { shutdownAndWait(); }
+        [[nodiscard]] AssertionResult setUp(
+                const Param& param,
+                std::unique_ptr<RpcAuth> auth = std::make_unique<RpcAuthSelfSigned>()) {
+            auto [socketType, rpcSecurity, certificateFormat] = param;
+            auto rpcServer = RpcServer::make(newFactory(rpcSecurity));
+            switch (socketType) {
+                case SocketType::PRECONNECTED: {
+                    return AssertionFailure() << "Not supported by this test";
+                } break;
+                case SocketType::UNIX: {
+                    auto addr = allocateSocketAddress();
+                    auto status = rpcServer->setupUnixDomainServer(addr.c_str());
+                    if (status != OK) {
+                        return AssertionFailure()
+                                << "setupUnixDomainServer: " << statusToString(status);
+                    }
+                    mConnectToServer = [addr] {
+                        return connectTo(UnixSocketAddress(addr.c_str()));
+                    };
+                } break;
+                case SocketType::VSOCK: {
+                    auto port = allocateVsockPort();
+                    auto status = rpcServer->setupVsockServer(port);
+                    if (status != OK) {
+                        return AssertionFailure() << "setupVsockServer: " << statusToString(status);
+                    }
+                    mConnectToServer = [port] {
+                        return connectTo(VsockSocketAddress(VMADDR_CID_LOCAL, port));
+                    };
+                } break;
+                case SocketType::INET: {
+                    unsigned int port;
+                    auto status = rpcServer->setupInetServer(kLocalInetAddress, 0, &port);
+                    if (status != OK) {
+                        return AssertionFailure() << "setupInetServer: " << statusToString(status);
+                    }
+                    mConnectToServer = [port] {
+                        const char* addr = kLocalInetAddress;
+                        auto aiStart = InetSocketAddress::getAddrInfo(addr, port);
+                        if (aiStart == nullptr) return base::unique_fd{};
+                        for (auto ai = aiStart.get(); ai != nullptr; ai = ai->ai_next) {
+                            auto fd = connectTo(
+                                    InetSocketAddress(ai->ai_addr, ai->ai_addrlen, addr, port));
+                            if (fd.ok()) return fd;
+                        }
+                        ALOGE("None of the socket address resolved for %s:%u can be connected",
+                              addr, port);
+                        return base::unique_fd{};
+                    };
+                }
+            }
+            mFd = rpcServer->releaseServer();
+            if (!mFd.ok()) return AssertionFailure() << "releaseServer returns invalid fd";
+            mCtx = newFactory(rpcSecurity, mCertVerifier, std::move(auth))->newServerCtx();
+            if (mCtx == nullptr) return AssertionFailure() << "newServerCtx";
+            mSetup = true;
+            return AssertionSuccess();
+        }
+        RpcTransportCtx* getCtx() const { return mCtx.get(); }
+        std::shared_ptr<RpcCertificateVerifierSimple> getCertVerifier() const {
+            return mCertVerifier;
+        }
+        ConnectToServer getConnectToServerFn() { return mConnectToServer; }
+        void start() {
+            LOG_ALWAYS_FATAL_IF(!mSetup, "Call Server::setup first!");
+            mThread = std::make_unique<std::thread>(&Server::run, this);
+        }
+        void run() {
+            LOG_ALWAYS_FATAL_IF(!mSetup, "Call Server::setup first!");
+
+            std::vector<std::thread> threads;
+            while (OK == mFdTrigger->triggerablePoll(mFd, POLLIN)) {
+                base::unique_fd acceptedFd(
+                        TEMP_FAILURE_RETRY(accept4(mFd.get(), nullptr, nullptr /*length*/,
+                                                   SOCK_CLOEXEC | SOCK_NONBLOCK)));
+                threads.emplace_back(&Server::handleOne, this, std::move(acceptedFd));
+            }
+
+            for (auto& thread : threads) thread.join();
+        }
+        void handleOne(android::base::unique_fd acceptedFd) {
+            ASSERT_TRUE(acceptedFd.ok());
+            auto serverTransport = mCtx->newTransport(std::move(acceptedFd), mFdTrigger.get());
+            if (serverTransport == nullptr) return; // handshake failed
+            ASSERT_TRUE(mPostConnect(serverTransport.get(), mFdTrigger.get()));
+        }
+        void shutdownAndWait() {
+            shutdown();
+            join();
+        }
+        void shutdown() { mFdTrigger->trigger(); }
+
+        void setPostConnect(
+                std::function<AssertionResult(RpcTransport*, FdTrigger* fdTrigger)> fn) {
+            mPostConnect = std::move(fn);
+        }
+
+    private:
+        std::unique_ptr<std::thread> mThread;
+        ConnectToServer mConnectToServer;
+        std::unique_ptr<FdTrigger> mFdTrigger = FdTrigger::make();
+        base::unique_fd mFd;
+        std::unique_ptr<RpcTransportCtx> mCtx;
+        std::shared_ptr<RpcCertificateVerifierSimple> mCertVerifier =
+                std::make_shared<RpcCertificateVerifierSimple>();
+        bool mSetup = false;
+        // The function invoked after connection and handshake. By default, it is
+        // |defaultPostConnect| that sends |kMessage| to the client.
+        std::function<AssertionResult(RpcTransport*, FdTrigger* fdTrigger)> mPostConnect =
+                Server::defaultPostConnect;
+
+        void join() {
+            if (mThread != nullptr) {
+                mThread->join();
+                mThread = nullptr;
+            }
+        }
+
+        static AssertionResult defaultPostConnect(RpcTransport* serverTransport,
+                                                  FdTrigger* fdTrigger) {
+            std::string message(kMessage);
+            auto status = serverTransport->interruptableWriteFully(fdTrigger, message.data(),
+                                                                   message.size(), {});
+            if (status != OK) return AssertionFailure() << statusToString(status);
+            return AssertionSuccess();
+        }
+    };
+
+    class Client {
+    public:
+        explicit Client(ConnectToServer connectToServer) : mConnectToServer(connectToServer) {}
+        Client(Client&&) = default;
+        [[nodiscard]] AssertionResult setUp(const Param& param) {
+            auto [socketType, rpcSecurity, certificateFormat] = param;
+            mFdTrigger = FdTrigger::make();
+            mCtx = newFactory(rpcSecurity, mCertVerifier)->newClientCtx();
+            if (mCtx == nullptr) return AssertionFailure() << "newClientCtx";
+            return AssertionSuccess();
+        }
+        RpcTransportCtx* getCtx() const { return mCtx.get(); }
+        std::shared_ptr<RpcCertificateVerifierSimple> getCertVerifier() const {
+            return mCertVerifier;
+        }
+        // connect() and do handshake
+        bool setUpTransport() {
+            mFd = mConnectToServer();
+            if (!mFd.ok()) return AssertionFailure() << "Cannot connect to server";
+            mClientTransport = mCtx->newTransport(std::move(mFd), mFdTrigger.get());
+            return mClientTransport != nullptr;
+        }
+        AssertionResult readMessage(const std::string& expectedMessage = kMessage) {
+            LOG_ALWAYS_FATAL_IF(mClientTransport == nullptr, "setUpTransport not called or failed");
+            std::string readMessage(expectedMessage.size(), '\0');
+            status_t readStatus =
+                    mClientTransport->interruptableReadFully(mFdTrigger.get(), readMessage.data(),
+                                                             readMessage.size(), {});
+            if (readStatus != OK) {
+                return AssertionFailure() << statusToString(readStatus);
+            }
+            if (readMessage != expectedMessage) {
+                return AssertionFailure()
+                        << "Expected " << expectedMessage << ", actual " << readMessage;
+            }
+            return AssertionSuccess();
+        }
+        void run(bool handshakeOk = true, bool readOk = true) {
+            if (!setUpTransport()) {
+                ASSERT_FALSE(handshakeOk) << "newTransport returns nullptr, but it shouldn't";
+                return;
+            }
+            ASSERT_TRUE(handshakeOk) << "newTransport does not return nullptr, but it should";
+            ASSERT_EQ(readOk, readMessage());
+        }
+
+    private:
+        ConnectToServer mConnectToServer;
+        base::unique_fd mFd;
+        std::unique_ptr<FdTrigger> mFdTrigger = FdTrigger::make();
+        std::unique_ptr<RpcTransportCtx> mCtx;
+        std::shared_ptr<RpcCertificateVerifierSimple> mCertVerifier =
+                std::make_shared<RpcCertificateVerifierSimple>();
+        std::unique_ptr<RpcTransport> mClientTransport;
+    };
+
+    // Make A trust B.
+    template <typename A, typename B>
+    static status_t trust(RpcSecurity rpcSecurity,
+                          std::optional<RpcCertificateFormat> certificateFormat, const A& a,
+                          const B& b) {
+        if (rpcSecurity != RpcSecurity::TLS) return OK;
+        LOG_ALWAYS_FATAL_IF(!certificateFormat.has_value());
+        auto bCert = b->getCtx()->getCertificate(*certificateFormat);
+        return a->getCertVerifier()->addTrustedPeerCertificate(*certificateFormat, bCert);
+    }
+
+    static constexpr const char* kMessage = "hello";
+};
+
+class RpcTransportTest : public testing::TestWithParam<RpcTransportTestUtils::Param> {
+public:
+    using Server = RpcTransportTestUtils::Server;
+    using Client = RpcTransportTestUtils::Client;
+    static inline std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
+        auto [socketType, rpcSecurity, certificateFormat] = info.param;
+        auto ret = PrintToString(socketType) + "_" + newFactory(rpcSecurity)->toCString();
+        if (certificateFormat.has_value()) ret += "_" + PrintToString(*certificateFormat);
+        return ret;
+    }
+    static std::vector<ParamType> getRpcTranportTestParams() {
+        std::vector<ParamType> ret;
+        for (auto socketType : testSocketTypes(false /* hasPreconnected */)) {
+            for (auto rpcSecurity : RpcSecurityValues()) {
+                switch (rpcSecurity) {
+                    case RpcSecurity::RAW: {
+                        ret.emplace_back(socketType, rpcSecurity, std::nullopt);
+                    } break;
+                    case RpcSecurity::TLS: {
+                        ret.emplace_back(socketType, rpcSecurity, RpcCertificateFormat::PEM);
+                        ret.emplace_back(socketType, rpcSecurity, RpcCertificateFormat::DER);
+                    } break;
+                }
+            }
+        }
+        return ret;
+    }
+    template <typename A, typename B>
+    status_t trust(const A& a, const B& b) {
+        auto [socketType, rpcSecurity, certificateFormat] = GetParam();
+        return RpcTransportTestUtils::trust(rpcSecurity, certificateFormat, a, b);
+    }
+};
+
+TEST_P(RpcTransportTest, GoodCertificate) {
+    auto server = std::make_unique<Server>();
+    ASSERT_TRUE(server->setUp(GetParam()));
+
+    Client client(server->getConnectToServerFn());
+    ASSERT_TRUE(client.setUp(GetParam()));
+
+    ASSERT_EQ(OK, trust(&client, server));
+    ASSERT_EQ(OK, trust(server, &client));
+
+    server->start();
+    client.run();
+}
+
+TEST_P(RpcTransportTest, MultipleClients) {
+    auto server = std::make_unique<Server>();
+    ASSERT_TRUE(server->setUp(GetParam()));
+
+    std::vector<Client> clients;
+    for (int i = 0; i < 2; i++) {
+        auto& client = clients.emplace_back(server->getConnectToServerFn());
+        ASSERT_TRUE(client.setUp(GetParam()));
+        ASSERT_EQ(OK, trust(&client, server));
+        ASSERT_EQ(OK, trust(server, &client));
+    }
+
+    server->start();
+    for (auto& client : clients) client.run();
+}
+
+TEST_P(RpcTransportTest, UntrustedServer) {
+    auto [socketType, rpcSecurity, certificateFormat] = GetParam();
+
+    auto untrustedServer = std::make_unique<Server>();
+    ASSERT_TRUE(untrustedServer->setUp(GetParam()));
+
+    Client client(untrustedServer->getConnectToServerFn());
+    ASSERT_TRUE(client.setUp(GetParam()));
+
+    ASSERT_EQ(OK, trust(untrustedServer, &client));
+
+    untrustedServer->start();
+
+    // For TLS, this should reject the certificate. For RAW sockets, it should pass because
+    // the client can't verify the server's identity.
+    bool handshakeOk = rpcSecurity != RpcSecurity::TLS;
+    client.run(handshakeOk);
+}
+TEST_P(RpcTransportTest, MaliciousServer) {
+    auto [socketType, rpcSecurity, certificateFormat] = GetParam();
+    auto validServer = std::make_unique<Server>();
+    ASSERT_TRUE(validServer->setUp(GetParam()));
+
+    auto maliciousServer = std::make_unique<Server>();
+    ASSERT_TRUE(maliciousServer->setUp(GetParam()));
+
+    Client client(maliciousServer->getConnectToServerFn());
+    ASSERT_TRUE(client.setUp(GetParam()));
+
+    ASSERT_EQ(OK, trust(&client, validServer));
+    ASSERT_EQ(OK, trust(validServer, &client));
+    ASSERT_EQ(OK, trust(maliciousServer, &client));
+
+    maliciousServer->start();
+
+    // For TLS, this should reject the certificate. For RAW sockets, it should pass because
+    // the client can't verify the server's identity.
+    bool handshakeOk = rpcSecurity != RpcSecurity::TLS;
+    client.run(handshakeOk);
+}
+
+TEST_P(RpcTransportTest, UntrustedClient) {
+    auto [socketType, rpcSecurity, certificateFormat] = GetParam();
+    auto server = std::make_unique<Server>();
+    ASSERT_TRUE(server->setUp(GetParam()));
+
+    Client client(server->getConnectToServerFn());
+    ASSERT_TRUE(client.setUp(GetParam()));
+
+    ASSERT_EQ(OK, trust(&client, server));
+
+    server->start();
+
+    // For TLS, Client should be able to verify server's identity, so client should see
+    // do_handshake() successfully executed. However, server shouldn't be able to verify client's
+    // identity and should drop the connection, so client shouldn't be able to read anything.
+    bool readOk = rpcSecurity != RpcSecurity::TLS;
+    client.run(true, readOk);
+}
+
+TEST_P(RpcTransportTest, MaliciousClient) {
+    auto [socketType, rpcSecurity, certificateFormat] = GetParam();
+    auto server = std::make_unique<Server>();
+    ASSERT_TRUE(server->setUp(GetParam()));
+
+    Client validClient(server->getConnectToServerFn());
+    ASSERT_TRUE(validClient.setUp(GetParam()));
+    Client maliciousClient(server->getConnectToServerFn());
+    ASSERT_TRUE(maliciousClient.setUp(GetParam()));
+
+    ASSERT_EQ(OK, trust(&validClient, server));
+    ASSERT_EQ(OK, trust(&maliciousClient, server));
+
+    server->start();
+
+    // See UntrustedClient.
+    bool readOk = rpcSecurity != RpcSecurity::TLS;
+    maliciousClient.run(true, readOk);
+}
+
+TEST_P(RpcTransportTest, Trigger) {
+    std::string msg2 = ", world!";
+    std::mutex writeMutex;
+    std::condition_variable writeCv;
+    bool shouldContinueWriting = false;
+    auto serverPostConnect = [&](RpcTransport* serverTransport, FdTrigger* fdTrigger) {
+        std::string message(RpcTransportTestUtils::kMessage);
+        auto status = serverTransport->interruptableWriteFully(fdTrigger, message.data(),
+                                                               message.size(), {});
+        if (status != OK) return AssertionFailure() << statusToString(status);
+
+        {
+            std::unique_lock<std::mutex> lock(writeMutex);
+            if (!writeCv.wait_for(lock, 3s, [&] { return shouldContinueWriting; })) {
+                return AssertionFailure() << "write barrier not cleared in time!";
+            }
+        }
+
+        status = serverTransport->interruptableWriteFully(fdTrigger, msg2.data(), msg2.size(), {});
+        if (status != DEAD_OBJECT)
+            return AssertionFailure() << "When FdTrigger is shut down, interruptableWriteFully "
+                                         "should return DEAD_OBJECT, but it is "
+                                      << statusToString(status);
+        return AssertionSuccess();
+    };
+
+    auto server = std::make_unique<Server>();
+    ASSERT_TRUE(server->setUp(GetParam()));
+
+    // Set up client
+    Client client(server->getConnectToServerFn());
+    ASSERT_TRUE(client.setUp(GetParam()));
+
+    // Exchange keys
+    ASSERT_EQ(OK, trust(&client, server));
+    ASSERT_EQ(OK, trust(server, &client));
+
+    server->setPostConnect(serverPostConnect);
+
+    server->start();
+    // connect() to server and do handshake
+    ASSERT_TRUE(client.setUpTransport());
+    // read the first message. This ensures that server has finished handshake and start handling
+    // client fd. Server thread should pause at writeCv.wait_for().
+    ASSERT_TRUE(client.readMessage(RpcTransportTestUtils::kMessage));
+    // Trigger server shutdown after server starts handling client FD. This ensures that the second
+    // write is on an FdTrigger that has been shut down.
+    server->shutdown();
+    // Continues server thread to write the second message.
+    {
+        std::lock_guard<std::mutex> lock(writeMutex);
+        shouldContinueWriting = true;
+    }
+    writeCv.notify_all();
+    // After this line, server thread unblocks and attempts to write the second message, but
+    // shutdown is triggered, so write should failed with DEAD_OBJECT. See |serverPostConnect|.
+    // On the client side, second read fails with DEAD_OBJECT
+    ASSERT_FALSE(client.readMessage(msg2));
+}
+
+INSTANTIATE_TEST_CASE_P(BinderRpc, RpcTransportTest,
+                        ::testing::ValuesIn(RpcTransportTest::getRpcTranportTestParams()),
+                        RpcTransportTest::PrintParamInfo);
+
+class RpcTransportTlsKeyTest
+      : public testing::TestWithParam<std::tuple<SocketType, RpcCertificateFormat, RpcKeyFormat>> {
+public:
+    template <typename A, typename B>
+    status_t trust(const A& a, const B& b) {
+        auto [socketType, certificateFormat, keyFormat] = GetParam();
+        return RpcTransportTestUtils::trust(RpcSecurity::TLS, certificateFormat, a, b);
+    }
+    static std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
+        auto [socketType, certificateFormat, keyFormat] = info.param;
+        auto ret = PrintToString(socketType) + "_certificate_" + PrintToString(certificateFormat) +
+                "_key_" + PrintToString(keyFormat);
+        return ret;
+    };
+};
+
+TEST_P(RpcTransportTlsKeyTest, PreSignedCertificate) {
+    auto [socketType, certificateFormat, keyFormat] = GetParam();
+
+    std::vector<uint8_t> pkeyData, certData;
+    {
+        auto pkey = makeKeyPairForSelfSignedCert();
+        ASSERT_NE(nullptr, pkey);
+        auto cert = makeSelfSignedCert(pkey.get(), kCertValidSeconds);
+        ASSERT_NE(nullptr, cert);
+        pkeyData = serializeUnencryptedPrivatekey(pkey.get(), keyFormat);
+        certData = serializeCertificate(cert.get(), certificateFormat);
+    }
+
+    auto desPkey = deserializeUnencryptedPrivatekey(pkeyData, keyFormat);
+    auto desCert = deserializeCertificate(certData, certificateFormat);
+    auto auth = std::make_unique<RpcAuthPreSigned>(std::move(desPkey), std::move(desCert));
+    auto utilsParam =
+            std::make_tuple(socketType, RpcSecurity::TLS, std::make_optional(certificateFormat));
+
+    auto server = std::make_unique<RpcTransportTestUtils::Server>();
+    ASSERT_TRUE(server->setUp(utilsParam, std::move(auth)));
+
+    RpcTransportTestUtils::Client client(server->getConnectToServerFn());
+    ASSERT_TRUE(client.setUp(utilsParam));
+
+    ASSERT_EQ(OK, trust(&client, server));
+    ASSERT_EQ(OK, trust(server, &client));
+
+    server->start();
+    client.run();
+}
+
+INSTANTIATE_TEST_CASE_P(
+        BinderRpc, RpcTransportTlsKeyTest,
+        testing::Combine(testing::ValuesIn(testSocketTypes(false /* hasPreconnected*/)),
+                         testing::Values(RpcCertificateFormat::PEM, RpcCertificateFormat::DER),
+                         testing::Values(RpcKeyFormat::PEM, RpcKeyFormat::DER)),
+        RpcTransportTlsKeyTest::PrintParamInfo);
 
 } // namespace android
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
     android::base::InitLogging(argv, android::base::StderrLogger, android::base::DefaultAborter);
+
     return RUN_ALL_TESTS();
 }
diff --git a/libs/binder/tests/binderRpcWireProtocolTest.cpp b/libs/binder/tests/binderRpcWireProtocolTest.cpp
new file mode 100644
index 0000000..a807afa
--- /dev/null
+++ b/libs/binder/tests/binderRpcWireProtocolTest.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/hex.h>
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
+#include <binder/Parcel.h>
+#include <binder/RpcSession.h>
+#include <binder/Status.h>
+#include <gtest/gtest.h>
+
+#include "../Debug.h"
+
+namespace android {
+
+static const int32_t kInt32Array[] = {-1, 0, 17};
+static const uint8_t kByteArray[] = {0, 17, 255};
+enum EnumInt8 : int8_t { Int8A, Int8B };
+enum EnumInt32 : int32_t { Int32A, Int32B };
+enum EnumInt64 : int64_t { Int64A, Int64B };
+struct AParcelable : Parcelable {
+    status_t writeToParcel(Parcel* parcel) const { return parcel->writeInt32(37); }
+    status_t readFromParcel(const Parcel*) { return OK; }
+};
+
+// clang-format off
+constexpr size_t kFillFunIndexLineBase = __LINE__ + 2;
+static const std::vector<std::function<void(Parcel* p)>> kFillFuns {
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInterfaceToken(String16(u"tok"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32(-1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32(0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32(17)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint32(0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint32(1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint32(10003)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64(-1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64(0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64(17)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64(0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64(1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64(10003)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloat(0.0f)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloat(0.1f)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloat(9.1f)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDouble(0.0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDouble(0.1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDouble(9.1)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCString("")); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCString("a")); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCString("baba")); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString8(String8(""))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString8(String8("a"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString8(String8("baba"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16(String16(u""))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16(String16(u"a"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16(String16(u"baba"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeStrongBinder(nullptr)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32Array(arraysize(kInt32Array), kInt32Array)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteArray(arraysize(kByteArray), kByteArray)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBool(true)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBool(false)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeChar('a')); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeChar('?')); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeChar('\0')); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByte(-128)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByte(0)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByte(127)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::string(""))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::string("a"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::string("abab"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::nullopt)); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::optional<std::string>(""))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::optional<std::string>("a"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8AsUtf16(std::optional<std::string>("abab"))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::optional<std::vector<int8_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::optional<std::vector<int8_t>>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::vector<int8_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::vector<int8_t>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::optional<std::vector<uint8_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::optional<std::vector<uint8_t>>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::vector<uint8_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeByteVector(std::vector<uint8_t>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32Vector(std::optional<std::vector<int32_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32Vector(std::optional<std::vector<int32_t>>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32Vector(std::vector<int32_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt32Vector(std::vector<int32_t>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64Vector(std::optional<std::vector<int64_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64Vector(std::optional<std::vector<int64_t>>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64Vector(std::vector<int64_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeInt64Vector(std::vector<int64_t>({-1, 0, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64Vector(std::optional<std::vector<uint64_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64Vector(std::optional<std::vector<uint64_t>>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64Vector(std::vector<uint64_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUint64Vector(std::vector<uint64_t>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloatVector(std::optional<std::vector<float>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloatVector(std::optional<std::vector<float>>({0.0f, 0.1f, 9.1f}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloatVector(std::vector<float>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeFloatVector(std::vector<float>({0.0f, 0.1f, 9.1f}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDoubleVector(std::optional<std::vector<double>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDoubleVector(std::optional<std::vector<double>>({0.0, 0.1, 9.1}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDoubleVector(std::vector<double>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeDoubleVector(std::vector<double>({0.0, 0.1, 9.1}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBoolVector(std::optional<std::vector<bool>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBoolVector(std::optional<std::vector<bool>>({true, false}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBoolVector(std::vector<bool>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeBoolVector(std::vector<bool>({true, false}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCharVector(std::optional<std::vector<char16_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCharVector(std::optional<std::vector<char16_t>>({'a', '\0', '?'}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCharVector(std::vector<char16_t>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeCharVector(std::vector<char16_t>({'a', '\0', '?'}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16Vector(std::optional<std::vector<std::optional<String16>>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16Vector(std::optional<std::vector<std::optional<String16>>>({std::nullopt, String16(), String16(u"a")}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16Vector(std::vector<std::optional<String16>>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeString16Vector(std::vector<std::optional<String16>>({std::nullopt, String16(), String16(u"a")}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8VectorAsUtf16Vector(std::optional<std::vector<std::optional<std::string>>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8VectorAsUtf16Vector(std::optional<std::vector<std::optional<std::string>>>({std::nullopt, std::string(), std::string("a")}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8VectorAsUtf16Vector(std::vector<std::optional<std::string>>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeUtf8VectorAsUtf16Vector(std::vector<std::optional<std::string>>({std::nullopt, std::string(), std::string("a")}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeStrongBinderVector(std::optional<std::vector<sp<IBinder>>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeStrongBinderVector(std::optional<std::vector<sp<IBinder>>>({nullptr}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeStrongBinderVector(std::vector<sp<IBinder>>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeStrongBinderVector(std::vector<sp<IBinder>>({nullptr}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt8>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt8>>({Int8A, Int8B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::vector<EnumInt8>({Int8A, Int8B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt32>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt32>>({Int32A, Int32B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::vector<EnumInt32>({Int32A, Int32B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt64>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::optional<std::vector<EnumInt64>>({Int64A, Int64B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeEnumVector(std::vector<EnumInt64>({Int64A, Int64B}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeParcelableVector(std::optional<std::vector<std::optional<AParcelable>>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeParcelableVector(std::optional<std::vector<std::optional<AParcelable>>>({AParcelable()}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeParcelableVector(std::vector<AParcelable>({AParcelable()}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeNullableParcelable(std::optional<AParcelable>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeNullableParcelable(std::optional<AParcelable>(AParcelable()))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeParcelable(AParcelable())); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeVectorSize(std::vector<int32_t>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeVectorSize(std::vector<AParcelable>({}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeVectorSize(std::optional<std::vector<int32_t>>(std::nullopt))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeVectorSize(std::optional<std::vector<int32_t>>({0, 1, 17}))); },
+    [](Parcel* p) { ASSERT_EQ(OK, p->writeNoException()); },
+    [](Parcel* p) { ASSERT_EQ(OK, binder::Status::ok().writeToParcel(p)); },
+    [](Parcel* p) { ASSERT_EQ(OK, binder::Status::fromExceptionCode(7, ":D").writeToParcel(p)); },
+    [](Parcel* p) { ASSERT_EQ(OK, binder::Status::fromServiceSpecificError(8, ":/").writeToParcel(p)); },
+};
+// clang-format on
+
+static void setParcelForRpc(Parcel* p, uint32_t version) {
+    auto session = RpcSession::make();
+    CHECK(session->setProtocolVersion(version));
+    CHECK_EQ(OK, session->addNullDebuggingClient());
+    p->markForRpc(session);
+}
+
+static std::string buildRepr(uint32_t version) {
+    std::string result;
+    for (size_t i = 0; i < kFillFuns.size(); i++) {
+        if (i != 0) result += "|";
+        Parcel p;
+        setParcelForRpc(&p, version);
+        kFillFuns[i](&p);
+
+        result += base::HexString(p.data(), p.dataSize());
+    }
+    return result;
+}
+
+static void checkRepr(const std::string& repr, uint32_t version) {
+    const std::string actualRepr = buildRepr(version);
+
+    auto expected = base::Split(repr, "|");
+    ASSERT_EQ(expected.size(), kFillFuns.size());
+
+    auto actual = base::Split(actualRepr, "|");
+    ASSERT_EQ(actual.size(), kFillFuns.size());
+
+    for (size_t i = 0; i < kFillFuns.size(); i++) {
+        EXPECT_EQ(expected[i], actual[i])
+                << "Format mismatch, see " __FILE__ " line " << (kFillFunIndexLineBase + i);
+    }
+
+    // same check as in the loop, but the above error is more clear to debug,
+    // and this error is more clear to be able to update the source file here.
+    EXPECT_EQ(repr, actualRepr);
+}
+
+const std::string kCurrentRepr =
+        "0300000074006f006b000000|ffffffff|00000000|11000000|00000000|01000000|13270000|"
+        "ffffffffffffffff|0000000000000000|1100000000000000|0000000000000000|0100000000000000|"
+        "1327000000000000|00000000|cdcccc3d|9a991141|0000000000000000|9a9999999999b93f|"
+        "3333333333332240|00000000|61000000|6261626100000000|0000000000000000|0100000061000000|"
+        "040000006261626100000000|0000000000000000|0100000061000000|"
+        "04000000620061006200610000000000|0000000000000000|03000000ffffffff0000000011000000|"
+        "030000000011ff00|01000000|00000000|61000000|3f000000|00000000|80ffffff|00000000|7f000000|"
+        "0000000000000000|0100000061000000|04000000610062006100620000000000|ffffffff|"
+        "0000000000000000|0100000061000000|04000000610062006100620000000000|ffffffff|"
+        "03000000ff001100|00000000|03000000ff001100|ffffffff|0300000000011100|00000000|"
+        "0300000000011100|ffffffff|03000000ffffffff0000000011000000|00000000|"
+        "03000000ffffffff0000000011000000|ffffffff|"
+        "03000000ffffffffffffffff00000000000000001100000000000000|00000000|"
+        "03000000ffffffffffffffff00000000000000001100000000000000|ffffffff|"
+        "03000000000000000000000001000000000000001100000000000000|00000000|"
+        "03000000000000000000000001000000000000001100000000000000|ffffffff|"
+        "0300000000000000cdcccc3d9a991141|00000000|0300000000000000cdcccc3d9a991141|ffffffff|"
+        "0300000000000000000000009a9999999999b93f3333333333332240|00000000|"
+        "0300000000000000000000009a9999999999b93f3333333333332240|ffffffff|"
+        "020000000100000000000000|00000000|020000000100000000000000|ffffffff|"
+        "0300000061000000000000003f000000|00000000|0300000061000000000000003f000000|ffffffff|"
+        "03000000ffffffff00000000000000000100000061000000|00000000|"
+        "03000000ffffffff00000000000000000100000061000000|ffffffff|"
+        "03000000ffffffff00000000000000000100000061000000|00000000|"
+        "03000000ffffffff00000000000000000100000061000000|ffffffff|010000000000000000000000|"
+        "00000000|010000000000000000000000|ffffffff|0200000000010000|0200000000010000|ffffffff|"
+        "020000000000000001000000|020000000000000001000000|ffffffff|"
+        "0200000000000000000000000100000000000000|0200000000000000000000000100000000000000|"
+        "ffffffff|010000000100000025000000|010000000100000025000000|00000000|0100000025000000|"
+        "0100000025000000|03000000|00000000|ffffffff|03000000|00000000|00000000|"
+        "07000000020000003a0044000000000000000000|f8ffffff020000003a002f00000000000000000008000000";
+
+TEST(RpcWire, CurrentVersion) {
+    checkRepr(kCurrentRepr, RPC_WIRE_PROTOCOL_VERSION);
+}
+
+static_assert(RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL,
+              "you better update this test!");
+
+TEST(RpcWire, ReleaseBranchHasFrozenRpcWireProtocol) {
+    if (RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL) {
+        EXPECT_FALSE(base::GetProperty("ro.build.version.codename", "") == "REL")
+                << "Binder RPC wire protocol must be frozen on a release branch!";
+    }
+}
+
+TEST(RpcWire, IfNotExperimentalCodeHasNoExperimentalFeatures) {
+    if (RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL) {
+        GTEST_SKIP() << "Version is experimental, so experimental features are okay.";
+    }
+
+    // if we set the wire protocol version to experimental, none of the code
+    // should introduce a difference (if this fails, it means we have features
+    // which are enabled under experimental mode, but we aren't actually using
+    // or testing them!)
+    checkRepr(kCurrentRepr, RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
+}
+
+} // namespace android
diff --git a/libs/binder/tests/binderStabilityTest.cpp b/libs/binder/tests/binderStabilityTest.cpp
index 2ce13df..2398e1e 100644
--- a/libs/binder/tests/binderStabilityTest.cpp
+++ b/libs/binder/tests/binderStabilityTest.cpp
@@ -102,7 +102,7 @@
         return Status::ok();
     }
     Status sendAndCallBinder(const sp<IBinder>& binder) override {
-        Stability::debugLogStability("sendAndCallBinder got binder", binder);
+        ALOGI("Debug log stability: %s", Stability::debugToString(binder).c_str());
         return Status::fromExceptionCode(BadStableBinder::doUserTransaction(binder));
     }
     Status returnNoStabilityBinder(sp<IBinder>* _aidl_return) override {
@@ -197,6 +197,14 @@
     }
 }
 
+TEST(BinderStability, ConnectionInfoRequiresManifestEntries) {
+    sp<IServiceManager> sm = android::defaultServiceManager();
+    sp<IBinder> systemBinder = BadStableBinder::system();
+    EXPECT_EQ(OK, sm->addService(String16("no.connection.foo"), systemBinder));
+    std::optional<android::IServiceManager::ConnectionInfo> connectionInfo;
+    connectionInfo = sm->getConnectionInfo(String16("no.connection.foo"));
+    EXPECT_EQ(connectionInfo, std::nullopt);
+}
 TEST(BinderStability, CantCallVendorBinderInSystemContext) {
     sp<IBinder> serverBinder = android::defaultServiceManager()->getService(kSystemStabilityServer);
     auto server = interface_cast<IBinderStabilityTest>(serverBinder);
diff --git a/libs/binder/tests/binderUtilsHostTest.cpp b/libs/binder/tests/binderUtilsHostTest.cpp
new file mode 100644
index 0000000..4330e3e
--- /dev/null
+++ b/libs/binder/tests/binderUtilsHostTest.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sysexits.h>
+
+#include <chrono>
+
+#include <android-base/result-gmock.h>
+#include <android-base/strings.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "../UtilsHost.h"
+
+using android::base::testing::Ok;
+using testing::Optional;
+
+namespace android {
+
+TEST(UtilsHost, ExecuteImmediately) {
+    auto result = execute({"echo", "foo"}, nullptr);
+    ASSERT_THAT(result, Ok());
+    EXPECT_THAT(result->exitCode, Optional(EX_OK));
+    EXPECT_EQ(result->stdoutStr, "foo\n");
+}
+
+TEST(UtilsHost, ExecuteLongRunning) {
+    auto now = std::chrono::system_clock::now();
+
+    {
+        std::vector<std::string> args{"sh", "-c",
+                                      "sleep 0.5 && echo -n f && sleep 0.5 && echo oo && sleep 1"};
+        auto result = execute(std::move(args), [](const CommandResult& commandResult) {
+            return android::base::EndsWith(commandResult.stdoutStr, "\n");
+        });
+        auto elapsed = std::chrono::system_clock::now() - now;
+        auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
+        EXPECT_GE(elapsedMs, 1000);
+        EXPECT_LT(elapsedMs, 2000);
+
+        ASSERT_THAT(result, Ok());
+        EXPECT_EQ(std::nullopt, result->exitCode);
+        EXPECT_EQ(result->stdoutStr, "foo\n");
+    }
+
+    // ~CommandResult() called, child process is killed.
+    // Assert that the second sleep does not finish.
+    auto elapsed = std::chrono::system_clock::now() - now;
+    auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
+    EXPECT_LT(elapsedMs, 2000);
+}
+
+TEST(UtilsHost, ExecuteLongRunning2) {
+    auto now = std::chrono::system_clock::now();
+
+    {
+        std::vector<std::string> args{"sh", "-c",
+                                      "sleep 2 && echo -n f && sleep 2 && echo oo && sleep 2"};
+        auto result = execute(std::move(args), [](const CommandResult& commandResult) {
+            return android::base::EndsWith(commandResult.stdoutStr, "\n");
+        });
+        auto elapsed = std::chrono::system_clock::now() - now;
+        auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
+        EXPECT_GE(elapsedMs, 4000);
+        EXPECT_LT(elapsedMs, 6000);
+
+        ASSERT_THAT(result, Ok());
+        EXPECT_EQ(std::nullopt, result->exitCode);
+        EXPECT_EQ(result->stdoutStr, "foo\n");
+    }
+
+    // ~CommandResult() called, child process is killed.
+    // Assert that the second sleep does not finish.
+    auto elapsed = std::chrono::system_clock::now() - now;
+    auto elapsedMs = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
+    EXPECT_LT(elapsedMs, 6000);
+}
+
+TEST(UtilsHost, KillWithSigKill) {
+    std::vector<std::string> args{"sh", "-c", "echo foo && sleep 10"};
+    auto result = execute(std::move(args), [](const CommandResult& commandResult) {
+        // FOR TEST PURPOSE ONLY. DON'T DO THIS!
+        if (commandResult.pid.has_value()) {
+            (void)kill(*commandResult.pid, SIGKILL);
+        }
+        // FOR TEST PURPOSE ONLY. DON'T DO THIS!
+        return false;
+    });
+
+    ASSERT_THAT(result, Ok());
+    EXPECT_EQ(std::nullopt, result->exitCode);
+    EXPECT_THAT(result->signal, Optional(SIGKILL));
+}
+
+} // namespace android
diff --git a/libs/binder/tests/include_tls_test_utils/binder/RpcTlsTestUtils.h b/libs/binder/tests/include_tls_test_utils/binder/RpcTlsTestUtils.h
new file mode 100644
index 0000000..094addd
--- /dev/null
+++ b/libs/binder/tests/include_tls_test_utils/binder/RpcTlsTestUtils.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <mutex>
+
+#include <binder/RpcAuth.h>
+#include <binder/RpcCertificateFormat.h>
+#include <binder/RpcCertificateVerifier.h>
+#include <binder/RpcTransport.h>
+#include <openssl/ssl.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+constexpr const uint32_t kCertValidSeconds = 30 * (60 * 60 * 24); // 30 days
+bssl::UniquePtr<EVP_PKEY> makeKeyPairForSelfSignedCert();
+bssl::UniquePtr<X509> makeSelfSignedCert(EVP_PKEY* pKey, uint32_t validSeconds);
+
+// An implementation of RpcAuth that generates a key pair and a self-signed
+// certificate every time configure() is called.
+class RpcAuthSelfSigned : public RpcAuth {
+public:
+    RpcAuthSelfSigned(uint32_t validSeconds = kCertValidSeconds) : mValidSeconds(validSeconds) {}
+    status_t configure(SSL_CTX* ctx) override;
+
+private:
+    const uint32_t mValidSeconds;
+};
+
+class RpcAuthPreSigned : public RpcAuth {
+public:
+    RpcAuthPreSigned(bssl::UniquePtr<EVP_PKEY> pkey, bssl::UniquePtr<X509> cert)
+          : mPkey(std::move(pkey)), mCert(std::move(cert)) {}
+    status_t configure(SSL_CTX* ctx) override;
+
+private:
+    bssl::UniquePtr<EVP_PKEY> mPkey;
+    bssl::UniquePtr<X509> mCert;
+};
+
+// A simple certificate verifier for testing.
+// Keep a list of leaf certificates as trusted. No certificate chain support.
+//
+// All APIs are thread-safe. However, if verify() and addTrustedPeerCertificate() are called
+// simultaneously in different threads, it is not deterministic whether verify() will use the
+// certificate being added.
+class RpcCertificateVerifierSimple : public RpcCertificateVerifier {
+public:
+    status_t verify(const SSL*, uint8_t*) override;
+
+    // Add a trusted peer certificate. Peers presenting this certificate are accepted.
+    //
+    // Caller must ensure that RpcTransportCtx::newTransport() are called after all trusted peer
+    // certificates are added. Otherwise, RpcTransport-s created before may not trust peer
+    // certificates added later.
+    [[nodiscard]] status_t addTrustedPeerCertificate(RpcCertificateFormat format,
+                                                     const std::vector<uint8_t>& cert);
+
+private:
+    std::mutex mMutex; // for below
+    std::vector<bssl::UniquePtr<X509>> mTrustedPeerCertificates;
+};
+
+// A RpcCertificateVerifier that does not verify anything.
+class RpcCertificateVerifierNoOp : public RpcCertificateVerifier {
+public:
+    RpcCertificateVerifierNoOp(status_t status) : mStatus(status) {}
+    status_t verify(const SSL*, uint8_t*) override { return mStatus; }
+
+private:
+    status_t mStatus;
+};
+
+} // namespace android
diff --git a/libs/binder/tests/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp
index 74b8eb8..acf3f8f 100644
--- a/libs/binder/tests/parcel_fuzzer/Android.bp
+++ b/libs/binder/tests/parcel_fuzzer/Android.bp
@@ -23,7 +23,6 @@
         "main.cpp",
         "random_fd.cpp",
         "random_parcel.cpp",
-        "util.cpp",
     ],
     static_libs: [
         "libbase",
diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp
index 624def1..32406e5 100644
--- a/libs/binder/tests/parcel_fuzzer/binder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder.cpp
@@ -18,11 +18,13 @@
 #include "binder.h"
 #include "util.h"
 
+#include <android-base/hex.h>
 #include <android/os/IServiceManager.h>
 #include <binder/ParcelableHolder.h>
 #include <binder/PersistableBundle.h>
 
 using ::android::status_t;
+using ::android::base::HexString;
 
 enum ByteEnum : int8_t {};
 enum IntEnum : int32_t {};
@@ -66,6 +68,10 @@
     int32_t mValue = 0;
 };
 
+struct BigStruct {
+    uint8_t data[1337];
+};
+
 #define PARCEL_READ_WITH_STATUS(T, FUN) \
     [] (const ::android::Parcel& p, uint8_t /*data*/) {\
         FUZZ_LOG() << "about to read " #T " using " #FUN " with status";\
@@ -124,7 +130,7 @@
     [] (const ::android::Parcel& p, uint8_t len) {
         FUZZ_LOG() << "about to readInplace";
         const void* r = p.readInplace(len);
-        FUZZ_LOG() << "readInplace done. pointer: " << r << " bytes: " << hexString(r, len);
+        FUZZ_LOG() << "readInplace done. pointer: " << r << " bytes: " << (r ? HexString(r, len) : "null");
     },
     PARCEL_READ_OPT_STATUS(int32_t, readInt32),
     PARCEL_READ_OPT_STATUS(uint32_t, readUint32),
@@ -149,7 +155,7 @@
         FUZZ_LOG() << "about to readString8Inplace";
         size_t outLen = 0;
         const char* str = p.readString8Inplace(&outLen);
-        std::string bytes = hexString(str, sizeof(char) * (outLen + 1));
+        std::string bytes = str ? HexString(str, sizeof(char) * (outLen + 1)) : "null";
         FUZZ_LOG() << "readString8Inplace: " << bytes << " size: " << outLen;
     },
     PARCEL_READ_OPT_STATUS(android::String16, readString16),
@@ -159,28 +165,26 @@
         FUZZ_LOG() << "about to readString16Inplace";
         size_t outLen = 0;
         const char16_t* str = p.readString16Inplace(&outLen);
-        std::string bytes = hexString(str, sizeof(char16_t) * (outLen + 1));
+        std::string bytes = str ? HexString(str, sizeof(char16_t) * (outLen + 1)) : "null";
         FUZZ_LOG() << "readString16Inplace: " << bytes << " size: " << outLen;
     },
     PARCEL_READ_WITH_STATUS(android::sp<android::IBinder>, readStrongBinder),
     PARCEL_READ_WITH_STATUS(android::sp<android::IBinder>, readNullableStrongBinder),
 
-    // TODO(b/131868573): can force read of arbitrarily sized vector
-    // PARCEL_READ_WITH_STATUS(std::vector<ByteEnum>, readEnumVector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<ByteEnum>>, readEnumVector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<ByteEnum>>, readEnumVector),
-    // PARCEL_READ_WITH_STATUS(std::vector<IntEnum>, readEnumVector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<IntEnum>>, readEnumVector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<IntEnum>>, readEnumVector),
-    // PARCEL_READ_WITH_STATUS(std::vector<LongEnum>, readEnumVector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<LongEnum>>, readEnumVector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<LongEnum>>, readEnumVector),
+    PARCEL_READ_WITH_STATUS(std::vector<ByteEnum>, readEnumVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<ByteEnum>>, readEnumVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<ByteEnum>>, readEnumVector),
+    PARCEL_READ_WITH_STATUS(std::vector<IntEnum>, readEnumVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<IntEnum>>, readEnumVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<IntEnum>>, readEnumVector),
+    PARCEL_READ_WITH_STATUS(std::vector<LongEnum>, readEnumVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<LongEnum>>, readEnumVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<LongEnum>>, readEnumVector),
 
     // only reading one parcelable type for now
-    // TODO(b/131868573): can force read of arbitrarily sized vector
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<ExampleParcelable>>>, readParcelableVector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<ExampleParcelable>>>, readParcelableVector),
-    // PARCEL_READ_WITH_STATUS(std::vector<ExampleParcelable>, readParcelableVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<ExampleParcelable>>>, readParcelableVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<ExampleParcelable>>>, readParcelableVector),
+    PARCEL_READ_WITH_STATUS(std::vector<ExampleParcelable>, readParcelableVector),
     PARCEL_READ_WITH_STATUS(ExampleParcelable, readParcelable),
     PARCEL_READ_WITH_STATUS(std::unique_ptr<ExampleParcelable>, readParcelable),
     PARCEL_READ_WITH_STATUS(std::optional<ExampleParcelable>, readParcelable),
@@ -188,46 +192,46 @@
     // only reading one binder type for now
     PARCEL_READ_WITH_STATUS(android::sp<android::os::IServiceManager>, readStrongBinder),
     PARCEL_READ_WITH_STATUS(android::sp<android::os::IServiceManager>, readNullableStrongBinder),
+    PARCEL_READ_WITH_STATUS(std::vector<android::sp<android::os::IServiceManager>>, readStrongBinderVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<android::sp<android::os::IServiceManager>>>, readStrongBinderVector),
 
-    // TODO(b/131868573): can force read of arbitrarily sized vector
-    // PARCEL_READ_WITH_STATUS(::std::unique_ptr<std::vector<android::sp<android::IBinder>>>, readStrongBinderVector),
-    // PARCEL_READ_WITH_STATUS(::std::optional<std::vector<android::sp<android::IBinder>>>, readStrongBinderVector),
-    // PARCEL_READ_WITH_STATUS(std::vector<android::sp<android::IBinder>>, readStrongBinderVector),
+    PARCEL_READ_WITH_STATUS(::std::unique_ptr<std::vector<android::sp<android::IBinder>>>, readStrongBinderVector),
+    PARCEL_READ_WITH_STATUS(::std::optional<std::vector<android::sp<android::IBinder>>>, readStrongBinderVector),
+    PARCEL_READ_WITH_STATUS(std::vector<android::sp<android::IBinder>>, readStrongBinderVector),
 
-    // TODO(b/131868573): can force read of arbitrarily sized vector
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int8_t>>, readByteVector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<int8_t>>, readByteVector),
-    // PARCEL_READ_WITH_STATUS(std::vector<int8_t>, readByteVector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<uint8_t>>, readByteVector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<uint8_t>>, readByteVector),
-    // PARCEL_READ_WITH_STATUS(std::vector<uint8_t>, readByteVector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int32_t>>, readInt32Vector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<int32_t>>, readInt32Vector),
-    // PARCEL_READ_WITH_STATUS(std::vector<int32_t>, readInt32Vector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int64_t>>, readInt64Vector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<int64_t>>, readInt64Vector),
-    // PARCEL_READ_WITH_STATUS(std::vector<int64_t>, readInt64Vector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<uint64_t>>, readUint64Vector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<uint64_t>>, readUint64Vector),
-    // PARCEL_READ_WITH_STATUS(std::vector<uint64_t>, readUint64Vector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<float>>, readFloatVector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<float>>, readFloatVector),
-    // PARCEL_READ_WITH_STATUS(std::vector<float>, readFloatVector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<double>>, readDoubleVector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<double>>, readDoubleVector),
-    // PARCEL_READ_WITH_STATUS(std::vector<double>, readDoubleVector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<bool>>, readBoolVector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<bool>>, readBoolVector),
-    // PARCEL_READ_WITH_STATUS(std::vector<bool>, readBoolVector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<char16_t>>, readCharVector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<char16_t>>, readCharVector),
-    // PARCEL_READ_WITH_STATUS(std::vector<char16_t>, readCharVector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<android::String16>>>, readString16Vector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<android::String16>>>, readString16Vector),
-    // PARCEL_READ_WITH_STATUS(std::vector<android::String16>, readString16Vector),
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<std::string>>>, readUtf8VectorFromUtf16Vector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<std::string>>>, readUtf8VectorFromUtf16Vector),
-    // PARCEL_READ_WITH_STATUS(std::vector<std::string>, readUtf8VectorFromUtf16Vector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int8_t>>, readByteVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<int8_t>>, readByteVector),
+    PARCEL_READ_WITH_STATUS(std::vector<int8_t>, readByteVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<uint8_t>>, readByteVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<uint8_t>>, readByteVector),
+    PARCEL_READ_WITH_STATUS(std::vector<uint8_t>, readByteVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int32_t>>, readInt32Vector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<int32_t>>, readInt32Vector),
+    PARCEL_READ_WITH_STATUS(std::vector<int32_t>, readInt32Vector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<int64_t>>, readInt64Vector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<int64_t>>, readInt64Vector),
+    PARCEL_READ_WITH_STATUS(std::vector<int64_t>, readInt64Vector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<uint64_t>>, readUint64Vector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<uint64_t>>, readUint64Vector),
+    PARCEL_READ_WITH_STATUS(std::vector<uint64_t>, readUint64Vector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<float>>, readFloatVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<float>>, readFloatVector),
+    PARCEL_READ_WITH_STATUS(std::vector<float>, readFloatVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<double>>, readDoubleVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<double>>, readDoubleVector),
+    PARCEL_READ_WITH_STATUS(std::vector<double>, readDoubleVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<bool>>, readBoolVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<bool>>, readBoolVector),
+    PARCEL_READ_WITH_STATUS(std::vector<bool>, readBoolVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<char16_t>>, readCharVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<char16_t>>, readCharVector),
+    PARCEL_READ_WITH_STATUS(std::vector<char16_t>, readCharVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<android::String16>>>, readString16Vector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<android::String16>>>, readString16Vector),
+    PARCEL_READ_WITH_STATUS(std::vector<android::String16>, readString16Vector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<std::unique_ptr<std::string>>>, readUtf8VectorFromUtf16Vector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<std::optional<std::string>>>, readUtf8VectorFromUtf16Vector),
+    PARCEL_READ_WITH_STATUS(std::vector<std::string>, readUtf8VectorFromUtf16Vector),
 
     [] (const android::Parcel& p, uint8_t /*len*/) {
         FUZZ_LOG() << "about to read flattenable";
@@ -242,8 +246,12 @@
         FUZZ_LOG() << "read lite flattenable: " << status;
     },
 
-    // TODO(b/131868573): can force read of arbitrarily sized vector
-    // TODO: resizeOutVector
+    PARCEL_READ_WITH_STATUS(std::vector<uint8_t>, resizeOutVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<uint8_t>>, resizeOutVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<uint8_t>>, resizeOutVector),
+    PARCEL_READ_WITH_STATUS(std::vector<BigStruct>, resizeOutVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<BigStruct>>, resizeOutVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<BigStruct>>, resizeOutVector),
 
     PARCEL_READ_NO_STATUS(int32_t, readExceptionCode),
     [] (const android::Parcel& p, uint8_t /*len*/) {
@@ -261,10 +269,9 @@
     PARCEL_READ_NO_STATUS(int, readParcelFileDescriptor),
     PARCEL_READ_WITH_STATUS(android::base::unique_fd, readUniqueFileDescriptor),
 
-    // TODO(b/131868573): can force read of arbitrarily sized vector
-    // PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<android::base::unique_fd>>, readUniqueFileDescriptorVector),
-    // PARCEL_READ_WITH_STATUS(std::optional<std::vector<android::base::unique_fd>>, readUniqueFileDescriptorVector),
-    // PARCEL_READ_WITH_STATUS(std::vector<android::base::unique_fd>, readUniqueFileDescriptorVector),
+    PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<android::base::unique_fd>>, readUniqueFileDescriptorVector),
+    PARCEL_READ_WITH_STATUS(std::optional<std::vector<android::base::unique_fd>>, readUniqueFileDescriptorVector),
+    PARCEL_READ_WITH_STATUS(std::vector<android::base::unique_fd>, readUniqueFileDescriptorVector),
 
     [] (const android::Parcel& p, uint8_t len) {
         FUZZ_LOG() << "about to readBlob";
@@ -279,7 +286,6 @@
         FUZZ_LOG() << "readObject: " << obj;
     },
     PARCEL_READ_NO_STATUS(uid_t, readCallingWorkSourceUid),
-    PARCEL_READ_NO_STATUS(size_t, getBlobAshmemSize),
     PARCEL_READ_NO_STATUS(size_t, getOpenAshmemSize),
 
     // additional parcelable objects defined in libbinder
@@ -296,6 +302,23 @@
         FUZZ_LOG() << "ParcelableHolder status: " << status;
     },
     PARCEL_READ_WITH_STATUS(android::os::PersistableBundle, readParcelable),
+    [] (const ::android::Parcel& p, uint8_t /* data */) {
+        FUZZ_LOG() << "about to call hasFileDescriptorsInRange() with status";
+        size_t offset = p.readUint32();
+        size_t length = p.readUint32();
+        bool result;
+        status_t status = p.hasFileDescriptorsInRange(offset, length, &result);
+        FUZZ_LOG() << " status: " << status  << " result: " << result;
+    },
+    [] (const ::android::Parcel& p, uint8_t /* data */) {
+        FUZZ_LOG() << "about to call compareDataInRange() with status";
+        size_t thisOffset = p.readUint32();
+        size_t otherOffset = p.readUint32();
+        size_t length = p.readUint32();
+        int result;
+        status_t status = p.compareDataInRange(thisOffset, p, otherOffset, length, &result);
+        FUZZ_LOG() << " status: " << status  << " result: " << result;
+    },
 };
 // clang-format on
 #pragma clang diagnostic pop
diff --git a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
index 008780c..752fcbb 100644
--- a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
@@ -25,6 +25,7 @@
 // TODO(b/142061461): parent class
 class SomeParcelable {
 public:
+    binder_status_t writeToParcel(AParcel* /*parcel*/) { return STATUS_OK; }
     binder_status_t readFromParcel(const AParcel* parcel) {
         return AParcel_readInt32(parcel, &mValue);
     }
@@ -33,6 +34,41 @@
     int32_t mValue = 0;
 };
 
+class ISomeInterface : public ::ndk::ICInterface {
+public:
+    ISomeInterface() = default;
+    virtual ~ISomeInterface() = default;
+    static binder_status_t readFromParcel(const AParcel* parcel,
+                                          std::shared_ptr<ISomeInterface>* instance);
+};
+
+static binder_status_t onTransact(AIBinder*, transaction_code_t, const AParcel*, AParcel*) {
+    return STATUS_UNKNOWN_TRANSACTION;
+}
+
+static AIBinder_Class* g_class = ::ndk::ICInterface::defineClass("ISomeInterface", onTransact);
+
+class BpSomeInterface : public ::ndk::BpCInterface<ISomeInterface> {
+public:
+    explicit BpSomeInterface(const ::ndk::SpAIBinder& binder) : BpCInterface(binder) {}
+    virtual ~BpSomeInterface() = default;
+};
+
+binder_status_t ISomeInterface::readFromParcel(const AParcel* parcel,
+                                               std::shared_ptr<ISomeInterface>* instance) {
+    ::ndk::SpAIBinder binder;
+    binder_status_t status = AParcel_readStrongBinder(parcel, binder.getR());
+    if (status == STATUS_OK) {
+        if (AIBinder_associateClass(binder.get(), g_class)) {
+            *instance = std::static_pointer_cast<ISomeInterface>(
+                    ::ndk::ICInterface::asInterface(binder.get()));
+        } else {
+            *instance = ::ndk::SharedRefBase::make<BpSomeInterface>(binder);
+        }
+    }
+    return status;
+}
+
 #define PARCEL_READ(T, FUN)                                              \
     [](const NdkParcelAdapter& p, uint8_t /*data*/) {                    \
         FUZZ_LOG() << "about to read " #T " using " #FUN " with status"; \
@@ -91,28 +127,34 @@
         PARCEL_READ(ndk::ScopedFileDescriptor, ndk::AParcel_readRequiredParcelFileDescriptor),
         PARCEL_READ(std::string, ndk::AParcel_readString),
         PARCEL_READ(std::optional<std::string>, ndk::AParcel_readString),
-        // TODO(b/131868573): can force process to allocate arbitrary amount of
-        // memory
-        // PARCEL_READ(std::vector<std::string>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::optional<std::vector<std::optional<std::string>>>,
-        // ndk::AParcel_readVector), PARCEL_READ(std::vector<SomeParcelable>,
-        // ndk::AParcel_readVector), PARCEL_READ(std::vector<int32_t>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::vector<uint32_t>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::optional<std::vector<uint32_t>>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::vector<int64_t>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::optional<std::vector<int64_t>>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::vector<uint64_t>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::optional<std::vector<uint64_t>>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::vector<float>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::optional<std::vector<float>>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::vector<double>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::optional<std::vector<double>>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::vector<bool>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::optional<std::vector<bool>>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::vector<char16_t>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::optional<std::vector<char16_t>>, ndk::AParcel_readVector),
-        // PARCEL_READ(std::vector<int32_t>, ndk::AParcel_resizeVector),
-        // PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_resizeVector),
+
+        PARCEL_READ(std::vector<std::string>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<std::optional<std::string>>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<SomeParcelable>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<std::optional<SomeParcelable>>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<ndk::SpAIBinder>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<ndk::SpAIBinder>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<ndk::ScopedFileDescriptor>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<ndk::ScopedFileDescriptor>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<std::shared_ptr<ISomeInterface>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<std::shared_ptr<ISomeInterface>>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<int32_t>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<uint32_t>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<uint32_t>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<int64_t>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<int64_t>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<uint64_t>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<uint64_t>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<float>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<float>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<double>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<double>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<bool>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<bool>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<char16_t>, ndk::AParcel_readVector),
+        PARCEL_READ(std::optional<std::vector<char16_t>>, ndk::AParcel_readVector),
+        PARCEL_READ(std::vector<int32_t>, ndk::AParcel_resizeVector),
+        PARCEL_READ(std::optional<std::vector<int32_t>>, ndk::AParcel_resizeVector),
 };
 // clang-format on
diff --git a/libs/binder/tests/parcel_fuzzer/hwbinder.cpp b/libs/binder/tests/parcel_fuzzer/hwbinder.cpp
index 0fec393..ee9840f 100644
--- a/libs/binder/tests/parcel_fuzzer/hwbinder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/hwbinder.cpp
@@ -18,10 +18,12 @@
 #include "hwbinder.h"
 #include "util.h"
 
+#include <android-base/hex.h>
 #include <android-base/logging.h>
 #include <hwbinder/Parcel.h>
 
 using ::android::status_t;
+using ::android::base::HexString;
 
 // TODO: support scatter-gather types
 
@@ -70,13 +72,13 @@
         FUZZ_LOG() << "about to read";
         std::vector<uint8_t> data (length);
         status_t status = p.read(data.data(), length);
-        FUZZ_LOG() << "read status: " << status << " data: " << hexString(data.data(), data.size());
+        FUZZ_LOG() << "read status: " << status << " data: " << HexString(data.data(), data.size());
     },
     [] (const ::android::hardware::Parcel& p, uint8_t length) {
         FUZZ_LOG() << "about to read";
         std::vector<uint8_t> data (length);
         const void* inplace = p.readInplace(length);
-        FUZZ_LOG() << "read status: " << hexString(inplace, length);
+        FUZZ_LOG() << "read status: " << (inplace ? HexString(inplace, length) : "null");
     },
     PARCEL_READ_WITH_STATUS(int8_t, readInt8),
     PARCEL_READ_WITH_STATUS(uint8_t, readUint8),
@@ -100,7 +102,7 @@
         FUZZ_LOG() << "about to readString16Inplace";
         size_t outSize = 0;
         const char16_t* str = p.readString16Inplace(&outSize);
-        FUZZ_LOG() << "readString16Inplace: " << hexString(str, sizeof(char16_t) * outSize);
+        FUZZ_LOG() << "readString16Inplace: " << HexString(str, sizeof(char16_t) * outSize);
     },
     PARCEL_READ_OPT_STATUS(::android::sp<::android::hardware::IBinder>, readStrongBinder),
     PARCEL_READ_WITH_STATUS(::android::sp<::android::hardware::IBinder>, readNullableStrongBinder),
@@ -148,28 +150,6 @@
         // should be null since we don't create any IPC objects
         CHECK(data == nullptr) << data;
     },
-    [] (const ::android::hardware::Parcel& p, uint8_t size) {
-        FUZZ_LOG() << "about to readEmbeddedNativeHandle";
-        size_t parent_buffer_handle = size & 0xf;
-        size_t parent_offset = size >> 4;
-        const native_handle_t* handle = nullptr;
-        status_t status = p.readEmbeddedNativeHandle(parent_buffer_handle, parent_offset, &handle);
-        FUZZ_LOG() << "readEmbeddedNativeHandle status: " << status << " handle: " << handle << " handle: " << handle;
-
-        // should be null since we don't create any IPC objects
-        CHECK(handle == nullptr) << handle;
-    },
-    [] (const ::android::hardware::Parcel& p, uint8_t size) {
-        FUZZ_LOG() << "about to readNullableEmbeddedNativeHandle";
-        size_t parent_buffer_handle = size & 0xf;
-        size_t parent_offset = size >> 4;
-        const native_handle_t* handle = nullptr;
-        status_t status = p.readNullableEmbeddedNativeHandle(parent_buffer_handle, parent_offset, &handle);
-        FUZZ_LOG() << "readNullableEmbeddedNativeHandle status: " << status << " handle: " << handle << " handle: " << handle;
-
-        // should be null since we don't create any IPC objects
-        CHECK(handle == nullptr) << handle;
-    },
     [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
         FUZZ_LOG() << "about to readNativeHandleNoDup";
         const native_handle_t* handle = nullptr;
@@ -180,14 +160,5 @@
         CHECK(handle == nullptr) << handle;
         CHECK(status != ::android::OK);
     },
-    [] (const ::android::hardware::Parcel& p, uint8_t /*data*/) {
-        FUZZ_LOG() << "about to readNullableNativeHandleNoDup";
-        const native_handle_t* handle = nullptr;
-        status_t status = p.readNullableNativeHandleNoDup(&handle);
-        FUZZ_LOG() << "readNullableNativeHandleNoDup status: " << status << " handle: " << handle;
-
-        // should be null since we don't create any IPC objects
-        CHECK(handle == nullptr) << handle;
-    },
 };
 // clang-format on
diff --git a/libs/binder/tests/parcel_fuzzer/main.cpp b/libs/binder/tests/parcel_fuzzer/main.cpp
index a47b753..f435dae 100644
--- a/libs/binder/tests/parcel_fuzzer/main.cpp
+++ b/libs/binder/tests/parcel_fuzzer/main.cpp
@@ -22,8 +22,10 @@
 
 #include <iostream>
 
+#include <android-base/hex.h>
 #include <android-base/logging.h>
-#include <binder/RpcSession.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_libbinder.h>
 #include <fuzzbinder/random_parcel.h>
 #include <fuzzer/FuzzedDataProvider.h>
 
@@ -33,8 +35,8 @@
 #include <sys/time.h>
 
 using android::fillRandomParcel;
-using android::RpcSession;
 using android::sp;
+using android::base::HexString;
 
 void fillRandomParcel(::android::hardware::Parcel* p, FuzzedDataProvider&& provider) {
     // TODO: functionality to create random parcels for libhwbinder parcels
@@ -46,9 +48,22 @@
     fillRandomParcel(p->parcel(), std::move(provider));
 }
 
+template <typename P, typename B>
+void doTransactFuzz(const char* backend, const sp<B>& binder, FuzzedDataProvider&& provider) {
+    uint32_t code = provider.ConsumeIntegral<uint32_t>();
+    uint32_t flag = provider.ConsumeIntegral<uint32_t>();
+
+    FUZZ_LOG() << "backend: " << backend;
+
+    P reply;
+    P data;
+    fillRandomParcel(&data, std::move(provider));
+    (void)binder->transact(code, data, &reply, flag);
+}
+
 template <typename P>
-void doFuzz(const char* backend, const std::vector<ParcelRead<P>>& reads,
-            FuzzedDataProvider&& provider) {
+void doReadFuzz(const char* backend, const std::vector<ParcelRead<P>>& reads,
+                FuzzedDataProvider&& provider) {
     // Allow some majority of the bytes to be dedicated to telling us what to
     // do. The fixed value added here represents that we want to test doing a
     // lot of 'instructions' even on really short parcels.
@@ -59,25 +74,14 @@
             provider.ConsumeIntegralInRange<size_t>(0, maxInstructions));
 
     P p;
-    if constexpr (std::is_same_v<P, android::Parcel>) {
-        if (provider.ConsumeBool()) {
-            auto session = sp<RpcSession>::make();
-            CHECK(session->addNullDebuggingClient());
-            p.markForRpc(session);
-            fillRandomParcelData(&p, std::move(provider));
-        } else {
-            fillRandomParcel(&p, std::move(provider));
-        }
-    } else {
-        fillRandomParcel(&p, std::move(provider));
-    }
+    fillRandomParcel(&p, std::move(provider));
 
     // since we are only using a byte to index
     CHECK(reads.size() <= 255) << reads.size();
 
     FUZZ_LOG() << "backend: " << backend;
-    FUZZ_LOG() << "input: " << hexString(p.data(), p.dataSize());
-    FUZZ_LOG() << "instructions: " << hexString(instructions);
+    FUZZ_LOG() << "input: " << HexString(p.data(), p.dataSize());
+    FUZZ_LOG() << "instructions: " << HexString(instructions.data(), instructions.size());
 
     for (size_t i = 0; i + 1 < instructions.size(); i += 2) {
         uint8_t a = instructions[i];
@@ -95,25 +99,18 @@
     }
 }
 
-size_t getHardMemoryLimit() {
-    struct rlimit limit;
-    CHECK(0 == getrlimit(RLIMIT_AS, &limit)) << errno;
-    return limit.rlim_max;
+void* NothingClass_onCreate(void* args) {
+    return args;
 }
-
-void setMemoryLimit(size_t cur, size_t max) {
-    const struct rlimit kLimit = {
-       .rlim_cur = cur,
-       .rlim_max = max,
-    };
-    CHECK(0 == setrlimit(RLIMIT_AS, &kLimit)) << errno;
+void NothingClass_onDestroy(void* /*userData*/) {}
+binder_status_t NothingClass_onTransact(AIBinder*, transaction_code_t, const AParcel*, AParcel*) {
+    return STATUS_UNKNOWN_ERROR;
 }
+static AIBinder_Class* kNothingClass =
+        AIBinder_Class_define("nothing", NothingClass_onCreate, NothingClass_onDestroy,
+                              NothingClass_onTransact);
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-    static constexpr size_t kMemLimit = 1 * 1024 * 1024;
-    size_t hardLimit = getHardMemoryLimit();
-    setMemoryLimit(std::min(kMemLimit, hardLimit), hardLimit);
-
     if (size <= 1) return 0;  // no use
 
     // avoid timeouts, see b/142617274, b/142473153
@@ -121,24 +118,39 @@
 
     FuzzedDataProvider provider = FuzzedDataProvider(data, size);
 
-    const std::function<void(FuzzedDataProvider &&)> fuzzBackend[3] = {
+    const std::function<void(FuzzedDataProvider &&)> fuzzBackend[] = {
             [](FuzzedDataProvider&& provider) {
-                doFuzz<::android::hardware::Parcel>("hwbinder", HWBINDER_PARCEL_READ_FUNCTIONS,
-                                                    std::move(provider));
+                doTransactFuzz<
+                        ::android::hardware::Parcel>("hwbinder",
+                                                     sp<::android::hardware::BHwBinder>::make(),
+                                                     std::move(provider));
             },
             [](FuzzedDataProvider&& provider) {
-                doFuzz<::android::Parcel>("binder", BINDER_PARCEL_READ_FUNCTIONS,
-                                          std::move(provider));
+                doTransactFuzz<::android::Parcel>("binder", sp<::android::BBinder>::make(),
+                                                  std::move(provider));
             },
             [](FuzzedDataProvider&& provider) {
-                doFuzz<NdkParcelAdapter>("binder_ndk", BINDER_NDK_PARCEL_READ_FUNCTIONS,
-                                         std::move(provider));
+                // fuzz from the libbinder layer since it's a superset of the
+                // interface you get at the libbinder_ndk layer
+                auto ndkBinder = ndk::SpAIBinder(AIBinder_new(kNothingClass, nullptr));
+                auto binder = AIBinder_toPlatformBinder(ndkBinder.get());
+                doTransactFuzz<::android::Parcel>("binder_ndk", binder, std::move(provider));
+            },
+            [](FuzzedDataProvider&& provider) {
+                doReadFuzz<::android::hardware::Parcel>("hwbinder", HWBINDER_PARCEL_READ_FUNCTIONS,
+                                                        std::move(provider));
+            },
+            [](FuzzedDataProvider&& provider) {
+                doReadFuzz<::android::Parcel>("binder", BINDER_PARCEL_READ_FUNCTIONS,
+                                              std::move(provider));
+            },
+            [](FuzzedDataProvider&& provider) {
+                doReadFuzz<NdkParcelAdapter>("binder_ndk", BINDER_NDK_PARCEL_READ_FUNCTIONS,
+                                             std::move(provider));
             },
     };
 
     provider.PickValueInArray(fuzzBackend)(std::move(provider));
 
-    setMemoryLimit(hardLimit, hardLimit);
-
     return 0;
 }
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
index b045a22..8bf04cc 100644
--- a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
@@ -18,6 +18,8 @@
 
 #include <android-base/logging.h>
 #include <binder/IServiceManager.h>
+#include <binder/RpcSession.h>
+#include <binder/RpcTransportRaw.h>
 #include <fuzzbinder/random_fd.h>
 #include <utils/String16.h>
 
@@ -33,6 +35,14 @@
 };
 
 void fillRandomParcel(Parcel* p, FuzzedDataProvider&& provider) {
+    if (provider.ConsumeBool()) {
+        auto session = RpcSession::make(RpcTransportCtxFactoryRaw::make());
+        CHECK_EQ(OK, session->addNullDebuggingClient());
+        p->markForRpc(session);
+        fillRandomParcelData(p, std::move(provider));
+        return;
+    }
+
     while (provider.remaining_bytes() > 0) {
         auto fillFunc = provider.PickValueInArray<const std::function<void()>>({
                 // write data
diff --git a/libs/binder/tests/parcel_fuzzer/util.cpp b/libs/binder/tests/parcel_fuzzer/util.cpp
deleted file mode 100644
index 479f406..0000000
--- a/libs/binder/tests/parcel_fuzzer/util.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define FUZZ_LOG_TAG "util"
-#include "util.h"
-
-#include <android-base/logging.h>
-
-#include <iomanip>
-#include <sstream>
-
-std::string hexString(const void* bytes, size_t len) {
-    if (bytes == nullptr) return "<null>";
-
-    const uint8_t* bytes8 = static_cast<const uint8_t*>(bytes);
-    char chars[] = "0123456789abcdef";
-    std::string result;
-    result.resize(len * 2);
-
-    for (size_t i = 0; i < len; i++) {
-        result[2 * i] = chars[bytes8[i] >> 4];
-        result[2 * i + 1] = chars[bytes8[i] & 0xf];
-    }
-
-    return result;
-}
-std::string hexString(const std::vector<uint8_t>& bytes) {
-    return hexString(bytes.data(), bytes.size());
-}
diff --git a/libs/binder/tests/parcel_fuzzer/util.h b/libs/binder/tests/parcel_fuzzer/util.h
index 45e8c57..a5d0dae 100644
--- a/libs/binder/tests/parcel_fuzzer/util.h
+++ b/libs/binder/tests/parcel_fuzzer/util.h
@@ -49,6 +49,3 @@
     FuzzLog& log() { return *this; }
 };
 #endif
-
-std::string hexString(const void* bytes, size_t len);
-std::string hexString(const std::vector<uint8_t>& bytes);
diff --git a/libs/binder/tests/rpc_fuzzer/Android.bp b/libs/binder/tests/rpc_fuzzer/Android.bp
index 1c75306..71e847f 100644
--- a/libs/binder/tests/rpc_fuzzer/Android.bp
+++ b/libs/binder/tests/rpc_fuzzer/Android.bp
@@ -14,27 +14,41 @@
     fuzz_config: {
         cc: ["smoreland@google.com"],
     },
+    corpus: ["corpus/*"],
+    dictionary: "binder_rpc_fuzzer.dict",
 
     srcs: [
         "main.cpp",
     ],
+    // Not using libbinder_tls_shared_deps to use deterministic boringssl libraries.
     static_libs: [
         "libbase",
         "libcutils",
         "liblog",
-        "libutils",
+        "libbinder_tls_static",
+        "libbinder_tls_test_utils",
+        "libssl_fuzz_unsafe",
+        "libcrypto_fuzz_unsafe",
     ],
-
+    cflags: [
+        "-DBORINGSSL_UNSAFE_DETERMINISTIC_MODE" // for RAND_reset_for_fuzzing
+    ],
     target: {
         android: {
             shared_libs: [
                 "libbinder",
+                "libutils",
             ],
         },
         host: {
             static_libs: [
                 "libbinder",
+                "libutils",
             ],
         },
     },
+    data: [
+        "server.crt",
+        "server.key",
+    ],
 }
diff --git a/libs/binder/tests/rpc_fuzzer/binder_rpc_fuzzer.dict b/libs/binder/tests/rpc_fuzzer/binder_rpc_fuzzer.dict
new file mode 100644
index 0000000..b110a02
--- /dev/null
+++ b/libs/binder/tests/rpc_fuzzer/binder_rpc_fuzzer.dict
@@ -0,0 +1,2 @@
+# connection okay header
+"cci"
diff --git a/libs/binder/tests/rpc_fuzzer/corpus/special_transaction b/libs/binder/tests/rpc_fuzzer/corpus/special_transaction
new file mode 100644
index 0000000..37228ee
--- /dev/null
+++ b/libs/binder/tests/rpc_fuzzer/corpus/special_transaction
Binary files differ
diff --git a/libs/binder/tests/rpc_fuzzer/create_certs.sh b/libs/binder/tests/rpc_fuzzer/create_certs.sh
new file mode 100755
index 0000000..4ae4cb1
--- /dev/null
+++ b/libs/binder/tests/rpc_fuzzer/create_certs.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# As explained in
+#  https://gist.github.com/darrenjs/4645f115d10aa4b5cebf57483ec82eca
+
+openssl genrsa -des3 -passout pass:xxxx -out server.pass.key 2048
+openssl rsa -passin pass:xxxx -in server.pass.key -out server.key
+rm -f server.pass.key
+
+openssl req \
+    -subj "/" \
+    -new -key server.key -out server.csr
+
+openssl x509 -req -sha256 -days 99999 -in server.csr -signkey server.key -out server.crt
+rm -f server.csr
diff --git a/libs/binder/tests/rpc_fuzzer/main.cpp b/libs/binder/tests/rpc_fuzzer/main.cpp
index 3603ebe..a8713a2 100644
--- a/libs/binder/tests/rpc_fuzzer/main.cpp
+++ b/libs/binder/tests/rpc_fuzzer/main.cpp
@@ -13,13 +13,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/unique_fd.h>
 #include <binder/Binder.h>
 #include <binder/Parcel.h>
 #include <binder/RpcServer.h>
-#include <binder/RpcSession.h>
+#include <binder/RpcTlsTestUtils.h>
+#include <binder/RpcTransport.h>
+#include <binder/RpcTransportRaw.h>
+#include <binder/RpcTransportTls.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <openssl/rand.h>
+#include <openssl/ssl.h>
 
 #include <sys/resource.h>
 #include <sys/un.h>
@@ -29,20 +36,6 @@
 static const std::string kSock = std::string(getenv("TMPDIR") ?: "/tmp") +
         "/binderRpcFuzzerSocket_" + std::to_string(getpid());
 
-size_t getHardMemoryLimit() {
-    struct rlimit limit;
-    CHECK(0 == getrlimit(RLIMIT_AS, &limit)) << errno;
-    return limit.rlim_max;
-}
-
-void setMemoryLimit(size_t cur, size_t max) {
-    const struct rlimit kLimit = {
-            .rlim_cur = cur,
-            .rlim_max = max,
-    };
-    CHECK(0 == setrlimit(RLIMIT_AS, &kLimit)) << errno;
-}
-
 class SomeBinder : public BBinder {
     status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) {
         (void)flags;
@@ -65,21 +58,70 @@
     }
 };
 
+int passwordCallback(char* buf, int size, int /*rwflag*/, void* /*u*/) {
+    constexpr const char pass[] = "xxxx"; // See create_certs.sh
+    if (size <= 0) return 0;
+    int numCopy = std::min<int>(size, sizeof(pass));
+    (void)memcpy(buf, pass, numCopy);
+    return numCopy;
+}
+
+struct ServerAuth {
+    bssl::UniquePtr<EVP_PKEY> pkey;
+    bssl::UniquePtr<X509> cert;
+};
+
+// Use pre-configured keys because runtime generated keys / certificates are not
+// deterministic, and the algorithm is time consuming.
+ServerAuth readServerKeyAndCert() {
+    ServerAuth ret;
+
+    auto keyPath = android::base::GetExecutableDirectory() + "/data/server.key";
+    bssl::UniquePtr<BIO> keyBio(BIO_new_file(keyPath.c_str(), "r"));
+    ret.pkey.reset(PEM_read_bio_PrivateKey(keyBio.get(), nullptr, passwordCallback, nullptr));
+    CHECK_NE(ret.pkey.get(), nullptr);
+
+    auto certPath = android::base::GetExecutableDirectory() + "/data/server.crt";
+    bssl::UniquePtr<BIO> certBio(BIO_new_file(certPath.c_str(), "r"));
+    ret.cert.reset(PEM_read_bio_X509(certBio.get(), nullptr, nullptr, nullptr));
+    CHECK_NE(ret.cert.get(), nullptr);
+
+    return ret;
+}
+
+std::unique_ptr<RpcAuth> createServerRpcAuth() {
+    static auto sAuth = readServerKeyAndCert();
+
+    CHECK(EVP_PKEY_up_ref(sAuth.pkey.get()));
+    bssl::UniquePtr<EVP_PKEY> pkey(sAuth.pkey.get());
+    CHECK(X509_up_ref(sAuth.cert.get()));
+    bssl::UniquePtr<X509> cert(sAuth.cert.get());
+
+    return std::make_unique<RpcAuthPreSigned>(std::move(pkey), std::move(cert));
+}
+
+std::unique_ptr<RpcTransportCtxFactory> makeTransportCtxFactory(FuzzedDataProvider* provider) {
+    bool isTls = provider->ConsumeBool();
+    if (!isTls) {
+        return RpcTransportCtxFactoryRaw::make();
+    }
+    status_t verifyStatus = provider->ConsumeIntegral<status_t>();
+    auto verifier = std::make_shared<RpcCertificateVerifierNoOp>(verifyStatus);
+    return RpcTransportCtxFactoryTls::make(verifier, createServerRpcAuth());
+}
+
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
     if (size > 50000) return 0;
+    FuzzedDataProvider provider(data, size);
+    RAND_reset_for_fuzzing();
 
     unlink(kSock.c_str());
 
-    sp<RpcServer> server = RpcServer::make();
+    sp<RpcServer> server = RpcServer::make(makeTransportCtxFactory(&provider));
     server->setRootObject(sp<SomeBinder>::make());
-    server->iUnderstandThisCodeIsExperimentalAndIWillNotUseItInProduction();
-    CHECK(server->setupUnixDomainServer(kSock.c_str()));
+    CHECK_EQ(OK, server->setupUnixDomainServer(kSock.c_str()));
 
-    static constexpr size_t kMemLimit = 1llu * 1024 * 1024 * 1024;
-    size_t hardLimit = getHardMemoryLimit();
-    setMemoryLimit(std::min(kMemLimit, hardLimit), hardLimit);
-
-    std::thread serverThread([=] { (void)server->acceptOne(); });
+    std::thread serverThread([=] { (void)server->join(); });
 
     sockaddr_un addr{
             .sun_family = AF_UNIX,
@@ -87,33 +129,46 @@
     CHECK_LT(kSock.size(), sizeof(addr.sun_path));
     memcpy(&addr.sun_path, kSock.c_str(), kSock.size());
 
-    base::unique_fd clientFd(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)));
-    CHECK_NE(clientFd.get(), -1);
-    CHECK_EQ(0,
-             TEMP_FAILURE_RETRY(
-                     connect(clientFd.get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr))))
-            << strerror(errno);
+    std::vector<base::unique_fd> connections;
 
-    serverThread.join();
+    bool hangupBeforeShutdown = provider.ConsumeBool();
 
-    // TODO(b/182938024): fuzz multiple sessions, instead of just one
+    while (provider.remaining_bytes() > 0) {
+        if (connections.empty() || provider.ConsumeBool()) {
+            base::unique_fd fd(TEMP_FAILURE_RETRY(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)));
+            CHECK_NE(fd.get(), -1);
+            CHECK_EQ(0,
+                     TEMP_FAILURE_RETRY(
+                             connect(fd.get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr))))
+                    << strerror(errno);
+            connections.push_back(std::move(fd));
+        } else {
+            size_t idx = provider.ConsumeIntegralInRange<size_t>(0, connections.size() - 1);
 
-#if 0
-    // make fuzzer more productive locally by forcing it to create a new session
-    int32_t id = -1;
-    CHECK(base::WriteFully(clientFd, &id, sizeof(id)));
-#endif
-
-    CHECK(base::WriteFully(clientFd, data, size));
-
-    clientFd.reset();
-
-    // TODO(b/185167543): better way to force a server to shutdown
-    while (!server->listSessions().empty() && server->numUninitializedSessions()) {
-        usleep(1);
+            if (provider.ConsumeBool()) {
+                std::string writeData = provider.ConsumeRandomLengthString();
+                ssize_t size = TEMP_FAILURE_RETRY(send(connections.at(idx).get(), writeData.data(),
+                                                       writeData.size(), MSG_NOSIGNAL));
+                CHECK(errno == EPIPE || size == writeData.size())
+                        << size << " " << writeData.size() << " " << strerror(errno);
+            } else {
+                connections.erase(connections.begin() + idx); // hang up
+            }
+        }
     }
 
-    setMemoryLimit(hardLimit, hardLimit);
+    usleep(10000);
+
+    if (hangupBeforeShutdown) {
+        connections.clear();
+        while (!server->listSessions().empty() || server->numUninitializedSessions()) {
+            // wait for all threads to finish processing existing information
+            usleep(1);
+        }
+    }
+
+    while (!server->shutdown()) usleep(1);
+    serverThread.join();
 
     return 0;
 }
diff --git a/libs/binder/tests/rpc_fuzzer/server.crt b/libs/binder/tests/rpc_fuzzer/server.crt
new file mode 100644
index 0000000..9142474
--- /dev/null
+++ b/libs/binder/tests/rpc_fuzzer/server.crt
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICiTCCAXECFG1ggXE36l2WXeG6YTnaRVB7EmgQMA0GCSqGSIb3DQEBCwUAMAAw
+IBcNMjEwOTI5MDEzOTEzWhgPMjI5NTA3MTQwMTM5MTNaMAAwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDE3KnhPMwINpP5aIHIo/3GTlROZOK5AmkEsWmP
+w8smSWo2hJ7M0sOhruvOz82WORj48K8C0W72yFN+e9g32qoNMJFP/s6j1RWmaAKZ
+eSQUq6ixyaGhFLBOoukVykfTnY4qn4RbX5HzgpAPR1gv5ELvMXXPrxvtpIcVIrhm
+/dBQIa3iHZS6kypNbmRx/nhDVU8FK9s9WU5VLpbuNxv+m4X4Y1M/VZNatUMx5I0o
+ystV4JTqzjRZRPR4sxtMhu8/A11JsBVLeu8ZM/0IGCjmLOF4hy5a5YDv8MOJtdG2
+LI7ibZNtyrZiKwwhJc3tElzeIFit4T5Xjx69y/EMS4Hwhf3zAgMBAAEwDQYJKoZI
+hvcNAQELBQADggEBAD3gRbUybW7P2CihMyskTgS9HoIT9c02JWjtueWQIiQkyqTB
+6QdUQTHM5weil6TiW8NfpQQUIvrh66Pkph65shvFqxUsjdW25b4RbfUldFihfs1n
+kTa+e+hZONnVuzLvezIs2b8dygH9GA5y2OiLxwrMUcyaoCHGwKF7iOE0SJhfx0kY
+JDs4O+gAVjEsBSc24pm9aHBxgRCiEm1I4+RZf6PRBIz1ZadGBFsCZ+Gj6wyLP2Wq
+kjjMiV6o8pEjJjM+Oi4GfxvNewMCd2hMZYuJYpYC3cc7fPIpx8luidqKJdve8c6m
+KQ+dJ6ZQxEi0Zc9Jzre7NNoVcpIdc8SbkEM/DDo=
+-----END CERTIFICATE-----
diff --git a/libs/binder/tests/rpc_fuzzer/server.key b/libs/binder/tests/rpc_fuzzer/server.key
new file mode 100644
index 0000000..743470e
--- /dev/null
+++ b/libs/binder/tests/rpc_fuzzer/server.key
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAxNyp4TzMCDaT+WiByKP9xk5UTmTiuQJpBLFpj8PLJklqNoSe
+zNLDoa7rzs/NljkY+PCvAtFu9shTfnvYN9qqDTCRT/7Oo9UVpmgCmXkkFKuoscmh
+oRSwTqLpFcpH052OKp+EW1+R84KQD0dYL+RC7zF1z68b7aSHFSK4Zv3QUCGt4h2U
+upMqTW5kcf54Q1VPBSvbPVlOVS6W7jcb/puF+GNTP1WTWrVDMeSNKMrLVeCU6s40
+WUT0eLMbTIbvPwNdSbAVS3rvGTP9CBgo5izheIcuWuWA7/DDibXRtiyO4m2Tbcq2
+YisMISXN7RJc3iBYreE+V48evcvxDEuB8IX98wIDAQABAoIBACcI5jp+NqrOP6st
+uMZTFifzMi5VPMuYmcBPeXIDTc3qsr/ari5JAHeX2rQoakiGS9hYySsS4iDW+g9T
+eT0iA6QX5Ehrawf7YY6cgx9xcOEUZJ/ULlNlacw961/huzpPvHfhJ3qCycryMaSF
+7guZBFivgv/KZgxKGmrrdosdeufYXL3eHWZIrvcN4cDVgxslZg0o3Y5kCW3/KmDO
+QwvBlqgja93yImmkFA5BA/hQUsWuMBiR0xAd4b1NSBVCGTAYuCm6Up+6tIxeBSu5
+MVnNXbAIyVkbAS+gaR4uut6ObzFwUyGKDMaMpJ0LHLbusZy0svevu6Hjx+eH0ePC
+rj1xmDECgYEA4WR+1m3Tej0botG68+pZ8yLBgomSBAqpINCFkMEGQ2sQ1CqMMkHq
+8LAQNotU56W/0/H3eQemE3qBSKt1BUffpCvCHWkL9DRyDNhiq9U2PvV2Lx0Bv77e
+ET5MSDECUjlIsDqnv2qbq/m23BiP7AM8c9s6HjD0PqptyHjLlWHK86kCgYEA35hW
+AZEqMzsTNVQ8lXQtbqCyv8lls1SJbvIf3b5KItw9CwqpLr+UXssXh713j+yMW+WN
+3nv5+VaggkNBa9fHdqQEYT0L52OnLNjsfTlVhP5g2lOIa5VQYb/wqF1TaiZ27SGU
+lmLqiyArZgTnc3yo1wuIRPAbYbbm6CVnz7bm5jsCgYEAqfov7WZF5hnPjaq9YtWJ
+oGLFrLwy8flYMvcOw2vOXWmQ93Be6kfr9jfRAlFxZoEJeb0w9IVgKbBpb3Ree+0I
+K7cUXTmrWi9zE1zcjNnuXuyehElL2F8I+dgRjx/msDujJcQWXbT4UWmxDas4XrTS
+Ek1yNvKUP+4nfNgcMDvf4oECgYEAjgfYajpqEgzukKunqFAaI/HUWdt2zMlgW6dV
+8qdTtH0uEXt+KIHtn6FmmwURk8zxA9b3nWInUeljIBvUzMpOm+BoH9SFYUB+CxDo
+eEsZNdfYchcpyx0X6F/iYTCXMhCo7syr9DN1RVbz+mQXGdcP8ToUH6Zd3l4uozxP
+izRly80CgYEAqz7fCgQH74BwHoroSNdD3Cn6KNVx+oPuwRmzO4xMSOGyd/dNB2NA
+uzzuCTbrzC0jCXpqR0Bh9gYMjxyRZbifPX/YuFHyCIKK4+SQfeC4ZEwmSJVGWeh7
+3NksFJPCH4K3KbLNputByWJWOgKUdy70e/xOi83acBAVyRs+7H9LocE=
+-----END RSA PRIVATE KEY-----
diff --git a/libs/binder/tests/unit_fuzzers/Android.bp b/libs/binder/tests/unit_fuzzers/Android.bp
index b1263e8..8ea948c 100644
--- a/libs/binder/tests/unit_fuzzers/Android.bp
+++ b/libs/binder/tests/unit_fuzzers/Android.bp
@@ -30,16 +30,28 @@
         "-Wall",
         "-Werror",
     ],
-    shared_libs: [
-        "libbinder",
-        "libutils",
-        "libbase",
-    ],
     target: {
+        android: {
+            shared_libs: [
+                "libcutils",
+                "libutils",
+                "libbase",
+                "libbinder",
+            ],
+        },
+        host: {
+            static_libs: [
+                "libcutils",
+                "liblog",
+                "libutils",
+                "libbase",
+                "libbinder",
+            ],
+        },
         darwin: {
             enabled: false,
-        }
-    }
+        },
+    },
 }
 
 cc_fuzz {
@@ -51,7 +63,6 @@
 cc_fuzz {
     name: "binder_bpBinderFuzz",
     defaults: ["binder_fuzz_defaults"],
-    host_supported: false,
     srcs: ["BpBinderFuzz.cpp"],
 }
 
diff --git a/libs/binder/tests/unit_fuzzers/BinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/BinderFuzzFunctions.h
index 69f1b9d..8d2b714 100644
--- a/libs/binder/tests/unit_fuzzers/BinderFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/BinderFuzzFunctions.h
@@ -72,6 +72,10 @@
                               },
                               [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void {
                                   bbinder->getDebugPid();
+                              },
+                              [](FuzzedDataProvider*, const sp<BBinder>& bbinder) -> void {
+                                  (void)bbinder->setRpcClientDebug(android::base::unique_fd(),
+                                                                   sp<BBinder>::make());
                               }};
 
 } // namespace android
diff --git a/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp b/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp
index c50279b..e77c55c 100644
--- a/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp
+++ b/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp
@@ -19,8 +19,15 @@
 #include <commonFuzzHelpers.h>
 #include <fuzzer/FuzzedDataProvider.h>
 
+#include <android-base/logging.h>
 #include <binder/BpBinder.h>
 #include <binder/IServiceManager.h>
+#include <binder/RpcServer.h>
+#include <binder/RpcSession.h>
+
+#include <signal.h>
+#include <sys/prctl.h>
+#include <thread>
 
 namespace android {
 
@@ -28,13 +35,29 @@
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
     FuzzedDataProvider fdp(data, size);
 
-    // TODO: In the future it would be more effective to fork a new process and then pass a BBinder
-    // to your process. Right now this is not implemented because it would involved fuzzing IPC on a
-    // forked process, and libfuzzer will not be able to handle code coverage. This would lead to
-    // crashes that are not easy to diagnose.
-    int32_t handle = fdp.ConsumeIntegralInRange<int32_t>(0, 1024);
-    sp<BpBinder> bpbinder = BpBinder::create(handle);
-    if (bpbinder == nullptr) return 0;
+    std::string addr = std::string(getenv("TMPDIR") ?: "/tmp") + "/binderRpcBenchmark";
+    (void)unlink(addr.c_str());
+
+    sp<RpcServer> server = RpcServer::make();
+
+    // use RPC binder because fuzzer can't get coverage from another process.
+    auto thread = std::thread([&]() {
+        prctl(PR_SET_PDEATHSIG, SIGHUP); // racey, okay
+        server->setRootObject(sp<BBinder>::make());
+        CHECK_EQ(OK, server->setupUnixDomainServer(addr.c_str()));
+        server->join();
+    });
+
+    sp<RpcSession> session = RpcSession::make();
+    status_t status;
+    for (size_t tries = 0; tries < 5; tries++) {
+        usleep(10000);
+        status = session->setupUnixDomainClient(addr.c_str());
+        if (status == OK) break;
+    }
+    CHECK_EQ(status, OK) << "Unable to connect";
+
+    sp<BpBinder> bpBinder = session->getRootObject()->remoteBinder();
 
     // To prevent memory from running out from calling too many add item operations.
     const uint32_t MAX_RUNS = 2048;
@@ -43,12 +66,16 @@
 
     while (fdp.remaining_bytes() > 0 && count++ < MAX_RUNS) {
         if (fdp.ConsumeBool()) {
-            callArbitraryFunction(&fdp, gBPBinderOperations, bpbinder, s_recipient);
+            callArbitraryFunction(&fdp, gBPBinderOperations, bpBinder, s_recipient);
         } else {
-            callArbitraryFunction(&fdp, gIBinderOperations, bpbinder.get());
+            callArbitraryFunction(&fdp, gIBinderOperations, bpBinder.get());
         }
     }
 
+    CHECK(session->shutdownAndWait(true)) << "couldn't shutdown session";
+    CHECK(server->shutdown()) << "couldn't shutdown server";
+    thread.join();
+
     return 0;
 }
 } // namespace android
diff --git a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
index 6ca0e2f..741987f 100644
--- a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
@@ -52,7 +52,7 @@
                     const sp<IBinder::DeathRecipient>& s_recipient) -> void {
                      // Clean up possible leftover memory.
                      wp<IBinder::DeathRecipient> outRecipient(nullptr);
-                     bpbinder->sendObituary();
+                     if (!bpbinder->isRpcBinder()) bpbinder->sendObituary();
                      bpbinder->unlinkToDeath(nullptr, reinterpret_cast<void*>(&kBpBinderCookie), 0,
                                              &outRecipient);
 
@@ -72,7 +72,9 @@
                  [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder,
                     const sp<IBinder::DeathRecipient>&) -> void { bpbinder->remoteBinder(); },
                  [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder,
-                    const sp<IBinder::DeathRecipient>&) -> void { bpbinder->sendObituary(); },
+                    const sp<IBinder::DeathRecipient>&) -> void {
+                     if (!bpbinder->isRpcBinder()) bpbinder->sendObituary();
+                 },
                  [](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder,
                     const sp<IBinder::DeathRecipient>&) -> void {
                      uint32_t uid = fdp->ConsumeIntegral<uint32_t>();
diff --git a/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h
index 626b758..4a0aeba 100644
--- a/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h
@@ -62,20 +62,22 @@
              object = fdp->ConsumeIntegral<uint32_t>();
              cleanup_cookie = fdp->ConsumeIntegral<uint32_t>();
              IBinder::object_cleanup_func func = IBinder::object_cleanup_func();
-             ibinder->attachObject(fdp->ConsumeBool() ? reinterpret_cast<void*>(&objectID)
-                                                      : nullptr,
-                                   fdp->ConsumeBool() ? reinterpret_cast<void*>(&object) : nullptr,
-                                   fdp->ConsumeBool() ? reinterpret_cast<void*>(&cleanup_cookie)
-                                                      : nullptr,
-                                   func);
+             (void)ibinder->attachObject(fdp->ConsumeBool() ? reinterpret_cast<void*>(&objectID)
+                                                            : nullptr,
+                                         fdp->ConsumeBool() ? reinterpret_cast<void*>(&object)
+                                                            : nullptr,
+                                         fdp->ConsumeBool()
+                                                 ? reinterpret_cast<void*>(&cleanup_cookie)
+                                                 : nullptr,
+                                         func);
          },
          [](FuzzedDataProvider* fdp, IBinder* ibinder) -> void {
              uint32_t id = fdp->ConsumeIntegral<uint32_t>();
-             ibinder->findObject(reinterpret_cast<void*>(&id));
+             (void)ibinder->findObject(reinterpret_cast<void*>(&id));
          },
          [](FuzzedDataProvider* fdp, IBinder* ibinder) -> void {
              uint32_t id = fdp->ConsumeIntegral<uint32_t>();
-             ibinder->detachObject(reinterpret_cast<void*>(&id));
+             (void)ibinder->detachObject(reinterpret_cast<void*>(&id));
          },
          [](FuzzedDataProvider* fdp, IBinder* ibinder) -> void {
              uint32_t code = fdp->ConsumeIntegral<uint32_t>();
diff --git a/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp b/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp
index f9dda8c..f5e3af5 100644
--- a/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp
+++ b/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp
@@ -46,15 +46,6 @@
                 [&]() -> void { dealer->getAllocationAlignment(); },
                 [&]() -> void { dealer->getMemoryHeap(); },
                 [&]() -> void {
-                    size_t offset = fdp.ConsumeIntegral<size_t>();
-
-                    // Offset has already been freed, so return instead.
-                    if (free_list.find(offset) != free_list.end()) return;
-
-                    dealer->deallocate(offset);
-                    free_list.insert(offset);
-                },
-                [&]() -> void {
                     std::string randString = fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
                     dealer->dump(randString.c_str());
                 },
diff --git a/libs/binder/tests/unit_fuzzers/StabilityFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/StabilityFuzzFunctions.h
index 8b4ed70..371dcbd 100644
--- a/libs/binder/tests/unit_fuzzers/StabilityFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/StabilityFuzzFunctions.h
@@ -31,37 +31,27 @@
 static const std::vector<
         std::function<void(FuzzedDataProvider*, android::sp<android::IBinder> const&)>>
         gStabilityOperations = {
-                // markCompilationUnit(IBinder* binder)
                 [](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void {
                     if (!marked) {
                         android::internal::Stability::markCompilationUnit(bbinder.get());
                         marked = true;
                     }
                 },
-
-                // markVintf(IBinder* binder)
                 [](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void {
                     if (!marked) {
                         android::internal::Stability::markVintf(bbinder.get());
                         marked = true;
                     }
                 },
-
-                // debugLogStability(const std::string& tag, const sp<IBinder>& binder)
-                [](FuzzedDataProvider* fdp, android::sp<android::IBinder> const& bbinder) -> void {
-                    std::string tag = fdp->ConsumeRandomLengthString(STABILITY_MAX_TAG_LENGTH);
-                    android::internal::Stability::debugLogStability(tag, bbinder);
+                [](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void {
+                    (void)android::internal::Stability::debugToString(bbinder);
                 },
-
-                // markVndk(IBinder* binder)
                 [](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void {
                     if (!marked) {
                         android::internal::Stability::markVndk(bbinder.get());
                         marked = true;
                     }
                 },
-
-                // requiresVintfDeclaration(const sp<IBinder>& binder)
                 [](FuzzedDataProvider*, android::sp<android::IBinder> const& bbinder) -> void {
                     android::internal::Stability::requiresVintfDeclaration(bbinder);
                 }};
diff --git a/libs/binderdebug/BinderDebug.cpp b/libs/binderdebug/BinderDebug.cpp
index b435dba..d086b49 100644
--- a/libs/binderdebug/BinderDebug.cpp
+++ b/libs/binderdebug/BinderDebug.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <android-base/logging.h>
 #include <android-base/parseint.h>
 #include <android-base/strings.h>
 #include <binder/Binder.h>
@@ -116,4 +117,60 @@
     return ret;
 }
 
+status_t getBinderClientPids(BinderDebugContext context, pid_t pid, pid_t servicePid,
+                             int32_t handle, std::vector<pid_t>* pids) {
+    std::smatch match;
+    static const std::regex kNodeNumber("^\\s+ref \\d+:\\s+desc\\s+(\\d+)\\s+node\\s+(\\d+).*");
+    std::string contextStr = contextToString(context);
+    int32_t node;
+    status_t ret = scanBinderContext(pid, contextStr, [&](const std::string& line) {
+        if (std::regex_search(line, match, kNodeNumber)) {
+            const std::string& descString = match.str(1);
+            int32_t desc;
+            if (!::android::base::ParseInt(descString.c_str(), &desc)) {
+                LOG(ERROR) << "Failed to parse desc int: " << descString;
+                return;
+            }
+            if (handle != desc) {
+                return;
+            }
+            const std::string& nodeString = match.str(2);
+            if (!::android::base::ParseInt(nodeString.c_str(), &node)) {
+                LOG(ERROR) << "Failed to parse node int: " << nodeString;
+                return;
+            }
+            return;
+        }
+        return;
+    });
+    if (ret != OK) {
+        return ret;
+    }
+    static const std::regex kClients("^\\s+node\\s+(\\d+).*proc\\s+([\\d+\\s*]*)");
+    ret = scanBinderContext(servicePid, contextStr, [&](const std::string& line) {
+        if (std::regex_search(line, match, kClients)) {
+            const std::string nodeString = match.str(1);
+            int32_t matchedNode;
+            if (!::android::base::ParseInt(nodeString.c_str(), &matchedNode)) {
+                LOG(ERROR) << "Failed to parse node int: " << nodeString;
+                return;
+            }
+            if (node != matchedNode) {
+                return;
+            }
+            const std::string clients = match.str(2);
+            for (const std::string& pidStr : base::Split(clients, " ")) {
+                int32_t pid;
+                if (!::android::base::ParseInt(pidStr, &pid)) {
+                    return;
+                }
+                pids->push_back(pid);
+            }
+            return;
+        }
+        return;
+    });
+    return ret;
+}
+
 } // namespace  android
diff --git a/libs/binderdebug/include/binderdebug/BinderDebug.h b/libs/binderdebug/include/binderdebug/BinderDebug.h
index 14a0ef3..dfd5a7c 100644
--- a/libs/binderdebug/include/binderdebug/BinderDebug.h
+++ b/libs/binderdebug/include/binderdebug/BinderDebug.h
@@ -32,6 +32,14 @@
     VNDBINDER,
 };
 
+/**
+ * pid is the pid of the service
+ */
 status_t getBinderPidInfo(BinderDebugContext context, pid_t pid, BinderPidInfo* pidInfo);
+/**
+ * pid is typically the pid of this process that is making the query
+ */
+status_t getBinderClientPids(BinderDebugContext context, pid_t pid, pid_t servicePid,
+                             int32_t handle, std::vector<pid_t>* pids);
 
 } // namespace  android
diff --git a/libs/fakeservicemanager/ServiceManager.cpp b/libs/fakeservicemanager/ServiceManager.cpp
index 761e45c..9f0754b 100644
--- a/libs/fakeservicemanager/ServiceManager.cpp
+++ b/libs/fakeservicemanager/ServiceManager.cpp
@@ -78,4 +78,10 @@
     return std::nullopt;
 }
 
+std::optional<IServiceManager::ConnectionInfo> ServiceManager::getConnectionInfo(
+        const String16& name) {
+    (void)name;
+    return std::nullopt;
+}
+
 }  // namespace android
diff --git a/libs/fakeservicemanager/ServiceManager.h b/libs/fakeservicemanager/ServiceManager.h
index e26c21b..b1496ba 100644
--- a/libs/fakeservicemanager/ServiceManager.h
+++ b/libs/fakeservicemanager/ServiceManager.h
@@ -51,6 +51,8 @@
 
     std::optional<String16> updatableViaApex(const String16& name) override;
 
+    std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override;
+
 private:
     std::map<String16, sp<IBinder>> mNameToService;
 };
diff --git a/libs/gralloc/types/Android.bp b/libs/gralloc/types/Android.bp
index a0032ae..cda9e19 100644
--- a/libs/gralloc/types/Android.bp
+++ b/libs/gralloc/types/Android.bp
@@ -52,14 +52,14 @@
     ],
 
     shared_libs: [
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "android.hardware.graphics.mapper@4.0",
         "libhidlbase",
         "liblog",
     ],
 
     export_shared_lib_headers: [
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "android.hardware.graphics.mapper@4.0",
         "libhidlbase",
     ],
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 8c250a4..514988b 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -206,7 +206,6 @@
     ],
 
     shared_libs: [
-        "android.frameworks.bufferhub@1.0",
         "libbinder",
         "libbufferhub",
         "libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui.
@@ -232,7 +231,6 @@
                 "BufferHubProducer.cpp",
             ],
             exclude_shared_libs: [
-                "android.frameworks.bufferhub@1.0",
                 "libbufferhub",
                 "libbufferhubqueue",
                 "libpdx_default_transport",
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index df308d8..5fe5e71 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -645,7 +645,10 @@
                     slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
             return BAD_VALUE;
         } else if (!mSlots[slot].mBufferState.isDequeued()) {
-            BQ_LOGE("detachBuffer: slot %d is not owned by the producer "
+            // TODO(http://b/140581935): This message is BQ_LOGW because it
+            // often logs when no actionable errors are present. Return to
+            // using BQ_LOGE after ensuring this only logs during errors.
+            BQ_LOGW("detachBuffer: slot %d is not owned by the producer "
                     "(state = %s)", slot, mSlots[slot].mBufferState.string());
             return BAD_VALUE;
         } else if (!mSlots[slot].mRequestBufferCalled) {
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index 8edf604..a626970 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -71,6 +71,7 @@
         case HAL_PIXEL_FORMAT_Y8:
         case HAL_PIXEL_FORMAT_Y16:
         case HAL_PIXEL_FORMAT_RAW16:
+        case HAL_PIXEL_FORMAT_RAW12:
         case HAL_PIXEL_FORMAT_RAW10:
         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
         case HAL_PIXEL_FORMAT_BLOB:
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index e1b1efc..46800f2 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -33,10 +33,13 @@
 // using just a few large reads.
 static const size_t EVENT_BUFFER_SIZE = 100;
 
+static constexpr nsecs_t WAITING_FOR_VSYNC_TIMEOUT = ms2ns(300);
+
 DisplayEventDispatcher::DisplayEventDispatcher(
         const sp<Looper>& looper, ISurfaceComposer::VsyncSource vsyncSource,
         ISurfaceComposer::EventRegistrationFlags eventRegistration)
-      : mLooper(looper), mReceiver(vsyncSource, eventRegistration), mWaitingForVsync(false) {
+      : mLooper(looper), mReceiver(vsyncSource, eventRegistration), mWaitingForVsync(false),
+        mLastVsyncCount(0), mLastScheduleVsyncTime(0) {
     ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this);
 }
 
@@ -86,6 +89,7 @@
         }
 
         mWaitingForVsync = true;
+        mLastScheduleVsyncTime = systemTime(SYSTEM_TIME_MONOTONIC);
     }
     return OK;
 }
@@ -124,9 +128,21 @@
               this, ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount,
               vsyncEventData.id);
         mWaitingForVsync = false;
+        mLastVsyncCount = vsyncCount;
         dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount, vsyncEventData);
     }
 
+    if (mWaitingForVsync) {
+        const nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
+        const nsecs_t vsyncScheduleDelay = currentTime - mLastScheduleVsyncTime;
+        if (vsyncScheduleDelay > WAITING_FOR_VSYNC_TIMEOUT) {
+            ALOGW("Vsync time out! vsyncScheduleDelay=%" PRId64 "ms", ns2ms(vsyncScheduleDelay));
+            mWaitingForVsync = false;
+            dispatchVsync(currentTime, vsyncDisplayId /* displayId is not used */,
+                          ++mLastVsyncCount, vsyncEventData /* empty data */);
+        }
+    }
+
     return 1; // keep the callback
 }
 
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 30d19e3..b3647d6 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -301,7 +301,7 @@
         // continues to use it.
         sp<GraphicBuffer> buffer = new GraphicBuffer(
                 kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888,
-                GraphicBuffer::USAGE_SW_WRITE_RARELY,
+                DEFAULT_USAGE_FLAGS | GraphicBuffer::USAGE_SW_WRITE_RARELY,
                 "[GLConsumer debug texture]");
         uint32_t* bits;
         buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits));
diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h
index 4ade240..08f3597 100644
--- a/libs/gui/include/gui/DisplayEventDispatcher.h
+++ b/libs/gui/include/gui/DisplayEventDispatcher.h
@@ -56,6 +56,8 @@
     sp<Looper> mLooper;
     DisplayEventReceiver mReceiver;
     bool mWaitingForVsync;
+    uint32_t mLastVsyncCount;
+    nsecs_t mLastScheduleVsyncTime;
 
     std::vector<FrameRateOverride> mFrameRateOverrides;
 
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index 220c8e1..1aec477 100644
--- a/libs/input/InputDevice.cpp
+++ b/libs/input/InputDevice.cpp
@@ -89,8 +89,15 @@
 
     // Treblized input device config files will be located /product/usr, /system_ext/usr,
     // /odm/usr or /vendor/usr.
-    const char* rootsForPartition[]{"/product", "/system_ext", "/odm", "/vendor",
-                                    getenv("ANDROID_ROOT")};
+    // These files may also be in the com.android.input.config APEX.
+    const char* rootsForPartition[]{
+            "/product",
+            "/system_ext",
+            "/odm",
+            "/vendor",
+            "/apex/com.android.input.config/etc",
+            getenv("ANDROID_ROOT"),
+    };
     for (size_t i = 0; i < size(rootsForPartition); i++) {
         if (rootsForPartition[i] == nullptr) {
             continue;
diff --git a/libs/input/VelocityControl.cpp b/libs/input/VelocityControl.cpp
index 2c04d42..6e991e9 100644
--- a/libs/input/VelocityControl.cpp
+++ b/libs/input/VelocityControl.cpp
@@ -18,7 +18,7 @@
 //#define LOG_NDEBUG 0
 
 // Log debug messages about acceleration.
-#define DEBUG_ACCELERATION 0
+static constexpr bool DEBUG_ACCELERATION = false;
 
 #include <math.h>
 #include <limits.h>
@@ -52,10 +52,10 @@
 void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) {
     if ((deltaX && *deltaX) || (deltaY && *deltaY)) {
         if (eventTime >= mLastMovementTime + STOP_TIME) {
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl: stopped, last movement was %0.3fms ago",
-                    (eventTime - mLastMovementTime) * 0.000001f);
-#endif
+            if (DEBUG_ACCELERATION && mLastMovementTime != LLONG_MIN) {
+                ALOGD("VelocityControl: stopped, last movement was %0.3fms ago",
+                           (eventTime - mLastMovementTime) * 0.000001f);
+            }
             reset();
         }
 
@@ -83,19 +83,20 @@
                         * (mParameters.acceleration - 1);
             }
 
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): "
-                    "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f",
-                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
-                    mParameters.acceleration,
-                    vx, vy, speed, scale / mParameters.scale);
-#endif
+            if (DEBUG_ACCELERATION) {
+                ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): "
+                        "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f",
+                        mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
+                        mParameters.acceleration,
+                        vx, vy, speed, scale / mParameters.scale);
+            }
+
         } else {
-#if DEBUG_ACCELERATION
-            ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity",
-                    mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
-                    mParameters.acceleration);
-#endif
+            if (DEBUG_ACCELERATION) {
+                ALOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity",
+                        mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold,
+                        mParameters.acceleration);
+            }
         }
 
         if (deltaX) {
diff --git a/libs/nativedisplay/surfacetexture/EGLConsumer.cpp b/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
index 2f31888..6882ea3 100644
--- a/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
+++ b/libs/nativedisplay/surfacetexture/EGLConsumer.cpp
@@ -191,7 +191,7 @@
         // continues to use it.
         sp<GraphicBuffer> buffer =
                 new GraphicBuffer(kDebugData.width, kDebugData.height, PIXEL_FORMAT_RGBA_8888,
-                                  GraphicBuffer::USAGE_SW_WRITE_RARELY,
+                                  DEFAULT_USAGE_FLAGS | GraphicBuffer::USAGE_SW_WRITE_RARELY,
                                   "[EGLConsumer debug texture]");
         uint32_t* bits;
         buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits));
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 79b47a1..e2f32e3 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -653,6 +653,8 @@
       case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
       case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
           return 4;
+      case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
+          return 8;
       default:
           return 0;
   }
@@ -696,6 +698,10 @@
             "gralloc and AHardwareBuffer flags don't match");
     static_assert(AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE == (uint64_t)BufferUsage::GPU_MIPMAP_COMPLETE,
             "gralloc and AHardwareBuffer flags don't match");
+    static_assert(AHARDWAREBUFFER_USAGE_CAMERA_WRITE == (uint64_t)BufferUsage::CAMERA_OUTPUT,
+            "gralloc and AHardwareBuffer flags don't match");
+    static_assert(AHARDWAREBUFFER_USAGE_CAMERA_READ == (uint64_t)BufferUsage::CAMERA_INPUT,
+            "gralloc and AHardwareBuffer flags don't match");
     return usage;
 }
 
diff --git a/libs/nativewindow/include/vndk/hardware_buffer.h b/libs/nativewindow/include/vndk/hardware_buffer.h
index 50fe0b7..21931bb 100644
--- a/libs/nativewindow/include/vndk/hardware_buffer.h
+++ b/libs/nativewindow/include/vndk/hardware_buffer.h
@@ -91,6 +91,20 @@
     AHARDWAREBUFFER_FORMAT_YCbCr_422_I              = 0x14,
 };
 
+/**
+ * Buffer usage flags.
+ */
+enum {
+    /* for future proofing, keep these in sync with hardware/gralloc.h */
+
+    /* The buffer will be written by the HW camera pipeline. */
+    AHARDWAREBUFFER_USAGE_CAMERA_WRITE              = 2UL << 16,
+    /* The buffer will be read by the HW camera pipeline. */
+    AHARDWAREBUFFER_USAGE_CAMERA_READ               = 4UL << 16,
+    /* Mask for the camera access values. */
+    AHARDWAREBUFFER_USAGE_CAMERA_MASK               = 6UL << 16,
+};
+
 __END_DECLS
 
 #endif /* ANDROID_VNDK_NATIVEWINDOW_AHARDWAREBUFFER_H */
diff --git a/libs/permission/include/binder/AppOpsManager.h b/libs/permission/include/binder/AppOpsManager.h
index e3d705f..abcd527 100644
--- a/libs/permission/include/binder/AppOpsManager.h
+++ b/libs/permission/include/binder/AppOpsManager.h
@@ -147,7 +147,8 @@
         OP_ACTIVITY_RECOGNITION_SOURCE = 113,
         OP_BLUETOOTH_ADVERTISE = 114,
         OP_RECORD_INCOMING_PHONE_AUDIO = 115,
-        _NUM_OP = 116
+        OP_NEARBY_WIFI_DEVICES = 116,
+        _NUM_OP = 117
     };
 
     AppOpsManager();
diff --git a/libs/renderengine/OWNERS b/libs/renderengine/OWNERS
index c478506..5d23a5e 100644
--- a/libs/renderengine/OWNERS
+++ b/libs/renderengine/OWNERS
@@ -1,3 +1,4 @@
+adyabr@google.com
 alecmouri@google.com
 djsollen@google.com
 jreck@google.com
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index ae8f238..cc627b8 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -388,7 +388,10 @@
             drawBlurLayers(renderengine, display, dstTexture);
         }
 
-        // should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+        // The majority of skia shaders needed by RenderEngine are related to sampling images.
+        // These need to be generated with various source textures.
+        // Make a list of applicable sources.
+        // GRALLOC_USAGE_HW_TEXTURE should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE.
         const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE;
         sp<GraphicBuffer> externalBuffer =
                 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888,
@@ -396,24 +399,24 @@
         const auto externalTexture =
                 std::make_shared<ExternalTexture>(externalBuffer, *renderengine,
                                                   ExternalTexture::Usage::READABLE);
+        std::vector<const std::shared_ptr<ExternalTexture>> textures =
+            {srcTexture, externalTexture};
 
-        // Another external texture with a different pixel format triggers useIsOpaqueWorkaround
+        // Another external texture with a different pixel format triggers useIsOpaqueWorkaround.
+        // It doesn't have to be f16, but it can't be the usual 8888.
         sp<GraphicBuffer> f16ExternalBuffer =
                 new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_FP16,
                                   1, usageExternal, "primeShaderCache_external_f16");
-        const auto f16ExternalTexture =
+        // The F16 texture may not be usable on all devices, so check first that it was created.
+        status_t error = f16ExternalBuffer->initCheck();
+        if (!error) {
+            const auto f16ExternalTexture =
                 std::make_shared<ExternalTexture>(f16ExternalBuffer, *renderengine,
                                                   ExternalTexture::Usage::READABLE);
+            textures.push_back(f16ExternalTexture);
+        }
 
-        // The majority of shaders are related to sampling images.
-        // These need to be generated with various source textures
-        // The F16 texture may not be usable on all devices, so check first that it was created with
-        // the requested usage bit.
-        auto textures = {srcTexture, externalTexture};
-        auto texturesWithF16 = {srcTexture, externalTexture, f16ExternalTexture};
-        bool canUsef16 = f16ExternalBuffer->getUsage() & GRALLOC_USAGE_HW_TEXTURE;
-
-        for (auto texture : canUsef16 ? texturesWithF16 : textures) {
+        for (auto texture : textures) {
             drawImageLayers(renderengine, display, dstTexture, texture);
             // Draw layers for b/185569240.
             drawClippedLayers(renderengine, display, dstTexture, texture);
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 74d17ce..eed58c5 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -159,7 +159,7 @@
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.allocator@3.0",
         "android.hardware.graphics.allocator@4.0",
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "android.hardware.graphics.common@1.2",
         "android.hardware.graphics.mapper@2.0",
         "android.hardware.graphics.mapper@2.1",
@@ -176,7 +176,7 @@
 
     export_shared_lib_headers: [
         "android.hardware.graphics.common@1.2",
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "android.hardware.graphics.mapper@4.0",
         "libgralloctypes",
     ],
diff --git a/libs/vibrator/OWNERS b/libs/vibrator/OWNERS
index 0997e9f..d073e2b 100644
--- a/libs/vibrator/OWNERS
+++ b/libs/vibrator/OWNERS
@@ -1,2 +1 @@
-lsandrade@google.com
-michaelwr@google.com
+include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 5505726..ca29dd1 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1268,6 +1268,11 @@
           entry.deviceId);
 #endif
 
+    // Reset key repeating in case a keyboard device was disabled or enabled.
+    if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
+        resetKeyRepeatLocked();
+    }
+
     CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, "device was reset");
     options.deviceId = entry.deviceId;
     synthesizeCancelationEventsForAllConnectionsLocked(options);
@@ -3937,6 +3942,13 @@
                                               args->downTime, args->pointerCount,
                                               args->pointerProperties, args->pointerCoords, 0, 0);
 
+        if (args->id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
+            IdGenerator::getSource(args->id) == IdGenerator::Source::INPUT_READER &&
+            !mInputFilterEnabled) {
+            const bool isDown = args->action == AMOTION_EVENT_ACTION_DOWN;
+            mLatencyTracker.trackListener(args->id, isDown, args->eventTime, args->readTime);
+        }
+
         needWake = enqueueInboundEventLocked(std::move(newEntry));
         mLock.unlock();
     } // release lock
diff --git a/services/inputflinger/dispatcher/LatencyTracker.cpp b/services/inputflinger/dispatcher/LatencyTracker.cpp
index d634dcd..52f189c 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.cpp
+++ b/services/inputflinger/dispatcher/LatencyTracker.cpp
@@ -50,13 +50,12 @@
  * key-value pair. Equivalent to the imaginary std api std::multimap::erase(key, value).
  */
 template <typename K, typename V>
-static void eraseByKeyAndValue(std::multimap<K, V>& map, K key, V value) {
-    auto iterpair = map.equal_range(key);
-
-    for (auto it = iterpair.first; it != iterpair.second; ++it) {
+static void eraseByValue(std::multimap<K, V>& map, const V& value) {
+    for (auto it = map.begin(); it != map.end();) {
         if (it->second == value) {
-            map.erase(it);
-            break;
+            it = map.erase(it);
+        } else {
+            it++;
         }
     }
 }
@@ -76,9 +75,7 @@
         // confuse us by reporting the rest of the timeline for one of them. This should happen
         // rarely, so we won't lose much data
         mTimelines.erase(it);
-        // In case we have another input event with a different id and at the same eventTime,
-        // only erase this specific inputEventId.
-        eraseByKeyAndValue(mEventTimes, eventTime, inputEventId);
+        eraseByValue(mEventTimes, inputEventId);
         return;
     }
     mTimelines.emplace(inputEventId, InputEventTimeline(isDown, eventTime, readTime));
@@ -90,7 +87,8 @@
                                         nsecs_t finishTime) {
     const auto it = mTimelines.find(inputEventId);
     if (it == mTimelines.end()) {
-        // It's possible that an app sends a bad (or late)'Finish' signal, since it's free to do
+        // This could happen if we erased this event when duplicate events were detected. It's
+        // also possible that an app sent a bad (or late) 'Finish' signal, since it's free to do
         // anything in its process. Just drop the report and move on.
         return;
     }
@@ -120,7 +118,8 @@
         std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline) {
     const auto it = mTimelines.find(inputEventId);
     if (it == mTimelines.end()) {
-        // It's possible that an app sends a bad (or late) 'Timeline' signal, since it's free to do
+        // This could happen if we erased this event when duplicate events were detected. It's
+        // also possible that an app sent a bad (or late) 'Timeline' signal, since it's free to do
         // anything in its process. Just drop the report and move on.
         return;
     }
@@ -166,14 +165,6 @@
     }
 }
 
-void LatencyTracker::reportNow() {
-    for (const auto& [inputEventId, timeline] : mTimelines) {
-        mTimelineProcessor->processTimeline(timeline);
-    }
-    mTimelines.clear();
-    mEventTimes.clear();
-}
-
 std::string LatencyTracker::dump(const char* prefix) {
     return StringPrintf("%sLatencyTracker:\n", prefix) +
             StringPrintf("%s  mTimelines.size() = %zu\n", prefix, mTimelines.size()) +
diff --git a/services/inputflinger/dispatcher/LatencyTracker.h b/services/inputflinger/dispatcher/LatencyTracker.h
index 289b8ed..4b0c618 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.h
+++ b/services/inputflinger/dispatcher/LatencyTracker.h
@@ -43,6 +43,12 @@
     LatencyTracker(InputEventTimelineProcessor* processor);
     /**
      * Start keeping track of an event identified by inputEventId. This must be called first.
+     * If duplicate events are encountered (events that have the same eventId), none of them will be
+     * tracked. This is because there is not enough information to correctly track them. The api's
+     * 'trackFinishedEvent' and 'trackGraphicsLatency' only contain the inputEventId, and not the
+     * eventTime. Even if eventTime was provided, there would still be a possibility of having
+     * duplicate events that happen to have the same eventTime and inputEventId. Therefore, we
+     * must drop all duplicate data.
      */
     void trackListener(int32_t inputEventId, bool isDown, nsecs_t eventTime, nsecs_t readTime);
     void trackFinishedEvent(int32_t inputEventId, const sp<IBinder>& connectionToken,
@@ -50,14 +56,6 @@
     void trackGraphicsLatency(int32_t inputEventId, const sp<IBinder>& connectionToken,
                               std::array<nsecs_t, GraphicsTimeline::SIZE> timeline);
 
-    /**
-     * Report all collected events immediately, even if some of them are currently incomplete
-     * and may receive 'trackFinishedEvent' or 'trackGraphicsLatency' calls in the future.
-     * This is useful for tests. Otherwise, tests would have to inject additional "future" events,
-     * which is not convenient.
-     */
-    void reportNow();
-
     std::string dump(const char* prefix);
 
 private:
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index b19b419..68d5e7c 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -63,9 +63,9 @@
 
 namespace android {
 
-static const char* DEVICE_PATH = "/dev/input";
+static const char* DEVICE_INPUT_PATH = "/dev/input";
 // v4l2 devices go directly into /dev
-static const char* VIDEO_DEVICE_PATH = "/dev";
+static const char* DEVICE_PATH = "/dev";
 
 static constexpr size_t OBFUSCATED_LENGTH = 8;
 
@@ -685,15 +685,23 @@
     LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));
 
     mINotifyFd = inotify_init();
-    mInputWd = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
-    LOG_ALWAYS_FATAL_IF(mInputWd < 0, "Could not register INotify for %s: %s", DEVICE_PATH,
-                        strerror(errno));
-    if (isV4lScanningEnabled()) {
-        mVideoWd = inotify_add_watch(mINotifyFd, VIDEO_DEVICE_PATH, IN_DELETE | IN_CREATE);
-        LOG_ALWAYS_FATAL_IF(mVideoWd < 0, "Could not register INotify for %s: %s",
-                            VIDEO_DEVICE_PATH, strerror(errno));
+
+    std::error_code errorCode;
+    bool isDeviceInotifyAdded = false;
+    if (std::filesystem::exists(DEVICE_INPUT_PATH, errorCode)) {
+        addDeviceInputInotify();
     } else {
-        mVideoWd = -1;
+        addDeviceInotify();
+        isDeviceInotifyAdded = true;
+        if (errorCode) {
+            ALOGW("Could not run filesystem::exists() due to error %d : %s.", errorCode.value(),
+                  errorCode.message().c_str());
+        }
+    }
+
+    if (isV4lScanningEnabled() && !isDeviceInotifyAdded) {
+        addDeviceInotify();
+    } else {
         ALOGI("Video device scanning disabled");
     }
 
@@ -733,6 +741,23 @@
     ::close(mWakeWritePipeFd);
 }
 
+/**
+ * On devices that don't have any input devices (like some development boards), the /dev/input
+ * directory will be absent. However, the user may still plug in an input device at a later time.
+ * Add watch for contents of /dev/input only when /dev/input appears.
+ */
+void EventHub::addDeviceInputInotify() {
+    mDeviceInputWd = inotify_add_watch(mINotifyFd, DEVICE_INPUT_PATH, IN_DELETE | IN_CREATE);
+    LOG_ALWAYS_FATAL_IF(mDeviceInputWd < 0, "Could not register INotify for %s: %s",
+                        DEVICE_INPUT_PATH, strerror(errno));
+}
+
+void EventHub::addDeviceInotify() {
+    mDeviceWd = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
+    LOG_ALWAYS_FATAL_IF(mDeviceWd < 0, "Could not register INotify for %s: %s", DEVICE_PATH,
+                        strerror(errno));
+}
+
 InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const {
     std::scoped_lock _l(mLock);
     Device* device = getDeviceLocked(deviceId);
@@ -1739,14 +1764,24 @@
 }
 
 void EventHub::scanDevicesLocked() {
-    status_t result = scanDirLocked(DEVICE_PATH);
-    if (result < 0) {
-        ALOGE("scan dir failed for %s", DEVICE_PATH);
+    status_t result;
+    std::error_code errorCode;
+
+    if (std::filesystem::exists(DEVICE_INPUT_PATH, errorCode)) {
+        result = scanDirLocked(DEVICE_INPUT_PATH);
+        if (result < 0) {
+            ALOGE("scan dir failed for %s", DEVICE_INPUT_PATH);
+        }
+    } else {
+        if (errorCode) {
+            ALOGW("Could not run filesystem::exists() due to error %d : %s.", errorCode.value(),
+                  errorCode.message().c_str());
+        }
     }
     if (isV4lScanningEnabled()) {
-        result = scanVideoDirLocked(VIDEO_DEVICE_PATH);
+        result = scanVideoDirLocked(DEVICE_PATH);
         if (result != OK) {
-            ALOGE("scan video dir failed for %s", VIDEO_DEVICE_PATH);
+            ALOGE("scan video dir failed for %s", DEVICE_PATH);
         }
     }
     if (mDevices.find(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID) == mDevices.end()) {
@@ -2357,23 +2392,25 @@
     while (res >= (int)sizeof(*event)) {
         event = (struct inotify_event*)(event_buf + event_pos);
         if (event->len) {
-            if (event->wd == mInputWd) {
-                std::string filename = std::string(DEVICE_PATH) + "/" + event->name;
+            if (event->wd == mDeviceInputWd) {
+                std::string filename = std::string(DEVICE_INPUT_PATH) + "/" + event->name;
                 if (event->mask & IN_CREATE) {
                     openDeviceLocked(filename);
                 } else {
                     ALOGI("Removing device '%s' due to inotify event\n", filename.c_str());
                     closeDeviceByPathLocked(filename);
                 }
-            } else if (event->wd == mVideoWd) {
+            } else if (event->wd == mDeviceWd) {
                 if (isV4lTouchNode(event->name)) {
-                    std::string filename = std::string(VIDEO_DEVICE_PATH) + "/" + event->name;
+                    std::string filename = std::string(DEVICE_PATH) + "/" + event->name;
                     if (event->mask & IN_CREATE) {
                         openVideoDeviceLocked(filename);
                     } else {
                         ALOGI("Removing video device '%s' due to inotify event", filename.c_str());
                         closeVideoDeviceByPathLocked(filename);
                     }
+                } else if (strcmp(event->name, "input") == 0 && event->mask & IN_CREATE) {
+                    addDeviceInputInotify();
                 }
             } else {
                 LOG_ALWAYS_FATAL("Unexpected inotify event, wd = %i", event->wd);
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 1016a2c..3c3f88e 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -663,6 +663,9 @@
     const std::unordered_map<int32_t, RawLightInfo>& getLightInfoLocked(int32_t deviceId) const
             REQUIRES(mLock);
 
+    void addDeviceInputInotify();
+    void addDeviceInotify();
+
     // Protect all internal state.
     mutable std::mutex mLock;
 
@@ -702,8 +705,8 @@
     int mWakeReadPipeFd;
     int mWakeWritePipeFd;
 
-    int mInputWd;
-    int mVideoWd;
+    int mDeviceInputWd;
+    int mDeviceWd = -1;
 
     // Maximum number of signalled FDs to handle at a time.
     static const int EPOLL_MAX_EVENTS = 16;
diff --git a/services/inputflinger/reader/mapper/SensorInputMapper.cpp b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
index 7ac2dec..a507632 100644
--- a/services/inputflinger/reader/mapper/SensorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SensorInputMapper.cpp
@@ -303,7 +303,7 @@
      * the device
      */
     mDeviceEnabled = false;
-    for (const auto& [sensorType, sensor] : mSensors) {
+    for (const auto& [_, sensor] : mSensors) {
         // If any sensor is on we will turn on the device.
         if (sensor.enabled) {
             mDeviceEnabled = true;
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 29a0fc7..ac5f6b6 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -925,6 +925,13 @@
             mTiltXScale = M_PI / 180;
             mTiltYScale = M_PI / 180;
 
+            if (mRawPointerAxes.tiltX.resolution) {
+                mTiltXScale = 1.0 / mRawPointerAxes.tiltX.resolution;
+            }
+            if (mRawPointerAxes.tiltY.resolution) {
+                mTiltYScale = 1.0 / mRawPointerAxes.tiltY.resolution;
+            }
+
             mOrientedRanges.haveTilt = true;
 
             mOrientedRanges.tilt.axis = AMOTION_EVENT_AXIS_TILT;
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 83e74ba..471c5f9 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -3023,6 +3023,16 @@
     mWindow->assertNoEvents();
 }
 
+TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_StopsKeyRepeatAfterDisableInputDevice) {
+    sendAndConsumeKeyDown(DEVICE_ID);
+    expectKeyRepeatOnce(1 /*repeatCount*/);
+    NotifyDeviceResetArgs args(10 /*id*/, 20 /*eventTime*/, DEVICE_ID);
+    mDispatcher->notifyDeviceReset(&args);
+    mWindow->consumeKeyUp(ADISPLAY_ID_DEFAULT,
+                          AKEY_EVENT_FLAG_CANCELED | AKEY_EVENT_FLAG_LONG_PRESS);
+    mWindow->assertNoEvents();
+}
+
 TEST_F(InputDispatcherKeyRepeatTest, FocusedWindow_RepeatKeyEventsUseEventIdFromInputDispatcher) {
     sendAndConsumeKeyDown(1 /* deviceId */);
     for (int32_t repeatCount = 1; repeatCount <= 10; ++repeatCount) {
diff --git a/services/inputflinger/tests/LatencyTracker_test.cpp b/services/inputflinger/tests/LatencyTracker_test.cpp
index e7e1937..89c0741 100644
--- a/services/inputflinger/tests/LatencyTracker_test.cpp
+++ b/services/inputflinger/tests/LatencyTracker_test.cpp
@@ -16,6 +16,7 @@
 
 #include "../dispatcher/LatencyTracker.h"
 
+#include <android-base/properties.h>
 #include <binder/Binder.h>
 #include <gtest/gtest.h>
 #include <inttypes.h>
@@ -23,11 +24,16 @@
 
 #define TAG "LatencyTracker_test"
 
+using android::base::HwTimeoutMultiplier;
 using android::inputdispatcher::InputEventTimeline;
 using android::inputdispatcher::LatencyTracker;
 
 namespace android::inputdispatcher {
 
+const std::chrono::duration ANR_TIMEOUT = std::chrono::milliseconds(
+        android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
+        HwTimeoutMultiplier());
+
 InputEventTimeline getTestTimeline() {
     InputEventTimeline t(
             /*isDown*/ true,
@@ -57,6 +63,8 @@
     }
     void TearDown() override {}
 
+    void triggerEventReporting(nsecs_t lastEventTime);
+
     void assertReceivedTimeline(const InputEventTimeline& timeline);
     /**
      * Timelines can be received in any order (order is not guaranteed). So if we are expecting more
@@ -72,8 +80,17 @@
     std::deque<InputEventTimeline> mReceivedTimelines;
 };
 
+/**
+ * Send an event that would trigger the reporting of all of the events that are at least as old as
+ * the provided 'lastEventTime'.
+ */
+void LatencyTrackerTest::triggerEventReporting(nsecs_t lastEventTime) {
+    const nsecs_t triggerEventTime =
+            lastEventTime + std::chrono::nanoseconds(ANR_TIMEOUT).count() + 1;
+    mTracker->trackListener(1 /*inputEventId*/, true /*isDown*/, triggerEventTime, 3 /*readTime*/);
+}
+
 void LatencyTrackerTest::assertReceivedTimeline(const InputEventTimeline& timeline) {
-    mTracker->reportNow();
     ASSERT_FALSE(mReceivedTimelines.empty());
     const InputEventTimeline& t = mReceivedTimelines.front();
     ASSERT_EQ(timeline, t);
@@ -88,7 +105,6 @@
  * equal element in B, and for every element in B there is an equal element in A.
  */
 void LatencyTrackerTest::assertReceivedTimelines(const std::vector<InputEventTimeline>& timelines) {
-    mTracker->reportNow();
     ASSERT_EQ(timelines.size(), mReceivedTimelines.size());
     for (const InputEventTimeline& expectedTimeline : timelines) {
         bool found = false;
@@ -121,6 +137,7 @@
  */
 TEST_F(LatencyTrackerTest, TrackListener_DoesNotTriggerReporting) {
     mTracker->trackListener(1 /*inputEventId*/, false /*isDown*/, 2 /*eventTime*/, 3 /*readTime*/);
+    triggerEventReporting(2 /*eventTime*/);
     assertReceivedTimeline(InputEventTimeline{false, 2, 3});
 }
 
@@ -130,6 +147,7 @@
 TEST_F(LatencyTrackerTest, TrackFinishedEvent_DoesNotTriggerReporting) {
     mTracker->trackFinishedEvent(1 /*inputEventId*/, connection1, 2 /*deliveryTime*/,
                                  3 /*consumeTime*/, 4 /*finishTime*/);
+    triggerEventReporting(4 /*eventTime*/);
     assertReceivedTimelines({});
 }
 
@@ -141,6 +159,7 @@
     graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME] = 2;
     graphicsTimeline[GraphicsTimeline::PRESENT_TIME] = 3;
     mTracker->trackGraphicsLatency(1 /*inputEventId*/, connection2, graphicsTimeline);
+    triggerEventReporting(3 /*eventTime*/);
     assertReceivedTimelines({});
 }
 
@@ -155,9 +174,30 @@
                                  expectedCT.consumeTime, expectedCT.finishTime);
     mTracker->trackGraphicsLatency(inputEventId, connectionToken, expectedCT.graphicsTimeline);
 
+    triggerEventReporting(expected.eventTime);
     assertReceivedTimeline(expected);
 }
 
+/**
+ * Send 2 events with the same inputEventId, but different eventTime's. Ensure that no crash occurs,
+ * and that the tracker drops such events completely.
+ */
+TEST_F(LatencyTrackerTest, WhenDuplicateEventsAreReported_DoesNotCrash) {
+    constexpr nsecs_t inputEventId = 1;
+    constexpr nsecs_t readTime = 3; // does not matter for this test
+    constexpr bool isDown = true;   // does not matter for this test
+
+    // In the following 2 calls to trackListener, the inputEventId's are the same, but event times
+    // are different.
+    mTracker->trackListener(inputEventId, isDown, 1 /*eventTime*/, readTime);
+    mTracker->trackListener(inputEventId, isDown, 2 /*eventTime*/, readTime);
+
+    triggerEventReporting(2 /*eventTime*/);
+    // Since we sent duplicate input events, the tracker should just delete all of them, because it
+    // does not have enough information to properly track them.
+    assertReceivedTimelines({});
+}
+
 TEST_F(LatencyTrackerTest, MultipleEvents_AreReportedConsistently) {
     constexpr int32_t inputEventId1 = 1;
     InputEventTimeline timeline1(
@@ -204,6 +244,7 @@
     mTracker->trackGraphicsLatency(inputEventId2, connection2,
                                    connectionTimeline2.graphicsTimeline);
     // Now both events should be completed
+    triggerEventReporting(timeline2.eventTime);
     assertReceivedTimelines({timeline1, timeline2});
 }
 
@@ -228,6 +269,7 @@
     mTracker->trackGraphicsLatency(1 /*inputEventId*/, token, expectedCT.graphicsTimeline);
 
     expectedTimelines[0].connectionTimelines.emplace(token, std::move(expectedCT));
+    triggerEventReporting(timeline.eventTime);
     assertReceivedTimelines(expectedTimelines);
 }
 
@@ -246,6 +288,7 @@
     mTracker->trackGraphicsLatency(inputEventId, connection1, expectedCT.graphicsTimeline);
 
     mTracker->trackListener(inputEventId, expected.isDown, expected.eventTime, expected.readTime);
+    triggerEventReporting(expected.eventTime);
     assertReceivedTimeline(
             InputEventTimeline{expected.isDown, expected.eventTime, expected.readTime});
 }
diff --git a/services/inputflinger/tests/fuzzers/Android.bp b/services/inputflinger/tests/fuzzers/Android.bp
new file mode 100644
index 0000000..df4db19
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/Android.bp
@@ -0,0 +1,45 @@
+// Copyright (C) 2021 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.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_native_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
+
+cc_fuzz {
+    name: "inputflinger_latencytracker_fuzzer",
+    defaults: [
+        "inputflinger_defaults",
+    ],
+    include_dirs: [
+        "frameworks/native/services/inputflinger",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "liblog",
+        "libui",
+        "libutils",
+        "libinput",
+        "libinputflinger",
+    ],
+    srcs: [
+        "LatencyTrackerFuzzer.cpp",
+    ],
+}
diff --git a/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
new file mode 100644
index 0000000..4f066ad
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include "dispatcher/LatencyTracker.h"
+
+namespace android {
+
+namespace inputdispatcher {
+
+/**
+ * A processor of InputEventTimelines that does nothing with the provided data.
+ */
+class EmptyProcessor : public InputEventTimelineProcessor {
+public:
+    /**
+     * Just ignore the provided timeline
+     */
+    void processTimeline(const InputEventTimeline& timeline) override {
+        for (const auto& [token, connectionTimeline] : timeline.connectionTimelines) {
+            connectionTimeline.isComplete();
+        }
+    };
+};
+
+static sp<IBinder> getConnectionToken(FuzzedDataProvider& fdp,
+                                      std::array<sp<IBinder>, 10>& tokens) {
+    const bool useExistingToken = fdp.ConsumeBool();
+    if (useExistingToken) {
+        return tokens[fdp.ConsumeIntegralInRange<size_t>(0ul, tokens.size() - 1)];
+    }
+    return new BBinder();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+    FuzzedDataProvider fdp(data, size);
+
+    EmptyProcessor emptyProcessor;
+    LatencyTracker tracker(&emptyProcessor);
+
+    // Make some pre-defined tokens to ensure that some timelines are complete.
+    std::array<sp<IBinder> /*token*/, 10> predefinedTokens;
+    for (size_t i = 0; i < predefinedTokens.size(); i++) {
+        predefinedTokens[i] = new BBinder();
+    }
+
+    // Randomly invoke LatencyTracker api's until randomness is exhausted.
+    while (fdp.remaining_bytes() > 0) {
+        fdp.PickValueInArray<std::function<void()>>({
+                [&]() -> void {
+                    int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
+                    int32_t isDown = fdp.ConsumeBool();
+                    nsecs_t eventTime = fdp.ConsumeIntegral<nsecs_t>();
+                    nsecs_t readTime = fdp.ConsumeIntegral<nsecs_t>();
+                    tracker.trackListener(inputEventId, isDown, eventTime, readTime);
+                },
+                [&]() -> void {
+                    int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
+                    sp<IBinder> connectionToken = getConnectionToken(fdp, predefinedTokens);
+                    nsecs_t deliveryTime = fdp.ConsumeIntegral<nsecs_t>();
+                    nsecs_t consumeTime = fdp.ConsumeIntegral<nsecs_t>();
+                    nsecs_t finishTime = fdp.ConsumeIntegral<nsecs_t>();
+                    tracker.trackFinishedEvent(inputEventId, connectionToken, deliveryTime,
+                                               consumeTime, finishTime);
+                },
+                [&]() -> void {
+                    int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
+                    sp<IBinder> connectionToken = getConnectionToken(fdp, predefinedTokens);
+                    std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
+                    for (size_t i = 0; i < graphicsTimeline.size(); i++) {
+                        graphicsTimeline[i] = fdp.ConsumeIntegral<nsecs_t>();
+                    }
+                    tracker.trackGraphicsLatency(inputEventId, connectionToken, graphicsTimeline);
+                },
+        })();
+    }
+
+    return 0;
+}
+
+} // namespace inputdispatcher
+
+} // namespace android
\ No newline at end of file
diff --git a/services/memtrackproxy/Android.bp b/services/memtrackproxy/Android.bp
index 7d78f3b..3233cc9 100644
--- a/services/memtrackproxy/Android.bp
+++ b/services/memtrackproxy/Android.bp
@@ -32,7 +32,7 @@
         "libcutils",
         "libutils",
         "android.hardware.memtrack@1.0",
-        "android.hardware.memtrack-V1-ndk_platform",
+        "android.hardware.memtrack-V1-ndk",
     ],
     srcs: [
         "MemtrackProxy.cpp",
@@ -45,6 +45,6 @@
     ],
     export_shared_lib_headers: [
         "android.hardware.memtrack@1.0",
-        "android.hardware.memtrack-V1-ndk_platform",
+        "android.hardware.memtrack-V1-ndk",
     ],
 }
diff --git a/services/memtrackproxy/test/Android.bp b/services/memtrackproxy/test/Android.bp
index f943761..1dc21bf 100644
--- a/services/memtrackproxy/test/Android.bp
+++ b/services/memtrackproxy/test/Android.bp
@@ -29,7 +29,7 @@
     shared_libs: [
         "libbinder_ndk",
         "libmemtrackproxy",
-        "android.hardware.memtrack-V1-ndk_platform",
+        "android.hardware.memtrack-V1-ndk",
     ],
     test_suites: ["general-tests"],
     require_root: true,
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index 4151b45..1be5a96 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -36,7 +36,7 @@
         "-Wall",
         "-Werror",
         "-Wextra",
-        "-fvisibility=hidden"
+        "-fvisibility=hidden",
     ],
 
     header_libs: [
@@ -60,6 +60,7 @@
         "libbase",
         "libhidlbase",
         "libfmq",
+        "packagemanager_aidl-cpp",
         "android.hardware.sensors@1.0",
         "android.hardware.sensors@2.0",
         "android.hardware.sensors@2.1",
diff --git a/services/stats/Android.bp b/services/stats/Android.bp
index a472c5f..7fea616 100644
--- a/services/stats/Android.bp
+++ b/services/stats/Android.bp
@@ -16,7 +16,7 @@
     cflags: ["-Wall", "-Werror"],
     shared_libs: [
         "android.frameworks.stats@1.0",
-        "android.frameworks.stats-V1-ndk_platform",
+        "android.frameworks.stats-V1-ndk",
         "libbinder_ndk",
         "libhidlbase",
         "liblog",
@@ -29,7 +29,7 @@
     ],
     export_shared_lib_headers: [
         "android.frameworks.stats@1.0",
-        "android.frameworks.stats-V1-ndk_platform",
+        "android.frameworks.stats-V1-ndk",
     ],
     local_include_dirs: [
         "include/stats",
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index e26ab11..82a9ae2 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -326,7 +326,7 @@
 
 status_t VirtualDisplaySurface::dequeueBuffer(Source source,
         PixelFormat format, uint64_t usage, int* sslot, sp<Fence>* fence) {
-    LOG_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId));
+    LOG_ALWAYS_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId).has_value());
 
     status_t result =
             mSource[source]->dequeueBuffer(sslot, fence, mSinkBufferWidth, mSinkBufferHeight,
@@ -641,7 +641,7 @@
 }
 
 status_t VirtualDisplaySurface::refreshOutputBuffer() {
-    LOG_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId));
+    LOG_ALWAYS_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId).has_value());
 
     if (mOutputProducerSlot >= 0) {
         mSource[SOURCE_SINK]->cancelBuffer(
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index e2f34fa..6547bd4 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -134,6 +134,7 @@
     mDrawingState.frameTimelineInfo = {};
     mDrawingState.postTime = -1;
     mDrawingState.destinationFrame.makeInvalid();
+    mDrawingState.isTrustedOverlay = false;
     mDrawingState.dropInputMode = gui::DropInputMode::NONE;
 
     if (args.flags & ISurfaceComposerClient::eNoColorFill) {
diff --git a/services/surfaceflinger/TimeStats/OWNERS b/services/surfaceflinger/TimeStats/OWNERS
index ded3ebb..d78f5e2 100644
--- a/services/surfaceflinger/TimeStats/OWNERS
+++ b/services/surfaceflinger/TimeStats/OWNERS
@@ -1 +1,2 @@
+adyabr@google.com
 alecmouri@google.com
diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp
index 673239d..caeff4a 100644
--- a/services/surfaceflinger/main_surfaceflinger.cpp
+++ b/services/surfaceflinger/main_surfaceflinger.cpp
@@ -63,18 +63,17 @@
     return OK;
 }
 
-static status_t startDisplayService() {
+static void startDisplayService() {
     using android::frameworks::displayservice::V1_0::implementation::DisplayService;
     using android::frameworks::displayservice::V1_0::IDisplayService;
 
     sp<IDisplayService> displayservice = new DisplayService();
     status_t err = displayservice->registerAsService();
 
+    // b/141930622
     if (err != OK) {
-        ALOGE("Could not register IDisplayService service.");
+        ALOGE("Did not register (deprecated) IDisplayService service.");
     }
-
-    return err;
 }
 
 int main(int, char**) {
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 26c91fa..32ad873 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -60,7 +60,7 @@
         "android.hardware.graphics.composer@2.1",
     ],
     shared_libs: [
-        "android.hardware.graphics.common-V2-ndk_platform",
+        "android.hardware.graphics.common-V2-ndk",
         "android.hardware.graphics.common@1.2",
         "libandroid",
         "libbase",
diff --git a/services/vibratorservice/OWNERS b/services/vibratorservice/OWNERS
new file mode 100644
index 0000000..d073e2b
--- /dev/null
+++ b/services/vibratorservice/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/base:/services/core/java/com/android/server/vibrator/OWNERS
diff --git a/services/vr/virtual_touchpad/virtual_touchpad.rc b/services/vr/virtual_touchpad/virtual_touchpad.rc
index 0de0f9e..1612743 100644
--- a/services/vr/virtual_touchpad/virtual_touchpad.rc
+++ b/services/vr/virtual_touchpad/virtual_touchpad.rc
@@ -2,4 +2,4 @@
   class core
   user system
   group system input uhid
-  writepid /dev/cpuset/system/tasks
+  task_profiles VrServiceCapacityNormal
diff --git a/vulkan/README.md b/vulkan/README.md
index 185aa39..144805c 100644
--- a/vulkan/README.md
+++ b/vulkan/README.md
@@ -14,7 +14,7 @@
 
 ## Code Generation
 
-We generate several parts of the loader and tools driectly from the Vulkan Registry (external/vulkan-headers/registry/vk.xml). Code generation must be done manually because the generator is not part of the platform toolchain (yet?). Files named `foo_gen.*` are generated by the code generator.
+We generate several parts of the loader and tools directly from the Vulkan Registry (external/vulkan-headers/registry/vk.xml). Code generation must be done manually because the generator is not part of the platform toolchain (yet?). Files named `foo_gen.*` are generated by the code generator.
 
 ### Run The Code Generator