Merge "Fix DisplayState sanitization." into main
diff --git a/Android.bp b/Android.bp
index 2520a71..4befb1b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -39,6 +39,11 @@
 cc_library_headers {
     name: "native_headers",
     host_supported: true,
+    target: {
+        windows: {
+            enabled: true,
+        },
+    },
     export_include_dirs: [
         "include/",
     ],
diff --git a/cmds/atrace/Android.bp b/cmds/atrace/Android.bp
index 1c4e63e..bc69b35 100644
--- a/cmds/atrace/Android.bp
+++ b/cmds/atrace/Android.bp
@@ -33,7 +33,6 @@
         "libcutils",
         "libz",
         "libbase",
-        "libpdx_default_transport",
         "android.hardware.atrace@1.0",
     ],
 
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index cd4926a..888dc4e 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -41,7 +41,6 @@
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <hidl/ServiceManagement.h>
 
-#include <pdx/default_transport/service_utility.h>
 #include <utils/String8.h>
 #include <utils/Timers.h>
 #include <utils/Tokenizer.h>
@@ -53,7 +52,6 @@
 #include <android-base/stringprintf.h>
 
 using namespace android;
-using pdx::default_transport::ServiceUtility;
 using hardware::hidl_vec;
 using hardware::hidl_string;
 using hardware::Return;
@@ -68,10 +66,10 @@
 const char* k_traceTagsProperty = "debug.atrace.tags.enableflags";
 const char* k_userInitiatedTraceProperty = "debug.atrace.user_initiated";
 
+const char* k_tracePreferSdkProperty = "debug.atrace.prefer_sdk";
 const char* k_traceAppsNumberProperty = "debug.atrace.app_number";
 const char* k_traceAppsPropertyTemplate = "debug.atrace.app_%d";
 const char* k_coreServiceCategory = "core_services";
-const char* k_pdxServiceCategory = "pdx";
 const char* k_coreServicesProp = "ro.atrace.core.services";
 
 const char* kVendorCategoriesPath = "/vendor/etc/atrace/atrace_categories.txt";
@@ -130,7 +128,6 @@
     { "nnapi",      "NNAPI",                    ATRACE_TAG_NNAPI, { } },
     { "rro",        "Runtime Resource Overlay", ATRACE_TAG_RRO, { } },
     { k_coreServiceCategory, "Core services", 0, { } },
-    { k_pdxServiceCategory, "PDX services", 0, { } },
     { "sched",      "CPU Scheduling",   0, {
         { REQ,      "events/sched/sched_switch/enable" },
         { REQ,      "events/sched/sched_wakeup/enable" },
@@ -298,7 +295,6 @@
 static const char* g_outputFile = nullptr;
 
 /* Global state */
-static bool g_tracePdx = false;
 static bool g_traceAborted = false;
 static bool g_categoryEnables[arraysize(k_categories)] = {};
 static std::string g_traceFolder;
@@ -455,10 +451,6 @@
         return !android::base::GetProperty(k_coreServicesProp, "").empty();
     }
 
-    if (strcmp(category.name, k_pdxServiceCategory) == 0) {
-        return true;
-    }
-
     bool ok = category.tags != 0;
     for (int i = 0; i < MAX_SYS_FILES; i++) {
         const char* path = category.sysfiles[i].path;
@@ -600,6 +592,17 @@
     }
 }
 
+// Set the property that's read by userspace to prefer the perfetto SDK.
+static bool setPreferSdkProperty(uint64_t tags)
+{
+    std::string value = android::base::StringPrintf("%#" PRIx64, tags);
+    if (!android::base::SetProperty(k_tracePreferSdkProperty, value)) {
+        fprintf(stderr, "error setting prefer_sdk system property\n");
+        return false;
+    }
+    return true;
+}
+
 // Set the system property that indicates which apps should perform
 // application-level tracing.
 static bool setAppCmdlineProperty(char* cmdline)
@@ -806,11 +809,6 @@
         if (strcmp(k_categories[i].name, k_coreServiceCategory) == 0) {
             coreServicesTagEnabled = g_categoryEnables[i];
         }
-
-        // Set whether to poke PDX services in this session.
-        if (strcmp(k_categories[i].name, k_pdxServiceCategory) == 0) {
-            g_tracePdx = g_categoryEnables[i];
-        }
     }
 
     std::string packageList(g_debugAppCmdLine);
@@ -822,9 +820,6 @@
     }
     ok &= setAppCmdlineProperty(&packageList[0]);
     ok &= setTagsProperty(tags);
-    if (g_tracePdx) {
-        ok &= ServiceUtility::PokeServices();
-    }
 
     return ok;
 }
@@ -833,10 +828,6 @@
 {
     setTagsProperty(0);
     clearAppProperties();
-
-    if (g_tracePdx) {
-        ServiceUtility::PokeServices();
-    }
 }
 
 
@@ -918,6 +909,17 @@
     setTracingEnabled(false);
 }
 
+static bool preferSdkCategories() {
+    uint64_t tags = 0;
+    for (size_t i = 0; i < arraysize(k_categories); i++) {
+        if (g_categoryEnables[i]) {
+            const TracingCategory& c = k_categories[i];
+            tags |= c.tags;
+        }
+    }
+    return setPreferSdkProperty(tags);
+}
+
 // Read data from the tracing pipe and forward to stdout
 static void streamTrace()
 {
@@ -1108,6 +1110,9 @@
                     "                    CPU performance, like pagecache usage.\n"
                     "  --list_categories\n"
                     "                  list the available tracing categories\n"
+                    "  --prefer_sdk\n"
+                    "                  prefer the perfetto sdk over legacy atrace for\n"
+                    "                    categories and exits immediately\n"
                     " -o filename      write the trace to the specified file instead\n"
                     "                    of stdout.\n"
             );
@@ -1252,6 +1257,7 @@
     bool traceStop = true;
     bool traceDump = true;
     bool traceStream = false;
+    bool preferSdk = false;
     bool onlyUserspace = false;
 
     if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
@@ -1276,6 +1282,7 @@
             {"only_userspace",    no_argument, nullptr,  0 },
             {"list_categories",   no_argument, nullptr,  0 },
             {"stream",            no_argument, nullptr,  0 },
+            {"prefer_sdk",        no_argument, nullptr,  0 },
             {nullptr,                       0, nullptr,  0 }
         };
 
@@ -1348,6 +1355,8 @@
                 } else if (!strcmp(long_options[option_index].name, "stream")) {
                     traceStream = true;
                     traceDump = false;
+                } else if (!strcmp(long_options[option_index].name, "prefer_sdk")) {
+                    preferSdk = true;
                 } else if (!strcmp(long_options[option_index].name, "list_categories")) {
                     listSupportedCategories();
                     exit(0);
@@ -1362,6 +1371,11 @@
         }
     }
 
+    if (preferSdk) {
+        bool res = preferSdkCategories();
+        exit(res ? 0 : 1);
+    }
+
     if (onlyUserspace) {
         if (!async || !(traceStart || traceStop)) {
             fprintf(stderr, "--only_userspace can only be used with "
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index a1c10f5..b22cc2a 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -159,7 +159,6 @@
         "tests/dumpstate_test.cpp",
     ],
     static_libs: [
-        "libc++fs",
         "libgmock",
     ],
     test_config: "dumpstate_test.xml",
diff --git a/cmds/idlcli/Android.bp b/cmds/idlcli/Android.bp
index c18d3f5..50c2cd8 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",
+        "android.hardware.vibrator-V3-ndk",
         "android.hardware.vibrator@1.0",
         "android.hardware.vibrator@1.1",
         "android.hardware.vibrator@1.2",
diff --git a/cmds/idlcli/vibrator.h b/cmds/idlcli/vibrator.h
index e100eac..b943495 100644
--- a/cmds/idlcli/vibrator.h
+++ b/cmds/idlcli/vibrator.h
@@ -49,7 +49,7 @@
 template <typename I>
 inline auto getService(std::string name) {
     const auto instance = std::string() + I::descriptor + "/" + name;
-    auto vibBinder = ndk::SpAIBinder(AServiceManager_getService(instance.c_str()));
+    auto vibBinder = ndk::SpAIBinder(AServiceManager_checkService(instance.c_str()));
     return I::fromBinder(vibBinder);
 }
 
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index 3897197..e5d7b74 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -29,6 +29,7 @@
         "liblog",
         "libutils",
         "libselinux",
+        "libperfetto_c",
     ],
 
     target: {
@@ -48,7 +49,13 @@
             enabled: false,
         },
         vendor: {
-            exclude_shared_libs: ["libvintf"],
+            exclude_shared_libs: [
+                "libvintf",
+                "libperfetto_c",
+            ],
+        },
+        recovery: {
+            exclude_shared_libs: ["libperfetto_c"],
         },
     },
 }
diff --git a/cmds/servicemanager/NameUtil.h b/cmds/servicemanager/NameUtil.h
index b080939..4b10c2b 100644
--- a/cmds/servicemanager/NameUtil.h
+++ b/cmds/servicemanager/NameUtil.h
@@ -19,8 +19,6 @@
 #include <string>
 #include <string_view>
 
-#include <android-base/strings.h>
-
 namespace android {
 
 #ifndef VENDORSERVICEMANAGER
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 95a05cd..d85182d 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -18,6 +18,7 @@
 
 #include <android-base/logging.h>
 #include <android-base/properties.h>
+#include <android-base/scopeguard.h>
 #include <android-base/strings.h>
 #include <binder/BpBinder.h>
 #include <binder/IPCThreadState.h>
@@ -27,6 +28,11 @@
 #include <cutils/multiuser.h>
 #include <thread>
 
+#if !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
+#include "perfetto/public/te_category_macros.h"
+#include "perfetto/public/te_macros.h"
+#endif // !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
+
 #ifndef VENDORSERVICEMANAGER
 #include <vintf/VintfObject.h>
 #ifdef __ANDROID_RECOVERY__
@@ -42,6 +48,17 @@
 
 namespace android {
 
+#if defined(VENDORSERVICEMANAGER) || defined(__ANDROID_RECOVERY__)
+#define SM_PERFETTO_TRACE_FUNC(...)
+#else
+
+PERFETTO_TE_CATEGORIES_DEFINE(PERFETTO_SM_CATEGORIES);
+
+#define SM_PERFETTO_TRACE_FUNC(...) \
+    PERFETTO_TE_SCOPED(servicemanager, PERFETTO_TE_SLICE_BEGIN(__func__) __VA_OPT__(, ) __VA_ARGS__)
+
+#endif // !(defined(VENDORSERVICEMANAGER) || defined(__ANDROID_RECOVERY__))
+
 bool is_multiuser_uid_isolated(uid_t uid) {
     uid_t appid = multiuser_get_app_id(uid);
     return appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
@@ -95,13 +112,15 @@
     std::string iface;
     std::string instance;
 
-    static bool fill(const std::string& name, AidlName* aname) {
+    static bool fill(const std::string& name, AidlName* aname, bool logError) {
         size_t firstSlash = name.find('/');
         size_t lastDot = name.rfind('.', firstSlash);
         if (firstSlash == std::string::npos || lastDot == std::string::npos) {
-            ALOGE("VINTF HALs require names in the format type/instance (e.g. "
-                  "some.package.foo.IFoo/default) but got: %s",
-                  name.c_str());
+            if (logError) {
+                ALOGE("VINTF HALs require names in the format type/instance (e.g. "
+                      "some.package.foo.IFoo/default) but got: %s",
+                      name.c_str());
+            }
             return false;
         }
         aname->package = name.substr(0, lastDot);
@@ -134,7 +153,7 @@
     }
 
     AidlName aname;
-    if (!AidlName::fill(name, &aname)) return false;
+    if (!AidlName::fill(name, &aname, true)) return false;
 
     bool found = forEachManifest([&](const ManifestWithDescription& mwd) {
         if (mwd.manifest->hasAidlInstance(aname.package, aname.iface, aname.instance)) {
@@ -192,7 +211,7 @@
     }
 
     AidlName aname;
-    if (!AidlName::fill(name, &aname)) return std::nullopt;
+    if (!AidlName::fill(name, &aname, true)) return std::nullopt;
 
     std::optional<std::string> updatableViaApex;
 
@@ -232,9 +251,28 @@
     return names;
 }
 
+static std::optional<std::string> getVintfAccessorName(const std::string& name) {
+    AidlName aname;
+    if (!AidlName::fill(name, &aname, false)) return std::nullopt;
+
+    std::optional<std::string> accessor;
+    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;
+            accessor = manifestInstance.accessor();
+            return false; // break (libvintf uses opposite convention)
+        });
+        return false; // continue
+    });
+    return accessor;
+}
+
 static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) {
     AidlName aname;
-    if (!AidlName::fill(name, &aname)) return std::nullopt;
+    if (!AidlName::fill(name, &aname, true)) return std::nullopt;
 
     std::optional<std::string> ip;
     std::optional<uint64_t> port;
@@ -347,19 +385,42 @@
     }
 }
 
-Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
-    *outBinder = tryGetService(name, true);
+Status ServiceManager::getService(const std::string& name, os::Service* outService) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
+    *outService = tryGetService(name, true);
     // returns ok regardless of result for legacy reasons
     return Status::ok();
 }
 
-Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
-    *outBinder = tryGetService(name, false);
+Status ServiceManager::checkService(const std::string& name, os::Service* outService) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
+    *outService = tryGetService(name, false);
     // returns ok regardless of result for legacy reasons
     return Status::ok();
 }
 
-sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
+os::Service ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
+    std::optional<std::string> accessorName;
+#ifndef VENDORSERVICEMANAGER
+    accessorName = getVintfAccessorName(name);
+#endif
+    if (accessorName.has_value()) {
+        auto ctx = mAccess->getCallingContext();
+        if (!mAccess->canFind(ctx, name)) {
+            return os::Service::make<os::Service::Tag::accessor>(nullptr);
+        }
+        return os::Service::make<os::Service::Tag::accessor>(
+                tryGetBinder(*accessorName, startIfNotFound));
+    } else {
+        return os::Service::make<os::Service::Tag::binder>(tryGetBinder(name, startIfNotFound));
+    }
+}
+
+sp<IBinder> ServiceManager::tryGetBinder(const std::string& name, bool startIfNotFound) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
     auto ctx = mAccess->getCallingContext();
 
     sp<IBinder> out;
@@ -398,6 +459,8 @@
 }
 
 bool isValidServiceName(const std::string& name) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
     if (name.size() == 0) return false;
     if (name.size() > 127) return false;
 
@@ -413,6 +476,8 @@
 }
 
 Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
     auto ctx = mAccess->getCallingContext();
 
     if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
@@ -505,6 +570,8 @@
 }
 
 Status ServiceManager::listServices(int32_t dumpPriority, std::vector<std::string>* outList) {
+    SM_PERFETTO_TRACE_FUNC();
+
     if (!mAccess->canList(mAccess->getCallingContext())) {
         return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
     }
@@ -532,10 +599,15 @@
 
 Status ServiceManager::registerForNotifications(
         const std::string& name, const sp<IServiceCallback>& callback) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
     auto ctx = mAccess->getCallingContext();
 
-    if (!mAccess->canFind(ctx, name)) {
-        return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux");
+    // TODO(b/338541373): Implement the notification mechanism for services accessed via
+    // IAccessor.
+    std::optional<std::string> accessorName;
+    if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) {
+        return status;
     }
 
     // note - we could allow isolated apps to get notifications if we
@@ -578,10 +650,13 @@
 }
 Status ServiceManager::unregisterForNotifications(
         const std::string& name, const sp<IServiceCallback>& callback) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
     auto ctx = mAccess->getCallingContext();
 
-    if (!mAccess->canFind(ctx, name)) {
-        return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+    std::optional<std::string> accessorName;
+    if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) {
+        return status;
     }
 
     bool found = false;
@@ -601,10 +676,13 @@
 }
 
 Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
     auto ctx = mAccess->getCallingContext();
 
-    if (!mAccess->canFind(ctx, name)) {
-        return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+    std::optional<std::string> accessorName;
+    if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) {
+        return status;
     }
 
     *outReturn = false;
@@ -616,6 +694,8 @@
 }
 
 binder::Status ServiceManager::getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("interface", interface.c_str()));
+
     auto ctx = mAccess->getCallingContext();
 
     std::vector<std::string> allInstances;
@@ -625,8 +705,10 @@
 
     outReturn->clear();
 
+    std::optional<std::string> _accessorName;
     for (const std::string& instance : allInstances) {
-        if (mAccess->canFind(ctx, interface + "/" + instance)) {
+        if (auto status = canFindService(ctx, interface + "/" + instance, &_accessorName);
+            status.isOk()) {
             outReturn->push_back(instance);
         }
     }
@@ -640,10 +722,13 @@
 
 Status ServiceManager::updatableViaApex(const std::string& name,
                                         std::optional<std::string>* outReturn) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
     auto ctx = mAccess->getCallingContext();
 
-    if (!mAccess->canFind(ctx, name)) {
-        return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+    std::optional<std::string> _accessorName;
+    if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) {
+        return status;
     }
 
     *outReturn = std::nullopt;
@@ -656,6 +741,8 @@
 
 Status ServiceManager::getUpdatableNames([[maybe_unused]] const std::string& apexName,
                                          std::vector<std::string>* outReturn) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("apexName", apexName.c_str()));
+
     auto ctx = mAccess->getCallingContext();
 
     std::vector<std::string> apexUpdatableNames;
@@ -665,8 +752,9 @@
 
     outReturn->clear();
 
+    std::optional<std::string> _accessorName;
     for (const std::string& name : apexUpdatableNames) {
-        if (mAccess->canFind(ctx, name)) {
+        if (auto status = canFindService(ctx, name, &_accessorName); status.isOk()) {
             outReturn->push_back(name);
         }
     }
@@ -674,16 +762,18 @@
     if (outReturn->size() == 0 && apexUpdatableNames.size() != 0) {
         return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
     }
-
     return Status::ok();
 }
 
 Status ServiceManager::getConnectionInfo(const std::string& name,
                                          std::optional<ConnectionInfo>* outReturn) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
     auto ctx = mAccess->getCallingContext();
 
-    if (!mAccess->canFind(ctx, name)) {
-        return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+    std::optional<std::string> _accessorName;
+    if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) {
+        return status;
     }
 
     *outReturn = std::nullopt;
@@ -697,6 +787,8 @@
 void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
                                     ServiceCallbackMap::iterator* it,
                                     bool* found) {
+    SM_PERFETTO_TRACE_FUNC();
+
     std::vector<sp<IServiceCallback>>& listeners = (*it)->second;
 
     for (auto lit = listeners.begin(); lit != listeners.end();) {
@@ -716,6 +808,8 @@
 }
 
 void ServiceManager::binderDied(const wp<IBinder>& who) {
+    SM_PERFETTO_TRACE_FUNC();
+
     for (auto it = mNameToService.begin(); it != mNameToService.end();) {
         if (who == it->second.binder) {
             // TODO: currently, this entry contains the state also
@@ -758,6 +852,8 @@
 
 Status ServiceManager::registerClientCallback(const std::string& name, const sp<IBinder>& service,
                                               const sp<IClientCallback>& cb) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
     if (cb == nullptr) {
         return Status::fromExceptionCode(Status::EX_NULL_POINTER, "Callback null.");
     }
@@ -918,6 +1014,8 @@
 }
 
 Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IBinder>& binder) {
+    SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+
     if (binder == nullptr) {
         return Status::fromExceptionCode(Status::EX_NULL_POINTER, "Null service.");
     }
@@ -982,7 +1080,25 @@
     return Status::ok();
 }
 
+Status ServiceManager::canFindService(const Access::CallingContext& ctx, const std::string& name,
+                                      std::optional<std::string>* accessor) {
+    if (!mAccess->canFind(ctx, name)) {
+        return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied for service.");
+    }
+#ifndef VENDORSERVICEMANAGER
+    *accessor = getVintfAccessorName(name);
+#endif
+    if (accessor->has_value()) {
+        if (!mAccess->canFind(ctx, accessor->value())) {
+            return Status::fromExceptionCode(Status::EX_SECURITY,
+                                             "SELinux denied for the accessor of the service.");
+        }
+    }
+    return Status::ok();
+}
+
 Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) {
+    SM_PERFETTO_TRACE_FUNC();
     if (!mAccess->canList(mAccess->getCallingContext())) {
         return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
     }
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 3b925a4..18bae68 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -20,6 +20,10 @@
 #include <android/os/IClientCallback.h>
 #include <android/os/IServiceCallback.h>
 
+#if !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
+#include "perfetto/public/te_category_macros.h"
+#endif // !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
+
 #include "Access.h"
 
 namespace android {
@@ -29,14 +33,19 @@
 using os::IServiceCallback;
 using os::ServiceDebugInfo;
 
+#if !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
+#define PERFETTO_SM_CATEGORIES(C) C(servicemanager, "servicemanager", "Service Manager category")
+PERFETTO_TE_CATEGORIES_DECLARE(PERFETTO_SM_CATEGORIES);
+#endif // !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
+
 class ServiceManager : public os::BnServiceManager, public IBinder::DeathRecipient {
 public:
     ServiceManager(std::unique_ptr<Access>&& access);
     ~ServiceManager();
 
     // getService will try to start any services it cannot find
-    binder::Status getService(const std::string& name, sp<IBinder>* outBinder) override;
-    binder::Status checkService(const std::string& name, sp<IBinder>* outBinder) override;
+    binder::Status getService(const std::string& name, os::Service* outService) override;
+    binder::Status checkService(const std::string& name, os::Service* outService) override;
     binder::Status addService(const std::string& name, const sp<IBinder>& binder,
                               bool allowIsolated, int32_t dumpPriority) override;
     binder::Status listServices(int32_t dumpPriority, std::vector<std::string>* outList) override;
@@ -103,7 +112,10 @@
     // this updates the iterator to the next location
     void removeClientCallback(const wp<IBinder>& who, ClientCallbackMap::iterator* it);
 
-    sp<IBinder> tryGetService(const std::string& name, bool startIfNotFound);
+    os::Service tryGetService(const std::string& name, bool startIfNotFound);
+    sp<IBinder> tryGetBinder(const std::string& name, bool startIfNotFound);
+    binder::Status canFindService(const Access::CallingContext& ctx, const std::string& name,
+                                  std::optional<std::string>* accessor);
 
     ServiceMap mNameToService;
     ServiceCallbackMap mNameToRegistrationCallback;
diff --git a/cmds/servicemanager/main.cpp b/cmds/servicemanager/main.cpp
index 07908ba..c126e91 100644
--- a/cmds/servicemanager/main.cpp
+++ b/cmds/servicemanager/main.cpp
@@ -26,6 +26,26 @@
 #include "Access.h"
 #include "ServiceManager.h"
 
+#if !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
+
+#include <perfetto/public/producer.h>
+#include <perfetto/public/te_category_macros.h>
+#include <perfetto/public/te_macros.h>
+#include <perfetto/public/track_event.h>
+
+namespace android {
+
+static void register_perfetto_te_categories() {
+    struct PerfettoProducerInitArgs perfetto_args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
+    perfetto_args.backends = PERFETTO_BACKEND_SYSTEM;
+    PerfettoProducerInit(perfetto_args);
+    PerfettoTeInit();
+    PERFETTO_TE_REGISTER_CATEGORIES(PERFETTO_SM_CATEGORIES);
+}
+} // namespace android
+
+#endif // !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
+
 using ::android::Access;
 using ::android::IPCThreadState;
 using ::android::Looper;
@@ -132,6 +152,10 @@
 
     const char* driver = argc == 2 ? argv[1] : "/dev/binder";
 
+#if !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
+    android::register_perfetto_te_categories();
+#endif // !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
+
     LOG(INFO) << "Starting sm instance on " << driver;
 
     sp<ProcessState> ps = ProcessState::initWithDriver(driver);
diff --git a/cmds/servicemanager/test_sm.cpp b/cmds/servicemanager/test_sm.cpp
index b575053..9d22641 100644
--- a/cmds/servicemanager/test_sm.cpp
+++ b/cmds/servicemanager/test_sm.cpp
@@ -38,6 +38,7 @@
 using android::binder::Status;
 using android::os::BnServiceCallback;
 using android::os::IServiceManager;
+using android::os::Service;
 using testing::_;
 using testing::ElementsAre;
 using testing::NiceMock;
@@ -153,18 +154,18 @@
     EXPECT_TRUE(sm->addService("foo", serviceA, false /*allowIsolated*/,
         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
 
-    sp<IBinder> outA;
+    Service outA;
     EXPECT_TRUE(sm->getService("foo", &outA).isOk());
-    EXPECT_EQ(serviceA, outA);
+    EXPECT_EQ(serviceA, outA.get<Service::Tag::binder>());
 
     // serviceA should be overwritten by serviceB
     sp<IBinder> serviceB = getBinder();
     EXPECT_TRUE(sm->addService("foo", serviceB, false /*allowIsolated*/,
         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
 
-    sp<IBinder> outB;
+    Service outB;
     EXPECT_TRUE(sm->getService("foo", &outB).isOk());
-    EXPECT_EQ(serviceB, outB);
+    EXPECT_EQ(serviceB, outB.get<Service::Tag::binder>());
 }
 
 TEST(AddService, NoPermissions) {
@@ -186,17 +187,17 @@
     EXPECT_TRUE(sm->addService("foo", service, false /*allowIsolated*/,
         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
 
-    sp<IBinder> out;
+    Service out;
     EXPECT_TRUE(sm->getService("foo", &out).isOk());
-    EXPECT_EQ(service, out);
+    EXPECT_EQ(service, out.get<Service::Tag::binder>());
 }
 
 TEST(GetService, NonExistant) {
     auto sm = getPermissiveServiceManager();
 
-    sp<IBinder> out;
+    Service out;
     EXPECT_TRUE(sm->getService("foo", &out).isOk());
-    EXPECT_EQ(nullptr, out.get());
+    EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
 }
 
 TEST(GetService, NoPermissionsForGettingService) {
@@ -211,10 +212,10 @@
     EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
 
-    sp<IBinder> out;
+    Service out;
     // returns nullptr but has OK status for legacy compatibility
     EXPECT_TRUE(sm->getService("foo", &out).isOk());
-    EXPECT_EQ(nullptr, out.get());
+    EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
 }
 
 TEST(GetService, AllowedFromIsolated) {
@@ -236,9 +237,9 @@
     EXPECT_TRUE(sm->addService("foo", service, true /*allowIsolated*/,
         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
 
-    sp<IBinder> out;
+    Service out;
     EXPECT_TRUE(sm->getService("foo", &out).isOk());
-    EXPECT_EQ(service, out.get());
+    EXPECT_EQ(service, out.get<Service::Tag::binder>());
 }
 
 TEST(GetService, NotAllowedFromIsolated) {
@@ -261,10 +262,10 @@
     EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
 
-    sp<IBinder> out;
+    Service out;
     // returns nullptr but has OK status for legacy compatibility
     EXPECT_TRUE(sm->getService("foo", &out).isOk());
-    EXPECT_EQ(nullptr, out.get());
+    EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
 }
 
 TEST(ListServices, NoPermissions) {
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 0300f8c..64ef827 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -376,6 +376,14 @@
     defaults: ["frameworks_native_data_etc_defaults"],
 }
 
+// installed in system for GSI
+prebuilt_etc {
+    name: "android.software.credentials.prebuilt.xml",
+    relative_install_path: "permissions",
+    src: "android.software.credentials.xml",
+    filename_from_src: true,
+}
+
 prebuilt_etc {
     name: "android.software.device_id_attestation.prebuilt.xml",
     src: "android.software.device_id_attestation.xml",
@@ -418,6 +426,14 @@
     defaults: ["frameworks_native_data_etc_defaults"],
 }
 
+// installed in system
+prebuilt_etc {
+    name: "android.software.preview_sdk.prebuilt.xml",
+    relative_install_path: "permissions",
+    src: "android.software.preview_sdk.xml",
+    filename_from_src: true,
+}
+
 prebuilt_etc {
     name: "android.software.sip.voip.prebuilt.xml",
     src: "android.software.sip.voip.xml",
@@ -460,6 +476,22 @@
     defaults: ["frameworks_native_data_etc_defaults"],
 }
 
+// installed in system
+prebuilt_etc {
+    name: "android.software.webview.prebuilt.xml",
+    relative_install_path: "permissions",
+    src: "android.software.webview.xml",
+    filename_from_src: true,
+}
+
+// installed in system
+prebuilt_etc {
+    name: "android.software.window_magnification.prebuilt.xml",
+    relative_install_path: "permissions",
+    src: "android.software.window_magnification.xml",
+    filename_from_src: true,
+}
+
 prebuilt_etc {
     name: "aosp_excluded_hardware.prebuilt.xml",
     src: "aosp_excluded_hardware.xml",
diff --git a/data/etc/android.hardware.telephony.satellite.xml b/data/etc/android.hardware.telephony.satellite.xml
new file mode 100644
index 0000000..945e720
--- /dev/null
+++ b/data/etc/android.hardware.telephony.satellite.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 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 is the standard set of features for devices to support Telephony Satellite API. -->
+<permissions>
+    <feature name="android.hardware.telephony" />
+    <feature name="android.hardware.telephony.satellite" />
+</permissions>
\ No newline at end of file
diff --git a/data/etc/input/motion_predictor_config.xml b/data/etc/input/motion_predictor_config.xml
index c3f2fed..14540ec 100644
--- a/data/etc/input/motion_predictor_config.xml
+++ b/data/etc/input/motion_predictor_config.xml
@@ -35,7 +35,10 @@
 
     The jerk thresholds are based on normalized dt = 1 calculations.
   -->
-  <low-jerk>1.0</low-jerk>
-  <high-jerk>1.1</high-jerk>
+  <low-jerk>1.5</low-jerk>
+  <high-jerk>2.0</high-jerk>
+
+  <!-- The forget factor in the first-order IIR filter for jerk smoothing -->
+  <jerk-forget-factor>0.25</jerk-forget-factor>
 </motion-predictor>
 
diff --git a/include/android/system_fonts.h b/include/android/system_fonts.h
index 94484ea..2d3a214 100644
--- a/include/android/system_fonts.h
+++ b/include/android/system_fonts.h
@@ -31,27 +31,27 @@
  *
  * \code{.cpp}
  *   ASystemFontIterator* iterator = ASystemFontIterator_open();
- *   ASystemFont* font = NULL;
+ *   AFont* font = NULL;
  *
  *   while ((font = ASystemFontIterator_next(iterator)) != nullptr) {
  *       // Look if the font is your desired one.
- *       if (ASystemFont_getWeight(font) == 400 && !ASystemFont_isItalic(font)
- *           && ASystemFont_getLocale(font) == NULL) {
+ *       if (AFont_getWeight(font) == 400 && !AFont_isItalic(font)
+ *           && AFont_getLocale(font) == NULL) {
  *           break;
  *       }
- *       ASystemFont_close(font);
+ *       AFont_close(font);
  *   }
  *   ASystemFontIterator_close(iterator);
  *
- *   int fd = open(ASystemFont_getFontFilePath(font), O_RDONLY);
- *   int collectionIndex = ASystemFont_getCollectionINdex(font);
+ *   int fd = open(AFont_getFontFilePath(font), O_RDONLY | O_CLOEXEC);
+ *   int collectionIndex = AFont_getCollectionIndex(font);
  *   std::vector<std::pair<uint32_t, float>> variationSettings;
- *   for (size_t i = 0; i < ASystemFont_getAxisCount(font); ++i) {
+ *   for (size_t i = 0; i < AFont_getAxisCount(font); ++i) {
  *       variationSettings.push_back(std::make_pair(
- *           ASystemFont_getAxisTag(font, i),
- *           ASystemFont_getAxisValue(font, i)));
+ *           AFont_getAxisTag(font, i),
+ *           AFont_getAxisValue(font, i)));
  *   }
- *   ASystemFont_close(font);
+ *   AFont_close(font);
  *
  *   // Use this font for your text rendering engine.
  *
@@ -99,7 +99,7 @@
 /**
  * Create a system font iterator.
  *
- * Use ASystemFont_close() to close the iterator.
+ * Use ASystemFontIterator_close() to close the iterator.
  *
  * Available since API level 29.
  *
@@ -123,7 +123,7 @@
  *
  * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
  * \return a font. If no more font is available, returns nullptr. You need to release the returned
- *         font by ASystemFont_close when it is no longer needed.
+ *         font with AFont_close() when it is no longer needed.
  */
 AFont* _Nullable ASystemFontIterator_next(ASystemFontIterator* _Nonnull iterator) __INTRODUCED_IN(29);
 
diff --git a/include/input/Input.h b/include/input/Input.h
index ec08cdd..1a3cb6a 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -25,6 +25,7 @@
 #include <android/input.h>
 #ifdef __linux__
 #include <android/os/IInputConstants.h>
+#include <android/os/MotionEventFlag.h>
 #endif
 #include <android/os/PointerIconType.h>
 #include <math.h>
@@ -69,15 +70,17 @@
      * actual intent.
      */
     AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED =
-            android::os::IInputConstants::MOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED,
+            static_cast<int32_t>(android::os::MotionEventFlag::WINDOW_IS_PARTIALLY_OBSCURED),
+
     AMOTION_EVENT_FLAG_HOVER_EXIT_PENDING =
-            android::os::IInputConstants::MOTION_EVENT_FLAG_HOVER_EXIT_PENDING,
+            static_cast<int32_t>(android::os::MotionEventFlag::HOVER_EXIT_PENDING),
+
     /**
      * This flag indicates that the event has been generated by a gesture generator. It
      * provides a hint to the GestureDetector to not apply any touch slop.
      */
     AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE =
-            android::os::IInputConstants::MOTION_EVENT_FLAG_IS_GENERATED_GESTURE,
+            static_cast<int32_t>(android::os::MotionEventFlag::IS_GENERATED_GESTURE),
 
     /**
      * This flag indicates that the event will not cause a focus change if it is directed to an
@@ -86,27 +89,27 @@
      * into focus.
      */
     AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE =
-            android::os::IInputConstants::MOTION_EVENT_FLAG_NO_FOCUS_CHANGE,
+            static_cast<int32_t>(android::os::MotionEventFlag::NO_FOCUS_CHANGE),
 
     /**
      * This event was generated or modified by accessibility service.
      */
     AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT =
-            android::os::IInputConstants::INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT,
+            static_cast<int32_t>(android::os::MotionEventFlag::IS_ACCESSIBILITY_EVENT),
 
     AMOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS =
-            android::os::IInputConstants::MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS,
+            static_cast<int32_t>(android::os::MotionEventFlag::TARGET_ACCESSIBILITY_FOCUS),
 
     /* Motion event is inconsistent with previously sent motion events. */
-    AMOTION_EVENT_FLAG_TAINTED = android::os::IInputConstants::INPUT_EVENT_FLAG_TAINTED,
+    AMOTION_EVENT_FLAG_TAINTED = static_cast<int32_t>(android::os::MotionEventFlag::TAINTED),
 
     /** Private flag, not used in Java. */
     AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION =
-            android::os::IInputConstants::MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION,
+            static_cast<int32_t>(android::os::MotionEventFlag::PRIVATE_FLAG_SUPPORTS_ORIENTATION),
 
     /** Private flag, not used in Java. */
-    AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION = android::os::IInputConstants::
-            MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION,
+    AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION = static_cast<int32_t>(
+            android::os::MotionEventFlag::PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION),
 
     /** Mask for all private flags that are not used in Java. */
     AMOTION_EVENT_PRIVATE_FLAG_MASK = AMOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION |
@@ -193,6 +196,13 @@
 #define MAX_POINTER_ID 31
 
 /*
+ * Number of high resolution scroll units for one detent (scroll wheel click), as defined in
+ * evdev. This is relevant when an input device is emitting REL_WHEEL_HI_RES or REL_HWHEEL_HI_RES
+ * events.
+ */
+constexpr int32_t kEvdevHighResScrollUnitsPerDetent = 120;
+
+/*
  * Declare a concrete type for the NDK's input event forward declaration.
  */
 struct AInputEvent {
@@ -890,9 +900,7 @@
     void splitFrom(const MotionEvent& other, std::bitset<MAX_POINTER_ID + 1> splitPointerIds,
                    int32_t newEventId);
 
-    void addSample(
-            nsecs_t eventTime,
-            const PointerCoords* pointerCoords);
+    void addSample(nsecs_t eventTime, const PointerCoords* pointerCoords, int32_t eventId);
 
     void offsetLocation(float xOffset, float yOffset);
 
diff --git a/include/input/InputConsumerNoResampling.h b/include/input/InputConsumerNoResampling.h
index 9e48b08..ae8de5f 100644
--- a/include/input/InputConsumerNoResampling.h
+++ b/include/input/InputConsumerNoResampling.h
@@ -16,15 +16,15 @@
 
 #pragma once
 
+#include <input/InputTransport.h>
 #include <utils/Looper.h>
-#include "InputTransport.h"
 
 namespace android {
 
 /**
  * An interface to receive batched input events. Even if you don't want batching, you still have to
  * use this interface, and some of the events will be batched if your implementation is slow to
- * handle the incoming input.
+ * handle the incoming input. The events received by these callbacks are never null.
  */
 class InputConsumerCallbacks {
 public:
@@ -182,6 +182,16 @@
      */
     std::map<DeviceId, std::queue<InputMessage>> mBatches;
     /**
+     * Creates a MotionEvent by consuming samples from the provided queue. If one message has
+     * eventTime > frameTime, all subsequent messages in the queue will be skipped. It is assumed
+     * that messages are queued in chronological order. In other words, only events that occurred
+     * prior to the requested frameTime will be consumed.
+     * @param frameTime the time up to which to consume events
+     * @param messages the queue of messages to consume from
+     */
+    std::pair<std::unique_ptr<MotionEvent>, std::optional<uint32_t>> createBatchedMotionEvent(
+            const nsecs_t frameTime, std::queue<InputMessage>& messages);
+    /**
      * A map from a single sequence number to several sequence numbers. This is needed because of
      * batching. When batching is enabled, a single MotionEvent will contain several samples. Each
      * sample came from an individual InputMessage of Type::Motion, and therefore will have to be
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 6548810..7d11f76 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -275,7 +275,7 @@
      * Return DEAD_OBJECT if the channel's peer has been closed.
      * Other errors probably indicate that the channel is broken.
      */
-    status_t receiveMessage(InputMessage* msg);
+    android::base::Result<InputMessage> receiveMessage();
 
     /* Tells whether there is a message in the channel available to be received.
      *
@@ -363,7 +363,8 @@
      * Returns OK on success.
      * Returns WOULD_BLOCK if the channel is full.
      * Returns DEAD_OBJECT if the channel's peer has been closed.
-     * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS.
+     * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS,
+     * or if the verifier is enabled and the event failed verification upon publishing.
      * Other errors probably indicate that the channel is broken.
      */
     status_t publishMotionEvent(uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source,
diff --git a/include/input/MotionPredictor.h b/include/input/MotionPredictor.h
index f715039..2f1ef86 100644
--- a/include/input/MotionPredictor.h
+++ b/include/input/MotionPredictor.h
@@ -56,12 +56,20 @@
     // acceleration) and has the units of d^3p/dt^3.
     std::optional<float> jerkMagnitude() const;
 
+    // forgetFactor is the coefficient of the first-order IIR filter for jerk. A factor of 1 results
+    // in no smoothing.
+    void setForgetFactor(float forgetFactor);
+    float getForgetFactor() const;
+
 private:
     const bool mNormalizedDt;
+    // Coefficient of first-order IIR filter to smooth jerk calculation.
+    float mForgetFactor = 1;
 
     RingBuffer<int64_t> mTimestamps{4};
     std::array<float, 4> mXDerivatives{}; // [x, x', x'', x''']
     std::array<float, 4> mYDerivatives{}; // [y, y', y'', y''']
+    float mJerkMagnitude;
 };
 
 /**
@@ -116,6 +124,11 @@
 
     bool isPredictionAvailable(int32_t deviceId, int32_t source);
 
+    /**
+     * Currently used to expose config constants in testing.
+     */
+    const TfLiteMotionPredictorModel::Config& getModelConfig();
+
 private:
     const nsecs_t mPredictionTimestampOffsetNanos;
     const std::function<bool()> mCheckMotionPredictionEnabled;
diff --git a/include/input/TfLiteMotionPredictor.h b/include/input/TfLiteMotionPredictor.h
index 728a8e1..08a4330 100644
--- a/include/input/TfLiteMotionPredictor.h
+++ b/include/input/TfLiteMotionPredictor.h
@@ -110,6 +110,9 @@
         // High jerk means more predictions will be pruned, vice versa for low.
         float lowJerk = 0;
         float highJerk = 0;
+
+        // Coefficient for the first-order IIR filter for jerk calculation.
+        float jerkForgetFactor = 1;
     };
 
     // Creates a model from an encoded Flatbuffer model.
diff --git a/include/input/VirtualInputDevice.h b/include/input/VirtualInputDevice.h
index 222dac8..dabe45c 100644
--- a/include/input/VirtualInputDevice.h
+++ b/include/input/VirtualInputDevice.h
@@ -77,6 +77,8 @@
 
 private:
     static const std::map<int, int> BUTTON_CODE_MAPPING;
+    int32_t mAccumulatedHighResScrollX;
+    int32_t mAccumulatedHighResScrollY;
 };
 
 class VirtualTouchscreen : public VirtualInputDevice {
@@ -122,4 +124,14 @@
     bool handleStylusUp(uint16_t tool, std::chrono::nanoseconds eventTime);
 };
 
+class VirtualRotaryEncoder : public VirtualInputDevice {
+public:
+    VirtualRotaryEncoder(android::base::unique_fd fd);
+    virtual ~VirtualRotaryEncoder() override;
+    bool writeScrollEvent(float scrollAmount, std::chrono::nanoseconds eventTime);
+
+private:
+    int32_t mAccumulatedHighResScrollAmount;
+};
+
 } // namespace android
diff --git a/libs/adbd_auth/adbd_auth.cpp b/libs/adbd_auth/adbd_auth.cpp
index ebc74fb..78896ed 100644
--- a/libs/adbd_auth/adbd_auth.cpp
+++ b/libs/adbd_auth/adbd_auth.cpp
@@ -365,7 +365,7 @@
                         if (event.events & EPOLLIN) {
                             int rc = TEMP_FAILURE_RETRY(read(framework_fd_.get(), buf, sizeof(buf)));
                             if (rc == -1) {
-                                LOG(FATAL) << "adbd_auth: failed to read from framework fd";
+                                PLOG(FATAL) << "adbd_auth: failed to read from framework fd";
                             } else if (rc == 0) {
                                 LOG(INFO) << "adbd_auth: hit EOF on framework fd";
                                 std::lock_guard<std::mutex> lock(mutex_);
diff --git a/libs/binder/ActivityManager.cpp b/libs/binder/ActivityManager.cpp
index 5264276..98349c6 100644
--- a/libs/binder/ActivityManager.cpp
+++ b/libs/binder/ActivityManager.cpp
@@ -23,10 +23,10 @@
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 
-#include <utils/SystemClock.h>
-
 namespace android {
 
+using namespace std::chrono_literals;
+
 ActivityManager::ActivityManager()
 {
 }
@@ -43,15 +43,16 @@
         }
     } else {
         ALOGI("Thread pool not started. Polling for activity service.");
-        int64_t startTime = 0;
+        auto startTime = std::chrono::steady_clock::now().min();
         while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) {
             sp<IBinder> binder = defaultServiceManager()->checkService(String16("activity"));
             if (binder == nullptr) {
                 // Wait for the activity service to come back...
-                if (startTime == 0) {
-                    startTime = uptimeMillis();
+                if (startTime == startTime.min()) {
+                    startTime = std::chrono::steady_clock::now();
                     ALOGI("Waiting for activity service");
-                } else if ((uptimeMillis() - startTime) > 1000000) {
+                } else if (std::chrono::steady_clock::now() - startTime > 1000s) {
+                    // TODO(b/342453147): timeout of 1000s = 16min and 40s doesn't seem intended
                     ALOGW("Waiting too long for activity service, giving up");
                     service = nullptr;
                     break;
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index cb1d114..de331b7 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -19,6 +19,7 @@
     // to get the below license kinds:
     //   SPDX-license-identifier-Apache-2.0
     default_applicable_licenses: ["frameworks_native_license"],
+    default_team: "trendy_team_virtualization",
 }
 
 cc_library_headers {
@@ -86,16 +87,19 @@
 
 cc_cmake_snapshot {
     name: "binder_sdk",
-    modules: [
+    modules_host: [
         "libbinder_sdk",
         "libbinder_sdk_single_threaded",
         "libbinder_ndk_sdk",
+        "googletest_cmake",
+
         "binderRpcTestNoKernel",
+        "binderRpcTestSingleThreadedNoKernel",
+        "binderRpcWireProtocolTest",
     ],
     prebuilts: [
         // to enable arm64 host support, build with musl - e.g. on aosp_cf_arm64_phone
         "aidl",
-        "libc++",
     ],
     include_sources: true,
     cflags: [
@@ -133,12 +137,16 @@
         {
             android_name: "libgtest",
             mapped_name: "GTest::gtest",
-            package_system: "GTest",
+            package_pregenerated: "external/googletest",
         },
         {
             android_name: "libgtest_main",
-            mapped_name: "GTest::gtest",
-            package_system: "GTest",
+            mapped_name: "GTest::gtest_main",
+            package_pregenerated: "external/googletest",
+        },
+        {
+            android_name: "googletest_cmake",
+            package_pregenerated: "external/googletest",
         },
 
         // use libbinder_sdk and friends instead of full Android's libbinder
@@ -258,7 +266,20 @@
         "-Wunused-const-variable",
         "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
         "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+        // Hide symbols by default and set the BUILDING_LIBBINDER macro so that
+        // the code knows to export them.
+        "-fvisibility=hidden",
+        "-DBUILDING_LIBBINDER",
     ],
+
+    target: {
+        vendor: {
+            // Trimming the exported symbols reveals a bug in vendor code, so
+            // disable it for the vendor variant for now. http://b/349657329
+            // TODO: Fix the issue and remove this override.
+            cflags: ["-fvisibility=default"],
+        },
+    },
 }
 
 cc_defaults {
@@ -429,12 +450,37 @@
     ],
 }
 
+soong_config_module_type {
+    name: "libbinder_client_cache_config",
+    module_type: "cc_defaults",
+    config_namespace: "libbinder",
+    bool_variables: ["release_libbinder_client_cache"],
+    properties: [
+        "cflags",
+    ],
+}
+
+libbinder_client_cache_config {
+    name: "libbinder_client_cache_flag",
+    soong_config_variables: {
+        release_libbinder_client_cache: {
+            cflags: ["-DLIBBINDER_CLIENT_CACHE"],
+            conditions_default: {
+                cflags: ["-DNO_LIBBINDER_CLIENT_CACHE"],
+            },
+        },
+    },
+}
+
 cc_defaults {
     name: "libbinder_kernel_defaults",
+    defaults: ["libbinder_client_cache_flag"],
     srcs: [
         "BufferedTextOutput.cpp",
+        "BackendUnifiedServiceManager.cpp",
         "IPCThreadState.cpp",
         "IServiceManager.cpp",
+        "IServiceManagerFFI.cpp",
         "ProcessState.cpp",
         "Static.cpp",
         ":libbinder_aidl",
@@ -510,7 +556,6 @@
         "ParcelableHolder.cpp",
         "PersistableBundle.cpp",
     ],
-
     target: {
         android: {
             // NOT static to keep the wire protocol unfrozen
@@ -749,11 +794,41 @@
         "aidl/android/os/IClientCallback.aidl",
         "aidl/android/os/IServiceCallback.aidl",
         "aidl/android/os/IServiceManager.aidl",
+        "aidl/android/os/Service.aidl",
         "aidl/android/os/ServiceDebugInfo.aidl",
+        ":libbinder_accessor_aidl",
     ],
     path: "aidl",
 }
 
+filegroup {
+    name: "libbinder_accessor_aidl",
+    srcs: [
+        "aidl/android/os/IAccessor.aidl",
+    ],
+    path: "aidl",
+}
+
+// TODO(b/353492849): Make this interface private to libbinder.
+aidl_interface {
+    name: "android.os.accessor",
+    srcs: [":libbinder_accessor_aidl"],
+    unstable: true,
+    backend: {
+        rust: {
+            enabled: true,
+            apex_available: [
+                "com.android.virt",
+            ],
+        },
+    },
+    visibility: [
+        ":__subpackages__",
+        "//system/tools/aidl:__subpackages__",
+        "//packages/modules/Virtualization:__subpackages__",
+    ],
+}
+
 aidl_interface {
     name: "packagemanager_aidl",
     unstable: true,
@@ -889,7 +964,4 @@
         "libutils",
         "android.debug_aidl-cpp",
     ],
-    static_libs: [
-        "libc++fs",
-    ],
 }
diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp
new file mode 100644
index 0000000..0bf3cad
--- /dev/null
+++ b/libs/binder/BackendUnifiedServiceManager.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2024 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 "BackendUnifiedServiceManager.h"
+
+#include <android/os/IAccessor.h>
+#include <binder/RpcSession.h>
+
+#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
+#include <android-base/properties.h>
+#endif
+
+namespace android {
+
+using AidlServiceManager = android::os::IServiceManager;
+using IAccessor = android::os::IAccessor;
+
+BackendUnifiedServiceManager::BackendUnifiedServiceManager(const sp<AidlServiceManager>& impl)
+      : mTheRealServiceManager(impl) {}
+
+sp<AidlServiceManager> BackendUnifiedServiceManager::getImpl() {
+    return mTheRealServiceManager;
+}
+binder::Status BackendUnifiedServiceManager::getService(const ::std::string& name,
+                                                        os::Service* _out) {
+    os::Service service;
+    binder::Status status = mTheRealServiceManager->getService(name, &service);
+    toBinderService(service, _out);
+    return status;
+}
+
+binder::Status BackendUnifiedServiceManager::checkService(const ::std::string& name,
+                                                          os::Service* _out) {
+    os::Service service;
+    binder::Status status = mTheRealServiceManager->checkService(name, &service);
+    toBinderService(service, _out);
+    return status;
+}
+
+void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Service* _out) {
+    switch (in.getTag()) {
+        case os::Service::Tag::binder: {
+            *_out = in;
+            break;
+        }
+        case os::Service::Tag::accessor: {
+            sp<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>();
+            sp<IAccessor> accessor = interface_cast<IAccessor>(accessorBinder);
+            if (accessor == nullptr) {
+                ALOGE("Service#accessor doesn't have accessor. VM is maybe starting...");
+                *_out = os::Service::make<os::Service::Tag::binder>(nullptr);
+                break;
+            }
+            auto request = [=] {
+                os::ParcelFileDescriptor fd;
+                binder::Status ret = accessor->addConnection(&fd);
+                if (ret.isOk()) {
+                    return base::unique_fd(fd.release());
+                } else {
+                    ALOGE("Failed to connect to RpcSession: %s", ret.toString8().c_str());
+                    return base::unique_fd(-1);
+                }
+            };
+            auto session = RpcSession::make();
+            session->setupPreconnectedClient(base::unique_fd{}, request);
+            session->setSessionSpecificRoot(accessorBinder);
+            *_out = os::Service::make<os::Service::Tag::binder>(session->getRootObject());
+            break;
+        }
+        default: {
+            LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag());
+        }
+    }
+}
+
+binder::Status BackendUnifiedServiceManager::addService(const ::std::string& name,
+                                                        const sp<IBinder>& service,
+                                                        bool allowIsolated, int32_t dumpPriority) {
+    return mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority);
+}
+binder::Status BackendUnifiedServiceManager::listServices(
+        int32_t dumpPriority, ::std::vector<::std::string>* _aidl_return) {
+    return mTheRealServiceManager->listServices(dumpPriority, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::registerForNotifications(
+        const ::std::string& name, const sp<os::IServiceCallback>& callback) {
+    return mTheRealServiceManager->registerForNotifications(name, callback);
+}
+binder::Status BackendUnifiedServiceManager::unregisterForNotifications(
+        const ::std::string& name, const sp<os::IServiceCallback>& callback) {
+    return mTheRealServiceManager->unregisterForNotifications(name, callback);
+}
+binder::Status BackendUnifiedServiceManager::isDeclared(const ::std::string& name,
+                                                        bool* _aidl_return) {
+    return mTheRealServiceManager->isDeclared(name, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::getDeclaredInstances(
+        const ::std::string& iface, ::std::vector<::std::string>* _aidl_return) {
+    return mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::updatableViaApex(
+        const ::std::string& name, ::std::optional<::std::string>* _aidl_return) {
+    return mTheRealServiceManager->updatableViaApex(name, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::getUpdatableNames(
+        const ::std::string& apexName, ::std::vector<::std::string>* _aidl_return) {
+    return mTheRealServiceManager->getUpdatableNames(apexName, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::getConnectionInfo(
+        const ::std::string& name, ::std::optional<os::ConnectionInfo>* _aidl_return) {
+    return mTheRealServiceManager->getConnectionInfo(name, _aidl_return);
+}
+binder::Status BackendUnifiedServiceManager::registerClientCallback(
+        const ::std::string& name, const sp<IBinder>& service,
+        const sp<os::IClientCallback>& callback) {
+    return mTheRealServiceManager->registerClientCallback(name, service, callback);
+}
+binder::Status BackendUnifiedServiceManager::tryUnregisterService(const ::std::string& name,
+                                                                  const sp<IBinder>& service) {
+    return mTheRealServiceManager->tryUnregisterService(name, service);
+}
+binder::Status BackendUnifiedServiceManager::getServiceDebugInfo(
+        ::std::vector<os::ServiceDebugInfo>* _aidl_return) {
+    return mTheRealServiceManager->getServiceDebugInfo(_aidl_return);
+}
+
+[[clang::no_destroy]] static std::once_flag gUSmOnce;
+[[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager;
+
+sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() {
+    std::call_once(gUSmOnce, []() {
+#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
+        /* wait for service manager */ {
+            using std::literals::chrono_literals::operator""s;
+            using android::base::WaitForProperty;
+            while (!WaitForProperty("servicemanager.ready", "true", 1s)) {
+                ALOGE("Waited for servicemanager.ready for a second, waiting another...");
+            }
+        }
+#endif
+
+        sp<AidlServiceManager> sm = nullptr;
+        while (sm == nullptr) {
+            sm = interface_cast<AidlServiceManager>(
+                    ProcessState::self()->getContextObject(nullptr));
+            if (sm == nullptr) {
+                ALOGE("Waiting 1s on context object on %s.",
+                      ProcessState::self()->getDriverName().c_str());
+                sleep(1);
+            }
+        }
+
+        gUnifiedServiceManager = sp<BackendUnifiedServiceManager>::make(sm);
+    });
+
+    return gUnifiedServiceManager;
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/libs/binder/BackendUnifiedServiceManager.h b/libs/binder/BackendUnifiedServiceManager.h
new file mode 100644
index 0000000..4715be4
--- /dev/null
+++ b/libs/binder/BackendUnifiedServiceManager.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2024 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/os/BnServiceManager.h>
+#include <android/os/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+
+namespace android {
+
+class BackendUnifiedServiceManager : public android::os::BnServiceManager {
+public:
+    explicit BackendUnifiedServiceManager(const sp<os::IServiceManager>& impl);
+
+    sp<os::IServiceManager> getImpl();
+    binder::Status getService(const ::std::string& name, os::Service* out) override;
+    binder::Status checkService(const ::std::string& name, os::Service* out) override;
+    binder::Status addService(const ::std::string& name, const sp<IBinder>& service,
+                              bool allowIsolated, int32_t dumpPriority) override;
+    binder::Status listServices(int32_t dumpPriority,
+                                ::std::vector<::std::string>* _aidl_return) override;
+    binder::Status registerForNotifications(const ::std::string& name,
+                                            const sp<os::IServiceCallback>& callback) override;
+    binder::Status unregisterForNotifications(const ::std::string& name,
+                                              const sp<os::IServiceCallback>& callback) override;
+    binder::Status isDeclared(const ::std::string& name, bool* _aidl_return) override;
+    binder::Status getDeclaredInstances(const ::std::string& iface,
+                                        ::std::vector<::std::string>* _aidl_return) override;
+    binder::Status updatableViaApex(const ::std::string& name,
+                                    ::std::optional<::std::string>* _aidl_return) override;
+    binder::Status getUpdatableNames(const ::std::string& apexName,
+                                     ::std::vector<::std::string>* _aidl_return) override;
+    binder::Status getConnectionInfo(const ::std::string& name,
+                                     ::std::optional<os::ConnectionInfo>* _aidl_return) override;
+    binder::Status registerClientCallback(const ::std::string& name, const sp<IBinder>& service,
+                                          const sp<os::IClientCallback>& callback) override;
+    binder::Status tryUnregisterService(const ::std::string& name,
+                                        const sp<IBinder>& service) override;
+    binder::Status getServiceDebugInfo(::std::vector<os::ServiceDebugInfo>* _aidl_return) override;
+
+    // for legacy ABI
+    const String16& getInterfaceDescriptor() const override {
+        return mTheRealServiceManager->getInterfaceDescriptor();
+    }
+
+    IBinder* onAsBinder() override { return IInterface::asBinder(mTheRealServiceManager).get(); }
+
+private:
+    sp<os::IServiceManager> mTheRealServiceManager;
+    void toBinderService(const os::Service& in, os::Service* _out);
+};
+
+sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager();
+
+} // namespace android
\ No newline at end of file
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index fbc8125..984c93d 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -22,10 +22,7 @@
 #include <binder/BpBinder.h>
 #include <binder/TextOutput.h>
 
-#include <cutils/sched_policy.h>
 #include <utils/CallStack.h>
-#include <utils/Log.h>
-#include <utils/SystemClock.h>
 
 #include <atomic>
 #include <errno.h>
@@ -38,6 +35,7 @@
 #include <sys/resource.h>
 #include <unistd.h>
 
+#include "Utils.h"
 #include "binder_module.h"
 
 #if LOG_NDEBUG
@@ -65,6 +63,8 @@
 
 namespace android {
 
+using namespace std::chrono_literals;
+
 // Static const and functions will be optimized out if not used,
 // when LOG_NDEBUG and references in IF_LOG_COMMANDS() are optimized out.
 static const char* kReturnStrings[] = {
@@ -285,7 +285,9 @@
     return cmd;
 }
 
+LIBBINDER_IGNORE("-Wzero-as-null-pointer-constant")
 static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
+LIBBINDER_IGNORE_END()
 static std::atomic<bool> gHaveTLS(false);
 static pthread_key_t gTLS = 0;
 static std::atomic<bool> gShutdown = false;
@@ -613,16 +615,19 @@
 
 void IPCThreadState::blockUntilThreadAvailable()
 {
-    pthread_mutex_lock(&mProcess->mThreadCountLock);
-    mProcess->mWaitingForThreads++;
-    while (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads) {
-        ALOGW("Waiting for thread to be free. mExecutingThreadsCount=%lu mMaxThreads=%lu\n",
-                static_cast<unsigned long>(mProcess->mExecutingThreadsCount),
-                static_cast<unsigned long>(mProcess->mMaxThreads));
-        pthread_cond_wait(&mProcess->mThreadCountDecrement, &mProcess->mThreadCountLock);
-    }
-    mProcess->mWaitingForThreads--;
-    pthread_mutex_unlock(&mProcess->mThreadCountLock);
+    std::unique_lock lock_guard_(mProcess->mOnThreadAvailableLock);
+    mProcess->mOnThreadAvailableWaiting++;
+    mProcess->mOnThreadAvailableCondVar.wait(lock_guard_, [&] {
+        size_t max = mProcess->mMaxThreads;
+        size_t cur = mProcess->mExecutingThreadsCount;
+        if (cur < max) {
+            return true;
+        }
+        ALOGW("Waiting for thread to be free. mExecutingThreadsCount=%zu mMaxThreads=%zu\n", cur,
+              max);
+        return false;
+    });
+    mProcess->mOnThreadAvailableWaiting--;
 }
 
 status_t IPCThreadState::getAndExecuteCommand()
@@ -642,34 +647,35 @@
             ALOGI("%s", message.c_str());
         }
 
-        pthread_mutex_lock(&mProcess->mThreadCountLock);
-        mProcess->mExecutingThreadsCount++;
-        if (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads &&
-                mProcess->mStarvationStartTimeMs == 0) {
-            mProcess->mStarvationStartTimeMs = uptimeMillis();
+        size_t newThreadsCount = mProcess->mExecutingThreadsCount.fetch_add(1) + 1;
+        if (newThreadsCount >= mProcess->mMaxThreads) {
+            auto expected = ProcessState::never();
+            mProcess->mStarvationStartTime
+                    .compare_exchange_strong(expected, std::chrono::steady_clock::now());
         }
-        pthread_mutex_unlock(&mProcess->mThreadCountLock);
 
         result = executeCommand(cmd);
 
-        pthread_mutex_lock(&mProcess->mThreadCountLock);
-        mProcess->mExecutingThreadsCount--;
-        if (mProcess->mExecutingThreadsCount < mProcess->mMaxThreads &&
-                mProcess->mStarvationStartTimeMs != 0) {
-            int64_t starvationTimeMs = uptimeMillis() - mProcess->mStarvationStartTimeMs;
-            if (starvationTimeMs > 100) {
-                ALOGE("binder thread pool (%zu threads) starved for %" PRId64 " ms",
-                      mProcess->mMaxThreads, starvationTimeMs);
+        size_t maxThreads = mProcess->mMaxThreads;
+        newThreadsCount = mProcess->mExecutingThreadsCount.fetch_sub(1) - 1;
+        if (newThreadsCount < maxThreads) {
+            auto starvationStartTime =
+                    mProcess->mStarvationStartTime.exchange(ProcessState::never());
+            if (starvationStartTime != ProcessState::never()) {
+                auto starvationTime = std::chrono::steady_clock::now() - starvationStartTime;
+                if (starvationTime > 100ms) {
+                    ALOGE("binder thread pool (%zu threads) starved for %" PRId64 " ms", maxThreads,
+                          to_ms(starvationTime));
+                }
             }
-            mProcess->mStarvationStartTimeMs = 0;
         }
 
         // Cond broadcast can be expensive, so don't send it every time a binder
         // call is processed. b/168806193
-        if (mProcess->mWaitingForThreads > 0) {
-            pthread_cond_broadcast(&mProcess->mThreadCountDecrement);
+        if (mProcess->mOnThreadAvailableWaiting > 0) {
+            std::lock_guard lock_guard_(mProcess->mOnThreadAvailableLock);
+            mProcess->mOnThreadAvailableCondVar.notify_all();
         }
-        pthread_mutex_unlock(&mProcess->mThreadCountLock);
     }
 
     return result;
@@ -727,10 +733,9 @@
 
 void IPCThreadState::joinThreadPool(bool isMain)
 {
-    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
-    pthread_mutex_lock(&mProcess->mThreadCountLock);
+    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(),
+                   getpid());
     mProcess->mCurrentThreads++;
-    pthread_mutex_unlock(&mProcess->mThreadCountLock);
     mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
 
     mIsLooper = true;
@@ -758,13 +763,11 @@
     mOut.writeInt32(BC_EXIT_LOOPER);
     mIsLooper = false;
     talkWithDriver(false);
-    pthread_mutex_lock(&mProcess->mThreadCountLock);
-    LOG_ALWAYS_FATAL_IF(mProcess->mCurrentThreads == 0,
-                        "Threadpool thread count = 0. Thread cannot exist and exit in empty "
-                        "threadpool\n"
+    size_t oldCount = mProcess->mCurrentThreads.fetch_sub(1);
+    LOG_ALWAYS_FATAL_IF(oldCount == 0,
+                        "Threadpool thread count underflowed. Thread cannot exist and exit in "
+                        "empty threadpool\n"
                         "Misconfiguration. Increase threadpool max threads configuration\n");
-    mProcess->mCurrentThreads--;
-    pthread_mutex_unlock(&mProcess->mThreadCountLock);
 }
 
 status_t IPCThreadState::setupPolling(int* fd)
@@ -776,9 +779,7 @@
     mOut.writeInt32(BC_ENTER_LOOPER);
     flushCommands();
     *fd = mProcess->mDriverFD;
-    pthread_mutex_lock(&mProcess->mThreadCountLock);
     mProcess->mCurrentThreads++;
-    pthread_mutex_unlock(&mProcess->mThreadCountLock);
     return 0;
 }
 
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index fbcf823..12a18f2 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -17,19 +17,20 @@
 #define LOG_TAG "ServiceManagerCppClient"
 
 #include <binder/IServiceManager.h>
+#include "BackendUnifiedServiceManager.h"
 
 #include <inttypes.h>
 #include <unistd.h>
+#include <chrono>
 #include <condition_variable>
 
 #include <android-base/properties.h>
 #include <android/os/BnServiceCallback.h>
+#include <android/os/IAccessor.h>
 #include <android/os/IServiceManager.h>
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
-#include <utils/Log.h>
 #include <utils/String8.h>
-#include <utils/SystemClock.h>
 
 #ifndef __ANDROID_VNDK__
 #include <binder/IPermissionController.h>
@@ -47,13 +48,18 @@
 #endif
 
 #include "Static.h"
+#include "Utils.h"
 
 namespace android {
 
+using namespace std::chrono_literals;
+
 using AidlRegistrationCallback = IServiceManager::LocalRegistrationCallback;
 
 using AidlServiceManager = android::os::IServiceManager;
 using android::binder::Status;
+using android::os::IAccessor;
+using android::os::Service;
 
 // libbinder's IServiceManager.h can't rely on the values generated by AIDL
 // because many places use its headers via include_dirs (meaning, without
@@ -111,14 +117,12 @@
     std::vector<IServiceManager::ServiceDebugInfo> getServiceDebugInfo() override;
     // for legacy ABI
     const String16& getInterfaceDescriptor() const override {
-        return mTheRealServiceManager->getInterfaceDescriptor();
+        return mUnifiedServiceManager->getInterfaceDescriptor();
     }
-    IBinder* onAsBinder() override {
-        return IInterface::asBinder(mTheRealServiceManager).get();
-    }
+    IBinder* onAsBinder() override { return IInterface::asBinder(mUnifiedServiceManager).get(); }
 
 protected:
-    sp<AidlServiceManager> mTheRealServiceManager;
+    sp<BackendUnifiedServiceManager> mUnifiedServiceManager;
     // AidlRegistrationCallback -> services that its been registered for
     // notifications.
     using LocalRegistrationAndWaiter =
@@ -136,9 +140,12 @@
     // 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.
+    // mUnifiedServiceManager->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);
+        Service service;
+        Status status = mUnifiedServiceManager->getService(name, &service);
+        *_aidl_return = service.get<Service::Tag::binder>();
+        return status;
     }
 };
 
@@ -148,26 +155,7 @@
 sp<IServiceManager> defaultServiceManager()
 {
     std::call_once(gSmOnce, []() {
-#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
-        /* wait for service manager */ {
-            using std::literals::chrono_literals::operator""s;
-            using android::base::WaitForProperty;
-            while (!WaitForProperty("servicemanager.ready", "true", 1s)) {
-                ALOGE("Waited for servicemanager.ready for a second, waiting another...");
-            }
-        }
-#endif
-
-        sp<AidlServiceManager> sm = nullptr;
-        while (sm == nullptr) {
-            sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
-            if (sm == nullptr) {
-                ALOGE("Waiting 1s on context object on %s.", ProcessState::self()->getDriverName().c_str());
-                sleep(1);
-            }
-        }
-
-        gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
+        gDefaultServiceManager = sp<ServiceManagerShim>::make(getBackendUnifiedServiceManager());
     });
 
     return gDefaultServiceManager;
@@ -214,16 +202,16 @@
     pc = gPermissionController;
     gPermissionControllerLock.unlock();
 
-    int64_t startTime = 0;
+    auto startTime = std::chrono::steady_clock::now().min();
 
     while (true) {
         if (pc != nullptr) {
             bool res = pc->checkPermission(permission, pid, uid);
             if (res) {
-                if (startTime != 0) {
-                    ALOGI("Check passed after %d seconds for %s from uid=%d pid=%d",
-                          (int)((uptimeMillis() - startTime) / 1000), String8(permission).c_str(),
-                          uid, pid);
+                if (startTime != startTime.min()) {
+                    const auto waitTime = std::chrono::steady_clock::now() - startTime;
+                    ALOGI("Check passed after %" PRIu64 "ms for %s from uid=%d pid=%d",
+                          to_ms(waitTime), String8(permission).c_str(), uid, pid);
                 }
                 return res;
             }
@@ -249,8 +237,8 @@
         sp<IBinder> binder = defaultServiceManager()->checkService(_permission);
         if (binder == nullptr) {
             // Wait for the permission controller to come back...
-            if (startTime == 0) {
-                startTime = uptimeMillis();
+            if (startTime == startTime.min()) {
+                startTime = std::chrono::steady_clock::now();
                 ALOGI("Waiting to check permission %s from uid=%d pid=%d",
                       String8(permission).c_str(), uid, pid);
             }
@@ -290,9 +278,9 @@
 
 // ----------------------------------------------------------------------
 
-ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl)
- : mTheRealServiceManager(impl)
-{}
+ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl) {
+    mUnifiedServiceManager = sp<BackendUnifiedServiceManager>::make(impl);
+}
 
 // This implementation could be simplified and made more efficient by delegating
 // to waitForService. However, this changes the threading structure in some
@@ -307,8 +295,8 @@
 
     const bool isVendorService =
         strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0;
-    constexpr int64_t timeout = 5000;
-    int64_t startTime = uptimeMillis();
+    constexpr auto timeout = 5s;
+    const auto startTime = std::chrono::steady_clock::now();
     // Vendor code can't access system properties
     if (!gSystemBootCompleted && !isVendorService) {
 #ifdef __ANDROID__
@@ -326,15 +314,16 @@
           ProcessState::self()->getDriverName().c_str());
 
     int n = 0;
-    while (uptimeMillis() - startTime < timeout) {
+    while (std::chrono::steady_clock::now() - startTime < timeout) {
         n++;
         usleep(1000*sleepTime);
 
         sp<IBinder> svc = checkService(name);
         if (svc != nullptr) {
-            ALOGI("Waiting for service '%s' on '%s' successful after waiting %" PRIi64 "ms",
+            const auto waitTime = std::chrono::steady_clock::now() - startTime;
+            ALOGI("Waiting for service '%s' on '%s' successful after waiting %" PRIu64 "ms",
                   String8(name).c_str(), ProcessState::self()->getDriverName().c_str(),
-                  uptimeMillis() - startTime);
+                  to_ms(waitTime));
             return svc;
         }
     }
@@ -344,25 +333,25 @@
 
 sp<IBinder> ServiceManagerShim::checkService(const String16& name) const
 {
-    sp<IBinder> ret;
-    if (!mTheRealServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
+    Service ret;
+    if (!mUnifiedServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
         return nullptr;
     }
-    return ret;
+    return ret.get<Service::Tag::binder>();
 }
 
 status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
                                         bool allowIsolated, int dumpsysPriority)
 {
-    Status status = mTheRealServiceManager->addService(
-        String8(name).c_str(), service, allowIsolated, dumpsysPriority);
+    Status status = mUnifiedServiceManager->addService(String8(name).c_str(), service,
+                                                       allowIsolated, dumpsysPriority);
     return status.exceptionCode();
 }
 
 Vector<String16> ServiceManagerShim::listServices(int dumpsysPriority)
 {
     std::vector<std::string> ret;
-    if (!mTheRealServiceManager->listServices(dumpsysPriority, &ret).isOk()) {
+    if (!mUnifiedServiceManager->listServices(dumpsysPriority, &ret).isOk()) {
         return {};
     }
 
@@ -420,15 +409,13 @@
     if (out != nullptr) return out;
 
     sp<Waiter> waiter = sp<Waiter>::make();
-    if (Status status = mTheRealServiceManager->registerForNotifications(name, waiter);
+    if (Status status = mUnifiedServiceManager->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 ([&] {
-        mTheRealServiceManager->unregisterForNotifications(name, waiter);
-    });
+    Defer unregister([&] { mUnifiedServiceManager->unregisterForNotifications(name, waiter); });
 
     while(true) {
         {
@@ -438,7 +425,6 @@
             // that another thread serves the callback, and we never get a
             // command, so we hang indefinitely.
             std::unique_lock<std::mutex> lock(waiter->mMutex);
-            using std::literals::chrono_literals::operator""s;
             waiter->mCv.wait_for(lock, 1s, [&] {
                 return waiter->mBinder != nullptr;
             });
@@ -469,7 +455,7 @@
 
 bool ServiceManagerShim::isDeclared(const String16& name) {
     bool declared;
-    if (Status status = mTheRealServiceManager->isDeclared(String8(name).c_str(), &declared);
+    if (Status status = mUnifiedServiceManager->isDeclared(String8(name).c_str(), &declared);
         !status.isOk()) {
         ALOGW("Failed to get isDeclared for %s: %s", String8(name).c_str(),
               status.toString8().c_str());
@@ -481,7 +467,7 @@
 Vector<String16> ServiceManagerShim::getDeclaredInstances(const String16& interface) {
     std::vector<std::string> out;
     if (Status status =
-                mTheRealServiceManager->getDeclaredInstances(String8(interface).c_str(), &out);
+                mUnifiedServiceManager->getDeclaredInstances(String8(interface).c_str(), &out);
         !status.isOk()) {
         ALOGW("Failed to getDeclaredInstances for %s: %s", String8(interface).c_str(),
               status.toString8().c_str());
@@ -498,7 +484,7 @@
 
 std::optional<String16> ServiceManagerShim::updatableViaApex(const String16& name) {
     std::optional<std::string> declared;
-    if (Status status = mTheRealServiceManager->updatableViaApex(String8(name).c_str(), &declared);
+    if (Status status = mUnifiedServiceManager->updatableViaApex(String8(name).c_str(), &declared);
         !status.isOk()) {
         ALOGW("Failed to get updatableViaApex for %s: %s", String8(name).c_str(),
               status.toString8().c_str());
@@ -509,7 +495,7 @@
 
 Vector<String16> ServiceManagerShim::getUpdatableNames(const String16& apexName) {
     std::vector<std::string> out;
-    if (Status status = mTheRealServiceManager->getUpdatableNames(String8(apexName).c_str(), &out);
+    if (Status status = mUnifiedServiceManager->getUpdatableNames(String8(apexName).c_str(), &out);
         !status.isOk()) {
         ALOGW("Failed to getUpdatableNames for %s: %s", String8(apexName).c_str(),
               status.toString8().c_str());
@@ -528,7 +514,7 @@
         const String16& name) {
     std::optional<os::ConnectionInfo> connectionInfo;
     if (Status status =
-                mTheRealServiceManager->getConnectionInfo(String8(name).c_str(), &connectionInfo);
+                mUnifiedServiceManager->getConnectionInfo(String8(name).c_str(), &connectionInfo);
         !status.isOk()) {
         ALOGW("Failed to get ConnectionInfo for %s: %s", String8(name).c_str(),
               status.toString8().c_str());
@@ -549,7 +535,7 @@
     sp<RegistrationWaiter> registrationWaiter = sp<RegistrationWaiter>::make(cb);
     std::lock_guard<std::mutex> lock(mNameToRegistrationLock);
     if (Status status =
-                mTheRealServiceManager->registerForNotifications(nameStr, registrationWaiter);
+                mUnifiedServiceManager->registerForNotifications(nameStr, registrationWaiter);
         !status.isOk()) {
         ALOGW("Failed to registerForNotifications for %s: %s", nameStr.c_str(),
               status.toString8().c_str());
@@ -600,7 +586,7 @@
         ALOGE("%s Callback passed wasn't used to register for notifications", __FUNCTION__);
         return BAD_VALUE;
     }
-    if (Status status = mTheRealServiceManager->unregisterForNotifications(String8(name).c_str(),
+    if (Status status = mUnifiedServiceManager->unregisterForNotifications(String8(name).c_str(),
                                                                            registrationWaiter);
         !status.isOk()) {
         ALOGW("Failed to get service manager to unregisterForNotifications for %s: %s",
@@ -613,7 +599,7 @@
 std::vector<IServiceManager::ServiceDebugInfo> ServiceManagerShim::getServiceDebugInfo() {
     std::vector<os::ServiceDebugInfo> serviceDebugInfos;
     std::vector<IServiceManager::ServiceDebugInfo> ret;
-    if (Status status = mTheRealServiceManager->getServiceDebugInfo(&serviceDebugInfos);
+    if (Status status = mUnifiedServiceManager->getServiceDebugInfo(&serviceDebugInfos);
         !status.isOk()) {
         ALOGW("%s Failed to get ServiceDebugInfo", __FUNCTION__);
         return ret;
diff --git a/libs/binder/IServiceManagerFFI.cpp b/libs/binder/IServiceManagerFFI.cpp
new file mode 100644
index 0000000..7d4d7dc
--- /dev/null
+++ b/libs/binder/IServiceManagerFFI.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 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/os/IServiceManager.h>
+
+#include <BackendUnifiedServiceManager.h>
+#include <binder/IServiceManagerFFI.h>
+
+namespace android::impl {
+sp<android::os::IServiceManager>
+getJavaServicemanagerImplPrivateDoNotUseExceptInTheOnePlaceItIsUsed() {
+    return getBackendUnifiedServiceManager();
+}
+
+} // namespace android::impl
diff --git a/libs/binder/IShellCallback.cpp b/libs/binder/IShellCallback.cpp
index 86dd5c4..1d6852a 100644
--- a/libs/binder/IShellCallback.cpp
+++ b/libs/binder/IShellCallback.cpp
@@ -21,7 +21,6 @@
 
 #include <binder/IShellCallback.h>
 
-#include <utils/Log.h>
 #include <binder/Parcel.h>
 #include <utils/String8.h>
 
diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp
index 7644806..0f0af0b 100644
--- a/libs/binder/LazyServiceRegistrar.cpp
+++ b/libs/binder/LazyServiceRegistrar.cpp
@@ -14,15 +14,13 @@
  * limitations under the License.
  */
 
-#include "log/log_main.h"
 #define LOG_TAG "AidlLazyServiceRegistrar"
 
-#include <binder/LazyServiceRegistrar.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
 #include <android/os/BnClientCallback.h>
 #include <android/os/IServiceManager.h>
-#include <utils/Log.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/LazyServiceRegistrar.h>
 
 namespace android {
 namespace binder {
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 3f70e8c..e8fe555 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1585,10 +1585,15 @@
             fdVariant = borrowed_fd(fd);
         }
         if (!mAllowFds) {
+            ALOGE("FDs are not allowed in this parcel. Both the service and the client must set "
+                  "the FileDescriptorTransportMode and agree on the support.");
             return FDS_NOT_ALLOWED;
         }
         switch (rpcFields->mSession->getFileDescriptorTransportMode()) {
             case RpcSession::FileDescriptorTransportMode::NONE: {
+                ALOGE("FDs are not allowed in this RpcSession. Both the service and the client "
+                      "must set "
+                      "the FileDescriptorTransportMode and agree on the support.");
                 return FDS_NOT_ALLOWED;
             }
             case RpcSession::FileDescriptorTransportMode::UNIX:
diff --git a/libs/binder/PermissionController.cpp b/libs/binder/PermissionController.cpp
index 0c89245..c11eb7d 100644
--- a/libs/binder/PermissionController.cpp
+++ b/libs/binder/PermissionController.cpp
@@ -19,10 +19,10 @@
 #include <binder/Binder.h>
 #include <binder/IServiceManager.h>
 
-#include <utils/SystemClock.h>
-
 namespace android {
 
+using namespace std::chrono_literals;
+
 PermissionController::PermissionController()
 {
 }
@@ -30,16 +30,16 @@
 sp<IPermissionController> PermissionController::getService()
 {
     std::lock_guard<Mutex> scoped_lock(mLock);
-    int64_t startTime = 0;
+    auto startTime = std::chrono::steady_clock::now().min();
     sp<IPermissionController> service = mService;
     while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) {
         sp<IBinder> binder = defaultServiceManager()->checkService(String16("permission"));
         if (binder == nullptr) {
             // Wait for the activity service to come back...
-            if (startTime == 0) {
-                startTime = uptimeMillis();
+            if (startTime == startTime.min()) {
+                startTime = std::chrono::steady_clock::now();
                 ALOGI("Waiting for permission service");
-            } else if ((uptimeMillis() - startTime) > 10000) {
+            } else if (std::chrono::steady_clock::now() - startTime > 10s) {
                 ALOGW("Waiting too long for permission service, giving up");
                 service = nullptr;
                 break;
diff --git a/libs/binder/PersistableBundle.cpp b/libs/binder/PersistableBundle.cpp
index 5b157cc..abb6612 100644
--- a/libs/binder/PersistableBundle.cpp
+++ b/libs/binder/PersistableBundle.cpp
@@ -113,7 +113,7 @@
     // Backpatch length. This length value includes the length header.
     parcel->setDataPosition(length_pos);
     size_t length = end_pos - start_pos;
-    if (length > std::numeric_limits<int32_t>::max()) {
+    if (length > static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
         ALOGE("Parcel length (%zu) too large to store in 32-bit signed int", length);
         return BAD_VALUE;
     }
@@ -319,7 +319,7 @@
      * pairs themselves.
      */
     size_t num_entries = size();
-    if (num_entries > std::numeric_limits<int32_t>::max()) {
+    if (num_entries > static_cast<size_t>(std::numeric_limits<int32_t>::max())) {
         ALOGE("The size of this PersistableBundle (%zu) too large to store in 32-bit signed int",
               num_entries);
         return BAD_VALUE;
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 8485ecd..a42ede2 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -26,7 +26,6 @@
 #include <binder/Stability.h>
 #include <cutils/atomic.h>
 #include <utils/AndroidThreads.h>
-#include <utils/Log.h>
 #include <utils/String8.h>
 #include <utils/Thread.h>
 
@@ -407,9 +406,7 @@
         ALOGV("Spawning new pooled thread, name=%s\n", name.c_str());
         sp<Thread> t = sp<PoolThread>::make(isMain);
         t->run(name.c_str());
-        pthread_mutex_lock(&mThreadCountLock);
         mKernelStartedThreads++;
-        pthread_mutex_unlock(&mThreadCountLock);
     }
     // TODO: if startThreadPool is called on another thread after the process
     // starts up, the kernel might think that it already requested those
@@ -432,19 +429,19 @@
 }
 
 size_t ProcessState::getThreadPoolMaxTotalThreadCount() const {
-    pthread_mutex_lock(&mThreadCountLock);
-    auto detachGuard = make_scope_guard([&]() { pthread_mutex_unlock(&mThreadCountLock); });
-
     if (mThreadPoolStarted) {
-        LOG_ALWAYS_FATAL_IF(mKernelStartedThreads > mMaxThreads + 1,
-                            "too many kernel-started threads: %zu > %zu + 1", mKernelStartedThreads,
-                            mMaxThreads);
+        size_t kernelStarted = mKernelStartedThreads;
+        size_t max = mMaxThreads;
+        size_t current = mCurrentThreads;
+
+        LOG_ALWAYS_FATAL_IF(kernelStarted > max + 1,
+                            "too many kernel-started threads: %zu > %zu + 1", kernelStarted, max);
 
         // calling startThreadPool starts a thread
         size_t threads = 1;
 
         // the kernel is configured to start up to mMaxThreads more threads
-        threads += mMaxThreads;
+        threads += max;
 
         // Users may call IPCThreadState::joinThreadPool directly. We don't
         // currently have a way to count this directly (it could be added by
@@ -454,8 +451,8 @@
         // in IPCThreadState, temporarily forget about the extra join threads.
         // This is okay, because most callers of this method only care about
         // having 0, 1, or more threads.
-        if (mCurrentThreads > mKernelStartedThreads) {
-            threads += mCurrentThreads - mKernelStartedThreads;
+        if (current > kernelStarted) {
+            threads += current - kernelStarted;
         }
 
         return threads;
@@ -463,10 +460,9 @@
 
     // must not be initialized or maybe has poll thread setup, we
     // currently don't track this in libbinder
-    LOG_ALWAYS_FATAL_IF(mKernelStartedThreads != 0,
-                        "Expecting 0 kernel started threads but have"
-                        " %zu",
-                        mKernelStartedThreads);
+    size_t kernelStarted = mKernelStartedThreads;
+    LOG_ALWAYS_FATAL_IF(kernelStarted != 0, "Expecting 0 kernel started threads but have %zu",
+                        kernelStarted);
     return mCurrentThreads;
 }
 
@@ -554,14 +550,11 @@
       : 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),
         mCurrentThreads(0),
         mKernelStartedThreads(0),
-        mStarvationStartTimeMs(0),
+        mStarvationStartTime(never()),
         mForked(false),
         mThreadPoolStarted(false),
         mThreadPoolSeq(1),
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index d9e926a..b8742af 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -71,8 +71,23 @@
     return setupSocketServer(UnixSocketAddress(path));
 }
 
-status_t RpcServer::setupVsockServer(unsigned int bindCid, unsigned int port) {
-    return setupSocketServer(VsockSocketAddress(bindCid, port));
+status_t RpcServer::setupVsockServer(unsigned bindCid, unsigned port, unsigned* assignedPort) {
+    auto status = setupSocketServer(VsockSocketAddress(bindCid, port));
+    if (status != OK) return status;
+
+    if (assignedPort == nullptr) return OK;
+    sockaddr_vm addr;
+    socklen_t len = sizeof(addr);
+    if (0 != getsockname(mServer.fd.get(), reinterpret_cast<sockaddr*>(&addr), &len)) {
+        status = -errno;
+        ALOGE("setupVsockServer: Failed to getsockname: %s", strerror(-status));
+        return status;
+    }
+
+    LOG_ALWAYS_FATAL_IF(len != sizeof(addr), "Wrong socket type: len %zu vs len %zu",
+                        static_cast<size_t>(len), sizeof(addr));
+    *assignedPort = addr.svm_port;
+    return OK;
 }
 
 status_t RpcServer::setupInetServer(const char* address, unsigned int port,
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 16a7f9f..49def82 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -801,6 +801,14 @@
     return true;
 }
 
+void RpcSession::setSessionSpecificRoot(const sp<IBinder>& sessionSpecificRoot) {
+    LOG_ALWAYS_FATAL_IF(mSessionSpecificRootObject != nullptr,
+                        "Session specific root object already set");
+    LOG_ALWAYS_FATAL_IF(mForServer != nullptr,
+                        "Session specific root object cannot be set for a server");
+    mSessionSpecificRootObject = sessionSpecificRoot;
+}
+
 sp<RpcSession::RpcConnection> RpcSession::assignIncomingConnectionToThisThread(
         std::unique_ptr<RpcTransport> rpcTransport) {
     RpcMutexLockGuard _l(mMutex);
diff --git a/libs/binder/TEST_MAPPING b/libs/binder/TEST_MAPPING
index 2b3ff44..1256173 100644
--- a/libs/binder/TEST_MAPPING
+++ b/libs/binder/TEST_MAPPING
@@ -129,6 +129,12 @@
       "name": "memunreachable_binder_test"
     }
   ],
+  "postsubmit": [
+    {
+      "name": "binder_sdk_test",
+      "host": true
+    }
+  ],
   "imports": [
     {
       "path": "packages/modules/Virtualization"
diff --git a/libs/binder/Utils.h b/libs/binder/Utils.h
index df8a4ce..881cdf3 100644
--- a/libs/binder/Utils.h
+++ b/libs/binder/Utils.h
@@ -18,6 +18,7 @@
 
 #include <stddef.h>
 #include <sys/uio.h>
+#include <chrono>
 #include <cstdint>
 #include <optional>
 
@@ -57,6 +58,19 @@
         }                                       \
     } while (0)
 
+#define LIBBINDER_PRAGMA(arg) _Pragma(#arg)
+#if defined(__clang__)
+#define LIBBINDER_PRAGMA_FOR_COMPILER(arg) LIBBINDER_PRAGMA(clang arg)
+#elif defined(__GNUC__)
+#define LIBBINDER_PRAGMA_FOR_COMPILER(arg) LIBBINDER_PRAGMA(GCC arg)
+#else
+#define LIBBINDER_PRAGMA_FOR_COMPILER(arg)
+#endif
+#define LIBBINDER_IGNORE(warning_flag)             \
+    LIBBINDER_PRAGMA_FOR_COMPILER(diagnostic push) \
+    LIBBINDER_PRAGMA_FOR_COMPILER(diagnostic ignored warning_flag)
+#define LIBBINDER_IGNORE_END() LIBBINDER_PRAGMA_FOR_COMPILER(diagnostic pop)
+
 namespace android {
 
 /**
@@ -114,4 +128,10 @@
 // Android is little-endian.
 LIBBINDER_INTERNAL_EXPORTED std::string HexString(const void* bytes, size_t len);
 
+// Converts any std::chrono duration to the number of milliseconds
+template <class Rep, class Period>
+uint64_t to_ms(std::chrono::duration<Rep, Period> duration) {
+    return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
+}
+
 }   // namespace android
diff --git a/libs/binder/aidl/android/os/IAccessor.aidl b/libs/binder/aidl/android/os/IAccessor.aidl
new file mode 100644
index 0000000..a3134a3
--- /dev/null
+++ b/libs/binder/aidl/android/os/IAccessor.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 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;
+
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Interface for accessing the RPC server of a service.
+ *
+ * @hide
+ */
+interface IAccessor {
+    /**
+     * Adds a connection to the RPC server of the service managed by the IAccessor.
+     *
+     * This method can be called multiple times to establish multiple distinct
+     * connections to the same RPC server.
+     *
+     * @return A file descriptor connected to the RPC session of the service managed
+     *         by IAccessor.
+     */
+    ParcelFileDescriptor addConnection();
+
+    // TODO(b/350941051): Add API for debugging.
+}
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 0fb1615..ac95188 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -18,6 +18,7 @@
 
 import android.os.IClientCallback;
 import android.os.IServiceCallback;
+import android.os.Service;
 import android.os.ServiceDebugInfo;
 import android.os.ConnectionInfo;
 
@@ -61,7 +62,7 @@
      * Returns null if the service does not exist.
      */
     @UnsupportedAppUsage
-    @nullable IBinder getService(@utf8InCpp String name);
+    Service getService(@utf8InCpp String name);
 
     /**
      * Retrieve an existing service called @a name from the service
@@ -69,7 +70,7 @@
      * exist.
      */
     @UnsupportedAppUsage
-    @nullable IBinder checkService(@utf8InCpp String name);
+    Service checkService(@utf8InCpp String name);
 
     /**
      * Place a new @a service called @a name into the service
diff --git a/libs/tracing_perfetto/include/trace_result.h b/libs/binder/aidl/android/os/Service.aidl
similarity index 64%
copy from libs/tracing_perfetto/include/trace_result.h
copy to libs/binder/aidl/android/os/Service.aidl
index f7581fc..4c52109 100644
--- a/libs/tracing_perfetto/include/trace_result.h
+++ b/libs/binder/aidl/android/os/Service.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -14,17 +14,15 @@
  * limitations under the License.
  */
 
-#ifndef TRACE_RESULT_H
-#define TRACE_RESULT_H
+package android.os;
 
-namespace tracing_perfetto {
-
-enum class Result {
-  SUCCESS,
-  NOT_SUPPORTED,
-  INVALID_INPUT,
-};
-
-}
-
-#endif  // TRACE_RESULT_H
+/**
+ * Service is a union of different service types that can be returned
+ * by the internal {@link ServiceManager#getService(name)} API.
+ *
+ * @hide
+ */
+union Service {
+    @nullable IBinder binder;
+    @nullable IBinder accessor;
+}
\ No newline at end of file
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 8ac30ba..d7f74c4 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -176,10 +176,10 @@
     BpBinder(BinderHandle&& handle, int32_t trackedUid);
     explicit BpBinder(RpcHandle&& handle);
 
-    virtual             ~BpBinder();
-    virtual void        onFirstRef();
-    virtual void        onLastStrongRef(const void* id);
-    virtual bool        onIncStrongAttempted(uint32_t flags, const void* id);
+    virtual ~BpBinder();
+    virtual void onFirstRef();
+    virtual void onLastStrongRef(const void* id);
+    virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
 
     friend ::android::internal::Stability;
 
@@ -192,30 +192,30 @@
         uint32_t flags;
     };
 
-            void                reportOneDeath(const Obituary& obit);
-            bool                isDescriptorCached() const;
+    void reportOneDeath(const Obituary& obit);
+    bool isDescriptorCached() const;
 
-    mutable RpcMutex            mLock;
-            volatile int32_t    mAlive;
-            volatile int32_t    mObitsSent;
-            Vector<Obituary>*   mObituaries;
-            ObjectManager       mObjects;
-    mutable String16            mDescriptorCache;
-            int32_t             mTrackedUid;
+    mutable RpcMutex mLock;
+    volatile int32_t mAlive;
+    volatile int32_t mObitsSent;
+    Vector<Obituary>* mObituaries;
+    ObjectManager mObjects;
+    mutable String16 mDescriptorCache;
+    int32_t mTrackedUid;
 
-    static RpcMutex                             sTrackingLock;
-    static std::unordered_map<int32_t,uint32_t> sTrackingMap;
-    static int                                  sNumTrackedUids;
-    static std::atomic_bool                     sCountByUidEnabled;
-    static binder_proxy_limit_callback          sLimitCallback;
-    static uint32_t                             sBinderProxyCountHighWatermark;
-    static uint32_t                             sBinderProxyCountLowWatermark;
-    static bool                                 sBinderProxyThrottleCreate;
-    static std::unordered_map<int32_t,uint32_t> sLastLimitCallbackMap;
-    static std::atomic<uint32_t>                sBinderProxyCount;
-    static std::atomic<uint32_t>                sBinderProxyCountWarned;
-    static binder_proxy_warning_callback        sWarningCallback;
-    static uint32_t                             sBinderProxyCountWarningWatermark;
+    static RpcMutex sTrackingLock;
+    static std::unordered_map<int32_t, uint32_t> sTrackingMap;
+    static int sNumTrackedUids;
+    static std::atomic_bool sCountByUidEnabled;
+    static binder_proxy_limit_callback sLimitCallback;
+    static uint32_t sBinderProxyCountHighWatermark;
+    static uint32_t sBinderProxyCountLowWatermark;
+    static bool sBinderProxyThrottleCreate;
+    static std::unordered_map<int32_t, uint32_t> sLastLimitCallbackMap;
+    static std::atomic<uint32_t> sBinderProxyCount;
+    static std::atomic<uint32_t> sBinderProxyCountWarned;
+    static binder_proxy_warning_callback sWarningCallback;
+    static uint32_t sBinderProxyCountWarningWatermark;
 };
 
 } // namespace android
diff --git a/libs/binder/include/binder/Functional.h b/libs/binder/include/binder/Functional.h
index 08e3b21..e153969 100644
--- a/libs/binder/include/binder/Functional.h
+++ b/libs/binder/include/binder/Functional.h
@@ -17,11 +17,38 @@
 #pragma once
 
 #include <functional>
-#include <memory>
+#include <optional>
 
 namespace android::binder::impl {
 
 template <typename F>
+class scope_guard;
+
+template <typename F>
+scope_guard<F> make_scope_guard(F f);
+
+template <typename F>
+class scope_guard {
+public:
+    inline ~scope_guard() {
+        if (f_.has_value()) std::move(f_.value())();
+    }
+    inline void release() { f_.reset(); }
+
+private:
+    friend scope_guard<F> android::binder::impl::make_scope_guard<>(F);
+
+    inline scope_guard(F&& f) : f_(std::move(f)) {}
+
+    std::optional<F> f_;
+};
+
+template <typename F>
+inline scope_guard<F> make_scope_guard(F f) {
+    return scope_guard<F>(std::move(f));
+}
+
+template <typename F>
 constexpr void assert_small_callable() {
     // While this buffer (std::function::__func::__buf_) is an implementation detail generally not
     // accessible to users, it's a good bet to assume its size to be around 3 pointers.
@@ -32,12 +59,6 @@
                   "Try using std::ref, but make sure lambda lives long enough to be called.");
 }
 
-template <typename F>
-std::unique_ptr<void, std::function<void(void*)>> make_scope_guard(F&& f) {
-    assert_small_callable<decltype(std::bind(f))>();
-    return {reinterpret_cast<void*>(true), std::bind(f)};
-}
-
 template <typename T>
 class SmallFunction : public std::function<T> {
 public:
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index 17248ce..4eb1c08 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -102,6 +102,10 @@
      */
     virtual const String16& getInterfaceDescriptor() const = 0;
 
+    /**
+     * Last known alive status, from last call. May be arbitrarily stale.
+     * May be incorrect if a service returns an incorrect status code.
+     */
     virtual bool            isBinderAlive() const = 0;
     virtual status_t        pingBinder() = 0;
     virtual status_t        dump(int fd, const Vector<String16>& args) = 0;
diff --git a/libs/tracing_perfetto/include/trace_result.h b/libs/binder/include/binder/IServiceManagerFFI.h
similarity index 66%
copy from libs/tracing_perfetto/include/trace_result.h
copy to libs/binder/include/binder/IServiceManagerFFI.h
index f7581fc..7537355 100644
--- a/libs/tracing_perfetto/include/trace_result.h
+++ b/libs/binder/include/binder/IServiceManagerFFI.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -13,18 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#pragma once
 
-#ifndef TRACE_RESULT_H
-#define TRACE_RESULT_H
+#include <android/os/IServiceManager.h>
 
-namespace tracing_perfetto {
+namespace android::impl {
 
-enum class Result {
-  SUCCESS,
-  NOT_SUPPORTED,
-  INVALID_INPUT,
-};
+LIBBINDER_EXPORTED sp<android::os::IServiceManager>
+getJavaServicemanagerImplPrivateDoNotUseExceptInTheOnePlaceItIsUsed();
 
-}
-
-#endif  // TRACE_RESULT_H
+} // namespace android::impl
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index a466638..021bd58 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -23,6 +23,9 @@
 
 #include <pthread.h>
 
+#include <atomic>
+#include <chrono>
+#include <condition_variable>
 #include <mutex>
 
 // ---------------------------------------------------------------------------
@@ -162,22 +165,23 @@
     int mDriverFD;
     void* mVMStart;
 
-    // Protects thread count and wait variables below.
-    mutable pthread_mutex_t mThreadCountLock;
-    // Broadcast whenever mWaitingForThreads > 0
-    pthread_cond_t mThreadCountDecrement;
+    mutable std::mutex mOnThreadAvailableLock;
+    std::condition_variable mOnThreadAvailableCondVar;
+    // Number of threads waiting on `mOnThreadAvailableCondVar`.
+    std::atomic_int64_t mOnThreadAvailableWaiting = 0;
+
     // Number of binder threads current executing a command.
-    size_t mExecutingThreadsCount;
-    // Number of threads calling IPCThreadState::blockUntilThreadAvailable()
-    size_t mWaitingForThreads;
+    std::atomic_size_t mExecutingThreadsCount;
     // Maximum number of lazy threads to be started in the threadpool by the kernel.
-    size_t mMaxThreads;
+    std::atomic_size_t mMaxThreads;
     // Current number of threads inside the thread pool.
-    size_t mCurrentThreads;
+    std::atomic_size_t mCurrentThreads;
     // Current number of pooled threads inside the thread pool.
-    size_t mKernelStartedThreads;
+    std::atomic_size_t mKernelStartedThreads;
     // Time when thread pool was emptied
-    int64_t mStarvationStartTimeMs;
+    std::atomic<std::chrono::steady_clock::time_point> mStarvationStartTime;
+
+    static constexpr auto never = &std::chrono::steady_clock::time_point::min;
 
     mutable std::mutex mLock; // protects everything below.
 
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index abea0fb..c241d31 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -85,9 +85,12 @@
 
     /**
      * Creates an RPC server binding to the given CID at the given port.
+     *
+     * Set |port| to VMADDR_PORT_ANY to pick an ephemeral port. In this case, |assignedPort|
+     * will be set to the picked port number, if it is not null.
      */
-    [[nodiscard]] LIBBINDER_EXPORTED status_t setupVsockServer(unsigned int bindCid,
-                                                               unsigned int port);
+    [[nodiscard]] LIBBINDER_EXPORTED status_t setupVsockServer(unsigned bindCid, unsigned port,
+                                                               unsigned* assignedPort = nullptr);
 
     /**
      * Creates an RPC server at the current port using IPv4.
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index 40102bb..af37bf2 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -220,6 +220,12 @@
     // internal only
     LIBBINDER_EXPORTED const std::unique_ptr<RpcState>& state() { return mRpcBinderState; }
 
+    /**
+     * Sets the session-specific root object. This is the object that will be used to attach
+     * the IAccessor binder to the RpcSession when a binder is set up via accessor.
+     */
+    LIBBINDER_EXPORTED void setSessionSpecificRoot(const sp<IBinder>& sessionSpecificRoot);
+
 private:
     friend sp<RpcSession>;
     friend RpcServer;
diff --git a/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h b/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h
index d570eab..c1d0e9f 100644
--- a/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h
+++ b/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h
@@ -25,14 +25,13 @@
 // Include llndk-versioning.h only for vendor build as it is not available for NDK headers.
 #if defined(__ANDROID_VENDOR__)
 #include <android/llndk-versioning.h>
-#else  // __ANDROID_VENDOR__
-#if defined(API_LEVEL_AT_LEAST)
-// Redefine API_LEVEL_AT_LEAST here to replace the version to __ANDROID_API_FUTURE__ as a workaround
-#undef API_LEVEL_AT_LEAST
-#endif
-// TODO(b/322384429) switch this __ANDROID_API_FUTURE__ to sdk_api_level when V is finalized
+#elif !defined(API_LEVEL_AT_LEAST)
+#if defined(__BIONIC__)
 #define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) \
-    (__builtin_available(android __ANDROID_API_FUTURE__, *))
+    (__builtin_available(android sdk_api_level, *))
+#else
+#define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) (true)
+#endif  // __BIONIC__
 #endif  // __ANDROID_VENDOR__
 
 namespace aidl::android::os {
@@ -267,7 +266,7 @@
         }
     }
 
-    bool getBoolean(const std::string& key, bool* _Nonnull val) {
+    bool getBoolean(const std::string& key, bool* _Nonnull val) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return APersistableBundle_getBoolean(mPBundle, key.c_str(), val);
         } else {
@@ -275,7 +274,7 @@
         }
     }
 
-    bool getInt(const std::string& key, int32_t* _Nonnull val) {
+    bool getInt(const std::string& key, int32_t* _Nonnull val) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return APersistableBundle_getInt(mPBundle, key.c_str(), val);
         } else {
@@ -283,7 +282,7 @@
         }
     }
 
-    bool getLong(const std::string& key, int64_t* _Nonnull val) {
+    bool getLong(const std::string& key, int64_t* _Nonnull val) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return APersistableBundle_getLong(mPBundle, key.c_str(), val);
         } else {
@@ -291,7 +290,7 @@
         }
     }
 
-    bool getDouble(const std::string& key, double* _Nonnull val) {
+    bool getDouble(const std::string& key, double* _Nonnull val) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return APersistableBundle_getDouble(mPBundle, key.c_str(), val);
         } else {
@@ -303,7 +302,7 @@
         return (char*)malloc(bufferSizeBytes);
     }
 
-    bool getString(const std::string& key, std::string* _Nonnull val) {
+    bool getString(const std::string& key, std::string* _Nonnull val) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             char* outString = nullptr;
             bool ret = APersistableBundle_getString(mPBundle, key.c_str(), &outString,
@@ -321,7 +320,7 @@
     bool getVecInternal(int32_t (*_Nonnull getVec)(const APersistableBundle* _Nonnull,
                                                    const char* _Nonnull, T* _Nullable, int32_t),
                         const APersistableBundle* _Nonnull pBundle, const char* _Nonnull key,
-                        std::vector<T>* _Nonnull vec) {
+                        std::vector<T>* _Nonnull vec) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             int32_t bytes = 0;
             // call first with nullptr to get required size in bytes
@@ -343,28 +342,28 @@
         return false;
     }
 
-    bool getBooleanVector(const std::string& key, std::vector<bool>* _Nonnull vec) {
+    bool getBooleanVector(const std::string& key, std::vector<bool>* _Nonnull vec) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getVecInternal<bool>(&APersistableBundle_getBooleanVector, mPBundle, key.c_str(),
                                         vec);
         }
         return false;
     }
-    bool getIntVector(const std::string& key, std::vector<int32_t>* _Nonnull vec) {
+    bool getIntVector(const std::string& key, std::vector<int32_t>* _Nonnull vec) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getVecInternal<int32_t>(&APersistableBundle_getIntVector, mPBundle, key.c_str(),
                                            vec);
         }
         return false;
     }
-    bool getLongVector(const std::string& key, std::vector<int64_t>* _Nonnull vec) {
+    bool getLongVector(const std::string& key, std::vector<int64_t>* _Nonnull vec) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getVecInternal<int64_t>(&APersistableBundle_getLongVector, mPBundle, key.c_str(),
                                            vec);
         }
         return false;
     }
-    bool getDoubleVector(const std::string& key, std::vector<double>* _Nonnull vec) {
+    bool getDoubleVector(const std::string& key, std::vector<double>* _Nonnull vec) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getVecInternal<double>(&APersistableBundle_getDoubleVector, mPBundle,
                                           key.c_str(), vec);
@@ -375,7 +374,7 @@
     // Takes ownership of and frees the char** and its elements.
     // Creates a new set or vector based on the array of char*.
     template <typename T>
-    T moveStringsInternal(char* _Nullable* _Nonnull strings, int32_t bufferSizeBytes) {
+    T moveStringsInternal(char* _Nullable* _Nonnull strings, int32_t bufferSizeBytes) const {
         if (strings && bufferSizeBytes > 0) {
             int32_t num = bufferSizeBytes / sizeof(char*);
             T ret;
@@ -389,7 +388,7 @@
         return T();
     }
 
-    bool getStringVector(const std::string& key, std::vector<std::string>* _Nonnull vec) {
+    bool getStringVector(const std::string& key, std::vector<std::string>* _Nonnull vec) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             int32_t bytes = APersistableBundle_getStringVector(mPBundle, key.c_str(), nullptr, 0,
                                                                &stringAllocator, nullptr);
@@ -406,7 +405,7 @@
         return false;
     }
 
-    bool getPersistableBundle(const std::string& key, PersistableBundle* _Nonnull val) {
+    bool getPersistableBundle(const std::string& key, PersistableBundle* _Nonnull val) const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             APersistableBundle* bundle = nullptr;
             bool ret = APersistableBundle_getPersistableBundle(mPBundle, key.c_str(), &bundle);
@@ -425,7 +424,7 @@
                                              int32_t bufferSizeBytes,
                                              APersistableBundle_stringAllocator stringAllocator,
                                              void* _Nullable),
-            const APersistableBundle* _Nonnull pBundle) {
+            const APersistableBundle* _Nonnull pBundle) const {
         // call first with nullptr to get required size in bytes
         int32_t bytes = getTypedKeys(pBundle, nullptr, 0, &stringAllocator, nullptr);
         if (bytes > 0) {
@@ -438,84 +437,84 @@
         return {};
     }
 
-    std::set<std::string> getBooleanKeys() {
+    std::set<std::string> getBooleanKeys() const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getKeys(&APersistableBundle_getBooleanKeys, mPBundle);
         } else {
             return {};
         }
     }
-    std::set<std::string> getIntKeys() {
+    std::set<std::string> getIntKeys() const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getKeys(&APersistableBundle_getIntKeys, mPBundle);
         } else {
             return {};
         }
     }
-    std::set<std::string> getLongKeys() {
+    std::set<std::string> getLongKeys() const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getKeys(&APersistableBundle_getLongKeys, mPBundle);
         } else {
             return {};
         }
     }
-    std::set<std::string> getDoubleKeys() {
+    std::set<std::string> getDoubleKeys() const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getKeys(&APersistableBundle_getDoubleKeys, mPBundle);
         } else {
             return {};
         }
     }
-    std::set<std::string> getStringKeys() {
+    std::set<std::string> getStringKeys() const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getKeys(&APersistableBundle_getStringKeys, mPBundle);
         } else {
             return {};
         }
     }
-    std::set<std::string> getBooleanVectorKeys() {
+    std::set<std::string> getBooleanVectorKeys() const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getKeys(&APersistableBundle_getBooleanVectorKeys, mPBundle);
         } else {
             return {};
         }
     }
-    std::set<std::string> getIntVectorKeys() {
+    std::set<std::string> getIntVectorKeys() const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getKeys(&APersistableBundle_getIntVectorKeys, mPBundle);
         } else {
             return {};
         }
     }
-    std::set<std::string> getLongVectorKeys() {
+    std::set<std::string> getLongVectorKeys() const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getKeys(&APersistableBundle_getLongVectorKeys, mPBundle);
         } else {
             return {};
         }
     }
-    std::set<std::string> getDoubleVectorKeys() {
+    std::set<std::string> getDoubleVectorKeys() const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getKeys(&APersistableBundle_getDoubleVectorKeys, mPBundle);
         } else {
             return {};
         }
     }
-    std::set<std::string> getStringVectorKeys() {
+    std::set<std::string> getStringVectorKeys() const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getKeys(&APersistableBundle_getStringVectorKeys, mPBundle);
         } else {
             return {};
         }
     }
-    std::set<std::string> getPersistableBundleKeys() {
+    std::set<std::string> getPersistableBundleKeys() const {
         if API_LEVEL_AT_LEAST(__ANDROID_API_V__, 202404) {
             return getKeys(&APersistableBundle_getPersistableBundleKeys, mPBundle);
         } else {
             return {};
         }
     }
-    std::set<std::string> getMonKeys() {
+    std::set<std::string> getMonKeys() const {
         // :P
         return {"c(o,o)b", "c(o,o)b"};
     }
diff --git a/libs/binder/ndk/include_ndk/android/binder_status.h b/libs/binder/ndk/include_ndk/android/binder_status.h
index 14edf2b..e968bac 100644
--- a/libs/binder/ndk/include_ndk/android/binder_status.h
+++ b/libs/binder/ndk/include_ndk/android/binder_status.h
@@ -117,9 +117,9 @@
 };
 
 /**
- * One of the EXCEPTION_* types.
+ * One of the EX_* enumerators.
  *
- * All unrecognized values are coerced into EXCEPTION_TRANSACTION_FAILED.
+ * All unrecognized values are coerced into EX_TRANSACTION_FAILED.
  *
  * These exceptions values are used by the SDK for parcelables. Also see Parcel.java.
  */
diff --git a/libs/binder/ndk/include_ndk/android/persistable_bundle.h b/libs/binder/ndk/include_ndk/android/persistable_bundle.h
index 42ae15a..5e0d4da 100644
--- a/libs/binder/ndk/include_ndk/android/persistable_bundle.h
+++ b/libs/binder/ndk/include_ndk/android/persistable_bundle.h
@@ -29,6 +29,11 @@
 #include <sys/cdefs.h>
 #include <sys/types.h>
 
+#ifndef __clang__
+#define _Nullable
+#define _Nonnull
+#endif
+
 __BEGIN_DECLS
 
 /*
diff --git a/libs/binder/ndk/persistable_bundle.cpp b/libs/binder/ndk/persistable_bundle.cpp
index 9b6877d..afa032e 100644
--- a/libs/binder/ndk/persistable_bundle.cpp
+++ b/libs/binder/ndk/persistable_bundle.cpp
@@ -17,11 +17,12 @@
 #include <android/persistable_bundle.h>
 #include <binder/PersistableBundle.h>
 #include <log/log.h>
-#include <persistable_bundle_internal.h>
 #include <string.h>
 
 #include <set>
 
+#include "persistable_bundle_internal.h"
+
 __BEGIN_DECLS
 
 struct APersistableBundle {
diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp
index 4436dbe..d6ac4ac 100644
--- a/libs/binder/ndk/service_manager.cpp
+++ b/libs/binder/ndk/service_manager.cpp
@@ -18,6 +18,7 @@
 #include <binder/IServiceManager.h>
 #include <binder/LazyServiceRegistrar.h>
 
+#include "../Utils.h"
 #include "ibinder_internal.h"
 #include "status_internal.h"
 
@@ -89,7 +90,9 @@
     }
 
     sp<IServiceManager> sm = defaultServiceManager();
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     sp<IBinder> binder = sm->getService(String16(instance));
+    LIBBINDER_IGNORE_END()
 
     sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(binder);
     AIBinder_incStrong(ret.get());
diff --git a/libs/binder/ndk/tests/Android.bp b/libs/binder/ndk/tests/Android.bp
index 8fb755c..c61a164 100644
--- a/libs/binder/ndk/tests/Android.bp
+++ b/libs/binder/ndk/tests/Android.bp
@@ -34,6 +34,11 @@
     cflags: [
         "-O0",
         "-g",
+        "-Wall",
+        "-Wextra",
+        "-Wextra-semi",
+        "-Werror",
+        "-Winconsistent-missing-override",
     ],
 }
 
diff --git a/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp b/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp
index 43b2cb8..66be94f 100644
--- a/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp
+++ b/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp
@@ -18,8 +18,6 @@
 #include <aidl/BnBinderVendorDoubleLoadTest.h>
 #include <aidl/android/os/IServiceManager.h>
 #include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/strings.h>
 #include <android/binder_ibinder.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
@@ -30,13 +28,9 @@
 #include <binder/Stability.h>
 #include <binder/Status.h>
 #include <gtest/gtest.h>
-
 #include <sys/prctl.h>
 
 using namespace android;
-using ::android::base::EndsWith;
-using ::android::base::GetProperty;
-using ::android::base::Split;
 using ::android::binder::Status;
 using ::android::internal::Stability;
 using ::ndk::ScopedAStatus;
diff --git a/libs/binder/ndk/tests/iface.cpp b/libs/binder/ndk/tests/iface.cpp
index ca92727..08b857f 100644
--- a/libs/binder/ndk/tests/iface.cpp
+++ b/libs/binder/ndk/tests/iface.cpp
@@ -20,6 +20,8 @@
 
 #include <android/binder_auto_utils.h>
 
+#include "../../Utils.h"
+
 using ::android::sp;
 using ::android::wp;
 
@@ -157,10 +159,9 @@
 }
 
 sp<IFoo> IFoo::getService(const char* instance, AIBinder** outBinder) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     AIBinder* binder = AServiceManager_getService(instance);  // maybe nullptr
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
     if (binder == nullptr) {
         return nullptr;
     }
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 471ab0c..f518a22 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -34,6 +34,7 @@
 #include <binder/IServiceManager.h>
 #include <binder/IShellCallback.h>
 #include <sys/prctl.h>
+#include <sys/socket.h>
 
 #include <chrono>
 #include <condition_variable>
@@ -41,6 +42,7 @@
 #include <mutex>
 #include <thread>
 
+#include "../Utils.h"
 #include "android/binder_ibinder.h"
 
 using namespace android;
@@ -68,21 +70,21 @@
 };
 
 class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest {
-    ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) {
+    ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) override {
         *out = in;
         return ndk::ScopedAStatus::ok();
     }
-    ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) {
+    ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) override {
         (void)empty;
         return ndk::ScopedAStatus::ok();
     }
-    ndk::ScopedAStatus forceFlushCommands() {
+    ndk::ScopedAStatus forceFlushCommands() override {
         // warning: this is assuming that libbinder_ndk is using the same copy
         // of libbinder that we are.
         android::IPCThreadState::self()->flushCommands();
         return ndk::ScopedAStatus::ok();
     }
-    ndk::ScopedAStatus getsRequestedSid(bool* out) {
+    ndk::ScopedAStatus getsRequestedSid(bool* out) override {
         const char* sid = AIBinder_getCallingSid();
         std::cout << "Got security context: " << (sid ?: "null") << std::endl;
         *out = sid != nullptr;
@@ -96,11 +98,11 @@
         fsync(out);
         return STATUS_OK;
     }
-    ndk::ScopedAStatus forcePersist(bool persist) {
+    ndk::ScopedAStatus forcePersist(bool persist) override {
         AServiceManager_forceLazyServicesPersist(persist);
         return ndk::ScopedAStatus::ok();
     }
-    ndk::ScopedAStatus setCustomActiveServicesCallback() {
+    ndk::ScopedAStatus setCustomActiveServicesCallback() override {
         AServiceManager_setActiveServicesCallback(activeServicesCallback, this);
         return ndk::ScopedAStatus::ok();
     }
@@ -341,10 +343,9 @@
     // libbinder across processes to the NDK service which doesn't implement
     // shell
     static const sp<android::IServiceManager> sm(android::defaultServiceManager());
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     sp<IBinder> testService = sm->getService(String16(IFoo::kSomeInstanceName));
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
 
     Vector<String16> argsVec;
     EXPECT_EQ(OK, IBinder::shellCommand(testService, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,
@@ -387,10 +388,9 @@
     // checkService on it, since the other process serving it might not be started yet.
     {
         // getService, not waitForService, to take advantage of timeout
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+        LIBBINDER_IGNORE("-Wdeprecated-declarations")
         auto binder = ndk::SpAIBinder(AServiceManager_getService(IFoo::kSomeInstanceName));
-#pragma clang diagnostic pop
+        LIBBINDER_IGNORE_END()
         ASSERT_NE(nullptr, binder.get());
     }
 
@@ -424,7 +424,7 @@
     // At the time of writing this test, there is no good interface guaranteed
     // to be on all devices. Cuttlefish has light, so this will generally test
     // things.
-    EXPECT_EQ(count, hasLight ? 1 : 0);
+    EXPECT_EQ(count, hasLight ? 1u : 0u);
 }
 
 TEST(NdkBinder, GetLazyService) {
@@ -514,7 +514,7 @@
     // may reference other cookie members
 
     (*funcs->onDeath)();
-};
+}
 void LambdaOnUnlink(void* cookie) {
     auto funcs = static_cast<DeathRecipientCookie*>(cookie);
     (*funcs->onUnlink)();
@@ -522,7 +522,7 @@
     // may reference other cookie members
 
     delete funcs;
-};
+}
 TEST(NdkBinder, DeathRecipient) {
     using namespace std::chrono_literals;
 
@@ -700,7 +700,7 @@
 void LambdaOnUnlinkMultiple(void* cookie) {
     auto funcs = static_cast<DeathRecipientCookie*>(cookie);
     (*funcs->onUnlink)();
-};
+}
 
 TEST(NdkBinder, DeathRecipientMultipleLinks) {
     using namespace std::chrono_literals;
@@ -732,7 +732,7 @@
     ndk::ScopedAIBinder_DeathRecipient recipient(AIBinder_DeathRecipient_new(LambdaOnDeath));
     AIBinder_DeathRecipient_setOnUnlinked(recipient.get(), LambdaOnUnlinkMultiple);
 
-    for (int32_t i = 0; i < kNumberOfLinksToDeath; i++) {
+    for (uint32_t i = 0; i < kNumberOfLinksToDeath; i++) {
         EXPECT_EQ(STATUS_OK,
                   AIBinder_linkToDeath(binder.get(), recipient.get(), static_cast<void*>(cookie)));
     }
@@ -744,14 +744,13 @@
     EXPECT_TRUE(unlinkCv.wait_for(lockUnlink, 5s, [&] { return unlinkReceived; }))
             << "countdown: " << countdown;
     EXPECT_TRUE(unlinkReceived);
-    EXPECT_EQ(countdown, 0);
+    EXPECT_EQ(countdown, 0u);
 }
 
 TEST(NdkBinder, RetrieveNonNdkService) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
     ASSERT_NE(nullptr, binder);
     EXPECT_TRUE(AIBinder_isRemote(binder));
     EXPECT_TRUE(AIBinder_isAlive(binder));
@@ -765,10 +764,9 @@
 }
 
 TEST(NdkBinder, LinkToDeath) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
     ASSERT_NE(nullptr, binder);
 
     AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(OnBinderDeath);
@@ -798,10 +796,9 @@
 }
 
 TEST(NdkBinder, SetInheritRtNonLocal) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
     ASSERT_NE(binder, nullptr);
 
     ASSERT_TRUE(AIBinder_isRemote(binder));
@@ -837,14 +834,13 @@
 }
 
 TEST(NdkBinder, EqualityOfRemoteBinderPointer) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     AIBinder* binderA = AServiceManager_getService(kExistingNonNdkService);
     ASSERT_NE(nullptr, binderA);
 
     AIBinder* binderB = AServiceManager_getService(kExistingNonNdkService);
     ASSERT_NE(nullptr, binderB);
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
 
     EXPECT_EQ(binderA, binderB);
 
@@ -858,10 +854,9 @@
 }
 
 TEST(NdkBinder, ABpBinderRefCount) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
     AIBinder_Weak* wBinder = AIBinder_Weak_new(binder);
 
     ASSERT_NE(nullptr, binder);
@@ -884,10 +879,9 @@
 }
 
 TEST(NdkBinder, RequestedSidWorks) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
     std::shared_ptr<aidl::IBinderNdkUnitTest> service =
             aidl::IBinderNdkUnitTest::fromBinder(binder);
 
@@ -910,10 +904,9 @@
 
     std::shared_ptr<MyEmpty> empty = ndk::SharedRefBase::make<MyEmpty>();
 
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
     std::shared_ptr<aidl::IBinderNdkUnitTest> service =
             aidl::IBinderNdkUnitTest::fromBinder(binder);
 
@@ -934,14 +927,11 @@
 }
 
 TEST(NdkBinder, ConvertToPlatformBinder) {
-    for (const ndk::SpAIBinder& binder :
-         {// remote
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-          ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
-#pragma clang diagnostic pop
-          // local
-          ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
+    ndk::SpAIBinder remoteBinder(AServiceManager_getService(kBinderNdkUnitTestService));
+    LIBBINDER_IGNORE_END()
+    auto localBinder = ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder();
+    for (const ndk::SpAIBinder& binder : {remoteBinder, localBinder}) {
         // convert to platform binder
         EXPECT_NE(binder, nullptr);
         sp<IBinder> platformBinder = AIBinder_toPlatformBinder(binder.get());
@@ -970,14 +960,11 @@
 }
 
 TEST(NdkBinder, GetAndVerifyScopedAIBinder_Weak) {
-    for (const ndk::SpAIBinder& binder :
-         {// remote
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-          ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
-#pragma clang diagnostic pop
-          // local
-          ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
+    ndk::SpAIBinder remoteBinder(AServiceManager_getService(kBinderNdkUnitTestService));
+    LIBBINDER_IGNORE_END()
+    auto localBinder = ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder();
+    for (const ndk::SpAIBinder& binder : {remoteBinder, localBinder}) {
         // get a const ScopedAIBinder_Weak and verify promote
         EXPECT_NE(binder.get(), nullptr);
         const ndk::ScopedAIBinder_Weak wkAIBinder =
@@ -994,22 +981,22 @@
 
 class MyResultReceiver : public BnResultReceiver {
    public:
-    Mutex mMutex;
-    Condition mCondition;
+    std::mutex mMutex;
+    std::condition_variable mCondition;
     bool mHaveResult = false;
     int32_t mResult = 0;
 
     virtual void send(int32_t resultCode) {
-        AutoMutex _l(mMutex);
+        std::unique_lock<std::mutex> _l(mMutex);
         mResult = resultCode;
         mHaveResult = true;
-        mCondition.signal();
+        mCondition.notify_one();
     }
 
     int32_t waitForResult() {
-        AutoMutex _l(mMutex);
+        std::unique_lock<std::mutex> _l(mMutex);
         while (!mHaveResult) {
-            mCondition.wait(mMutex);
+            mCondition.wait(_l);
         }
         return mResult;
     }
@@ -1046,7 +1033,7 @@
     sp<MyResultReceiver> resultReceiver = new MyResultReceiver();
 
     Vector<String16> argsVec;
-    for (int i = 0; i < args.size(); i++) {
+    for (size_t i = 0; i < args.size(); i++) {
         argsVec.add(String16(args[i]));
     }
     status_t error = IBinder::shellCommand(unitTestService, inFd[0], outFd[0], errFd[0], argsVec,
@@ -1070,10 +1057,9 @@
 
 TEST(NdkBinder, UseHandleShellCommand) {
     static const sp<android::IServiceManager> sm(android::defaultServiceManager());
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestService));
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
 
     EXPECT_EQ("", shellCmdToString(testService, {}));
     EXPECT_EQ("", shellCmdToString(testService, {"", ""}));
@@ -1083,10 +1069,9 @@
 
 TEST(NdkBinder, FlaggedServiceAccessible) {
     static const sp<android::IServiceManager> sm(android::defaultServiceManager());
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestServiceFlagged));
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
     ASSERT_NE(nullptr, testService);
 }
 
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index e34d31e..9a252b8 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -768,14 +768,14 @@
         $interface:path[$descriptor:expr] {
             native: $native:ident($on_transact:path),
             proxy: $proxy:ident,
-            $(async: $async_interface:ident,)?
+            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
         }
     } => {
         $crate::declare_binder_interface! {
             $interface[$descriptor] {
                 native: $native($on_transact),
                 proxy: $proxy {},
-                $(async: $async_interface,)?
+                $(async: $async_interface $(($try_into_local_async))?,)?
                 stability: $crate::binder_impl::Stability::default(),
             }
         }
@@ -785,7 +785,7 @@
         $interface:path[$descriptor:expr] {
             native: $native:ident($on_transact:path),
             proxy: $proxy:ident,
-            $(async: $async_interface:ident,)?
+            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
             stability: $stability:expr,
         }
     } => {
@@ -793,7 +793,7 @@
             $interface[$descriptor] {
                 native: $native($on_transact),
                 proxy: $proxy {},
-                $(async: $async_interface,)?
+                $(async: $async_interface $(($try_into_local_async))?,)?
                 stability: $stability,
             }
         }
@@ -805,7 +805,7 @@
             proxy: $proxy:ident {
                 $($fname:ident: $fty:ty = $finit:expr),*
             },
-            $(async: $async_interface:ident,)?
+            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
         }
     } => {
         $crate::declare_binder_interface! {
@@ -814,7 +814,7 @@
                 proxy: $proxy {
                     $($fname: $fty = $finit),*
                 },
-                $(async: $async_interface,)?
+                $(async: $async_interface $(($try_into_local_async))?,)?
                 stability: $crate::binder_impl::Stability::default(),
             }
         }
@@ -826,7 +826,7 @@
             proxy: $proxy:ident {
                 $($fname:ident: $fty:ty = $finit:expr),*
             },
-            $(async: $async_interface:ident,)?
+            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
             stability: $stability:expr,
         }
     } => {
@@ -838,7 +838,7 @@
                 proxy: $proxy {
                     $($fname: $fty = $finit),*
                 },
-                $(async: $async_interface,)?
+                $(async: $async_interface $(($try_into_local_async))?,)?
                 stability: $stability,
             }
         }
@@ -854,7 +854,7 @@
                 $($fname:ident: $fty:ty = $finit:expr),*
             },
 
-            $( async: $async_interface:ident, )?
+            $(async: $async_interface:ident $(($try_into_local_async:ident))?,)?
 
             stability: $stability:expr,
         }
@@ -1043,6 +1043,24 @@
                 }
 
                 if ibinder.associate_class(<$native as $crate::binder_impl::Remotable>::get_class()) {
+                    let service: std::result::Result<$crate::binder_impl::Binder<$native>, $crate::StatusCode> =
+                        std::convert::TryFrom::try_from(ibinder.clone());
+                    $(
+                    // This part is only generated if the user of the macro specifies that the
+                    // trait has an `try_into_local_async` implementation.
+                    if let Ok(service) = service {
+                        if let Some(async_service) = $native::$try_into_local_async(service) {
+                            // We were able to associate with our expected class,
+                            // the service is local, and the local service is async.
+                            return Ok(async_service);
+                        }
+                        // The service is local but not async. Fall back to treating it as a
+                        // remote service. This means that calls to this local service have an
+                        // extra performance cost due to serialization, but async handle to
+                        // non-async server is considered a rare case, so this is okay.
+                    }
+                    )?
+                    // Treat service as remote.
                     return Ok($crate::Strong::new(Box::new(<$proxy as $crate::binder_impl::Proxy>::from_binder(ibinder)?)));
                 }
 
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index 15ae56f..5359832 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -182,7 +182,7 @@
         proxy: BpTest {
             x: i32 = 100
         },
-        async: IATest,
+        async: IATest(try_into_local_async),
     }
 }
 
@@ -323,6 +323,14 @@
     }
 }
 
+impl BnTest {
+    fn try_into_local_async<P: binder::BinderAsyncPool + 'static>(
+        me: Binder<BnTest>,
+    ) -> Option<binder::Strong<dyn IATest<P>>> {
+        Some(binder::Strong::new(Box::new(me) as _))
+    }
+}
+
 /// Trivial testing binder interface
 pub trait ITestSameDescriptor: Interface {}
 
@@ -900,6 +908,19 @@
         assert_eq!(service.test().unwrap(), service_name);
     }
 
+    #[tokio::test]
+    async fn reassociate_rust_binder_async() {
+        let service_name = "testing_service";
+        let service_ibinder =
+            BnTest::new_binder(TestService::new(service_name), BinderFeatures::default())
+                .as_binder();
+
+        let service: Strong<dyn IATest<Tokio>> =
+            service_ibinder.into_interface().expect("Could not reassociate the generic ibinder");
+
+        assert_eq!(service.test().await.unwrap(), service_name);
+    }
+
     #[test]
     fn weak_binder_upgrade() {
         let service_name = "testing_service";
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
index 18b178b..201dfbc 100644
--- a/libs/binder/servicedispatcher.cpp
+++ b/libs/binder/servicedispatcher.cpp
@@ -118,13 +118,11 @@
 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 {
+    android::binder::Status getService(const std::string&, android::os::Service*) 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 {
+    android::binder::Status checkService(const std::string&, android::os::Service*) override {
         // We can't send BpBinder for regular binder over RPC.
         return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
     }
diff --git a/libs/binder/tests/BinderRpcTestServerConfig.aidl b/libs/binder/tests/BinderRpcTestServerConfig.aidl
index b2e0ef2..96550bc 100644
--- a/libs/binder/tests/BinderRpcTestServerConfig.aidl
+++ b/libs/binder/tests/BinderRpcTestServerConfig.aidl
@@ -20,7 +20,6 @@
     int socketType;
     int rpcSecurity;
     int serverVersion;
-    int vsockPort;
     int socketFd; // Inherited from the parent process.
     @utf8InCpp String addr;
 }
diff --git a/libs/binder/tests/binderClearBufTest.cpp b/libs/binder/tests/binderClearBufTest.cpp
index 3230a3f..63254cd 100644
--- a/libs/binder/tests/binderClearBufTest.cpp
+++ b/libs/binder/tests/binderClearBufTest.cpp
@@ -75,10 +75,9 @@
 };
 
 TEST(BinderClearBuf, ClearKernelBuffer) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     sp<IBinder> binder = defaultServiceManager()->getService(kServerName);
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
     ASSERT_NE(nullptr, binder);
 
     std::string replyBuffer;
diff --git a/libs/binder/tests/binderDriverInterfaceTest.cpp b/libs/binder/tests/binderDriverInterfaceTest.cpp
index cf23a46..7be4f21 100644
--- a/libs/binder/tests/binderDriverInterfaceTest.cpp
+++ b/libs/binder/tests/binderDriverInterfaceTest.cpp
@@ -19,11 +19,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <binder/IBinder.h>
 #include <gtest/gtest.h>
 #include <linux/android/binder.h>
-#include <binder/IBinder.h>
-#include <sys/mman.h>
 #include <poll.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
 
 #define BINDER_DEV_NAME "/dev/binder"
 
@@ -93,8 +94,9 @@
             ret = ioctl(m_binderFd, cmd, arg);
             EXPECT_EQ(expect_ret, ret);
             if (ret < 0) {
-                if (errno != accept_errno)
+                if (errno != accept_errno) {
                     EXPECT_EQ(expect_errno, errno);
+                }
             }
         }
         void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
@@ -274,12 +276,15 @@
         binderTestIoctl(BINDER_WRITE_READ, &bwr);
     }
     EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed);
-    if (bwr.read_consumed > offsetof(typeof(br), cmd0))
+    if (bwr.read_consumed > offsetof(typeof(br), cmd0)) {
         EXPECT_EQ(BR_NOOP, br.cmd0);
-    if (bwr.read_consumed > offsetof(typeof(br), cmd1))
+    }
+    if (bwr.read_consumed > offsetof(typeof(br), cmd1)) {
         EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
-    if (bwr.read_consumed > offsetof(typeof(br), cmd2))
+    }
+    if (bwr.read_consumed > offsetof(typeof(br), cmd2)) {
         EXPECT_EQ(BR_REPLY, br.cmd2);
+    }
     if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
         EXPECT_EQ(0u, br.arg2.target.ptr);
         EXPECT_EQ(0u, br.arg2.cookie);
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 00406ed..9b1ba01 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -29,7 +29,6 @@
 
 #include <android-base/properties.h>
 #include <android-base/result-gmock.h>
-#include <android-base/strings.h>
 #include <binder/Binder.h>
 #include <binder/BpBinder.h>
 #include <binder/Functional.h>
@@ -48,16 +47,14 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
+#include "../Utils.h"
 #include "../binder_module.h"
 
-#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
-
 using namespace android;
 using namespace android::binder::impl;
 using namespace std::string_literals;
 using namespace std::chrono_literals;
 using android::base::testing::HasValue;
-using android::base::testing::Ok;
 using android::binder::Status;
 using android::binder::unique_fd;
 using testing::ExplainMatchResult;
@@ -218,10 +215,9 @@
 
             sp<IServiceManager> sm = defaultServiceManager();
             //printf("%s: pid %d, get service\n", __func__, m_pid);
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+            LIBBINDER_IGNORE("-Wdeprecated-declarations")
             m_server = sm->getService(binderLibTestServiceName);
-#pragma clang diagnostic pop
+            LIBBINDER_IGNORE_END()
             ASSERT_TRUE(m_server != nullptr);
             //printf("%s: pid %d, get service done\n", __func__, m_pid);
         }
@@ -568,7 +564,7 @@
 
 TEST_F(BinderLibTest, SetError) {
     int32_t testValue[] = { 0, -123, 123 };
-    for (size_t i = 0; i < ARRAY_SIZE(testValue); i++) {
+    for (size_t i = 0; i < countof(testValue); i++) {
         Parcel data, reply;
         data.writeInt32(testValue[i]);
         EXPECT_THAT(m_server->transact(BINDER_LIB_TEST_SET_ERROR_TRANSACTION, data, &reply),
@@ -599,8 +595,8 @@
     Parcel data, reply;
     int32_t serverId[3];
 
-    data.writeInt32(ARRAY_SIZE(serverId));
-    for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
+    data.writeInt32(countof(serverId));
+    for (size_t i = 0; i < countof(serverId); i++) {
         sp<IBinder> server;
         BinderLibTestBundle datai;
 
@@ -618,7 +614,7 @@
     EXPECT_EQ(0, id);
 
     ASSERT_THAT(reply.readInt32(&count), StatusEq(NO_ERROR));
-    EXPECT_EQ(ARRAY_SIZE(serverId), (size_t)count);
+    EXPECT_EQ(countof(serverId), (size_t)count);
 
     for (size_t i = 0; i < (size_t)count; i++) {
         BinderLibTestBundle replyi(&reply);
@@ -638,8 +634,8 @@
     Parcel data, reply;
     int32_t serverId[3];
 
-    data.writeInt32(ARRAY_SIZE(serverId));
-    for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
+    data.writeInt32(countof(serverId));
+    for (size_t i = 0; i < countof(serverId); i++) {
         sp<IBinder> server;
         BinderLibTestBundle datai;
         BinderLibTestBundle datai2;
@@ -664,7 +660,7 @@
     EXPECT_EQ(0, id);
 
     ASSERT_THAT(reply.readInt32(&count), StatusEq(NO_ERROR));
-    EXPECT_EQ(ARRAY_SIZE(serverId), (size_t)count);
+    EXPECT_EQ(countof(serverId), (size_t)count);
 
     for (size_t i = 0; i < (size_t)count; i++) {
         int32_t counti;
@@ -2114,10 +2110,9 @@
         if (index == 0) {
             ret = sm->addService(binderLibTestServiceName, testService);
         } else {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+            LIBBINDER_IGNORE("-Wdeprecated-declarations")
             sp<IBinder> server = sm->getService(binderLibTestServiceName);
-#pragma clang diagnostic pop
+            LIBBINDER_IGNORE_END()
             Parcel data, reply;
             data.writeInt32(index);
             data.writeStrongBinder(testService);
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 19882ea..3efd84f 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -141,11 +141,6 @@
     return ret;
 };
 
-static unsigned int allocateVsockPort() {
-    static unsigned int vsockPort = 34567;
-    return vsockPort++;
-}
-
 static unique_fd initUnixSocket(std::string addr) {
     auto socket_addr = UnixSocketAddress(addr.c_str());
     unique_fd fd(TEMP_FAILURE_RETRY(socket(socket_addr.addr()->sa_family, SOCK_STREAM, AF_UNIX)));
@@ -300,7 +295,6 @@
     serverConfig.socketType = static_cast<int32_t>(socketType);
     serverConfig.rpcSecurity = static_cast<int32_t>(rpcSecurity);
     serverConfig.serverVersion = serverVersion;
-    serverConfig.vsockPort = allocateVsockPort();
     serverConfig.addr = addr;
     serverConfig.socketFd = socketFd.get();
     for (auto mode : options.serverSupportedFileDescriptorTransportModes) {
@@ -379,7 +373,7 @@
                         unique_fd(dup(bootstrapClientFd.get())));
                 break;
             case SocketType::VSOCK:
-                status = session->setupVsockClient(VMADDR_CID_LOCAL, serverConfig.vsockPort);
+                status = session->setupVsockClient(VMADDR_CID_LOCAL, serverInfo.port);
                 break;
             case SocketType::INET:
                 status = session->setupInetClient("127.0.0.1", serverInfo.port);
@@ -1152,8 +1146,6 @@
 #else // BINDER_RPC_TO_TRUSTY_TEST
 bool testSupportVsockLoopback() {
     // We don't need to enable TLS to know if vsock is supported.
-    unsigned int vsockPort = allocateVsockPort();
-
     unique_fd serverFd(
             TEMP_FAILURE_RETRY(socket(AF_VSOCK, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)));
 
@@ -1165,16 +1157,22 @@
 
     sockaddr_vm serverAddr{
             .svm_family = AF_VSOCK,
-            .svm_port = vsockPort,
+            .svm_port = VMADDR_PORT_ANY,
             .svm_cid = VMADDR_CID_ANY,
     };
     int ret = TEMP_FAILURE_RETRY(
             bind(serverFd.get(), reinterpret_cast<sockaddr*>(&serverAddr), sizeof(serverAddr)));
-    LOG_ALWAYS_FATAL_IF(0 != ret, "Could not bind socket to port %u: %s", vsockPort,
+    LOG_ALWAYS_FATAL_IF(0 != ret, "Could not bind socket to port VMADDR_PORT_ANY: %s",
                         strerror(errno));
 
+    socklen_t len = sizeof(serverAddr);
+    ret = getsockname(serverFd.get(), reinterpret_cast<sockaddr*>(&serverAddr), &len);
+    LOG_ALWAYS_FATAL_IF(0 != ret, "Failed to getsockname: %s", strerror(errno));
+    LOG_ALWAYS_FATAL_IF(len < static_cast<socklen_t>(sizeof(serverAddr)),
+                        "getsockname didn't read the full addr struct");
+
     ret = TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/));
-    LOG_ALWAYS_FATAL_IF(0 != ret, "Could not listen socket on port %u: %s", vsockPort,
+    LOG_ALWAYS_FATAL_IF(0 != ret, "Could not listen socket on port %u: %s", serverAddr.svm_port,
                         strerror(errno));
 
     // Try to connect to the server using the VMADDR_CID_LOCAL cid
@@ -1183,13 +1181,13 @@
     // and they return ETIMEDOUT after that.
     unique_fd connectFd(
             TEMP_FAILURE_RETRY(socket(AF_VSOCK, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)));
-    LOG_ALWAYS_FATAL_IF(!connectFd.ok(), "Could not create socket for port %u: %s", vsockPort,
-                        strerror(errno));
+    LOG_ALWAYS_FATAL_IF(!connectFd.ok(), "Could not create socket for port %u: %s",
+                        serverAddr.svm_port, strerror(errno));
 
     bool success = false;
     sockaddr_vm connectAddr{
             .svm_family = AF_VSOCK,
-            .svm_port = vsockPort,
+            .svm_port = serverAddr.svm_port,
             .svm_cid = VMADDR_CID_LOCAL,
     };
     ret = TEMP_FAILURE_RETRY(connect(connectFd.get(), reinterpret_cast<sockaddr*>(&connectAddr),
@@ -1538,8 +1536,9 @@
                     };
                 } break;
                 case SocketType::VSOCK: {
-                    auto port = allocateVsockPort();
-                    auto status = rpcServer->setupVsockServer(VMADDR_CID_LOCAL, port);
+                    unsigned port;
+                    auto status =
+                            rpcServer->setupVsockServer(VMADDR_CID_LOCAL, VMADDR_PORT_ANY, &port);
                     if (status != OK) {
                         return AssertionFailure() << "setupVsockServer: " << statusToString(status);
                     }
diff --git a/libs/binder/tests/binderRpcTestService.cpp b/libs/binder/tests/binderRpcTestService.cpp
index 28125f1..aef9464 100644
--- a/libs/binder/tests/binderRpcTestService.cpp
+++ b/libs/binder/tests/binderRpcTestService.cpp
@@ -143,8 +143,8 @@
             break;
         case SocketType::VSOCK:
             LOG_ALWAYS_FATAL_IF(OK !=
-                                        server->setupVsockServer(VMADDR_CID_LOCAL,
-                                                                 serverConfig.vsockPort),
+                                        server->setupVsockServer(VMADDR_CID_LOCAL, VMADDR_PORT_ANY,
+                                                                 &outPort),
                                 "Need `sudo modprobe vsock_loopback`?");
             break;
         case SocketType::INET: {
diff --git a/libs/binder/tests/binderStabilityTest.cpp b/libs/binder/tests/binderStabilityTest.cpp
index 3d99358..7a8f48e 100644
--- a/libs/binder/tests/binderStabilityTest.cpp
+++ b/libs/binder/tests/binderStabilityTest.cpp
@@ -27,8 +27,9 @@
 
 #include <sys/prctl.h>
 
-#include "aidl/BnBinderStabilityTest.h"
+#include "../Utils.h"
 #include "BnBinderStabilityTest.h"
+#include "aidl/BnBinderStabilityTest.h"
 
 using namespace android;
 using namespace ndk;
@@ -155,10 +156,9 @@
 }
 
 TEST(BinderStability, ForceDowngradeToVendorStability) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     sp<IBinder> serverBinder = android::defaultServiceManager()->getService(kSystemStabilityServer);
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
     auto server = interface_cast<IBinderStabilityTest>(serverBinder);
 
     ASSERT_NE(nullptr, server.get());
@@ -209,10 +209,9 @@
     EXPECT_EQ(connectionInfo, std::nullopt);
 }
 TEST(BinderStability, CantCallVendorBinderInSystemContext) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     sp<IBinder> serverBinder = android::defaultServiceManager()->getService(kSystemStabilityServer);
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
     auto server = interface_cast<IBinderStabilityTest>(serverBinder);
 
     ASSERT_NE(nullptr, server.get());
@@ -316,11 +315,10 @@
 extern "C" void AIBinder_markVendorStability(AIBinder* binder); // <- BAD DO NOT COPY
 
 TEST(BinderStability, NdkCantCallVendorBinderInSystemContext) {
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    LIBBINDER_IGNORE("-Wdeprecated-declarations")
     SpAIBinder binder = SpAIBinder(AServiceManager_getService(
         String8(kSystemStabilityServer).c_str()));
-#pragma clang diagnostic pop
+    LIBBINDER_IGNORE_END()
 
     std::shared_ptr<aidl::IBinderStabilityTest> remoteServer =
         aidl::IBinderStabilityTest::fromBinder(binder);
diff --git a/libs/binder/tests/binder_sdk/Android.bp b/libs/binder/tests/binder_sdk/Android.bp
new file mode 100644
index 0000000..4e884ad
--- /dev/null
+++ b/libs/binder/tests/binder_sdk/Android.bp
@@ -0,0 +1,84 @@
+//
+// Copyright (C) 2024 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"],
+}
+
+sh_test_host {
+    name: "binder_sdk_test",
+    src: "binder_sdk_test.sh",
+    test_suites: ["general-tests"],
+    test_options: {
+        unit_test: false,
+    },
+
+    data: [
+        ":binder_sdk",
+        ":cmake_root",
+    ],
+    data_bins: [
+        "cmake",
+        "ctest",
+    ],
+}
+
+sh_test_host {
+    name: "binder_sdk_docker_test_gcc",
+    src: "binder_sdk_docker_test.sh",
+    test_suites: ["general-tests"],
+    test_options: {
+        unit_test: false,
+    },
+
+    data: [
+        ":binder_sdk",
+        "gcc.Dockerfile",
+    ],
+}
+
+sh_test_host {
+    name: "binder_sdk_docker_test_clang",
+    src: "binder_sdk_docker_test.sh",
+    test_suites: ["general-tests"],
+    test_options: {
+        unit_test: false,
+    },
+
+    data: [
+        ":binder_sdk",
+        "clang.Dockerfile",
+    ],
+}
+
+sh_test_host {
+    name: "binder_sdk_docker_test_gnumake",
+    src: "binder_sdk_docker_test.sh",
+    test_suites: ["general-tests"],
+    test_options: {
+        unit_test: false,
+    },
+
+    data: [
+        ":binder_sdk",
+        "gnumake.Dockerfile",
+    ],
+}
diff --git a/libs/binder/tests/binder_sdk/binder_sdk_docker_test.sh b/libs/binder/tests/binder_sdk/binder_sdk_docker_test.sh
new file mode 100755
index 0000000..9ea8cb3
--- /dev/null
+++ b/libs/binder/tests/binder_sdk/binder_sdk_docker_test.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+#
+# Copyright (C) 2024 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.
+#
+
+set -ex
+
+TEST_NAME="$(basename "$0")"
+DOCKER_TAG="${TEST_NAME}-${RANDOM}${RANDOM}"
+DOCKER_FILE=*.Dockerfile
+DOCKER_RUN_FLAGS=
+
+# Guess if we're running as an Android test or directly
+if [ "$(ls -1 ${DOCKER_FILE} | wc -l)" == "1" ]; then
+    # likely running as `atest binder_sdk_docker_test_XYZ`
+    DOCKER_PATH="$(dirname $(readlink --canonicalize --no-newline binder_sdk.zip))"
+else
+    # likely running directly as `./binder_sdk_docker_test.sh` - provide mode for easy testing
+    RED='\033[1;31m'
+    NO_COLOR='\033[0m'
+
+    if ! modinfo vsock_loopback &>/dev/null ; then
+        echo -e "${RED}Module vsock_loopback is not installed.${NO_COLOR}"
+        exit 1
+    fi
+    if modprobe --dry-run --first-time vsock_loopback &>/dev/null ; then
+        echo "Module vsock_loopback is not loaded. Attempting to load..."
+        if ! sudo modprobe vsock_loopback ; then
+            echo -e "${RED}Module vsock_loopback is not loaded and attempt to load failed.${NO_COLOR}"
+            exit 1
+        fi
+    fi
+
+    DOCKER_RUN_FLAGS="--interactive --tty"
+
+    DOCKER_FILE="$1"
+    if [ ! -f "${DOCKER_FILE}" ]; then
+        echo -e "${RED}Docker file '${DOCKER_FILE}' doesn't exist. Please provide one as an argument.${NO_COLOR}"
+        exit 1
+    fi
+
+    if [ ! -d "${ANDROID_BUILD_TOP}" ]; then
+        echo -e "${RED}ANDROID_BUILD_TOP doesn't exist. Please lunch some target.${NO_COLOR}"
+        exit 1
+    fi
+    ${ANDROID_BUILD_TOP}/build/soong/soong_ui.bash --make-mode binder_sdk
+    BINDER_SDK_ZIP="${ANDROID_BUILD_TOP}/out/soong/.intermediates/frameworks/native/libs/binder/binder_sdk/linux_glibc_x86_64/binder_sdk.zip"
+    DOCKER_PATH="$(dirname $(ls -1 ${BINDER_SDK_ZIP} | head --lines=1))"
+fi
+
+function cleanup {
+    docker rmi --force "${DOCKER_TAG}" 2>/dev/null || true
+}
+trap cleanup EXIT
+
+docker build --force-rm --tag "${DOCKER_TAG}" --file ${DOCKER_FILE} ${DOCKER_PATH}
+docker run ${DOCKER_RUN_FLAGS} --rm "${DOCKER_TAG}"
diff --git a/libs/binder/tests/binder_sdk/binder_sdk_test.sh b/libs/binder/tests/binder_sdk/binder_sdk_test.sh
new file mode 100644
index 0000000..1881ace
--- /dev/null
+++ b/libs/binder/tests/binder_sdk/binder_sdk_test.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+#
+# Copyright (C) 2024 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.
+#
+
+set -ex
+
+RED='\033[1;31m'
+NO_COLOR='\033[0m'
+
+if [ ! -f "binder_sdk.zip" ]; then
+    echo -e "${RED}binder_sdk.zip doesn't exist. Are you running this test through 'atest binder_sdk_test'?${NO_COLOR}"
+    exit 1
+fi
+
+mkdir -p bin
+cp `pwd`/cmake bin/cmake
+cp `pwd`/ctest bin/ctest
+export PATH="`pwd`/bin:$PATH"
+
+WORKDIR=workdir_$RANDOM$RANDOM$RANDOM
+unzip -q -d $WORKDIR binder_sdk.zip
+cd $WORKDIR
+
+cmake .
+make -j
+make test ARGS="--parallel 32 --output-on-failure"
diff --git a/libs/binder/tests/binder_sdk/clang.Dockerfile b/libs/binder/tests/binder_sdk/clang.Dockerfile
new file mode 100644
index 0000000..aa1fec2
--- /dev/null
+++ b/libs/binder/tests/binder_sdk/clang.Dockerfile
@@ -0,0 +1,32 @@
+#
+# Copyright (C) 2024 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.
+#
+
+FROM debian:bookworm
+
+RUN echo 'deb http://deb.debian.org/debian bookworm-backports main' >> /etc/apt/sources.list && \
+    apt-get update -y && \
+    apt-get install -y clang cmake ninja-build unzip
+
+ADD binder_sdk.zip /
+RUN unzip -q -d binder_sdk binder_sdk.zip
+
+WORKDIR /binder_sdk
+RUN CC=clang CXX=clang++ cmake -G Ninja -B build .
+RUN cmake --build build
+
+WORKDIR /binder_sdk/build
+# Alternatively: `ninja test`, but it won't pass parallel argument
+ENTRYPOINT [ "ctest", "--parallel", "32", "--output-on-failure" ]
diff --git a/libs/binder/tests/binder_sdk/gcc.Dockerfile b/libs/binder/tests/binder_sdk/gcc.Dockerfile
new file mode 100644
index 0000000..fb2ee2c
--- /dev/null
+++ b/libs/binder/tests/binder_sdk/gcc.Dockerfile
@@ -0,0 +1,32 @@
+#
+# Copyright (C) 2024 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.
+#
+
+FROM gcc:9
+
+RUN echo 'deb http://deb.debian.org/debian bullseye-backports main' >> /etc/apt/sources.list && \
+    apt-get update -y && \
+    apt-get install -y cmake ninja-build
+
+ADD binder_sdk.zip /
+RUN unzip -q -d binder_sdk binder_sdk.zip
+
+WORKDIR /binder_sdk
+RUN CC=gcc CXX=g++ cmake -G Ninja -B build .
+RUN cmake --build build
+
+WORKDIR /binder_sdk/build
+# Alternatively: `ninja test`, but it won't pass parallel argument
+ENTRYPOINT [ "ctest", "--parallel", "32", "--output-on-failure" ]
diff --git a/libs/binder/tests/binder_sdk/gnumake.Dockerfile b/libs/binder/tests/binder_sdk/gnumake.Dockerfile
new file mode 100644
index 0000000..abe12fb
--- /dev/null
+++ b/libs/binder/tests/binder_sdk/gnumake.Dockerfile
@@ -0,0 +1,30 @@
+#
+# Copyright (C) 2024 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.
+#
+
+FROM gcc:9
+
+RUN echo 'deb http://deb.debian.org/debian bullseye-backports main' >> /etc/apt/sources.list && \
+    apt-get update -y && \
+    apt-get install -y cmake
+
+ADD binder_sdk.zip /
+RUN unzip -q -d binder_sdk binder_sdk.zip
+
+WORKDIR /binder_sdk
+RUN cmake .
+RUN make -j
+
+ENTRYPOINT make test ARGS="--parallel 32 --output-on-failure"
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
index 62b8433..7c19614 100644
--- a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
@@ -111,7 +111,9 @@
                     } else {
                         binder = getRandomBinder(&provider);
                     }
-                    CHECK(OK == p->writeStrongBinder(binder));
+
+                    // may fail if mixing kernel binder and RPC binder
+                    (void) p->writeStrongBinder(binder);
                 },
         });
 
diff --git a/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp b/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp
index a6fd487..bc0d5af 100644
--- a/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp
+++ b/libs/binder/tests/unit_fuzzers/BpBinderFuzz.cpp
@@ -36,7 +36,9 @@
     FuzzedDataProvider fdp(data, size);
 
     std::string addr = std::string(getenv("TMPDIR") ?: "/tmp") + "/binderRpcBenchmark";
-    (void)unlink(addr.c_str());
+    if (0 != unlink(addr.c_str()) && errno != ENOENT) {
+        LOG(WARNING) << "Could not unlink: " << strerror(errno);
+    }
 
     sp<RpcServer> server = RpcServer::make();
 
diff --git a/libs/binder/trusty/binderRpcTest/rules.mk b/libs/binder/trusty/binderRpcTest/rules.mk
index e46ccfb..975f689 100644
--- a/libs/binder/trusty/binderRpcTest/rules.mk
+++ b/libs/binder/trusty/binderRpcTest/rules.mk
@@ -21,7 +21,6 @@
 MANIFEST := $(LOCAL_DIR)/manifest.json
 
 MODULE_SRCS += \
-	$(FMTLIB_DIR)/src/format.cc \
 	$(LIBBINDER_TESTS_DIR)/binderRpcUniversalTests.cpp \
 	$(LIBBINDER_TESTS_DIR)/binderRpcTestCommon.cpp \
 	$(LIBBINDER_TESTS_DIR)/binderRpcTestTrusty.cpp \
diff --git a/libs/binder/trusty/binderRpcTest/service/rules.mk b/libs/binder/trusty/binderRpcTest/service/rules.mk
index 50ae3d2..5d1a51d 100644
--- a/libs/binder/trusty/binderRpcTest/service/rules.mk
+++ b/libs/binder/trusty/binderRpcTest/service/rules.mk
@@ -21,7 +21,6 @@
 MANIFEST := $(LOCAL_DIR)/manifest.json
 
 MODULE_SRCS := \
-	$(FMTLIB_DIR)/src/format.cc \
 	$(LIBBINDER_TESTS_DIR)/binderRpcTestCommon.cpp \
 	$(LIBBINDER_TESTS_DIR)/binderRpcTestServiceTrusty.cpp \
 
diff --git a/libs/binder/trusty/kernel/rules.mk b/libs/binder/trusty/kernel/rules.mk
index 5cbe0af..7caa48c 100644
--- a/libs/binder/trusty/kernel/rules.mk
+++ b/libs/binder/trusty/kernel/rules.mk
@@ -22,7 +22,6 @@
 LIBBASE_DIR := system/libbase
 LIBLOG_STUB_DIR := $(LIBBINDER_DIR)/liblog_stub
 LIBUTILS_BINDER_DIR := system/core/libutils/binder
-FMTLIB_DIR := external/fmtlib
 
 MODULE_SRCS := \
 	$(LOCAL_DIR)/../OS.cpp \
@@ -59,7 +58,6 @@
 	$(LIBBINDER_DIR)/ndk/include_cpp \
 	$(LIBBASE_DIR)/include \
 	$(LIBUTILS_BINDER_DIR)/include \
-	$(FMTLIB_DIR)/include \
 
 GLOBAL_COMPILEFLAGS += \
 	-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION \
diff --git a/libs/binder/trusty/rules.mk b/libs/binder/trusty/rules.mk
index f2f140d..5e38ad0 100644
--- a/libs/binder/trusty/rules.mk
+++ b/libs/binder/trusty/rules.mk
@@ -22,7 +22,6 @@
 LIBBASE_DIR := system/libbase
 LIBLOG_STUB_DIR := $(LIBBINDER_DIR)/liblog_stub
 LIBUTILS_BINDER_DIR := system/core/libutils/binder
-FMTLIB_DIR := external/fmtlib
 
 MODULE_SRCS := \
 	$(LOCAL_DIR)/OS.cpp \
@@ -59,7 +58,6 @@
 	$(LIBBINDER_DIR)/include \
 	$(LIBBASE_DIR)/include \
 	$(LIBUTILS_BINDER_DIR)/include \
-	$(FMTLIB_DIR)/include \
 
 # The android/binder_to_string.h header is shared between libbinder and
 # libbinder_ndk and included by auto-generated AIDL C++ files
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index f4cf11e..a9bd11e 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 #include <set>
+#include <utility>
 
 #include <android-base/file.h>
 #include <android-base/parseint.h>
@@ -115,7 +116,7 @@
 
 /* list of extra hal interfaces to dump containing process during native dumps */
 // This is filled when dumpstate is called.
-static std::set<const std::string> extra_hal_interfaces_to_dump;
+static std::set<std::string> extra_hal_interfaces_to_dump;
 
 static void read_extra_hals_to_dump_from_property() {
     // extra hals to dump are already filled
@@ -129,7 +130,7 @@
         if (trimmed_token.length() == 0) {
             continue;
         }
-        extra_hal_interfaces_to_dump.insert(trimmed_token);
+        extra_hal_interfaces_to_dump.insert(std::move(trimmed_token));
     }
 }
 
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 2547297..1243b21 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -41,6 +41,11 @@
     aconfig_declarations: "libgui_flags",
 }
 
+cc_aconfig_library {
+    name: "libguiflags_no_apex",
+    aconfig_declarations: "libgui_flags",
+}
+
 cc_library_headers {
     name: "libgui_headers",
     vendor_available: true,
@@ -250,6 +255,7 @@
         "BitTube.cpp",
         "BLASTBufferQueue.cpp",
         "BufferItemConsumer.cpp",
+        "BufferReleaseChannel.cpp",
         "Choreographer.cpp",
         "CompositorTiming.cpp",
         "ConsumerBase.cpp",
@@ -332,9 +338,7 @@
 
     header_libs: [
         "jni_headers",
-        "libdvr_headers",
         "libgui_aidl_headers",
-        "libpdx_headers",
     ],
 
     afdo: true,
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 739c3c2..f13d499 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -38,13 +38,17 @@
 #include <private/gui/ComposerService.h>
 #include <private/gui/ComposerServiceAIDL.h>
 
+#include <android-base/stringprintf.h>
 #include <android-base/thread_annotations.h>
+#include <sys/epoll.h>
+#include <sys/eventfd.h>
 #include <chrono>
 
 #include <com_android_graphics_libgui_flags.h>
 
 using namespace com::android::graphics::libgui;
 using namespace std::chrono_literals;
+using android::base::unique_fd;
 
 namespace {
 inline const char* boolToString(bool b) {
@@ -179,8 +183,6 @@
     // explicitly so that dequeueBuffer will block
     mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max());
 
-    // safe default, most producers are expected to override this
-    mProducer->setMaxDequeuedBufferCount(2);
     mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
                                                       GraphicBuffer::USAGE_HW_COMPOSER |
                                                               GraphicBuffer::USAGE_HW_TEXTURE,
@@ -210,6 +212,12 @@
             },
             this);
 
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
+    std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> bufferReleaseConsumer;
+    gui::BufferReleaseChannel::open(mName, bufferReleaseConsumer, mBufferReleaseProducer);
+    mBufferReleaseReader.emplace(std::move(bufferReleaseConsumer));
+#endif
+
     BQA_LOGV("BLASTBufferQueue created");
 }
 
@@ -259,6 +267,9 @@
     if (surfaceControlChanged) {
         t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure,
                    layer_state_t::eEnableBackpressure);
+        if (mBufferReleaseProducer) {
+            t.setBufferReleaseChannel(mSurfaceControl, mBufferReleaseProducer);
+        }
         applyTransaction = true;
     }
     mTransformHint = mSurfaceControl->getTransformHint();
@@ -439,6 +450,21 @@
     BBQ_TRACE();
     releaseBufferCallbackLocked(id, releaseFence, currentMaxAcquiredBufferCount,
                                 false /* fakeRelease */);
+    if (!mBufferReleaseReader) {
+        return;
+    }
+    // Drain the buffer release channel socket
+    while (true) {
+        ReleaseCallbackId releaseCallbackId;
+        sp<Fence> releaseFence;
+        if (status_t status =
+                    mBufferReleaseReader->readNonBlocking(releaseCallbackId, releaseFence);
+            status != OK) {
+            break;
+        }
+        releaseBufferCallbackLocked(releaseCallbackId, releaseFence, std::nullopt,
+                                    false /* fakeRelease */);
+    }
 }
 
 void BLASTBufferQueue::releaseBufferCallbackLocked(
@@ -495,11 +521,11 @@
                                      const sp<Fence>& releaseFence) {
     auto it = mSubmitted.find(callbackId);
     if (it == mSubmitted.end()) {
-        BQA_LOGE("ERROR: releaseBufferCallback without corresponding submitted buffer %s",
-                 callbackId.to_string().c_str());
         return;
     }
     mNumAcquired--;
+    updateDequeueShouldBlockLocked();
+    mBufferReleaseReader->interruptBlockingRead();
     BBQ_TRACE("frame=%" PRIu64, callbackId.framenumber);
     BQA_LOGV("released %s", callbackId.to_string().c_str());
     mBufferItemConsumer->releaseBuffer(it->second, releaseFence);
@@ -564,6 +590,7 @@
 
     auto buffer = bufferItem.mGraphicBuffer;
     mNumFrameAvailable--;
+    updateDequeueShouldBlockLocked();
     BBQ_TRACE("frame=%" PRIu64, bufferItem.mFrameNumber);
 
     if (buffer == nullptr) {
@@ -582,6 +609,7 @@
     }
 
     mNumAcquired++;
+    updateDequeueShouldBlockLocked();
     mLastAcquiredFrameNumber = bufferItem.mFrameNumber;
     ReleaseCallbackId releaseCallbackId(buffer->getId(), mLastAcquiredFrameNumber);
     mSubmitted[releaseCallbackId] = bufferItem;
@@ -708,6 +736,7 @@
         return;
     }
     mNumFrameAvailable--;
+    updateDequeueShouldBlockLocked();
     mBufferItemConsumer->releaseBuffer(bufferItem, bufferItem.mFence);
 }
 
@@ -761,7 +790,9 @@
         }
 
         // add to shadow queue
+        mNumDequeued--;
         mNumFrameAvailable++;
+        updateDequeueShouldBlockLocked();
         if (waitForTransactionCallback && mNumFrameAvailable >= 2) {
             acquireAndReleaseBuffer();
         }
@@ -812,11 +843,21 @@
 void BLASTBufferQueue::onFrameDequeued(const uint64_t bufferId) {
     std::lock_guard _lock{mTimestampMutex};
     mDequeueTimestamps[bufferId] = systemTime();
-};
+    mNumDequeued++;
+}
 
 void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {
-    std::lock_guard _lock{mTimestampMutex};
-    mDequeueTimestamps.erase(bufferId);
+    {
+        std::lock_guard _lock{mTimestampMutex};
+        mDequeueTimestamps.erase(bufferId);
+    }
+
+    {
+        std::lock_guard lock{mMutex};
+        mNumDequeued--;
+        updateDequeueShouldBlockLocked();
+    }
+    mBufferReleaseReader->interruptBlockingRead();
 };
 
 bool BLASTBufferQueue::syncNextTransaction(
@@ -888,6 +929,22 @@
     return mSize != bufferSize;
 }
 
+void BLASTBufferQueue::updateDequeueShouldBlockLocked() {
+    int32_t buffersInUse = mNumDequeued + mNumFrameAvailable + mNumAcquired;
+    int32_t maxBufferCount = std::min(mMaxAcquiredBuffers + mMaxDequeuedBuffers, kMaxBufferCount);
+    bool bufferAvailable = buffersInUse < maxBufferCount;
+    // BLASTBufferQueueProducer should block until a buffer is released if
+    // (1) There are no free buffers available.
+    // (2) We're not in async mode. In async mode, BufferQueueProducer::dequeueBuffer returns
+    //     WOULD_BLOCK instead of blocking when there are no free buffers.
+    // (3) We're not in shared buffer mode. In shared buffer mode, both the producer and consumer
+    //     can access the same buffer simultaneously. BufferQueueProducer::dequeueBuffer returns
+    //     the shared buffer immediately instead of blocking.
+    mDequeueShouldBlock = !(bufferAvailable || mAsyncMode || mSharedBufferMode);
+    ATRACE_INT("Dequeued", mNumDequeued);
+    ATRACE_INT("DequeueShouldBlock", mDequeueShouldBlock);
+}
+
 class BBQSurface : public Surface {
 private:
     std::mutex mMutex;
@@ -1116,24 +1173,58 @@
                                             producerControlledByApp, output);
     }
 
+    status_t disconnect(int api, DisconnectMode mode) override {
+        if (status_t status = BufferQueueProducer::disconnect(api, mode); status != OK) {
+            return status;
+        }
+
+        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+        if (!bbq) {
+            return OK;
+        }
+
+        {
+            std::lock_guard lock{bbq->mMutex};
+            bbq->mNumDequeued = 0;
+            bbq->mNumFrameAvailable = 0;
+            bbq->mNumAcquired = 0;
+            bbq->mSubmitted.clear();
+            bbq->updateDequeueShouldBlockLocked();
+        }
+        bbq->mBufferReleaseReader->interruptBlockingRead();
+
+        return OK;
+    }
+
     // We want to resize the frame history when changing the size of the buffer queue
     status_t setMaxDequeuedBufferCount(int maxDequeuedBufferCount) override {
         int maxBufferCount;
         status_t status = BufferQueueProducer::setMaxDequeuedBufferCount(maxDequeuedBufferCount,
                                                                          &maxBufferCount);
-        // if we can't determine the max buffer count, then just skip growing the history size
-        if (status == OK) {
-            size_t newFrameHistorySize = maxBufferCount + 2; // +2 because triple buffer rendering
-            // optimize away resizing the frame history unless it will grow
-            if (newFrameHistorySize > FrameEventHistory::INITIAL_MAX_FRAME_HISTORY) {
-                sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
-                if (bbq != nullptr) {
-                    ALOGV("increasing frame history size to %zu", newFrameHistorySize);
-                    bbq->resizeFrameEventHistory(newFrameHistorySize);
-                }
-            }
+        if (status != OK) {
+            return status;
         }
-        return status;
+
+        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+        if (!bbq) {
+            return OK;
+        }
+
+        {
+            std::lock_guard lock{bbq->mMutex};
+            bbq->mMaxDequeuedBuffers = maxDequeuedBufferCount;
+            bbq->updateDequeueShouldBlockLocked();
+        }
+        bbq->mBufferReleaseReader->interruptBlockingRead();
+
+        size_t newFrameHistorySize = maxBufferCount + 2; // +2 because triple buffer rendering
+        // optimize away resizing the frame history unless it will grow
+        if (newFrameHistorySize > FrameEventHistory::INITIAL_MAX_FRAME_HISTORY) {
+            ALOGV("increasing frame history size to %zu", newFrameHistorySize);
+            bbq->resizeFrameEventHistory(newFrameHistorySize);
+        }
+
+        return OK;
     }
 
     int query(int what, int* value) override {
@@ -1144,6 +1235,125 @@
         return BufferQueueProducer::query(what, value);
     }
 
+    status_t setAsyncMode(bool asyncMode) override {
+        if (status_t status = BufferQueueProducer::setAsyncMode(asyncMode); status != NO_ERROR) {
+            return status;
+        }
+
+        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+        if (!bbq) {
+            return NO_ERROR;
+        }
+
+        {
+            std::lock_guard lock{bbq->mMutex};
+            bbq->mAsyncMode = asyncMode;
+            bbq->updateDequeueShouldBlockLocked();
+        }
+
+        bbq->mBufferReleaseReader->interruptBlockingRead();
+        return NO_ERROR;
+    }
+
+    status_t setSharedBufferMode(bool sharedBufferMode) override {
+        if (status_t status = BufferQueueProducer::setSharedBufferMode(sharedBufferMode);
+            status != NO_ERROR) {
+            return status;
+        }
+
+        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+        if (!bbq) {
+            return NO_ERROR;
+        }
+
+        {
+            std::lock_guard lock{bbq->mMutex};
+            bbq->mSharedBufferMode = sharedBufferMode;
+            bbq->updateDequeueShouldBlockLocked();
+        }
+
+        bbq->mBufferReleaseReader->interruptBlockingRead();
+        return NO_ERROR;
+    }
+
+    status_t detachBuffer(int slot) override {
+        if (status_t status = BufferQueueProducer::detachBuffer(slot); status != NO_ERROR) {
+            return status;
+        }
+
+        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+        if (!bbq) {
+            return NO_ERROR;
+        }
+
+        {
+            std::lock_guard lock{bbq->mMutex};
+            bbq->mNumDequeued--;
+            bbq->updateDequeueShouldBlockLocked();
+        }
+
+        bbq->mBufferReleaseReader->interruptBlockingRead();
+        return NO_ERROR;
+    }
+
+    // Override dequeueBuffer to block if there are no free buffers.
+    //
+    // Buffer releases are communicated via the BufferReleaseChannel. When dequeueBuffer determines
+    // a free buffer is not available, it blocks on an epoll file descriptor. Epoll is configured to
+    // detect messages on the BufferReleaseChannel's socket and an eventfd. The eventfd is signaled
+    // whenever an event other than a buffer release occurs that may change the number of free
+    // buffers. dequeueBuffer uses epoll in a similar manner as a condition variable by testing for
+    // the availability of a free buffer in a loop, breaking the loop once a free buffer is
+    // available.
+    //
+    // This is an optimization implemented to reduce thread scheduling delays in the previously
+    // existing binder release callback. The binder buffer release callback is still used and there
+    // are no guarantees around order between buffer releases via binder and the
+    // BufferReleaseChannel. If we attempt to a release a buffer here that has already been released
+    // via binder, the release is ignored.
+    status_t dequeueBuffer(int* outSlot, sp<Fence>* outFence, uint32_t width, uint32_t height,
+                           PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
+                           FrameEventHistoryDelta* outTimestamps) {
+        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
+        if (!bbq || !bbq->mBufferReleaseReader) {
+            return BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format,
+                                                      usage, outBufferAge, outTimestamps);
+        }
+
+        if (bbq->mDequeueShouldBlock) {
+            ATRACE_FORMAT("waiting for free buffer");
+            auto maxWaitTime = std::chrono::steady_clock::now() + 1s;
+            do {
+                auto timeout = std::chrono::duration_cast<std::chrono::milliseconds>(
+                        maxWaitTime - std::chrono::steady_clock::now());
+                if (timeout <= 0ms) {
+                    break;
+                }
+
+                ReleaseCallbackId releaseCallbackId;
+                sp<Fence> releaseFence;
+                status_t status = bbq->mBufferReleaseReader->readBlocking(releaseCallbackId,
+                                                                          releaseFence, timeout);
+                if (status == WOULD_BLOCK) {
+                    // readBlocking was interrupted. The loop will test if we have a free buffer.
+                    continue;
+                }
+
+                if (status != OK) {
+                    // An error occurred or readBlocking timed out.
+                    break;
+                }
+
+                std::lock_guard lock{bbq->mMutex};
+                bbq->releaseBufferCallbackLocked(releaseCallbackId, releaseFence, std::nullopt,
+                                                 false);
+            } while (bbq->mDequeueShouldBlock);
+        }
+
+        return BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format, usage,
+                                                  outBufferAge, outTimestamps);
+    }
+
 private:
     const wp<BLASTBufferQueue> mBLASTBufferQueue;
 };
@@ -1173,6 +1383,16 @@
     *outConsumer = consumer;
 }
 
+void BLASTBufferQueue::onFirstRef() {
+    // safe default, most producers are expected to override this
+    //
+    // This is done in onFirstRef instead of BLASTBufferQueue's constructor because
+    // BBQBufferQueueProducer::setMaxDequeuedBufferCount promotes a weak pointer to BLASTBufferQueue
+    // to a strong pointer. If this is done in the constructor, then when the strong pointer goes
+    // out of scope, it's the last reference so BLASTBufferQueue is deleted.
+    mProducer->setMaxDequeuedBufferCount(2);
+}
+
 void BLASTBufferQueue::resizeFrameEventHistory(size_t newSize) {
     // This can be null during creation of the buffer queue, but resizing won't do anything at that
     // point in time, so just ignore. This can go away once the class relationships and lifetimes of
@@ -1222,4 +1442,72 @@
     mTransactionHangCallback = callback;
 }
 
+BLASTBufferQueue::BufferReleaseReader::BufferReleaseReader(
+        std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> endpoint)
+      : mEndpoint(std::move(endpoint)) {
+    mEpollFd = android::base::unique_fd(epoll_create1(0));
+    if (!mEpollFd.ok()) {
+        ALOGE("Failed to create buffer release epoll file descriptor. errno=%d message='%s'", errno,
+              strerror(errno));
+    }
+
+    epoll_event event;
+    event.events = EPOLLIN;
+    event.data.fd = mEndpoint->getFd();
+    if (epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mEndpoint->getFd(), &event) == -1) {
+        ALOGE("Failed to register buffer release consumer file descriptor with epoll. errno=%d "
+              "message='%s'",
+              errno, strerror(errno));
+    }
+
+    mEventFd = android::base::unique_fd(eventfd(0, EFD_NONBLOCK));
+    event.data.fd = mEventFd.get();
+    if (epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mEventFd.get(), &event) == -1) {
+        ALOGE("Failed to register buffer release eventfd with epoll. errno=%d message='%s'", errno,
+              strerror(errno));
+    }
+}
+
+status_t BLASTBufferQueue::BufferReleaseReader::readNonBlocking(ReleaseCallbackId& outId,
+                                                                sp<Fence>& outFence) {
+    std::lock_guard lock{mMutex};
+    return mEndpoint->readReleaseFence(outId, outFence);
+}
+
+status_t BLASTBufferQueue::BufferReleaseReader::readBlocking(ReleaseCallbackId& outId,
+                                                             sp<Fence>& outFence,
+                                                             std::chrono::milliseconds timeout) {
+    epoll_event event;
+    int eventCount = epoll_wait(mEpollFd.get(), &event, 1 /* maxevents */, timeout.count());
+
+    if (eventCount == -1) {
+        ALOGE("epoll_wait error while waiting for buffer release. errno=%d message='%s'", errno,
+              strerror(errno));
+        return UNKNOWN_ERROR;
+    }
+
+    if (eventCount == 0) {
+        return TIMED_OUT;
+    }
+
+    if (event.data.fd == mEventFd.get()) {
+        uint64_t value;
+        if (read(mEventFd.get(), &value, sizeof(uint64_t)) == -1 && errno != EWOULDBLOCK) {
+            ALOGE("error while reading from eventfd. errno=%d message='%s'", errno,
+                  strerror(errno));
+        }
+        return WOULD_BLOCK;
+    }
+
+    std::lock_guard lock{mMutex};
+    return mEndpoint->readReleaseFence(outId, outFence);
+}
+
+void BLASTBufferQueue::BufferReleaseReader::interruptBlockingRead() {
+    uint64_t value = 1;
+    if (write(mEventFd.get(), &value, sizeof(uint64_t)) == -1) {
+        ALOGE("failed to notify dequeue event. errno=%d message='%s'", errno, strerror(errno));
+    }
+}
+
 } // namespace android
diff --git a/libs/gui/BufferReleaseChannel.cpp b/libs/gui/BufferReleaseChannel.cpp
new file mode 100644
index 0000000..183b25a
--- /dev/null
+++ b/libs/gui/BufferReleaseChannel.cpp
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2024 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 "BufferReleaseChannel"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include <errno.h>
+#include <fcntl.h>
+#include <math.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/stringprintf.h>
+#include <android/binder_status.h>
+#include <binder/Parcel.h>
+#include <cutils/properties.h>
+#include <ftl/enum.h>
+#include <log/log.h>
+#include <utils/Trace.h>
+
+#include <gui/TraceUtils.h>
+#include <private/gui/ParcelUtils.h>
+
+#include <gui/BufferReleaseChannel.h>
+
+using android::base::Result;
+
+namespace android::gui {
+
+namespace {
+
+template <typename T>
+static void readAligned(const void*& buffer, size_t& size, T& value) {
+    size -= FlattenableUtils::align<alignof(T)>(buffer);
+    FlattenableUtils::read(buffer, size, value);
+}
+
+template <typename T>
+static void writeAligned(void*& buffer, size_t& size, T value) {
+    size -= FlattenableUtils::align<alignof(T)>(buffer);
+    FlattenableUtils::write(buffer, size, value);
+}
+
+template <typename T>
+static void addAligned(size_t& size, T /* value */) {
+    size = FlattenableUtils::align<sizeof(T)>(size);
+    size += sizeof(T);
+}
+
+template <typename T>
+static inline constexpr uint32_t low32(const T n) {
+    return static_cast<uint32_t>(static_cast<uint64_t>(n));
+}
+
+template <typename T>
+static inline constexpr uint32_t high32(const T n) {
+    return static_cast<uint32_t>(static_cast<uint64_t>(n) >> 32);
+}
+
+template <typename T>
+static inline constexpr T to64(const uint32_t lo, const uint32_t hi) {
+    return static_cast<T>(static_cast<uint64_t>(hi) << 32 | lo);
+}
+
+} // namespace
+
+size_t BufferReleaseChannel::Message::getPodSize() const {
+    size_t size = 0;
+    addAligned(size, low32(releaseCallbackId.bufferId));
+    addAligned(size, high32(releaseCallbackId.bufferId));
+    addAligned(size, low32(releaseCallbackId.framenumber));
+    addAligned(size, high32(releaseCallbackId.framenumber));
+    return size;
+}
+
+size_t BufferReleaseChannel::Message::getFlattenedSize() const {
+    size_t size = releaseFence->getFlattenedSize();
+    size = FlattenableUtils::align<4>(size);
+    size += getPodSize();
+    return size;
+}
+
+status_t BufferReleaseChannel::Message::flatten(void*& buffer, size_t& size, int*& fds,
+                                                size_t& count) const {
+    if (status_t err = releaseFence->flatten(buffer, size, fds, count); err != OK) {
+        return err;
+    }
+    size -= FlattenableUtils::align<4>(buffer);
+
+    // Check we still have enough space
+    if (size < getPodSize()) {
+        return NO_MEMORY;
+    }
+
+    writeAligned(buffer, size, low32(releaseCallbackId.bufferId));
+    writeAligned(buffer, size, high32(releaseCallbackId.bufferId));
+    writeAligned(buffer, size, low32(releaseCallbackId.framenumber));
+    writeAligned(buffer, size, high32(releaseCallbackId.framenumber));
+    return OK;
+}
+
+status_t BufferReleaseChannel::Message::unflatten(void const*& buffer, size_t& size,
+                                                  int const*& fds, size_t& count) {
+    releaseFence = new Fence();
+    if (status_t err = releaseFence->unflatten(buffer, size, fds, count); err != OK) {
+        return err;
+    }
+    size -= FlattenableUtils::align<4>(buffer);
+
+    // Check we still have enough space
+    if (size < getPodSize()) {
+        return OK;
+    }
+
+    uint32_t bufferIdLo = 0, bufferIdHi = 0;
+    uint32_t frameNumberLo = 0, frameNumberHi = 0;
+
+    readAligned(buffer, size, bufferIdLo);
+    readAligned(buffer, size, bufferIdHi);
+    releaseCallbackId.bufferId = to64<int64_t>(bufferIdLo, bufferIdHi);
+    readAligned(buffer, size, frameNumberLo);
+    readAligned(buffer, size, frameNumberHi);
+    releaseCallbackId.framenumber = to64<uint64_t>(frameNumberLo, frameNumberHi);
+
+    return NO_ERROR;
+}
+
+status_t BufferReleaseChannel::ConsumerEndpoint::readReleaseFence(
+        ReleaseCallbackId& outReleaseCallbackId, sp<Fence>& outReleaseFence) {
+    Message releaseBufferMessage;
+    mFlattenedBuffer.resize(releaseBufferMessage.getFlattenedSize());
+    std::array<uint8_t, CMSG_SPACE(sizeof(int))> controlMessageBuffer;
+
+    iovec iov{
+            .iov_base = mFlattenedBuffer.data(),
+            .iov_len = mFlattenedBuffer.size(),
+    };
+
+    msghdr msg{
+            .msg_iov = &iov,
+            .msg_iovlen = 1,
+            .msg_control = controlMessageBuffer.data(),
+            .msg_controllen = controlMessageBuffer.size(),
+    };
+
+    int result;
+    do {
+        result = recvmsg(mFd, &msg, 0);
+    } while (result == -1 && errno == EINTR);
+    if (result == -1) {
+        if (errno == EWOULDBLOCK || errno == EAGAIN) {
+            return WOULD_BLOCK;
+        }
+        ALOGE("Error reading release fence from socket: error %#x (%s)", errno, strerror(errno));
+        return -errno;
+    }
+
+    if (msg.msg_iovlen != 1) {
+        ALOGE("Error reading release fence from socket: bad data length");
+        return UNKNOWN_ERROR;
+    }
+
+    if (msg.msg_controllen % sizeof(int) != 0) {
+        ALOGE("Error reading release fence from socket: bad fd length");
+        return UNKNOWN_ERROR;
+    }
+
+    size_t dataLen = msg.msg_iov->iov_len;
+    const void* data = static_cast<const void*>(msg.msg_iov->iov_base);
+    if (!data) {
+        ALOGE("Error reading release fence from socket: no buffer data");
+        return UNKNOWN_ERROR;
+    }
+
+    size_t fdCount = 0;
+    const int* fdData = nullptr;
+    if (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg)) {
+        fdData = reinterpret_cast<const int*>(CMSG_DATA(cmsg));
+        fdCount = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
+    }
+
+    if (status_t err = releaseBufferMessage.unflatten(data, dataLen, fdData, fdCount); err != OK) {
+        return err;
+    }
+
+    outReleaseCallbackId = releaseBufferMessage.releaseCallbackId;
+    outReleaseFence = std::move(releaseBufferMessage.releaseFence);
+
+    return OK;
+}
+
+int BufferReleaseChannel::ProducerEndpoint::writeReleaseFence(const ReleaseCallbackId& callbackId,
+                                                              const sp<Fence>& fence) {
+    Message releaseBufferMessage(callbackId, fence ? fence : Fence::NO_FENCE);
+    mFlattenedBuffer.resize(releaseBufferMessage.getFlattenedSize());
+    int flattenedFd;
+    {
+        // Make copies of needed items since flatten modifies them, and we don't
+        // want to send anything if there's an error during flatten.
+        void* flattenedBufferPtr = mFlattenedBuffer.data();
+        size_t flattenedBufferSize = mFlattenedBuffer.size();
+        int* flattenedFdPtr = &flattenedFd;
+        size_t flattenedFdCount = 1;
+        if (status_t err = releaseBufferMessage.flatten(flattenedBufferPtr, flattenedBufferSize,
+                                                        flattenedFdPtr, flattenedFdCount);
+            err != OK) {
+            ALOGE("Failed to flatten BufferReleaseChannel message.");
+            return err;
+        }
+    }
+
+    iovec iov{
+            .iov_base = mFlattenedBuffer.data(),
+            .iov_len = mFlattenedBuffer.size(),
+    };
+
+    msghdr msg{
+            .msg_iov = &iov,
+            .msg_iovlen = 1,
+    };
+
+    std::array<uint8_t, CMSG_SPACE(sizeof(int))> controlMessageBuffer;
+    if (fence && fence->isValid()) {
+        msg.msg_control = controlMessageBuffer.data();
+        msg.msg_controllen = controlMessageBuffer.size();
+
+        cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
+        cmsg->cmsg_level = SOL_SOCKET;
+        cmsg->cmsg_type = SCM_RIGHTS;
+        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+        memcpy(CMSG_DATA(cmsg), &flattenedFd, sizeof(int));
+    }
+
+    int result;
+    do {
+        result = sendmsg(mFd, &msg, 0);
+    } while (result == -1 && errno == EINTR);
+    if (result == -1) {
+        ALOGD("Error writing release fence to socket: error %#x (%s)", errno, strerror(errno));
+        return -errno;
+    }
+
+    return OK;
+}
+
+status_t BufferReleaseChannel::ProducerEndpoint::readFromParcel(const android::Parcel* parcel) {
+    if (!parcel) return STATUS_BAD_VALUE;
+    SAFE_PARCEL(parcel->readUtf8FromUtf16, &mName);
+    SAFE_PARCEL(parcel->readUniqueFileDescriptor, &mFd);
+    return STATUS_OK;
+}
+
+status_t BufferReleaseChannel::ProducerEndpoint::writeToParcel(android::Parcel* parcel) const {
+    if (!parcel) return STATUS_BAD_VALUE;
+    SAFE_PARCEL(parcel->writeUtf8AsUtf16, mName);
+    SAFE_PARCEL(parcel->writeUniqueFileDescriptor, mFd);
+    return STATUS_OK;
+}
+
+status_t BufferReleaseChannel::open(std::string name,
+                                    std::unique_ptr<ConsumerEndpoint>& outConsumer,
+                                    std::shared_ptr<ProducerEndpoint>& outProducer) {
+    outConsumer.reset();
+    outProducer.reset();
+
+    int sockets[2];
+    if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets)) {
+        ALOGE("[%s] Failed to create socket pair. errorno=%d message='%s'", name.c_str(), errno,
+              strerror(errno));
+        return -errno;
+    }
+
+    android::base::unique_fd consumerFd(sockets[0]);
+    android::base::unique_fd producerFd(sockets[1]);
+
+    // Socket buffer size.  The default is typically about 128KB, which is much larger than
+    // we really need.  So we make it smaller.  It just needs to be big enough to hold
+    // a few dozen release fences.
+    const int bufferSize = 32 * 1024;
+    if (setsockopt(consumerFd.get(), SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)) ==
+        -1) {
+        ALOGE("[%s] Failed to set consumer socket send buffer size. errno=%d message='%s'",
+              name.c_str(), errno, strerror(errno));
+        return -errno;
+    }
+    if (setsockopt(consumerFd.get(), SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) ==
+        -1) {
+        ALOGE("[%s] Failed to set consumer socket receive buffer size. errno=%d "
+              "message='%s'",
+              name.c_str(), errno, strerror(errno));
+        return -errno;
+    }
+    if (setsockopt(producerFd.get(), SOL_SOCKET, SO_SNDBUF, &bufferSize, sizeof(bufferSize)) ==
+        -1) {
+        ALOGE("[%s] Failed to set producer socket send buffer size. errno=%d message='%s'",
+              name.c_str(), errno, strerror(errno));
+        return -errno;
+    }
+    if (setsockopt(producerFd.get(), SOL_SOCKET, SO_RCVBUF, &bufferSize, sizeof(bufferSize)) ==
+        -1) {
+        ALOGE("[%s] Failed to set producer socket receive buffer size. errno=%d "
+              "message='%s'",
+              name.c_str(), errno, strerror(errno));
+        return -errno;
+    }
+
+    // Configure the consumer socket to be non-blocking.
+    int flags = fcntl(consumerFd.get(), F_GETFL, 0);
+    if (flags == -1) {
+        ALOGE("[%s] Failed to get consumer socket flags. errno=%d message='%s'", name.c_str(),
+              errno, strerror(errno));
+        return -errno;
+    }
+    if (fcntl(consumerFd.get(), F_SETFL, flags | O_NONBLOCK) == -1) {
+        ALOGE("[%s] Failed to set consumer socket to non-blocking mode. errno=%d "
+              "message='%s'",
+              name.c_str(), errno, strerror(errno));
+        return -errno;
+    }
+
+    // Configure a timeout for the producer socket.
+    const timeval timeout{.tv_sec = 1, .tv_usec = 0};
+    if (setsockopt(producerFd.get(), SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeval)) == -1) {
+        ALOGE("[%s] Failed to set producer socket timeout. errno=%d message='%s'", name.c_str(),
+              errno, strerror(errno));
+        return -errno;
+    }
+
+    // Make the consumer read-only
+    if (shutdown(consumerFd.get(), SHUT_WR) == -1) {
+        ALOGE("[%s] Failed to shutdown writing on consumer socket. errno=%d message='%s'",
+              name.c_str(), errno, strerror(errno));
+        return -errno;
+    }
+
+    // Make the producer write-only
+    if (shutdown(producerFd.get(), SHUT_RD) == -1) {
+        ALOGE("[%s] Failed to shutdown reading on producer socket. errno=%d message='%s'",
+              name.c_str(), errno, strerror(errno));
+        return -errno;
+    }
+
+    outConsumer = std::make_unique<ConsumerEndpoint>(name, std::move(consumerFd));
+    outProducer = std::make_shared<ProducerEndpoint>(std::move(name), std::move(producerFd));
+    return STATUS_OK;
+}
+
+} // namespace android::gui
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index f3de96d..c46f9c5 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -15,6 +15,7 @@
  */
 
 #define LOG_TAG "DisplayEventDispatcher"
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #include <cinttypes>
 #include <cstdint>
@@ -23,10 +24,13 @@
 #include <gui/DisplayEventReceiver.h>
 #include <utils/Log.h>
 #include <utils/Looper.h>
-
 #include <utils/Timers.h>
+#include <utils/Trace.h>
+
+#include <com_android_graphics_libgui_flags.h>
 
 namespace android {
+using namespace com::android::graphics::libgui;
 
 // Number of events to read at a time from the DisplayEventDispatcher pipe.
 // The value should be large enough that we can quickly drain the pipe
@@ -171,6 +175,13 @@
                     *outDisplayId = ev.header.displayId;
                     *outCount = ev.vsync.count;
                     *outVsyncEventData = ev.vsync.vsyncData;
+
+                    // Trace the RenderRate for this app
+                    if (ATRACE_ENABLED() && flags::trace_frame_rate_override()) {
+                        const auto frameInterval = ev.vsync.vsyncData.frameInterval;
+                        int fps = frameInterval > 0 ? 1e9f / frameInterval : 0;
+                        ATRACE_INT("RenderRate", fps);
+                    }
                     break;
                 case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
                     if (ev.hotplug.connectionError == 0) {
diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp
index f5d19aa..83fc827 100644
--- a/libs/gui/ITransactionCompletedListener.cpp
+++ b/libs/gui/ITransactionCompletedListener.cpp
@@ -43,12 +43,6 @@
 
 } // Anonymous namespace
 
-namespace { // Anonymous
-
-constexpr int32_t kSerializedCallbackTypeOnCompelteWithJankData = 2;
-
-} // Anonymous namespace
-
 status_t FrameEventHistoryStats::writeToParcel(Parcel* output) const {
     status_t err = output->writeUint64(frameNumber);
     if (err != NO_ERROR) return err;
@@ -119,23 +113,6 @@
     return err;
 }
 
-JankData::JankData()
-      : frameVsyncId(FrameTimelineInfo::INVALID_VSYNC_ID), jankType(JankType::None) {}
-
-status_t JankData::writeToParcel(Parcel* output) const {
-    SAFE_PARCEL(output->writeInt64, frameVsyncId);
-    SAFE_PARCEL(output->writeInt32, jankType);
-    SAFE_PARCEL(output->writeInt64, frameIntervalNs);
-    return NO_ERROR;
-}
-
-status_t JankData::readFromParcel(const Parcel* input) {
-    SAFE_PARCEL(input->readInt64, &frameVsyncId);
-    SAFE_PARCEL(input->readInt32, &jankType);
-    SAFE_PARCEL(input->readInt64, &frameIntervalNs);
-    return NO_ERROR;
-}
-
 status_t SurfaceStats::writeToParcel(Parcel* output) const {
     SAFE_PARCEL(output->writeStrongBinder, surfaceControl);
     if (const auto* acquireFence = std::get_if<sp<Fence>>(&acquireTimeOrFence)) {
@@ -160,10 +137,6 @@
 
     SAFE_PARCEL(output->writeUint32, currentMaxAcquiredBufferCount);
     SAFE_PARCEL(output->writeParcelable, eventStats);
-    SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(jankData.size()));
-    for (const auto& data : jankData) {
-        SAFE_PARCEL(output->writeParcelable, data);
-    }
     SAFE_PARCEL(output->writeParcelable, previousReleaseCallbackId);
     return NO_ERROR;
 }
@@ -200,13 +173,6 @@
     SAFE_PARCEL(input->readUint32, &currentMaxAcquiredBufferCount);
     SAFE_PARCEL(input->readParcelable, &eventStats);
 
-    int32_t jankData_size = 0;
-    SAFE_PARCEL_READ_SIZE(input->readInt32, &jankData_size, input->dataSize());
-    for (int i = 0; i < jankData_size; i++) {
-        JankData data;
-        SAFE_PARCEL(input->readParcelable, &data);
-        jankData.push_back(data);
-    }
     SAFE_PARCEL(input->readParcelable, &previousReleaseCallbackId);
     return NO_ERROR;
 }
@@ -371,11 +337,7 @@
 
 status_t CallbackId::writeToParcel(Parcel* output) const {
     SAFE_PARCEL(output->writeInt64, id);
-    if (type == Type::ON_COMPLETE && includeJankData) {
-        SAFE_PARCEL(output->writeInt32, kSerializedCallbackTypeOnCompelteWithJankData);
-    } else {
-        SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(type));
-    }
+    SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(type));
     return NO_ERROR;
 }
 
@@ -383,13 +345,7 @@
     SAFE_PARCEL(input->readInt64, &id);
     int32_t typeAsInt;
     SAFE_PARCEL(input->readInt32, &typeAsInt);
-    if (typeAsInt == kSerializedCallbackTypeOnCompelteWithJankData) {
-        type = Type::ON_COMPLETE;
-        includeJankData = true;
-    } else {
-        type = static_cast<CallbackId::Type>(typeAsInt);
-        includeJankData = false;
-    }
+    type = static_cast<CallbackId::Type>(typeAsInt);
     return NO_ERROR;
 }
 
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 3745805..adf1646 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -177,6 +177,7 @@
     }
 
     SAFE_PARCEL(output.write, stretchEffect);
+    SAFE_PARCEL(output.writeParcelable, edgeExtensionParameters);
     SAFE_PARCEL(output.write, bufferCrop);
     SAFE_PARCEL(output.write, destinationFrame);
     SAFE_PARCEL(output.writeInt32, static_cast<uint32_t>(trustedOverlay));
@@ -193,6 +194,12 @@
     SAFE_PARCEL(output.writeFloat, currentHdrSdrRatio);
     SAFE_PARCEL(output.writeFloat, desiredHdrSdrRatio);
     SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(cachingHint));
+
+    const bool hasBufferReleaseChannel = (bufferReleaseChannel != nullptr);
+    SAFE_PARCEL(output.writeBool, hasBufferReleaseChannel);
+    if (hasBufferReleaseChannel) {
+        SAFE_PARCEL(output.writeParcelable, *bufferReleaseChannel);
+    }
     return NO_ERROR;
 }
 
@@ -306,6 +313,7 @@
     }
 
     SAFE_PARCEL(input.read, stretchEffect);
+    SAFE_PARCEL(input.readParcelable, &edgeExtensionParameters);
     SAFE_PARCEL(input.read, bufferCrop);
     SAFE_PARCEL(input.read, destinationFrame);
     uint32_t trustedOverlayInt;
@@ -337,6 +345,12 @@
     SAFE_PARCEL(input.readInt32, &tmpInt32);
     cachingHint = static_cast<gui::CachingHint>(tmpInt32);
 
+    bool hasBufferReleaseChannel;
+    SAFE_PARCEL(input.readBool, &hasBufferReleaseChannel);
+    if (hasBufferReleaseChannel) {
+        bufferReleaseChannel = std::make_shared<gui::BufferReleaseChannel::ProducerEndpoint>();
+        SAFE_PARCEL(input.readParcelable, bufferReleaseChannel.get());
+    }
     return NO_ERROR;
 }
 
@@ -682,6 +696,10 @@
         what |= eStretchChanged;
         stretchEffect = other.stretchEffect;
     }
+    if (other.what & eEdgeExtensionChanged) {
+        what |= eEdgeExtensionChanged;
+        edgeExtensionParameters = other.edgeExtensionParameters;
+    }
     if (other.what & eBufferCropChanged) {
         what |= eBufferCropChanged;
         bufferCrop = other.bufferCrop;
@@ -712,6 +730,10 @@
     if (other.what & eFlushJankData) {
         what |= eFlushJankData;
     }
+    if (other.what & eBufferReleaseChannelChanged) {
+        what |= eBufferReleaseChannelChanged;
+        bufferReleaseChannel = other.bufferReleaseChannel;
+    }
     if ((other.what & what) != other.what) {
         ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
               "other.what=0x%" PRIX64 " what=0x%" PRIX64 " unmerged flags=0x%" PRIX64,
@@ -783,6 +805,7 @@
     CHECK_DIFF(diff, eAutoRefreshChanged, other, autoRefresh);
     CHECK_DIFF(diff, eTrustedOverlayChanged, other, trustedOverlay);
     CHECK_DIFF(diff, eStretchChanged, other, stretchEffect);
+    CHECK_DIFF(diff, eEdgeExtensionChanged, other, edgeExtensionParameters);
     CHECK_DIFF(diff, eBufferCropChanged, other, bufferCrop);
     CHECK_DIFF(diff, eDestinationFrameChanged, other, destinationFrame);
     if (other.what & eProducerDisconnect) diff |= eProducerDisconnect;
@@ -790,6 +813,7 @@
     CHECK_DIFF(diff, eColorChanged, other, color.rgb);
     CHECK_DIFF(diff, eColorSpaceAgnosticChanged, other, colorSpaceAgnostic);
     CHECK_DIFF(diff, eDimmingEnabledChanged, other, dimmingEnabled);
+    if (other.what & eBufferReleaseChannelChanged) diff |= eBufferReleaseChannelChanged;
     return diff;
 }
 
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 87fd448..685391e 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -44,8 +44,6 @@
 #include <gui/AidlStatusUtil.h>
 #include <gui/BufferItem.h>
 
-#include <gui/IProducerListener.h>
-
 #include <gui/ISurfaceComposer.h>
 #include <gui/LayerState.h>
 #include <private/gui/ComposerService.h>
@@ -1860,30 +1858,31 @@
 }
 
 int Surface::connect(int api) {
-    static sp<IProducerListener> listener = new StubProducerListener();
+    static sp<SurfaceListener> listener = new StubSurfaceListener();
     return connect(api, listener);
 }
 
-int Surface::connect(int api, const sp<IProducerListener>& listener) {
+int Surface::connect(int api, const sp<SurfaceListener>& listener) {
     return connect(api, listener, false);
 }
 
 int Surface::connect(
         int api, bool reportBufferRemoval, const sp<SurfaceListener>& sListener) {
-    if (sListener != nullptr) {
-        mListenerProxy = new ProducerListenerProxy(this, sListener);
-    }
-    return connect(api, mListenerProxy, reportBufferRemoval);
+    return connect(api, sListener, reportBufferRemoval);
 }
 
-int Surface::connect(
-        int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) {
+int Surface::connect(int api, const sp<SurfaceListener>& listener, bool reportBufferRemoval) {
     ATRACE_CALL();
     ALOGV("Surface::connect");
     Mutex::Autolock lock(mMutex);
     IGraphicBufferProducer::QueueBufferOutput output;
     mReportRemovedBuffers = reportBufferRemoval;
-    int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
+    if (listener != nullptr) {
+        mListenerProxy = new ProducerListenerProxy(this, listener);
+    }
+
+    int err =
+            mGraphicBufferProducer->connect(mListenerProxy, api, mProducerControlledByApp, &output);
     if (err == NO_ERROR) {
         mDefaultWidth = output.width;
         mDefaultHeight = output.height;
@@ -1911,7 +1910,6 @@
     return err;
 }
 
-
 int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) {
     ATRACE_CALL();
     ALOGV("Surface::disconnect");
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 5db5394..cdf57ff 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -20,8 +20,11 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <com_android_graphics_libgui_flags.h>
+
 #include <android/gui/BnWindowInfosReportedListener.h>
 #include <android/gui/DisplayState.h>
+#include <android/gui/EdgeExtensionParameters.h>
 #include <android/gui/ISurfaceComposerClient.h>
 #include <android/gui/IWindowInfosListener.h>
 #include <android/gui/TrustedPresentationThresholds.h>
@@ -86,7 +89,8 @@
     return (((int64_t)getpid()) << 32) | ++idCounter;
 }
 
-void emptyCallback(nsecs_t, const sp<Fence>&, const std::vector<SurfaceControlStats>&) {}
+constexpr int64_t INVALID_VSYNC = -1;
+
 } // namespace
 
 const std::string SurfaceComposerClient::kEmpty{};
@@ -207,9 +211,168 @@
     return DefaultComposerClient::getComposerClient();
 }
 
+// ---------------------------------------------------------------------------
+
 JankDataListener::~JankDataListener() {
 }
 
+status_t JankDataListener::flushJankData() {
+    if (mLayerId == -1) {
+        return INVALID_OPERATION;
+    }
+
+    binder::Status status = ComposerServiceAIDL::getComposerService()->flushJankData(mLayerId);
+    return statusTFromBinderStatus(status);
+}
+
+std::mutex JankDataListenerFanOut::sFanoutInstanceMutex;
+std::unordered_map<int32_t, sp<JankDataListenerFanOut>> JankDataListenerFanOut::sFanoutInstances;
+
+binder::Status JankDataListenerFanOut::onJankData(const std::vector<gui::JankData>& jankData) {
+    // Find the highest VSync ID.
+    int64_t lastVsync = jankData.empty()
+            ? 0
+            : std::max_element(jankData.begin(), jankData.end(),
+                               [](const gui::JankData& jd1, const gui::JankData& jd2) {
+                                   return jd1.frameVsyncId < jd2.frameVsyncId;
+                               })
+                      ->frameVsyncId;
+
+    // Fan out the jank data callback.
+    std::vector<wp<JankDataListener>> listenersToRemove;
+    for (auto listener : getActiveListeners()) {
+        if (!listener->onJankDataAvailable(jankData) ||
+            (listener->mRemoveAfter >= 0 && listener->mRemoveAfter <= lastVsync)) {
+            listenersToRemove.push_back(listener);
+        }
+    }
+
+    return removeListeners(listenersToRemove)
+            ? binder::Status::ok()
+            : binder::Status::fromExceptionCode(binder::Status::EX_NULL_POINTER);
+}
+
+status_t JankDataListenerFanOut::addListener(sp<SurfaceControl> sc, sp<JankDataListener> listener) {
+    sp<IBinder> layer = sc->getHandle();
+    if (layer == nullptr) {
+        return UNEXPECTED_NULL;
+    }
+    int32_t layerId = sc->getLayerId();
+
+    sFanoutInstanceMutex.lock();
+    auto it = sFanoutInstances.find(layerId);
+    bool registerNeeded = it == sFanoutInstances.end();
+    sp<JankDataListenerFanOut> fanout;
+    if (registerNeeded) {
+        fanout = sp<JankDataListenerFanOut>::make(layerId);
+        sFanoutInstances.insert({layerId, fanout});
+    } else {
+        fanout = it->second;
+    }
+
+    fanout->mMutex.lock();
+    fanout->mListeners.insert(listener);
+    fanout->mMutex.unlock();
+
+    sFanoutInstanceMutex.unlock();
+
+    if (registerNeeded) {
+        binder::Status status =
+                ComposerServiceAIDL::getComposerService()->addJankListener(layer, fanout);
+        return statusTFromBinderStatus(status);
+    }
+    return OK;
+}
+
+status_t JankDataListenerFanOut::removeListener(sp<JankDataListener> listener) {
+    int32_t layerId = listener->mLayerId;
+    if (layerId == -1) {
+        return INVALID_OPERATION;
+    }
+
+    int64_t removeAfter = INVALID_VSYNC;
+    sp<JankDataListenerFanOut> fanout;
+
+    sFanoutInstanceMutex.lock();
+    auto it = sFanoutInstances.find(layerId);
+    if (it != sFanoutInstances.end()) {
+        fanout = it->second;
+        removeAfter = fanout->updateAndGetRemovalVSync();
+    }
+
+    if (removeAfter != INVALID_VSYNC) {
+        // Remove this instance from the map, so that no new listeners are added
+        // while we're scheduled to be removed.
+        sFanoutInstances.erase(layerId);
+    }
+    sFanoutInstanceMutex.unlock();
+
+    if (removeAfter < 0) {
+        return OK;
+    }
+
+    binder::Status status =
+            ComposerServiceAIDL::getComposerService()->removeJankListener(layerId, fanout,
+                                                                          removeAfter);
+    return statusTFromBinderStatus(status);
+}
+
+std::vector<sp<JankDataListener>> JankDataListenerFanOut::getActiveListeners() {
+    std::scoped_lock<std::mutex> lock(mMutex);
+
+    std::vector<sp<JankDataListener>> listeners;
+    for (auto it = mListeners.begin(); it != mListeners.end();) {
+        auto listener = it->promote();
+        if (!listener) {
+            it = mListeners.erase(it);
+        } else {
+            listeners.push_back(std::move(listener));
+            it++;
+        }
+    }
+    return listeners;
+}
+
+bool JankDataListenerFanOut::removeListeners(const std::vector<wp<JankDataListener>>& listeners) {
+    std::scoped_lock<std::mutex> fanoutLock(sFanoutInstanceMutex);
+    std::scoped_lock<std::mutex> listenersLock(mMutex);
+
+    for (auto listener : listeners) {
+        mListeners.erase(listener);
+    }
+
+    if (mListeners.empty()) {
+        sFanoutInstances.erase(mLayerId);
+        return false;
+    }
+    return true;
+}
+
+int64_t JankDataListenerFanOut::updateAndGetRemovalVSync() {
+    std::scoped_lock<std::mutex> lock(mMutex);
+    if (mRemoveAfter >= 0) {
+        // We've already been scheduled to be removed. Don't schedule again.
+        return INVALID_VSYNC;
+    }
+
+    int64_t removeAfter = 0;
+    for (auto it = mListeners.begin(); it != mListeners.end();) {
+        auto listener = it->promote();
+        if (!listener) {
+            it = mListeners.erase(it);
+        } else if (listener->mRemoveAfter < 0) {
+            // We have at least one listener that's still interested. Don't remove.
+            return INVALID_VSYNC;
+        } else {
+            removeAfter = std::max(removeAfter, listener->mRemoveAfter);
+            it++;
+        }
+    }
+
+    mRemoveAfter = removeAfter;
+    return removeAfter;
+}
+
 // ---------------------------------------------------------------------------
 
 // TransactionCompletedListener does not use ANDROID_SINGLETON_STATIC_INSTANCE because it needs
@@ -256,14 +419,6 @@
                 surfaceControls,
         CallbackId::Type callbackType) {
     std::lock_guard<std::mutex> lock(mMutex);
-    return addCallbackFunctionLocked(callbackFunction, surfaceControls, callbackType);
-}
-
-CallbackId TransactionCompletedListener::addCallbackFunctionLocked(
-        const TransactionCompletedCallback& callbackFunction,
-        const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>&
-                surfaceControls,
-        CallbackId::Type callbackType) {
     startListeningLocked();
 
     CallbackId callbackId(getNextIdLocked(), callbackType);
@@ -272,33 +427,11 @@
 
     for (const auto& surfaceControl : surfaceControls) {
         callbackSurfaceControls[surfaceControl->getHandle()] = surfaceControl;
-
-        if (callbackType == CallbackId::Type::ON_COMPLETE &&
-            mJankListeners.count(surfaceControl->getLayerId()) != 0) {
-            callbackId.includeJankData = true;
-        }
     }
 
     return callbackId;
 }
 
-void TransactionCompletedListener::addJankListener(const sp<JankDataListener>& listener,
-                                                   sp<SurfaceControl> surfaceControl) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    mJankListeners.insert({surfaceControl->getLayerId(), listener});
-}
-
-void TransactionCompletedListener::removeJankListener(const sp<JankDataListener>& listener) {
-    std::lock_guard<std::mutex> lock(mMutex);
-    for (auto it = mJankListeners.begin(); it != mJankListeners.end();) {
-        if (it->second == listener) {
-            it = mJankListeners.erase(it);
-        } else {
-            it++;
-        }
-    }
-}
-
 void TransactionCompletedListener::setReleaseBufferCallback(const ReleaseCallbackId& callbackId,
                                                             ReleaseBufferCallback listener) {
     std::scoped_lock<std::mutex> lock(mMutex);
@@ -325,32 +458,20 @@
 }
 
 void TransactionCompletedListener::addSurfaceControlToCallbacks(
-        SurfaceComposerClient::CallbackInfo& callbackInfo,
-        const sp<SurfaceControl>& surfaceControl) {
+        const sp<SurfaceControl>& surfaceControl,
+        const std::unordered_set<CallbackId, CallbackIdHash>& callbackIds) {
     std::lock_guard<std::mutex> lock(mMutex);
 
-    bool includingJankData = false;
-    for (auto callbackId : callbackInfo.callbackIds) {
+    for (auto callbackId : callbackIds) {
         mCallbacks[callbackId].surfaceControls.emplace(std::piecewise_construct,
                                                        std::forward_as_tuple(
                                                                surfaceControl->getHandle()),
                                                        std::forward_as_tuple(surfaceControl));
-        includingJankData = includingJankData || callbackId.includeJankData;
-    }
-
-    // If no registered callback is requesting jank data, but there is a jank listener registered
-    // on the new surface control, add a synthetic callback that requests the jank data.
-    if (!includingJankData && mJankListeners.count(surfaceControl->getLayerId()) != 0) {
-        CallbackId callbackId =
-                addCallbackFunctionLocked(&emptyCallback, callbackInfo.surfaceControls,
-                                          CallbackId::Type::ON_COMPLETE);
-        callbackInfo.callbackIds.emplace(callbackId);
     }
 }
 
 void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) {
     std::unordered_map<CallbackId, CallbackTranslation, CallbackIdHash> callbacksMap;
-    std::multimap<int32_t, sp<JankDataListener>> jankListenersMap;
     {
         std::lock_guard<std::mutex> lock(mMutex);
 
@@ -366,7 +487,6 @@
          * sp<SurfaceControl> that could possibly exist for the callbacks.
          */
         callbacksMap = mCallbacks;
-        jankListenersMap = mJankListeners;
         for (const auto& transactionStats : listenerStats.transactionStats) {
             for (auto& callbackId : transactionStats.callbackIds) {
                 mCallbacks.erase(callbackId);
@@ -486,12 +606,6 @@
                         transactionStats.presentFence, surfaceStats);
                 }
             }
-
-            if (surfaceStats.jankData.empty()) continue;
-            auto jankRange = jankListenersMap.equal_range(layerId);
-            for (auto it = jankRange.first; it != jankRange.second; it++) {
-                it->second->onJankDataAvailable(surfaceStats.jankData);
-            }
         }
     }
 }
@@ -1004,8 +1118,9 @@
 
         // register all surface controls for all callbackIds for this listener that is merging
         for (const auto& surfaceControl : currentProcessCallbackInfo.surfaceControls) {
-            mTransactionCompletedListener->addSurfaceControlToCallbacks(currentProcessCallbackInfo,
-                                                                        surfaceControl);
+            mTransactionCompletedListener
+                    ->addSurfaceControlToCallbacks(surfaceControl,
+                                                   currentProcessCallbackInfo.callbackIds);
         }
     }
 
@@ -1362,7 +1477,7 @@
     auto& callbackInfo = mListenerCallbacks[TransactionCompletedListener::getIInstance()];
     callbackInfo.surfaceControls.insert(sc);
 
-    mTransactionCompletedListener->addSurfaceControlToCallbacks(callbackInfo, sc);
+    mTransactionCompletedListener->addSurfaceControlToCallbacks(sc, callbackInfo.callbackIds);
 }
 
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition(
@@ -2218,6 +2333,23 @@
     return *this;
 }
 
+bool SurfaceComposerClient::flagEdgeExtensionEffectUseShader() {
+    return com::android::graphics::libgui::flags::edge_extension_shader();
+}
+
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setEdgeExtensionEffect(
+        const sp<SurfaceControl>& sc, const gui::EdgeExtensionParameters& effect) {
+    layer_state_t* s = getLayerState(sc);
+    if (!s) {
+        mStatus = BAD_INDEX;
+        return *this;
+    }
+
+    s->what |= layer_state_t::eEdgeExtensionChanged;
+    s->edgeExtensionParameters = effect;
+    return *this;
+}
+
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBufferCrop(
         const sp<SurfaceControl>& sc, const Rect& bufferCrop) {
     layer_state_t* s = getLayerState(sc);
@@ -2263,6 +2395,22 @@
     return *this;
 }
 
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBufferReleaseChannel(
+        const sp<SurfaceControl>& sc,
+        const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel) {
+    layer_state_t* s = getLayerState(sc);
+    if (!s) {
+        mStatus = BAD_INDEX;
+        return *this;
+    }
+
+    s->what |= layer_state_t::eBufferReleaseChannelChanged;
+    s->bufferReleaseChannel = channel;
+
+    registerSurfaceControlForCallback(sc);
+    return *this;
+}
+
 // ---------------------------------------------------------------------------
 
 DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) {
diff --git a/libs/tracing_perfetto/include/trace_result.h b/libs/gui/aidl/android/gui/EdgeExtensionParameters.aidl
similarity index 70%
copy from libs/tracing_perfetto/include/trace_result.h
copy to libs/gui/aidl/android/gui/EdgeExtensionParameters.aidl
index f7581fc..44f4259 100644
--- a/libs/tracing_perfetto/include/trace_result.h
+++ b/libs/gui/aidl/android/gui/EdgeExtensionParameters.aidl
@@ -14,17 +14,14 @@
  * limitations under the License.
  */
 
-#ifndef TRACE_RESULT_H
-#define TRACE_RESULT_H
+package android.gui;
 
-namespace tracing_perfetto {
 
-enum class Result {
-  SUCCESS,
-  NOT_SUPPORTED,
-  INVALID_INPUT,
-};
-
-}
-
-#endif  // TRACE_RESULT_H
+/** @hide */
+parcelable EdgeExtensionParameters {
+    // These represent the translation of the window as requested by the animation
+    boolean extendRight;
+    boolean extendLeft;
+    boolean extendTop;
+    boolean extendBottom;
+}
\ No newline at end of file
diff --git a/libs/tracing_perfetto/include/trace_result.h b/libs/gui/aidl/android/gui/IJankListener.aidl
similarity index 68%
copy from libs/tracing_perfetto/include/trace_result.h
copy to libs/gui/aidl/android/gui/IJankListener.aidl
index f7581fc..2bfd1af 100644
--- a/libs/tracing_perfetto/include/trace_result.h
+++ b/libs/gui/aidl/android/gui/IJankListener.aidl
@@ -14,17 +14,16 @@
  * limitations under the License.
  */
 
-#ifndef TRACE_RESULT_H
-#define TRACE_RESULT_H
+package android.gui;
 
-namespace tracing_perfetto {
+import android.gui.JankData;
 
-enum class Result {
-  SUCCESS,
-  NOT_SUPPORTED,
-  INVALID_INPUT,
-};
+/** @hide */
+interface IJankListener {
 
+  /**
+   * Callback reporting jank data of the most recent frames.
+   * @See {@link ISurfaceComposer#addJankListener(IBinder, IJankListener)}
+   */
+  void onJankData(in JankData[] data);
 }
-
-#endif  // TRACE_RESULT_H
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
index 6d018ea..ac14138 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -42,6 +42,7 @@
 import android.gui.ITunnelModeEnabledListener;
 import android.gui.IWindowInfosListener;
 import android.gui.IWindowInfosPublisher;
+import android.gui.IJankListener;
 import android.gui.LayerCaptureArgs;
 import android.gui.OverlayProperties;
 import android.gui.PullAtomData;
@@ -580,4 +581,22 @@
      * This method should not block the ShutdownThread therefore it's handled asynchronously.
      */
     oneway void notifyShutdown();
+
+    /**
+     * Registers the jank listener on the given layer to receive jank data of future frames.
+     */
+    void addJankListener(IBinder layer, IJankListener listener);
+
+    /**
+     * Flushes any pending jank data on the given layer to any registered listeners on that layer.
+     */
+    oneway void flushJankData(int layerId);
+
+    /**
+     * Schedules the removal of the jank listener from the given layer after the VSync with the
+     * specified ID. Use a value <= 0 for afterVsync to remove the listener immediately. The given
+     * listener will not be removed before the given VSync, but may still receive data for frames
+     * past the provided VSync.
+     */
+    oneway void removeJankListener(int layerId, IJankListener listener, long afterVsync);
 }
diff --git a/libs/tracing_perfetto/include/trace_result.h b/libs/gui/aidl/android/gui/JankData.aidl
similarity index 64%
copy from libs/tracing_perfetto/include/trace_result.h
copy to libs/gui/aidl/android/gui/JankData.aidl
index f7581fc..7ea9d22 100644
--- a/libs/tracing_perfetto/include/trace_result.h
+++ b/libs/gui/aidl/android/gui/JankData.aidl
@@ -14,17 +14,22 @@
  * limitations under the License.
  */
 
-#ifndef TRACE_RESULT_H
-#define TRACE_RESULT_H
+ package android.gui;
 
-namespace tracing_perfetto {
+ /** @hide */
+parcelable JankData {
+  /**
+   * Identifier for the frame submitted with Transaction.setFrameTimelineVsyncId
+   */
+  long frameVsyncId;
 
-enum class Result {
-  SUCCESS,
-  NOT_SUPPORTED,
-  INVALID_INPUT,
-};
+  /**
+   * Bitmask of jank types that occurred.
+   */
+  int jankType;
 
+  /**
+   * Expected duration in nanoseconds of this frame.
+   */
+  long frameIntervalNs;
 }
-
-#endif  // TRACE_RESULT_H
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 0e1a505..e9a350c 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -19,7 +19,7 @@
 
 #include <gui/BufferItem.h>
 #include <gui/BufferItemConsumer.h>
-
+#include <gui/BufferReleaseChannel.h>
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/SurfaceComposerClient.h>
 
@@ -28,7 +28,6 @@
 #include <utils/RefBase.h>
 
 #include <system/window.h>
-#include <thread>
 #include <queue>
 
 #include <com_android_graphics_libgui_flags.h>
@@ -131,6 +130,8 @@
 
     virtual ~BLASTBufferQueue();
 
+    void onFirstRef() override;
+
 private:
     friend class BLASTBufferQueueHelper;
     friend class BBQBufferQueueProducer;
@@ -170,11 +171,23 @@
 
     // BufferQueue internally allows 1 more than
     // the max to be acquired
-    int32_t mMaxAcquiredBuffers = 1;
+    int32_t mMaxAcquiredBuffers GUARDED_BY(mMutex) = 1;
+    int32_t mMaxDequeuedBuffers GUARDED_BY(mMutex) = 1;
+    static constexpr int32_t kMaxBufferCount = BufferQueueDefs::NUM_BUFFER_SLOTS;
 
+    // mNumDequeued is an atomic instead of being guarded by mMutex so that it can be incremented in
+    // onFrameDequeued while avoiding lock contention. updateDequeueShouldBlockLocked is not called
+    // after mNumDequeued is incremented for this reason. This means mDequeueShouldBlock may be
+    // temporarily false when it should be true. This can happen if multiple threads are dequeuing
+    // buffers or if dequeueBuffers is called multiple times in a row without queuing a buffer in
+    // between. As mDequeueShouldBlock is only used for optimization, this is OK.
+    std::atomic_int mNumDequeued;
     int32_t mNumFrameAvailable GUARDED_BY(mMutex) = 0;
     int32_t mNumAcquired GUARDED_BY(mMutex) = 0;
 
+    bool mAsyncMode GUARDED_BY(mMutex) = false;
+    bool mSharedBufferMode GUARDED_BY(mMutex) = false;
+
     // A value used to identify if a producer has been changed for the same SurfaceControl.
     // This is needed to know when the frame number has been reset to make sure we don't
     // latch stale buffers and that we don't wait on barriers from an old producer.
@@ -300,6 +313,41 @@
     std::function<void(const std::string&)> mTransactionHangCallback;
 
     std::unordered_set<uint64_t> mSyncedFrameNumbers GUARDED_BY(mMutex);
+
+    class BufferReleaseReader {
+    public:
+        BufferReleaseReader(std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint>);
+
+        BufferReleaseReader(const BufferReleaseReader&) = delete;
+        BufferReleaseReader& operator=(const BufferReleaseReader&) = delete;
+
+        // Block until we can release a buffer.
+        //
+        // Returns:
+        // * OK if a ReleaseCallbackId and Fence were successfully read.
+        // * TIMED_OUT if the specified timeout was reached.
+        // * WOULD_BLOCK if the blocking read was interrupted by interruptBlockingRead.
+        // * UNKNOWN_ERROR if something went wrong.
+        status_t readBlocking(ReleaseCallbackId&, sp<Fence>&, std::chrono::milliseconds timeout);
+
+        status_t readNonBlocking(ReleaseCallbackId&, sp<Fence>&);
+
+        void interruptBlockingRead();
+
+    private:
+        std::mutex mMutex;
+        std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> mEndpoint GUARDED_BY(mMutex);
+        android::base::unique_fd mEpollFd;
+        android::base::unique_fd mEventFd;
+    };
+
+    // BufferReleaseChannel is used to communicate buffer releases from SurfaceFlinger to
+    // the client. See BBQBufferQueueProducer::dequeueBuffer for details.
+    std::optional<BufferReleaseReader> mBufferReleaseReader;
+    std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> mBufferReleaseProducer;
+
+    std::atomic_bool mDequeueShouldBlock{false};
+    void updateDequeueShouldBlockLocked() REQUIRES(mMutex);
 };
 
 } // namespace android
diff --git a/libs/gui/include/gui/BufferReleaseChannel.h b/libs/gui/include/gui/BufferReleaseChannel.h
new file mode 100644
index 0000000..cb0b261
--- /dev/null
+++ b/libs/gui/include/gui/BufferReleaseChannel.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2024 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 <string>
+
+#include <android-base/chrono_utils.h>
+#include <android-base/result.h>
+#include <android-base/unique_fd.h>
+
+#include <binder/IBinder.h>
+#include <binder/Parcelable.h>
+#include <gui/ITransactionCompletedListener.h>
+#include <sys/stat.h>
+#include <ui/Fence.h>
+#include <ui/Transform.h>
+#include <utils/BitSet.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+namespace android::gui {
+
+/**
+ * IPC wrapper to pass release fences from SurfaceFlinger to apps via a local unix domain socket.
+ */
+class BufferReleaseChannel {
+private:
+    class Endpoint {
+    public:
+        Endpoint(std::string name, android::base::unique_fd fd)
+              : mName(std::move(name)), mFd(std::move(fd)) {}
+        Endpoint() {}
+
+        Endpoint(Endpoint&&) noexcept = default;
+        Endpoint& operator=(Endpoint&&) noexcept = default;
+
+        Endpoint(const Endpoint&) = delete;
+        void operator=(const Endpoint&) = delete;
+
+        const android::base::unique_fd& getFd() const { return mFd; }
+
+    protected:
+        std::string mName;
+        android::base::unique_fd mFd;
+    };
+
+public:
+    class ConsumerEndpoint : public Endpoint {
+    public:
+        ConsumerEndpoint(std::string name, android::base::unique_fd fd)
+              : Endpoint(std::move(name), std::move(fd)) {}
+
+        /**
+         * Reads a release fence from the BufferReleaseChannel.
+         *
+         * Returns OK on success.
+         * Returns WOULD_BLOCK if there is no fence present.
+         * Other errors probably indicate that the channel is broken.
+         */
+        status_t readReleaseFence(ReleaseCallbackId& outReleaseCallbackId,
+                                  sp<Fence>& outReleaseFence);
+
+    private:
+        std::vector<uint8_t> mFlattenedBuffer;
+    };
+
+    class ProducerEndpoint : public Endpoint, public Parcelable {
+    public:
+        ProducerEndpoint(std::string name, android::base::unique_fd fd)
+              : Endpoint(std::move(name), std::move(fd)) {}
+        ProducerEndpoint() {}
+
+        status_t readFromParcel(const android::Parcel* parcel) override;
+        status_t writeToParcel(android::Parcel* parcel) const override;
+
+        status_t writeReleaseFence(const ReleaseCallbackId&, const sp<Fence>& releaseFence);
+
+    private:
+        std::vector<uint8_t> mFlattenedBuffer;
+    };
+
+    /**
+     * Create two endpoints that make up the BufferReleaseChannel.
+     *
+     * Return OK on success.
+     */
+    static status_t open(const std::string name, std::unique_ptr<ConsumerEndpoint>& outConsumer,
+                         std::shared_ptr<ProducerEndpoint>& outProducer);
+
+    struct Message : public Flattenable<Message> {
+        ReleaseCallbackId releaseCallbackId;
+        sp<Fence> releaseFence = Fence::NO_FENCE;
+
+        Message() = default;
+        Message(ReleaseCallbackId releaseCallbackId, sp<Fence> releaseFence)
+              : releaseCallbackId(releaseCallbackId), releaseFence(std::move(releaseFence)) {}
+
+        // Flattenable protocol
+        size_t getFlattenedSize() const;
+
+        size_t getFdCount() const { return releaseFence->getFdCount(); }
+
+        status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
+
+        status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
+
+    private:
+        size_t getPodSize() const;
+    };
+};
+
+} // namespace android::gui
diff --git a/libs/gui/include/gui/ITransactionCompletedListener.h b/libs/gui/include/gui/ITransactionCompletedListener.h
index bc97cd0..014029b 100644
--- a/libs/gui/include/gui/ITransactionCompletedListener.h
+++ b/libs/gui/include/gui/ITransactionCompletedListener.h
@@ -16,8 +16,6 @@
 
 #pragma once
 
-#include "JankInfo.h"
-
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
@@ -40,15 +38,10 @@
 class CallbackId : public Parcelable {
 public:
     int64_t id;
-    enum class Type : int32_t {
-        ON_COMPLETE = 0,
-        ON_COMMIT = 1,
-        /*reserved for serialization = 2*/
-    } type;
-    bool includeJankData; // Only respected for ON_COMPLETE callbacks.
+    enum class Type : int32_t { ON_COMPLETE = 0, ON_COMMIT = 1 } type;
 
     CallbackId() {}
-    CallbackId(int64_t id, Type type) : id(id), type(type), includeJankData(false) {}
+    CallbackId(int64_t id, Type type) : id(id), type(type) {}
     status_t writeToParcel(Parcel* output) const override;
     status_t readFromParcel(const Parcel* input) override;
 
@@ -113,29 +106,6 @@
     nsecs_t dequeueReadyTime;
 };
 
-/**
- * Jank information representing SurfaceFlinger's jank classification about frames for a specific
- * surface.
- */
-class JankData : public Parcelable {
-public:
-    status_t writeToParcel(Parcel* output) const override;
-    status_t readFromParcel(const Parcel* input) override;
-
-    JankData();
-    JankData(int64_t frameVsyncId, int32_t jankType, nsecs_t frameIntervalNs)
-          : frameVsyncId(frameVsyncId), jankType(jankType), frameIntervalNs(frameIntervalNs) {}
-
-    // Identifier for the frame submitted with Transaction.setFrameTimelineVsyncId
-    int64_t frameVsyncId;
-
-    // Bitmask of janks that occurred
-    int32_t jankType;
-
-    // Expected duration of the frame
-    nsecs_t frameIntervalNs;
-};
-
 class SurfaceStats : public Parcelable {
 public:
     status_t writeToParcel(Parcel* output) const override;
@@ -145,14 +115,13 @@
     SurfaceStats(const sp<IBinder>& sc, std::variant<nsecs_t, sp<Fence>> acquireTimeOrFence,
                  const sp<Fence>& prevReleaseFence, std::optional<uint32_t> hint,
                  uint32_t currentMaxAcquiredBuffersCount, FrameEventHistoryStats frameEventStats,
-                 std::vector<JankData> jankData, ReleaseCallbackId previousReleaseCallbackId)
+                 ReleaseCallbackId previousReleaseCallbackId)
           : surfaceControl(sc),
             acquireTimeOrFence(std::move(acquireTimeOrFence)),
             previousReleaseFence(prevReleaseFence),
             transformHint(hint),
             currentMaxAcquiredBufferCount(currentMaxAcquiredBuffersCount),
             eventStats(frameEventStats),
-            jankData(std::move(jankData)),
             previousReleaseCallbackId(previousReleaseCallbackId) {}
 
     sp<IBinder> surfaceControl;
@@ -161,7 +130,6 @@
     std::optional<uint32_t> transformHint = 0;
     uint32_t currentMaxAcquiredBufferCount = 0;
     FrameEventHistoryStats eventStats;
-    std::vector<JankData> jankData;
     ReleaseCallbackId previousReleaseCallbackId;
 };
 
diff --git a/libs/gui/include/gui/LayerMetadata.h b/libs/gui/include/gui/LayerMetadata.h
index 9cf62bc..7ee291d 100644
--- a/libs/gui/include/gui/LayerMetadata.h
+++ b/libs/gui/include/gui/LayerMetadata.h
@@ -74,6 +74,7 @@
 } // namespace android::gui
 
 using android::gui::METADATA_ACCESSIBILITY_ID;
+using android::gui::METADATA_CALLING_UID;
 using android::gui::METADATA_DEQUEUE_TIME;
 using android::gui::METADATA_GAME_MODE;
 using android::gui::METADATA_MOUSE_CURSOR;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index ba06101..d419945 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -29,10 +29,12 @@
 #include <math/mat4.h>
 
 #include <android/gui/DropInputMode.h>
+#include <android/gui/EdgeExtensionParameters.h>
 #include <android/gui/FocusRequest.h>
 #include <android/gui/TrustedOverlay.h>
 
 #include <ftl/flags.h>
+#include <gui/BufferReleaseChannel.h>
 #include <gui/DisplayCaptureArgs.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/LayerCaptureArgs.h>
@@ -218,6 +220,8 @@
         eTrustedOverlayChanged = 0x4000'00000000,
         eDropInputModeChanged = 0x8000'00000000,
         eExtendedRangeBrightnessChanged = 0x10000'00000000,
+        eEdgeExtensionChanged = 0x20000'00000000,
+        eBufferReleaseChannelChanged = 0x40000'00000000,
     };
 
     layer_state_t();
@@ -241,7 +245,7 @@
             layer_state_t::eCropChanged | layer_state_t::eDestinationFrameChanged |
             layer_state_t::eMatrixChanged | layer_state_t::ePositionChanged |
             layer_state_t::eTransformToDisplayInverseChanged |
-            layer_state_t::eTransparentRegionChanged;
+            layer_state_t::eTransparentRegionChanged | layer_state_t::eEdgeExtensionChanged;
 
     // Buffer and related updates.
     static constexpr uint64_t BUFFER_CHANGES = layer_state_t::eApiChanged |
@@ -278,9 +282,9 @@
             layer_state_t::eFrameRateSelectionPriority | layer_state_t::eFixedTransformHintChanged;
 
     // Changes affecting data sent to input.
-    static constexpr uint64_t INPUT_CHANGES = layer_state_t::eInputInfoChanged |
-            layer_state_t::eDropInputModeChanged | layer_state_t::eTrustedOverlayChanged |
-            layer_state_t::eLayerStackChanged;
+    static constexpr uint64_t INPUT_CHANGES = layer_state_t::eAlphaChanged |
+            layer_state_t::eInputInfoChanged | layer_state_t::eDropInputModeChanged |
+            layer_state_t::eTrustedOverlayChanged | layer_state_t::eLayerStackChanged;
 
     // Changes that affect the visible region on a display.
     static constexpr uint64_t VISIBLE_REGION_CHANGES = layer_state_t::GEOMETRY_CHANGES |
@@ -393,6 +397,9 @@
     // Stretch effect to be applied to this layer
     StretchEffect stretchEffect;
 
+    // Edge extension effect to be applied to this layer
+    gui::EdgeExtensionParameters edgeExtensionParameters;
+
     Rect bufferCrop;
     Rect destinationFrame;
 
@@ -407,6 +414,8 @@
 
     TrustedPresentationThresholds trustedPresentationThresholds;
     TrustedPresentationListener trustedPresentationListener;
+
+    std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> bufferReleaseChannel;
 };
 
 class ComposerState {
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index bdcaaf2..1245501 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -56,6 +56,16 @@
     virtual bool needsReleaseNotify() = 0;
 
     virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& buffers) = 0;
+    virtual void onBufferDetached(int slot) = 0;
+};
+
+class StubSurfaceListener : public SurfaceListener {
+public:
+    virtual ~StubSurfaceListener() {}
+    virtual void onBufferReleased() override {}
+    virtual bool needsReleaseNotify() { return false; }
+    virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& /*buffers*/) override {}
+    virtual void onBufferDetached(int /*slot*/) override {}
 };
 
 /*
@@ -357,15 +367,13 @@
     virtual int unlockAndPost();
     virtual int query(int what, int* value) const;
 
-    virtual int connect(int api, const sp<IProducerListener>& listener);
+    virtual int connect(int api, const sp<SurfaceListener>& listener);
 
     // When reportBufferRemoval is true, clients must call getAndFlushRemovedBuffers to fetch
     // GraphicBuffers removed from this surface after a dequeueBuffer, detachNextBuffer or
     // attachBuffer call. This allows clients with their own buffer caches to free up buffers no
     // longer in use by this surface.
-    virtual int connect(
-            int api, const sp<IProducerListener>& listener,
-            bool reportBufferRemoval);
+    virtual int connect(int api, const sp<SurfaceListener>& listener, bool reportBufferRemoval);
     virtual int detachNextBuffer(sp<GraphicBuffer>* outBuffer,
             sp<Fence>* outFence);
     virtual int attachBuffer(ANativeWindowBuffer*);
@@ -422,6 +430,8 @@
             return mSurfaceListener->needsReleaseNotify();
         }
 
+        virtual void onBufferDetached(int slot) { mSurfaceListener->onBufferDetached(slot); }
+
         virtual void onBuffersDiscarded(const std::vector<int32_t>& slots);
     private:
         wp<Surface> mParent;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 0862e03..8c1d644 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -35,14 +35,17 @@
 #include <ui/BlurRegion.h>
 #include <ui/ConfigStoreTypes.h>
 #include <ui/DisplayedFrameStats.h>
+#include <ui/EdgeExtensionEffect.h>
 #include <ui/FrameStats.h>
 #include <ui/GraphicTypes.h>
 #include <ui/PixelFormat.h>
 #include <ui/Rotation.h>
 #include <ui/StaticDisplayInfo.h>
 
+#include <android/gui/BnJankListener.h>
 #include <android/gui/ISurfaceComposerClient.h>
 
+#include <gui/BufferReleaseChannel.h>
 #include <gui/CpuConsumer.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/ITransactionCompletedListener.h>
@@ -337,6 +340,8 @@
     static std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>
     getDisplayDecorationSupport(const sp<IBinder>& displayToken);
 
+    static bool flagEdgeExtensionEffectUseShader();
+
     // ------------------------------------------------------------------------
     // surface creation / destruction
 
@@ -743,11 +748,26 @@
         Transaction& setStretchEffect(const sp<SurfaceControl>& sc,
                                       const StretchEffect& stretchEffect);
 
+        /**
+         * Provides the edge extension effect configured on a container that the
+         * surface is rendered within.
+         * @param sc target surface the edge extension should be applied to
+         * @param effect the corresponding EdgeExtensionParameters to be applied
+         *    to the surface.
+         * @return The transaction being constructed
+         */
+        Transaction& setEdgeExtensionEffect(const sp<SurfaceControl>& sc,
+                                            const gui::EdgeExtensionParameters& effect);
+
         Transaction& setBufferCrop(const sp<SurfaceControl>& sc, const Rect& bufferCrop);
         Transaction& setDestinationFrame(const sp<SurfaceControl>& sc,
                                          const Rect& destinationFrame);
         Transaction& setDropInputMode(const sp<SurfaceControl>& sc, gui::DropInputMode mode);
 
+        Transaction& setBufferReleaseChannel(
+                const sp<SurfaceControl>& sc,
+                const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel);
+
         status_t setDisplaySurface(const sp<IBinder>& token,
                 const sp<IGraphicBufferProducer>& bufferProducer);
 
@@ -864,12 +884,82 @@
 
 // ---------------------------------------------------------------------------
 
-class JankDataListener : public VirtualLightRefBase {
+class JankDataListener;
+
+// Acts as a representative listener to the composer for a single layer and
+// forwards any received jank data to multiple listeners. Will remove itself
+// from the composer only once the last listener is removed.
+class JankDataListenerFanOut : public gui::BnJankListener {
 public:
-    virtual ~JankDataListener() = 0;
-    virtual void onJankDataAvailable(const std::vector<JankData>& jankData) = 0;
+    JankDataListenerFanOut(int32_t layerId) : mLayerId(layerId) {}
+
+    binder::Status onJankData(const std::vector<gui::JankData>& jankData) override;
+
+    static status_t addListener(sp<SurfaceControl> sc, sp<JankDataListener> listener);
+    static status_t removeListener(sp<JankDataListener> listener);
+
+private:
+    std::vector<sp<JankDataListener>> getActiveListeners();
+    bool removeListeners(const std::vector<wp<JankDataListener>>& listeners);
+    int64_t updateAndGetRemovalVSync();
+
+    struct WpJDLHash {
+        std::size_t operator()(const wp<JankDataListener>& listener) const {
+            return std::hash<JankDataListener*>{}(listener.unsafe_get());
+        }
+    };
+
+    std::mutex mMutex;
+    std::unordered_set<wp<JankDataListener>, WpJDLHash> mListeners GUARDED_BY(mMutex);
+    int32_t mLayerId;
+    int64_t mRemoveAfter = -1;
+
+    static std::mutex sFanoutInstanceMutex;
+    static std::unordered_map<int32_t, sp<JankDataListenerFanOut>> sFanoutInstances;
 };
 
+// Base class for client listeners interested in jank classification data from
+// the composer. Subclasses should override onJankDataAvailable and call the add
+// and removal methods to receive jank data.
+class JankDataListener : public virtual RefBase {
+public:
+    JankDataListener() {}
+    virtual ~JankDataListener();
+
+    virtual bool onJankDataAvailable(const std::vector<gui::JankData>& jankData) = 0;
+
+    status_t addListener(sp<SurfaceControl> sc) {
+        if (mLayerId != -1) {
+            removeListener(0);
+            mLayerId = -1;
+        }
+
+        int32_t layerId = sc->getLayerId();
+        status_t status =
+                JankDataListenerFanOut::addListener(std::move(sc),
+                                                    sp<JankDataListener>::fromExisting(this));
+        if (status == OK) {
+            mLayerId = layerId;
+        }
+        return status;
+    }
+
+    status_t removeListener(int64_t afterVsync) {
+        mRemoveAfter = std::max(static_cast<int64_t>(0), afterVsync);
+        return JankDataListenerFanOut::removeListener(sp<JankDataListener>::fromExisting(this));
+    }
+
+    status_t flushJankData();
+
+    friend class JankDataListenerFanOut;
+
+private:
+    int32_t mLayerId = -1;
+    int64_t mRemoveAfter = -1;
+};
+
+// ---------------------------------------------------------------------------
+
 class TransactionCompletedListener : public BnTransactionCompletedListener {
 public:
     TransactionCompletedListener();
@@ -904,7 +994,6 @@
 
     std::unordered_map<CallbackId, CallbackTranslation, CallbackIdHash> mCallbacks
             GUARDED_BY(mMutex);
-    std::multimap<int32_t, sp<JankDataListener>> mJankListeners GUARDED_BY(mMutex);
     std::unordered_map<ReleaseCallbackId, ReleaseBufferCallback, ReleaseBufferCallbackIdHash>
             mReleaseBufferCallbacks GUARDED_BY(mMutex);
 
@@ -927,14 +1016,10 @@
             const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>&
                     surfaceControls,
             CallbackId::Type callbackType);
-    CallbackId addCallbackFunctionLocked(
-            const TransactionCompletedCallback& callbackFunction,
-            const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>&
-                    surfaceControls,
-            CallbackId::Type callbackType) REQUIRES(mMutex);
 
-    void addSurfaceControlToCallbacks(SurfaceComposerClient::CallbackInfo& callbackInfo,
-                                      const sp<SurfaceControl>& surfaceControl);
+    void addSurfaceControlToCallbacks(
+            const sp<SurfaceControl>& surfaceControl,
+            const std::unordered_set<CallbackId, CallbackIdHash>& callbackIds);
 
     void addQueueStallListener(std::function<void(const std::string&)> stallListener, void* id);
     void removeQueueStallListener(void *id);
@@ -943,18 +1028,6 @@
             TrustedPresentationCallback tpc, int id, void* context);
     void clearTrustedPresentationCallback(int id);
 
-    /*
-     * Adds a jank listener to be informed about SurfaceFlinger's jank classification for a specific
-     * surface. Jank classifications arrive as part of the transaction callbacks about previous
-     * frames submitted to this Surface.
-     */
-    void addJankListener(const sp<JankDataListener>& listener, sp<SurfaceControl> surfaceControl);
-
-    /**
-     * Removes a jank listener previously added to addJankCallback.
-     */
-    void removeJankListener(const sp<JankDataListener>& listener);
-
     void addSurfaceStatsListener(void* context, void* cookie, sp<SurfaceControl> surfaceControl,
                 SurfaceStatsCallback listener);
     void removeSurfaceStatsListener(void* context, void* cookie);
diff --git a/libs/gui/libgui_flags.aconfig b/libs/gui/libgui_flags.aconfig
index a902a8c..bd51413 100644
--- a/libs/gui/libgui_flags.aconfig
+++ b/libs/gui/libgui_flags.aconfig
@@ -7,7 +7,7 @@
   description: "This flag controls plumbing setFrameRate thru BufferQueue"
   bug: "281695725"
   is_fixed_read_only: true
-}
+} # bq_setframerate
 
 flag {
   name: "frametimestamps_previousrelease"
@@ -15,7 +15,7 @@
   description: "Controls a fence fixup for timestamp apis"
   bug: "310927247"
   is_fixed_read_only: true
-}
+} # frametimestamps_previousrelease
 
 flag {
   name: "bq_extendedallocate"
@@ -23,4 +23,47 @@
   description: "Add BQ support for allocate with extended options"
   bug: "268382490"
   is_fixed_read_only: true
-}
+} # bq_extendedallocate
+
+flag {
+  name: "trace_frame_rate_override"
+  namespace: "core_graphics"
+  description: "Trace FrameRateOverride fps"
+  bug: "347314033"
+  is_fixed_read_only: true
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+} # trace_frame_rate_override
+
+flag {
+  name: "wb_platform_api_improvements"
+  namespace: "core_graphics"
+  description: "Simple improvements to Surface and ConsumerBase classes"
+  bug: "340933794"
+  is_fixed_read_only: true
+} # wb_platform_api_improvements
+
+flag {
+  name: "edge_extension_shader"
+  namespace: "windowing_frontend"
+  description: "Enable edge extension via shader"
+  bug: "322036393"
+  is_fixed_read_only: true
+} # edge_extension_shader
+
+flag {
+  name: "buffer_release_channel"
+  namespace: "window_surfaces"
+  description: "Enable BufferReleaseChannel to optimize buffer releases"
+  bug: "294133380"
+  is_fixed_read_only: true
+} # buffer_release_channel
+
+flag {
+  name: "wb_surface_connect_methods"
+  namespace: "core_graphics"
+  description: "Remove redundant connect methods in Surface."
+  bug: "354273690"
+  is_fixed_read_only: true
+} # wb_surface_connect_methods
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index ea8acbb..daaddfb 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -32,6 +32,7 @@
         "BLASTBufferQueue_test.cpp",
         "BufferItemConsumer_test.cpp",
         "BufferQueue_test.cpp",
+        "BufferReleaseChannel_test.cpp",
         "Choreographer_test.cpp",
         "CompositorTiming_test.cpp",
         "CpuConsumer_test.cpp",
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index 946ff05..6852589 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -1269,6 +1269,20 @@
     }
 };
 
+class TestSurfaceListener : public SurfaceListener {
+public:
+    sp<IGraphicBufferProducer> mIgbp;
+    TestSurfaceListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
+    void onBufferReleased() override {
+        sp<GraphicBuffer> buffer;
+        sp<Fence> fence;
+        mIgbp->detachNextBuffer(&buffer, &fence);
+    }
+    bool needsReleaseNotify() override { return true; }
+    void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& /*buffers*/) override {}
+    void onBufferDetached(int /*slot*/) {}
+};
+
 TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
     sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
@@ -1327,7 +1341,7 @@
     ASSERT_EQ(ui::Transform::ROT_0, static_cast<ui::Transform::RotationFlags>(transformHint));
 
     ASSERT_EQ(NO_ERROR,
-              surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
+              surface->connect(NATIVE_WINDOW_API_CPU, new TestSurfaceListener(igbProducer)));
 
     // After connecting to the surface, we should get the correct hint.
     surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
diff --git a/libs/gui/tests/BufferReleaseChannel_test.cpp b/libs/gui/tests/BufferReleaseChannel_test.cpp
new file mode 100644
index 0000000..f3e962c
--- /dev/null
+++ b/libs/gui/tests/BufferReleaseChannel_test.cpp
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2024 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 <string>
+#include <vector>
+
+#include <gtest/gtest.h>
+#include <gui/BufferReleaseChannel.h>
+
+using namespace std::string_literals;
+using android::gui::BufferReleaseChannel;
+
+namespace android {
+
+namespace {
+
+// Helper function to check if two file descriptors point to the same file.
+bool is_same_file(int fd1, int fd2) {
+    struct stat stat1;
+    if (fstat(fd1, &stat1) != 0) {
+        return false;
+    }
+    struct stat stat2;
+    if (fstat(fd2, &stat2) != 0) {
+        return false;
+    }
+    return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino);
+}
+
+} // namespace
+
+TEST(BufferReleaseChannelTest, MessageFlattenable) {
+    ReleaseCallbackId releaseCallbackId{1, 2};
+    sp<Fence> releaseFence = sp<Fence>::make(memfd_create("fake-fence-fd", 0));
+
+    std::vector<uint8_t> dataBuffer;
+    std::vector<int> fdBuffer;
+
+    // Verify that we can flatten a message
+    {
+        BufferReleaseChannel::Message message{releaseCallbackId, releaseFence};
+
+        dataBuffer.resize(message.getFlattenedSize());
+        void* dataPtr = dataBuffer.data();
+        size_t dataSize = dataBuffer.size();
+
+        fdBuffer.resize(message.getFdCount());
+        int* fdPtr = fdBuffer.data();
+        size_t fdSize = fdBuffer.size();
+
+        ASSERT_EQ(OK, message.flatten(dataPtr, dataSize, fdPtr, fdSize));
+
+        // Fence's unique_fd uses fdsan to check ownership of the file descriptor. Normally the file
+        // descriptor is passed through the Unix socket and duplicated (and sent to another process)
+        // so there's no problem with duplicate file descriptor ownership. For this unit test, we
+        // need to set up a duplicate file descriptor to avoid crashing due to duplicate ownership.
+        ASSERT_EQ(releaseFence->get(), fdBuffer[0]);
+        fdBuffer[0] = message.releaseFence->dup();
+    }
+
+    // Verify that we can unflatten a message
+    {
+        BufferReleaseChannel::Message message;
+
+        const void* dataPtr = dataBuffer.data();
+        size_t dataSize = dataBuffer.size();
+
+        const int* fdPtr = fdBuffer.data();
+        size_t fdSize = fdBuffer.size();
+
+        ASSERT_EQ(OK, message.unflatten(dataPtr, dataSize, fdPtr, fdSize));
+        ASSERT_EQ(releaseCallbackId, message.releaseCallbackId);
+        ASSERT_TRUE(is_same_file(releaseFence->get(), message.releaseFence->get()));
+    }
+}
+
+// Verify that the BufferReleaseChannel consume returns WOULD_BLOCK when there's no message
+// available.
+TEST(BufferReleaseChannelTest, ConsumerEndpointIsNonBlocking) {
+    std::unique_ptr<BufferReleaseChannel::ConsumerEndpoint> consumer;
+    std::shared_ptr<BufferReleaseChannel::ProducerEndpoint> producer;
+    ASSERT_EQ(OK, BufferReleaseChannel::open("test-channel"s, consumer, producer));
+
+    ReleaseCallbackId releaseCallbackId;
+    sp<Fence> releaseFence;
+    ASSERT_EQ(WOULD_BLOCK, consumer->readReleaseFence(releaseCallbackId, releaseFence));
+}
+
+// Verify that we can write a message to the BufferReleaseChannel producer and read that message
+// using the BufferReleaseChannel consumer.
+TEST(BufferReleaseChannelTest, ProduceAndConsume) {
+    std::unique_ptr<BufferReleaseChannel::ConsumerEndpoint> consumer;
+    std::shared_ptr<BufferReleaseChannel::ProducerEndpoint> producer;
+    ASSERT_EQ(OK, BufferReleaseChannel::open("test-channel"s, consumer, producer));
+
+    ReleaseCallbackId producerReleaseCallbackId{1, 2};
+    sp<Fence> producerReleaseFence = sp<Fence>::make(memfd_create("fake-fence-fd", 0));
+    ASSERT_EQ(OK, producer->writeReleaseFence(producerReleaseCallbackId, producerReleaseFence));
+
+    ReleaseCallbackId consumerReleaseCallbackId;
+    sp<Fence> consumerReleaseFence;
+    ASSERT_EQ(OK, consumer->readReleaseFence(consumerReleaseCallbackId, consumerReleaseFence));
+
+    ASSERT_EQ(producerReleaseCallbackId, consumerReleaseCallbackId);
+    ASSERT_TRUE(is_same_file(producerReleaseFence->get(), consumerReleaseFence->get()));
+}
+
+} // namespace android
diff --git a/libs/gui/tests/RegionSampling_test.cpp b/libs/gui/tests/RegionSampling_test.cpp
index b18b544..223e4b6 100644
--- a/libs/gui/tests/RegionSampling_test.cpp
+++ b/libs/gui/tests/RegionSampling_test.cpp
@@ -239,8 +239,9 @@
     float const luma_green = 0.7152;
     uint32_t const rgba_blue = 0xFFFF0000;
     float const luma_blue = 0.0722;
-    float const error_margin = 0.01;
+    float const error_margin = 0.1;
     float const luma_gray = 0.50;
+    static constexpr std::chrono::milliseconds EVENT_WAIT_TIME_MS = 5000ms;
 };
 
 TEST_F(RegionSamplingTest, invalidLayerHandle_doesNotCrash) {
@@ -261,7 +262,7 @@
     composer->removeRegionSamplingListener(listener);
 }
 
-TEST_F(RegionSamplingTest, DISABLED_CollectsLuma) {
+TEST_F(RegionSamplingTest, CollectsLuma) {
     fill_render(rgba_green);
 
     sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
@@ -273,7 +274,30 @@
     sampleArea.bottom = 200;
     composer->addRegionSamplingListener(sampleArea, mTopLayer->getHandle(), listener);
 
-    EXPECT_TRUE(listener->wait_event(300ms)) << "timed out waiting for luma event to be received";
+    EXPECT_TRUE(listener->wait_event(EVENT_WAIT_TIME_MS))
+            << "timed out waiting for luma event to be received";
+    EXPECT_NEAR(listener->luma(), luma_green, error_margin);
+
+    composer->removeRegionSamplingListener(listener);
+}
+
+TEST_F(RegionSamplingTest, CollectsLumaForSecureLayer) {
+    fill_render(rgba_green);
+    SurfaceComposerClient::Transaction()
+            .setFlags(mContentLayer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure)
+            .apply(/*synchronous=*/true);
+
+    sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
+    sp<Listener> listener = new Listener();
+    gui::ARect sampleArea;
+    sampleArea.left = 100;
+    sampleArea.top = 100;
+    sampleArea.right = 200;
+    sampleArea.bottom = 200;
+    composer->addRegionSamplingListener(sampleArea, mTopLayer->getHandle(), listener);
+
+    EXPECT_TRUE(listener->wait_event(EVENT_WAIT_TIME_MS))
+            << "timed out waiting for luma event to be received";
     EXPECT_NEAR(listener->luma(), luma_green, error_margin);
 
     composer->removeRegionSamplingListener(listener);
@@ -291,13 +315,14 @@
     sampleArea.bottom = 200;
     composer->addRegionSamplingListener(sampleArea, mTopLayer->getHandle(), listener);
 
-    EXPECT_TRUE(listener->wait_event(300ms)) << "timed out waiting for luma event to be received";
+    EXPECT_TRUE(listener->wait_event(EVENT_WAIT_TIME_MS))
+            << "timed out waiting for luma event to be received";
     EXPECT_NEAR(listener->luma(), luma_green, error_margin);
 
     listener->reset();
 
     fill_render(rgba_blue);
-    EXPECT_TRUE(listener->wait_event(300ms))
+    EXPECT_TRUE(listener->wait_event(EVENT_WAIT_TIME_MS))
             << "timed out waiting for 2nd luma event to be received";
     EXPECT_NEAR(listener->luma(), luma_blue, error_margin);
 
@@ -323,10 +348,10 @@
     graySampleArea.bottom = 200;
     composer->addRegionSamplingListener(graySampleArea, mTopLayer->getHandle(), grayListener);
 
-    EXPECT_TRUE(grayListener->wait_event(300ms))
+    EXPECT_TRUE(grayListener->wait_event(EVENT_WAIT_TIME_MS))
             << "timed out waiting for luma event to be received";
     EXPECT_NEAR(grayListener->luma(), luma_gray, error_margin);
-    EXPECT_TRUE(greenListener->wait_event(300ms))
+    EXPECT_TRUE(greenListener->wait_event(EVENT_WAIT_TIME_MS))
             << "timed out waiting for luma event to be received";
     EXPECT_NEAR(greenListener->luma(), luma_green, error_margin);
 
@@ -334,7 +359,7 @@
     composer->removeRegionSamplingListener(grayListener);
 }
 
-TEST_F(RegionSamplingTest, DISABLED_TestIfInvalidInputParameters) {
+TEST_F(RegionSamplingTest, TestIfInvalidInputParameters) {
     sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
     sp<Listener> listener = new Listener();
 
@@ -369,7 +394,7 @@
     composer->removeRegionSamplingListener(listener);
 }
 
-TEST_F(RegionSamplingTest, DISABLED_TestCallbackAfterRemoveListener) {
+TEST_F(RegionSamplingTest, TestCallbackAfterRemoveListener) {
     fill_render(rgba_green);
     sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
     sp<Listener> listener = new Listener();
@@ -381,7 +406,8 @@
     composer->addRegionSamplingListener(sampleArea, mTopLayer->getHandle(), listener);
     fill_render(rgba_green);
 
-    EXPECT_TRUE(listener->wait_event(300ms)) << "timed out waiting for luma event to be received";
+    EXPECT_TRUE(listener->wait_event(EVENT_WAIT_TIME_MS))
+            << "timed out waiting for luma event to be received";
     EXPECT_NEAR(listener->luma(), luma_green, error_margin);
 
     listener->reset();
@@ -404,11 +430,13 @@
     // Test: listener in (100, 100). See layer before move, no layer after move.
     fill_render(rgba_blue);
     composer->addRegionSamplingListener(sampleAreaA, mTopLayer->getHandle(), listener);
-    EXPECT_TRUE(listener->wait_event(300ms)) << "timed out waiting for luma event to be received";
+    EXPECT_TRUE(listener->wait_event(EVENT_WAIT_TIME_MS))
+            << "timed out waiting for luma event to be received";
     EXPECT_NEAR(listener->luma(), luma_blue, error_margin);
     listener->reset();
     SurfaceComposerClient::Transaction{}.setPosition(mContentLayer, 600, 600).apply();
-    EXPECT_TRUE(listener->wait_event(300ms)) << "timed out waiting for luma event to be received";
+    EXPECT_TRUE(listener->wait_event(EVENT_WAIT_TIME_MS))
+            << "timed out waiting for luma event to be received";
     EXPECT_NEAR(listener->luma(), luma_gray, error_margin);
     composer->removeRegionSamplingListener(listener);
 
@@ -420,11 +448,13 @@
     sampleAreaA.right = sampleArea.right;
     sampleAreaA.bottom = sampleArea.bottom;
     composer->addRegionSamplingListener(sampleAreaA, mTopLayer->getHandle(), listener);
-    EXPECT_TRUE(listener->wait_event(300ms)) << "timed out waiting for luma event to be received";
+    EXPECT_TRUE(listener->wait_event(EVENT_WAIT_TIME_MS))
+            << "timed out waiting for luma event to be received";
     EXPECT_NEAR(listener->luma(), luma_gray, error_margin);
     listener->reset();
     SurfaceComposerClient::Transaction{}.setPosition(mContentLayer, 600, 600).apply();
-    EXPECT_TRUE(listener->wait_event(300ms)) << "timed out waiting for luma event to be received";
+    EXPECT_TRUE(listener->wait_event(EVENT_WAIT_TIME_MS))
+            << "timed out waiting for luma event to be received";
     EXPECT_NEAR(listener->luma(), luma_green, error_margin);
     composer->removeRegionSamplingListener(listener);
 }
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 5e91088..88168e3 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -27,7 +27,6 @@
 #include <configstore/Utils.h>
 #include <gui/AidlStatusUtil.h>
 #include <gui/BufferItemConsumer.h>
-#include <gui/IProducerListener.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
@@ -82,7 +81,7 @@
     virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& buffers) {
         mDiscardedBuffers.insert(mDiscardedBuffers.end(), buffers.begin(), buffers.end());
     }
-
+    virtual void onBufferDetached(int /*slot*/) {}
     int getReleaseNotifyCount() const {
         return mBuffersReleased;
     }
@@ -491,7 +490,7 @@
 
     sp<Surface> surface = new Surface(producer);
     sp<ANativeWindow> window(surface);
-    sp<StubProducerListener> listener = new StubProducerListener();
+    sp<StubSurfaceListener> listener = new StubSurfaceListener();
     ASSERT_EQ(OK, surface->connect(
             NATIVE_WINDOW_API_CPU,
             /*listener*/listener,
@@ -987,6 +986,19 @@
 
     binder::Status notifyShutdown() override { return binder::Status::ok(); }
 
+    binder::Status addJankListener(const sp<IBinder>& /*layer*/,
+                                   const sp<gui::IJankListener>& /*listener*/) override {
+        return binder::Status::ok();
+    }
+
+    binder::Status flushJankData(int32_t /*layerId*/) override { return binder::Status::ok(); }
+
+    binder::Status removeJankListener(int32_t /*layerId*/,
+                                      const sp<gui::IJankListener>& /*listener*/,
+                                      int64_t /*afterVsync*/) override {
+        return binder::Status::ok();
+    }
+
 protected:
     IBinder* onAsBinder() override { return nullptr; }
 
@@ -2141,7 +2153,7 @@
     sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
     sp<Surface> surface = new Surface(producer);
     sp<ANativeWindow> window(surface);
-    sp<StubProducerListener> listener = new StubProducerListener();
+    sp<StubSurfaceListener> listener = new StubSurfaceListener();
 
     ASSERT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, /*listener*/listener,
             /*reportBufferRemoval*/false));
@@ -2193,7 +2205,7 @@
     sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
     sp<Surface> surface = new Surface(producer);
     sp<ANativeWindow> window(surface);
-    sp<StubProducerListener> listener = new StubProducerListener();
+    sp<StubSurfaceListener> listener = new StubSurfaceListener();
 
     ASSERT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, /*listener*/listener,
             /*reportBufferRemoval*/false));
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index d782f42..8fbf5c6 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -30,6 +30,7 @@
         "android/os/InputEventInjectionResult.aidl",
         "android/os/InputEventInjectionSync.aidl",
         "android/os/InputConfig.aidl",
+        "android/os/MotionEventFlag.aidl",
         "android/os/PointerIconType.aidl",
     ],
 }
@@ -257,6 +258,7 @@
     ],
 
     shared_libs: [
+        "android.companion.virtualdevice.flags-aconfig-cc",
         "libbase",
         "libbinder",
         "libbinder_ndk",
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index b098147..a2bb345 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -580,7 +580,7 @@
                               &pointerProperties[pointerCount]);
     mSampleEventTimes.clear();
     mSamplePointerCoords.clear();
-    addSample(eventTime, pointerCoords);
+    addSample(eventTime, pointerCoords, mId);
 }
 
 void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
@@ -640,9 +640,9 @@
     mSampleEventTimes = other.mSampleEventTimes;
 }
 
-void MotionEvent::addSample(
-        int64_t eventTime,
-        const PointerCoords* pointerCoords) {
+void MotionEvent::addSample(int64_t eventTime, const PointerCoords* pointerCoords,
+                            int32_t eventId) {
+    mId = eventId;
     mSampleEventTimes.push_back(eventTime);
     mSamplePointerCoords.insert(mSamplePointerCoords.end(), &pointerCoords[0],
                                 &pointerCoords[getPointerCount()]);
diff --git a/libs/input/InputConsumer.cpp b/libs/input/InputConsumer.cpp
index fcf490d..1eeb4e6 100644
--- a/libs/input/InputConsumer.cpp
+++ b/libs/input/InputConsumer.cpp
@@ -135,7 +135,7 @@
     }
 
     event.setMetaState(event.getMetaState() | msg.body.motion.metaState);
-    event.addSample(msg.body.motion.eventTime, pointerCoords);
+    event.addSample(msg.body.motion.eventTime, pointerCoords, msg.body.motion.eventId);
 }
 
 void initializeTouchModeEvent(TouchModeEvent& event, const InputMessage& msg) {
@@ -235,8 +235,9 @@
             mMsgDeferred = false;
         } else {
             // Receive a fresh message.
-            status_t result = mChannel->receiveMessage(&mMsg);
-            if (result == OK) {
+            android::base::Result<InputMessage> result = mChannel->receiveMessage();
+            if (result.ok()) {
+                mMsg = std::move(result.value());
                 const auto [_, inserted] =
                         mConsumeTimes.emplace(mMsg.header.seq, systemTime(SYSTEM_TIME_MONOTONIC));
                 LOG_ALWAYS_FATAL_IF(!inserted, "Already have a consume time for seq=%" PRIu32,
@@ -244,11 +245,11 @@
 
                 // Trace the event processing timeline - event was just read from the socket
                 ATRACE_ASYNC_BEGIN(mProcessingTraceTag.c_str(), /*cookie=*/mMsg.header.seq);
-            }
-            if (result) {
+            } else {
                 // Consume the next batched event unless batches are being held for later.
-                if (consumeBatches || result != WOULD_BLOCK) {
-                    result = consumeBatch(factory, frameTime, outSeq, outEvent);
+                if (consumeBatches || result.error().code() != WOULD_BLOCK) {
+                    result = android::base::Error(
+                            consumeBatch(factory, frameTime, outSeq, outEvent));
                     if (*outEvent) {
                         ALOGD_IF(DEBUG_TRANSPORT_CONSUMER,
                                  "channel '%s' consumer ~ consumed batch event, seq=%u",
@@ -256,7 +257,7 @@
                         break;
                     }
                 }
-                return result;
+                return result.error().code();
             }
         }
 
@@ -696,7 +697,7 @@
                  currentCoords.getY(), otherCoords.getX(), otherCoords.getY(), alpha);
     }
 
-    event->addSample(sampleTime, touchState.lastResample.pointers);
+    event->addSample(sampleTime, touchState.lastResample.pointers, event->getId());
 }
 
 status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
diff --git a/libs/input/InputConsumerNoResampling.cpp b/libs/input/InputConsumerNoResampling.cpp
index 15d992f..c145d5c 100644
--- a/libs/input/InputConsumerNoResampling.cpp
+++ b/libs/input/InputConsumerNoResampling.cpp
@@ -114,7 +114,7 @@
 
     // TODO(b/329770983): figure out if it's safe to combine events with mismatching metaState
     event.setMetaState(event.getMetaState() | msg.body.motion.metaState);
-    event.addSample(msg.body.motion.eventTime, pointerCoords.data());
+    event.addSample(msg.body.motion.eventTime, pointerCoords.data(), msg.body.motion.eventId);
 }
 
 std::unique_ptr<TouchModeEvent> createTouchModeEvent(const InputMessage& msg) {
@@ -362,36 +362,36 @@
 std::vector<InputMessage> InputConsumerNoResampling::readAllMessages() {
     std::vector<InputMessage> messages;
     while (true) {
-        InputMessage msg;
-        status_t result = mChannel->receiveMessage(&msg);
-        switch (result) {
-            case OK: {
-                const auto [_, inserted] =
-                        mConsumeTimes.emplace(msg.header.seq, systemTime(SYSTEM_TIME_MONOTONIC));
-                LOG_ALWAYS_FATAL_IF(!inserted, "Already have a consume time for seq=%" PRIu32,
-                                    msg.header.seq);
+        android::base::Result<InputMessage> result = mChannel->receiveMessage();
+        if (result.ok()) {
+            const InputMessage& msg = *result;
+            const auto [_, inserted] =
+                    mConsumeTimes.emplace(msg.header.seq, systemTime(SYSTEM_TIME_MONOTONIC));
+            LOG_ALWAYS_FATAL_IF(!inserted, "Already have a consume time for seq=%" PRIu32,
+                                msg.header.seq);
 
-                // Trace the event processing timeline - event was just read from the socket
-                // TODO(b/329777420): distinguish between multiple instances of InputConsumer
-                // in the same process.
-                ATRACE_ASYNC_BEGIN("InputConsumer processing", /*cookie=*/msg.header.seq);
-                messages.push_back(msg);
-                break;
-            }
-            case WOULD_BLOCK: {
-                return messages;
-            }
-            case DEAD_OBJECT: {
-                LOG(FATAL) << "Got a dead object for " << mChannel->getName();
-                break;
-            }
-            case BAD_VALUE: {
-                LOG(FATAL) << "Got a bad value for " << mChannel->getName();
-                break;
-            }
-            default: {
-                LOG(FATAL) << "Unexpected error: " << result;
-                break;
+            // Trace the event processing timeline - event was just read from the socket
+            // TODO(b/329777420): distinguish between multiple instances of InputConsumer
+            // in the same process.
+            ATRACE_ASYNC_BEGIN("InputConsumer processing", /*cookie=*/msg.header.seq);
+            messages.push_back(msg);
+        } else { // !result.ok()
+            switch (result.error().code()) {
+                case WOULD_BLOCK: {
+                    return messages;
+                }
+                case DEAD_OBJECT: {
+                    LOG(FATAL) << "Got a dead object for " << mChannel->getName();
+                    break;
+                }
+                case BAD_VALUE: {
+                    LOG(FATAL) << "Got a bad value for " << mChannel->getName();
+                    break;
+                }
+                default: {
+                    LOG(FATAL) << "Unexpected error: " << result.error().message();
+                    break;
+                }
             }
         }
     }
@@ -445,6 +445,27 @@
     }
 }
 
+std::pair<std::unique_ptr<MotionEvent>, std::optional<uint32_t>>
+InputConsumerNoResampling::createBatchedMotionEvent(const nsecs_t frameTime,
+                                                    std::queue<InputMessage>& messages) {
+    std::unique_ptr<MotionEvent> motionEvent;
+    std::optional<uint32_t> firstSeqForBatch;
+    while (!messages.empty() && !(messages.front().body.motion.eventTime > frameTime)) {
+        if (motionEvent == nullptr) {
+            motionEvent = createMotionEvent(messages.front());
+            firstSeqForBatch = messages.front().header.seq;
+            const auto [_, inserted] = mBatchedSequenceNumbers.insert({*firstSeqForBatch, {}});
+            LOG_IF(FATAL, !inserted)
+                    << "The sequence " << messages.front().header.seq << " was already present!";
+        } else {
+            addSample(*motionEvent, messages.front());
+            mBatchedSequenceNumbers[*firstSeqForBatch].push_back(messages.front().header.seq);
+        }
+        messages.pop();
+    }
+    return std::make_pair(std::move(motionEvent), firstSeqForBatch);
+}
+
 bool InputConsumerNoResampling::consumeBatchedInputEvents(
         std::optional<nsecs_t> requestedFrameTime) {
     ensureCalledOnLooperThread(__func__);
@@ -452,28 +473,8 @@
     // infinite frameTime.
     const nsecs_t frameTime = requestedFrameTime.value_or(std::numeric_limits<nsecs_t>::max());
     bool producedEvents = false;
-    for (auto& [deviceId, messages] : mBatches) {
-        std::unique_ptr<MotionEvent> motion;
-        std::optional<uint32_t> firstSeqForBatch;
-        std::vector<uint32_t> sequences;
-        while (!messages.empty()) {
-            const InputMessage& msg = messages.front();
-            if (msg.body.motion.eventTime > frameTime) {
-                break;
-            }
-            if (motion == nullptr) {
-                motion = createMotionEvent(msg);
-                firstSeqForBatch = msg.header.seq;
-                const auto [_, inserted] = mBatchedSequenceNumbers.insert({*firstSeqForBatch, {}});
-                if (!inserted) {
-                    LOG(FATAL) << "The sequence " << msg.header.seq << " was already present!";
-                }
-            } else {
-                addSample(*motion, msg);
-                mBatchedSequenceNumbers[*firstSeqForBatch].push_back(msg.header.seq);
-            }
-            messages.pop();
-        }
+    for (auto& [_, messages] : mBatches) {
+        auto [motion, firstSeqForBatch] = createBatchedMotionEvent(frameTime, messages);
         if (motion != nullptr) {
             LOG_ALWAYS_FATAL_IF(!firstSeqForBatch.has_value());
             mCallbacks.onMotionEvent(std::move(motion), *firstSeqForBatch);
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 47b4228..77dcaa9 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -375,13 +375,11 @@
 
     sp<IBinder> token = sp<BBinder>::make();
 
-    std::string serverChannelName = name + " (server)";
     android::base::unique_fd serverFd(sockets[0]);
-    outServerChannel = InputChannel::create(serverChannelName, std::move(serverFd), token);
+    outServerChannel = InputChannel::create(name, std::move(serverFd), token);
 
-    std::string clientChannelName = name + " (client)";
     android::base::unique_fd clientFd(sockets[1]);
-    outClientChannel = InputChannel::create(clientChannelName, std::move(clientFd), token);
+    outClientChannel = InputChannel::create(name, std::move(clientFd), token);
     return OK;
 }
 
@@ -424,10 +422,11 @@
     return OK;
 }
 
-status_t InputChannel::receiveMessage(InputMessage* msg) {
+android::base::Result<InputMessage> InputChannel::receiveMessage() {
     ssize_t nRead;
+    InputMessage msg;
     do {
-        nRead = ::recv(getFd(), msg, sizeof(InputMessage), MSG_DONTWAIT);
+        nRead = ::recv(getFd(), &msg, sizeof(InputMessage), MSG_DONTWAIT);
     } while (nRead == -1 && errno == EINTR);
 
     if (nRead < 0) {
@@ -435,36 +434,36 @@
         ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ receive message failed, errno=%d",
                  name.c_str(), errno);
         if (error == EAGAIN || error == EWOULDBLOCK) {
-            return WOULD_BLOCK;
+            return android::base::Error(WOULD_BLOCK);
         }
         if (error == EPIPE || error == ENOTCONN || error == ECONNREFUSED) {
-            return DEAD_OBJECT;
+            return android::base::Error(DEAD_OBJECT);
         }
-        return -error;
+        return android::base::Error(-error);
     }
 
     if (nRead == 0) { // check for EOF
         ALOGD_IF(DEBUG_CHANNEL_MESSAGES,
                  "channel '%s' ~ receive message failed because peer was closed", name.c_str());
-        return DEAD_OBJECT;
+        return android::base::Error(DEAD_OBJECT);
     }
 
-    if (!msg->isValid(nRead)) {
+    if (!msg.isValid(nRead)) {
         ALOGE("channel '%s' ~ received invalid message of size %zd", name.c_str(), nRead);
-        return BAD_VALUE;
+        return android::base::Error(BAD_VALUE);
     }
 
     ALOGD_IF(DEBUG_CHANNEL_MESSAGES, "channel '%s' ~ received message of type %s", name.c_str(),
-             ftl::enum_string(msg->header.type).c_str());
+             ftl::enum_string(msg.header.type).c_str());
     if (ATRACE_ENABLED()) {
         // Add an additional trace point to include data about the received message.
         std::string message =
                 StringPrintf("receiveMessage(inputChannel=%s, seq=0x%" PRIx32 ", type=%s)",
-                             name.c_str(), msg->header.seq,
-                             ftl::enum_string(msg->header.type).c_str());
+                             name.c_str(), msg.header.seq,
+                             ftl::enum_string(msg.header.type).c_str());
         ATRACE_NAME(message.c_str());
     }
-    return OK;
+    return msg;
 }
 
 bool InputChannel::probablyHasInput() const {
@@ -589,7 +588,8 @@
                 mInputVerifier.processMovement(deviceId, source, action, pointerCount,
                                                pointerProperties, pointerCoords, flags);
         if (!result.ok()) {
-            LOG(FATAL) << "Bad stream: " << result.error();
+            LOG(ERROR) << "Bad stream: " << result.error();
+            return BAD_VALUE;
         }
     }
     if (debugTransportPublisher()) {
@@ -729,15 +729,16 @@
 }
 
 android::base::Result<InputPublisher::ConsumerResponse> InputPublisher::receiveConsumerResponse() {
-    InputMessage msg;
-    status_t result = mChannel->receiveMessage(&msg);
-    if (result) {
-        if (debugTransportPublisher() && result != WOULD_BLOCK) {
+    android::base::Result<InputMessage> result = mChannel->receiveMessage();
+    if (!result.ok()) {
+        if (debugTransportPublisher() && result.error().code() != WOULD_BLOCK) {
             LOG(INFO) << "channel '" << mChannel->getName() << "' publisher ~ " << __func__ << ": "
-                      << strerror(result);
+                      << result.error().message();
         }
-        return android::base::Error(result);
+        return result.error();
     }
+
+    const InputMessage& msg = *result;
     if (msg.header.type == InputMessage::Type::FINISHED) {
         ALOGD_IF(debugTransportPublisher(),
                  "channel '%s' publisher ~ %s: finished: seq=%u, handled=%s",
diff --git a/libs/input/MotionPredictor.cpp b/libs/input/MotionPredictor.cpp
index 5b61d39..9c70535 100644
--- a/libs/input/MotionPredictor.cpp
+++ b/libs/input/MotionPredictor.cpp
@@ -75,6 +75,9 @@
 JerkTracker::JerkTracker(bool normalizedDt) : mNormalizedDt(normalizedDt) {}
 
 void JerkTracker::pushSample(int64_t timestamp, float xPos, float yPos) {
+    // If we previously had full samples, we have a previous jerk calculation
+    // to do weighted smoothing.
+    const bool applySmoothing = mTimestamps.size() == mTimestamps.capacity();
     mTimestamps.pushBack(timestamp);
     const int numSamples = mTimestamps.size();
 
@@ -115,6 +118,16 @@
         }
     }
 
+    if (numSamples == static_cast<int>(mTimestamps.capacity())) {
+        float newJerkMagnitude = std::hypot(newXDerivatives[3], newYDerivatives[3]);
+        ALOGD_IF(isDebug(), "raw jerk: %f", newJerkMagnitude);
+        if (applySmoothing) {
+            mJerkMagnitude = mJerkMagnitude + (mForgetFactor * (newJerkMagnitude - mJerkMagnitude));
+        } else {
+            mJerkMagnitude = newJerkMagnitude;
+        }
+    }
+
     std::swap(newXDerivatives, mXDerivatives);
     std::swap(newYDerivatives, mYDerivatives);
 }
@@ -125,11 +138,19 @@
 
 std::optional<float> JerkTracker::jerkMagnitude() const {
     if (mTimestamps.size() == mTimestamps.capacity()) {
-        return std::hypot(mXDerivatives[3], mYDerivatives[3]);
+        return mJerkMagnitude;
     }
     return std::nullopt;
 }
 
+void JerkTracker::setForgetFactor(float forgetFactor) {
+    mForgetFactor = forgetFactor;
+}
+
+float JerkTracker::getForgetFactor() const {
+    return mForgetFactor;
+}
+
 // --- MotionPredictor ---
 
 MotionPredictor::MotionPredictor(nsecs_t predictionTimestampOffsetNanos,
@@ -159,6 +180,7 @@
     if (!mModel) {
         mModel = TfLiteMotionPredictorModel::create();
         LOG_ALWAYS_FATAL_IF(!mModel);
+        mJerkTracker.setForgetFactor(mModel->config().jerkForgetFactor);
     }
 
     if (!mBuffers) {
@@ -323,7 +345,7 @@
                                    event.getRawTransform(), event.getDownTime(), predictionTime,
                                    event.getPointerCount(), event.getPointerProperties(), &coords);
         } else {
-            prediction->addSample(predictionTime, &coords);
+            prediction->addSample(predictionTime, &coords, prediction->getId());
         }
 
         axisFrom = axisTo;
@@ -357,4 +379,12 @@
     return true;
 }
 
+const TfLiteMotionPredictorModel::Config& MotionPredictor::getModelConfig() {
+    if (!mModel) {
+        mModel = TfLiteMotionPredictorModel::create();
+        LOG_ALWAYS_FATAL_IF(!mModel);
+    }
+    return mModel->config();
+}
+
 } // namespace android
diff --git a/libs/input/TfLiteMotionPredictor.cpp b/libs/input/TfLiteMotionPredictor.cpp
index b843a4b..b401c98 100644
--- a/libs/input/TfLiteMotionPredictor.cpp
+++ b/libs/input/TfLiteMotionPredictor.cpp
@@ -283,6 +283,7 @@
             .distanceNoiseFloor = parseXMLFloat(*configRoot, "distance-noise-floor"),
             .lowJerk = parseXMLFloat(*configRoot, "low-jerk"),
             .highJerk = parseXMLFloat(*configRoot, "high-jerk"),
+            .jerkForgetFactor = parseXMLFloat(*configRoot, "jerk-forget-factor"),
     };
 
     return std::unique_ptr<TfLiteMotionPredictorModel>(
diff --git a/libs/input/VirtualInputDevice.cpp b/libs/input/VirtualInputDevice.cpp
index eea06f1..0579967 100644
--- a/libs/input/VirtualInputDevice.cpp
+++ b/libs/input/VirtualInputDevice.cpp
@@ -18,6 +18,7 @@
 
 #include <android/input.h>
 #include <android/keycodes.h>
+#include <android_companion_virtualdevice_flags.h>
 #include <fcntl.h>
 #include <input/Input.h>
 #include <input/VirtualInputDevice.h>
@@ -40,6 +41,8 @@
 
 namespace android {
 
+namespace vd_flags = android::companion::virtualdevice::flags;
+
 VirtualInputDevice::VirtualInputDevice(unique_fd fd) : mFd(std::move(fd)) {}
 
 VirtualInputDevice::~VirtualInputDevice() {
@@ -253,7 +256,10 @@
         // clang-format on
 };
 
-VirtualMouse::VirtualMouse(unique_fd fd) : VirtualInputDevice(std::move(fd)) {}
+VirtualMouse::VirtualMouse(unique_fd fd)
+      : VirtualInputDevice(std::move(fd)),
+        mAccumulatedHighResScrollX(0),
+        mAccumulatedHighResScrollY(0) {}
 
 VirtualMouse::~VirtualMouse() {}
 
@@ -272,9 +278,47 @@
 
 bool VirtualMouse::writeScrollEvent(float xAxisMovement, float yAxisMovement,
                                     std::chrono::nanoseconds eventTime) {
-    return writeInputEvent(EV_REL, REL_HWHEEL, xAxisMovement, eventTime) &&
-            writeInputEvent(EV_REL, REL_WHEEL, yAxisMovement, eventTime) &&
-            writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
+    if (!vd_flags::high_resolution_scroll()) {
+        return writeInputEvent(EV_REL, REL_HWHEEL, static_cast<int32_t>(xAxisMovement),
+                               eventTime) &&
+                writeInputEvent(EV_REL, REL_WHEEL, static_cast<int32_t>(yAxisMovement),
+                                eventTime) &&
+                writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
+    }
+
+    const auto highResScrollX =
+            static_cast<int32_t>(xAxisMovement * kEvdevHighResScrollUnitsPerDetent);
+    const auto highResScrollY =
+            static_cast<int32_t>(yAxisMovement * kEvdevHighResScrollUnitsPerDetent);
+    bool highResScrollResult =
+            writeInputEvent(EV_REL, REL_HWHEEL_HI_RES, highResScrollX, eventTime) &&
+            writeInputEvent(EV_REL, REL_WHEEL_HI_RES, highResScrollY, eventTime);
+    if (!highResScrollResult) {
+        return false;
+    }
+
+    // According to evdev spec, a high-resolution mouse needs to emit REL_WHEEL / REL_HWHEEL events
+    // in addition to high-res scroll events. Regular scroll events can approximate high-res scroll
+    // events, so we send a regular scroll event when the accumulated scroll motion reaches a detent
+    // (single mouse wheel click).
+    mAccumulatedHighResScrollX += highResScrollX;
+    mAccumulatedHighResScrollY += highResScrollY;
+    const int32_t scrollX = mAccumulatedHighResScrollX / kEvdevHighResScrollUnitsPerDetent;
+    const int32_t scrollY = mAccumulatedHighResScrollY / kEvdevHighResScrollUnitsPerDetent;
+    if (scrollX != 0) {
+        if (!writeInputEvent(EV_REL, REL_HWHEEL, scrollX, eventTime)) {
+            return false;
+        }
+        mAccumulatedHighResScrollX %= kEvdevHighResScrollUnitsPerDetent;
+    }
+    if (scrollY != 0) {
+        if (!writeInputEvent(EV_REL, REL_WHEEL, scrollY, eventTime)) {
+            return false;
+        }
+        mAccumulatedHighResScrollY %= kEvdevHighResScrollUnitsPerDetent;
+    }
+
+    return writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
 }
 
 // --- VirtualTouchscreen ---
@@ -509,4 +553,39 @@
     return true;
 }
 
+// --- VirtualRotaryEncoder ---
+VirtualRotaryEncoder::VirtualRotaryEncoder(unique_fd fd)
+      : VirtualInputDevice(std::move(fd)), mAccumulatedHighResScrollAmount(0) {}
+
+VirtualRotaryEncoder::~VirtualRotaryEncoder() {}
+
+bool VirtualRotaryEncoder::writeScrollEvent(float scrollAmount,
+                                            std::chrono::nanoseconds eventTime) {
+    if (!vd_flags::high_resolution_scroll()) {
+        return writeInputEvent(EV_REL, REL_WHEEL, static_cast<int32_t>(scrollAmount), eventTime) &&
+                writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
+    }
+
+    const auto highResScrollAmount =
+            static_cast<int32_t>(scrollAmount * kEvdevHighResScrollUnitsPerDetent);
+    if (!writeInputEvent(EV_REL, REL_WHEEL_HI_RES, highResScrollAmount, eventTime)) {
+        return false;
+    }
+
+    // According to evdev spec, a high-resolution scroll device needs to emit REL_WHEEL / REL_HWHEEL
+    // events in addition to high-res scroll events. Regular scroll events can approximate high-res
+    // scroll events, so we send a regular scroll event when the accumulated scroll motion reaches a
+    // detent (single wheel click).
+    mAccumulatedHighResScrollAmount += highResScrollAmount;
+    const int32_t scroll = mAccumulatedHighResScrollAmount / kEvdevHighResScrollUnitsPerDetent;
+    if (scroll != 0) {
+        if (!writeInputEvent(EV_REL, REL_WHEEL, scroll, eventTime)) {
+            return false;
+        }
+        mAccumulatedHighResScrollAmount %= kEvdevHighResScrollUnitsPerDetent;
+    }
+
+    return writeInputEvent(EV_SYN, SYN_REPORT, 0, eventTime);
+}
+
 } // namespace android
diff --git a/libs/input/android/os/IInputConstants.aidl b/libs/input/android/os/IInputConstants.aidl
index a77dfa5..e23fc94 100644
--- a/libs/input/android/os/IInputConstants.aidl
+++ b/libs/input/android/os/IInputConstants.aidl
@@ -49,130 +49,24 @@
     const int POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY = 0x20000;
 
     /**
-     * This flag indicates that the window that received this motion event is partly
-     * or wholly obscured by another visible window above it and the event directly passed through
-     * the obscured area.
-     *
-     * A security sensitive application can check this flag to identify situations in which
-     * a malicious application may have covered up part of its content for the purpose
-     * of misleading the user or hijacking touches.  An appropriate response might be
-     * to drop the suspect touches or to take additional precautions to confirm the user's
-     * actual intent.
-     */
-    const int MOTION_EVENT_FLAG_WINDOW_IS_OBSCURED = 0x1;
-
-    /**
-     * This flag indicates that the window that received this motion event is partly
-     * or wholly obscured by another visible window above it and the event did not directly pass
-     * through the obscured area.
-     *
-     * A security sensitive application can check this flag to identify situations in which
-     * a malicious application may have covered up part of its content for the purpose
-     * of misleading the user or hijacking touches.  An appropriate response might be
-     * to drop the suspect touches or to take additional precautions to confirm the user's
-     * actual intent.
-     *
-     * Unlike FLAG_WINDOW_IS_OBSCURED, this is only true if the window that received this event is
-     * obstructed in areas other than the touched location.
-     */
-    const int MOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 0x2;
-
-    /**
-     * This private flag is only set on {@link #ACTION_HOVER_MOVE} events and indicates that
-     * this event will be immediately followed by a {@link #ACTION_HOVER_EXIT}. It is used to
-     * prevent generating redundant {@link #ACTION_HOVER_ENTER} events.
-     * @hide
-     */
-    const int MOTION_EVENT_FLAG_HOVER_EXIT_PENDING = 0x4;
-
-    /**
-     * This flag indicates that the event has been generated by a gesture generator. It
-     * provides a hint to the GestureDetector to not apply any touch slop.
-     *
-     * @hide
-     */
-    const int MOTION_EVENT_FLAG_IS_GENERATED_GESTURE = 0x8;
-
-    /**
-     * This flag is only set for events with {@link #ACTION_POINTER_UP} and {@link #ACTION_CANCEL}.
-     * It indicates that the pointer going up was an unintentional user touch. When FLAG_CANCELED
-     * is set, the typical actions that occur in response for a pointer going up (such as click
-     * handlers, end of drawing) should be aborted. This flag is typically set when the user was
-     * accidentally touching the screen, such as by gripping the device, or placing the palm on the
-     * screen.
-     *
-     * @see #ACTION_POINTER_UP
-     * @see #ACTION_CANCEL
+     * Common input event flag used for both motion and key events for a gesture or pointer being
+     * canceled.
      */
     const int INPUT_EVENT_FLAG_CANCELED = 0x20;
 
     /**
-     * This flag indicates that the event will not cause a focus change if it is directed to an
-     * unfocused window, even if it an {@link #ACTION_DOWN}. This is typically used with pointer
-     * gestures to allow the user to direct gestures to an unfocused window without bringing the
-     * window into focus.
-     * @hide
-     */
-    const int MOTION_EVENT_FLAG_NO_FOCUS_CHANGE = 0x40;
-
-    /**
-     * This flag indicates that the event has a valid value for AXIS_ORIENTATION.
-     *
-     * This is a private flag that is not used in Java.
-     * @hide
-     */
-    const int MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION = 0x80;
-
-    /**
-     * This flag indicates that the pointers' AXIS_ORIENTATION can be used to precisely determine
-     * the direction in which the tool is pointing. The value of the orientation axis will be in
-     * the range [-pi, pi], which represents a full circle. This is usually supported by devices
-     * like styluses.
-     *
-     * Conversely, AXIS_ORIENTATION cannot be used to tell which direction the tool is pointing
-     * when this flag is not set. In this case, the axis value will have a range of [-pi/2, pi/2],
-     * which represents half a circle. This is usually the case for devices like touchscreens and
-     * touchpads, for which it is difficult to tell which direction along the major axis of the
-     * touch ellipse the finger is pointing.
-     *
-     * This is a private flag that is not used in Java.
-     * @hide
-     */
-    const int MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION = 0x100;
-
-    /**
-     * The input event was generated or modified by accessibility service.
-     * Shared by both KeyEvent and MotionEvent flags, so this value should not overlap with either
-     * set of flags, including in input/Input.h and in android/input.h.
+     * Common input event flag used for both motion and key events, indicating that the event
+     * was generated or modified by accessibility service.
      */
     const int INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT = 0x800;
 
     /**
-     * Private flag that indicates when the system has detected that this motion event
-     * may be inconsistent with respect to the sequence of previously delivered motion events,
-     * such as when a pointer move event is sent but the pointer is not down.
-     *
-     * @hide
-     * @see #isTainted
-     * @see #setTainted
+     * Common input event flag used for both motion and key events, indicating that the system has
+     * detected this event may be inconsistent with the current event sequence or gesture, such as
+     * when a pointer move event is sent but the pointer is not down.
      */
     const int INPUT_EVENT_FLAG_TAINTED = 0x80000000;
 
-    /**
-     * Private flag indicating that this event was synthesized by the system and should be delivered
-     * to the accessibility focused view first. When being dispatched such an event is not handled
-     * by predecessors of the accessibility focused view and after the event reaches that view the
-     * flag is cleared and normal event dispatch is performed. This ensures that the platform can
-     * click on any view that has accessibility focus which is semantically equivalent to asking the
-     * view to perform a click accessibility action but more generic as views not implementing click
-     * action correctly can still be activated.
-     *
-     * @hide
-     * @see #isTargetAccessibilityFocus()
-     * @see #setTargetAccessibilityFocus(boolean)
-     */
-    const int MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS = 0x40000000;
-
     /* The default pointer acceleration value. */
     const int DEFAULT_POINTER_ACCELERATION = 3;
 
diff --git a/libs/input/android/os/MotionEventFlag.aidl b/libs/input/android/os/MotionEventFlag.aidl
new file mode 100644
index 0000000..2093b06
--- /dev/null
+++ b/libs/input/android/os/MotionEventFlag.aidl
@@ -0,0 +1,152 @@
+/**
+ * Copyright 2024, 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;
+
+import android.os.IInputConstants;
+
+/**
+ * Flag definitions for MotionEvents.
+ * @hide
+ */
+@Backing(type="int")
+enum MotionEventFlag {
+
+    /**
+     * This flag indicates that the window that received this motion event is partly
+     * or wholly obscured by another visible window above it and the event directly passed through
+     * the obscured area.
+     *
+     * A security sensitive application can check this flag to identify situations in which
+     * a malicious application may have covered up part of its content for the purpose
+     * of misleading the user or hijacking touches.  An appropriate response might be
+     * to drop the suspect touches or to take additional precautions to confirm the user's
+     * actual intent.
+     */
+    WINDOW_IS_OBSCURED = 0x1,
+
+    /**
+     * This flag indicates that the window that received this motion event is partly
+     * or wholly obscured by another visible window above it and the event did not directly pass
+     * through the obscured area.
+     *
+     * A security sensitive application can check this flag to identify situations in which
+     * a malicious application may have covered up part of its content for the purpose
+     * of misleading the user or hijacking touches.  An appropriate response might be
+     * to drop the suspect touches or to take additional precautions to confirm the user's
+     * actual intent.
+     *
+     * Unlike FLAG_WINDOW_IS_OBSCURED, this is only true if the window that received this event is
+     * obstructed in areas other than the touched location.
+     */
+    WINDOW_IS_PARTIALLY_OBSCURED = 0x2,
+
+    /**
+     * This private flag is only set on {@link #ACTION_HOVER_MOVE} events and indicates that
+     * this event will be immediately followed by a {@link #ACTION_HOVER_EXIT}. It is used to
+     * prevent generating redundant {@link #ACTION_HOVER_ENTER} events.
+     * @hide
+     */
+    HOVER_EXIT_PENDING = 0x4,
+
+    /**
+     * This flag indicates that the event has been generated by a gesture generator. It
+     * provides a hint to the GestureDetector to not apply any touch slop.
+     *
+     * @hide
+     */
+    IS_GENERATED_GESTURE = 0x8,
+
+    /**
+     * This flag is only set for events with {@link #ACTION_POINTER_UP} and {@link #ACTION_CANCEL}.
+     * It indicates that the pointer going up was an unintentional user touch. When FLAG_CANCELED
+     * is set, the typical actions that occur in response for a pointer going up (such as click
+     * handlers, end of drawing) should be aborted. This flag is typically set when the user was
+     * accidentally touching the screen, such as by gripping the device, or placing the palm on the
+     * screen.
+     *
+     * @see #ACTION_POINTER_UP
+     * @see #ACTION_CANCEL
+     */
+    CANCELED = IInputConstants.INPUT_EVENT_FLAG_CANCELED,
+
+    /**
+     * This flag indicates that the event will not cause a focus change if it is directed to an
+     * unfocused window, even if it an {@link #ACTION_DOWN}. This is typically used with pointer
+     * gestures to allow the user to direct gestures to an unfocused window without bringing the
+     * window into focus.
+     * @hide
+     */
+    NO_FOCUS_CHANGE = 0x40,
+
+    /**
+     * This flag indicates that the event has a valid value for AXIS_ORIENTATION.
+     *
+     * This is a private flag that is not used in Java.
+     * @hide
+     */
+    PRIVATE_FLAG_SUPPORTS_ORIENTATION = 0x80,
+
+    /**
+     * This flag indicates that the pointers' AXIS_ORIENTATION can be used to precisely determine
+     * the direction in which the tool is pointing. The value of the orientation axis will be in
+     * the range [-pi, pi], which represents a full circle. This is usually supported by devices
+     * like styluses.
+     *
+     * Conversely, AXIS_ORIENTATION cannot be used to tell which direction the tool is pointing
+     * when this flag is not set. In this case, the axis value will have a range of [-pi/2, pi/2],
+     * which represents half a circle. This is usually the case for devices like touchscreens and
+     * touchpads, for which it is difficult to tell which direction along the major axis of the
+     * touch ellipse the finger is pointing.
+     *
+     * This is a private flag that is not used in Java.
+     * @hide
+     */
+    PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION = 0x100,
+
+    /**
+     * The input event was generated or modified by accessibility service.
+     * Shared by both KeyEvent and MotionEvent flags, so this value should not overlap with either
+     * set of flags, including in input/Input.h and in android/input.h.
+     */
+    IS_ACCESSIBILITY_EVENT = IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT,
+
+    /**
+     * Private flag that indicates when the system has detected that this motion event
+     * may be inconsistent with respect to the sequence of previously delivered motion events,
+     * such as when a pointer move event is sent but the pointer is not down.
+     *
+     * @hide
+     * @see #isTainted
+     * @see #setTainted
+     */
+    TAINTED = IInputConstants.INPUT_EVENT_FLAG_TAINTED,
+
+    /**
+     * Private flag indicating that this event was synthesized by the system and should be delivered
+     * to the accessibility focused view first. When being dispatched such an event is not handled
+     * by predecessors of the accessibility focused view and after the event reaches that view the
+     * flag is cleared and normal event dispatch is performed. This ensures that the platform can
+     * click on any view that has accessibility focus which is semantically equivalent to asking the
+     * view to perform a click accessibility action but more generic as views not implementing click
+     * action correctly can still be activated.
+     *
+     * @hide
+     * @see #isTargetAccessibilityFocus()
+     * @see #setTargetAccessibilityFocus(boolean)
+     */
+    TARGET_ACCESSIBILITY_FOCUS = 0x40000000,
+}
diff --git a/libs/input/input_flags.aconfig b/libs/input/input_flags.aconfig
index a2192cb..3830751 100644
--- a/libs/input/input_flags.aconfig
+++ b/libs/input/input_flags.aconfig
@@ -16,13 +16,13 @@
 }
 
 flag {
-  name: "enable_gestures_library_timer_provider"
+  name: "remove_input_channel_from_windowstate"
   namespace: "input"
-  description: "Set to true to enable timer support for the touchpad Gestures library"
-  bug: "297192727"
- }
+  description: "Do not store a copy of input channel inside WindowState."
+  bug: "323450804"
+}
 
- flag {
+flag {
   name: "enable_input_event_tracing"
   namespace: "input"
   description: "Set to true to enable input event tracing, including always-on tracing on non-user builds"
@@ -87,13 +87,6 @@
 }
 
 flag {
-  name: "remove_pointer_event_tracking_in_wm"
-  namespace: "input"
-  description: "Remove pointer event tracking in WM after the Pointer Icon Refactor"
-  bug: "315321016"
-}
-
-flag {
   name: "enable_new_mouse_pointer_ballistics"
   namespace: "input"
   description: "Change the acceleration curves for mouse pointer movements to match the touchpad ones"
@@ -157,3 +150,10 @@
   description: "Keyboard classifier that classifies all keyboards into alphabetic or non-alphabetic"
   bug: "263559234"
 }
+
+flag {
+  name: "show_pointers_for_partial_screenshare"
+  namespace: "input"
+  description: "Show touch and pointer indicators when mirroring a single task"
+  bug: "310179437"
+}
diff --git a/libs/input/rust/Android.bp b/libs/input/rust/Android.bp
index 018d199..63853f7 100644
--- a/libs/input/rust/Android.bp
+++ b/libs/input/rust/Android.bp
@@ -24,6 +24,8 @@
         "liblogger",
         "liblog_rust",
         "inputconstants-rust",
+        "libserde",
+        "libserde_json",
     ],
     whole_static_libs: [
         "libinput_from_rust_to_cpp",
diff --git a/libs/input/rust/data_store.rs b/libs/input/rust/data_store.rs
new file mode 100644
index 0000000..6bdcefd
--- /dev/null
+++ b/libs/input/rust/data_store.rs
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2024 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.
+ */
+
+//! Contains the DataStore, used to store input related data in a persistent way.
+
+use crate::input::KeyboardType;
+use log::{debug, error};
+use serde::{Deserialize, Serialize};
+use std::fs::File;
+use std::io::{Read, Write};
+use std::path::Path;
+use std::sync::{Arc, RwLock};
+
+/// Data store to be used to store information that persistent across device reboots.
+pub struct DataStore {
+    file_reader_writer: Box<dyn FileReaderWriter>,
+    inner: Arc<RwLock<DataStoreInner>>,
+}
+
+#[derive(Default)]
+struct DataStoreInner {
+    is_loaded: bool,
+    data: Data,
+}
+
+#[derive(Default, Serialize, Deserialize)]
+struct Data {
+    // Map storing data for keyboard classification for specific devices.
+    #[serde(default)]
+    keyboard_classifications: Vec<KeyboardClassification>,
+    // NOTE: Important things to consider:
+    // - Add any data that needs to be persisted here in this struct.
+    // - Mark all new fields with "#[serde(default)]" for backward compatibility.
+    // - Also, you can't modify the already added fields.
+    // - Can add new nested fields to existing structs. e.g. Add another field to the struct
+    //   KeyboardClassification and mark it "#[serde(default)]".
+}
+
+#[derive(Default, Serialize, Deserialize)]
+struct KeyboardClassification {
+    descriptor: String,
+    keyboard_type: KeyboardType,
+    is_finalized: bool,
+}
+
+impl DataStore {
+    /// Creates a new instance of Data store
+    pub fn new(file_reader_writer: Box<dyn FileReaderWriter>) -> Self {
+        Self { file_reader_writer, inner: Default::default() }
+    }
+
+    fn load(&mut self) {
+        if self.inner.read().unwrap().is_loaded {
+            return;
+        }
+        self.load_internal();
+    }
+
+    fn load_internal(&mut self) {
+        let s = self.file_reader_writer.read();
+        let data: Data = if !s.is_empty() {
+            let deserialize: Data = match serde_json::from_str(&s) {
+                Ok(deserialize) => deserialize,
+                Err(msg) => {
+                    error!("Unable to deserialize JSON data into struct: {:?} -> {:?}", msg, s);
+                    Default::default()
+                }
+            };
+            deserialize
+        } else {
+            Default::default()
+        };
+
+        let mut inner = self.inner.write().unwrap();
+        inner.data = data;
+        inner.is_loaded = true;
+    }
+
+    fn save(&mut self) {
+        let string_to_save;
+        {
+            let inner = self.inner.read().unwrap();
+            string_to_save = serde_json::to_string(&inner.data).unwrap();
+        }
+        self.file_reader_writer.write(string_to_save);
+    }
+
+    /// Get keyboard type of the device (as stored in the data store)
+    pub fn get_keyboard_type(&mut self, descriptor: &String) -> Option<(KeyboardType, bool)> {
+        self.load();
+        let data = &self.inner.read().unwrap().data;
+        for keyboard_classification in data.keyboard_classifications.iter() {
+            if keyboard_classification.descriptor == *descriptor {
+                return Some((
+                    keyboard_classification.keyboard_type,
+                    keyboard_classification.is_finalized,
+                ));
+            }
+        }
+        None
+    }
+
+    /// Save keyboard type of the device in the data store
+    pub fn set_keyboard_type(
+        &mut self,
+        descriptor: &String,
+        keyboard_type: KeyboardType,
+        is_finalized: bool,
+    ) {
+        {
+            let data = &mut self.inner.write().unwrap().data;
+            data.keyboard_classifications
+                .retain(|classification| classification.descriptor != *descriptor);
+            data.keyboard_classifications.push(KeyboardClassification {
+                descriptor: descriptor.to_string(),
+                keyboard_type,
+                is_finalized,
+            })
+        }
+        self.save();
+    }
+}
+
+pub trait FileReaderWriter {
+    fn read(&self) -> String;
+    fn write(&self, to_write: String);
+}
+
+/// Default file reader writer implementation
+pub struct DefaultFileReaderWriter {
+    filepath: String,
+}
+
+impl DefaultFileReaderWriter {
+    /// Creates a new instance of Default file reader writer that can read and write string to a
+    /// particular file in the filesystem
+    pub fn new(filepath: String) -> Self {
+        Self { filepath }
+    }
+}
+
+impl FileReaderWriter for DefaultFileReaderWriter {
+    fn read(&self) -> String {
+        let path = Path::new(&self.filepath);
+        let mut fs_string = String::new();
+        match File::open(path) {
+            Err(e) => error!("couldn't open {:?}: {}", path, e),
+            Ok(mut file) => match file.read_to_string(&mut fs_string) {
+                Err(e) => error!("Couldn't read from {:?}: {}", path, e),
+                Ok(_) => debug!("Successfully read from file {:?}", path),
+            },
+        };
+        fs_string
+    }
+
+    fn write(&self, to_write: String) {
+        let path = Path::new(&self.filepath);
+        match File::create(path) {
+            Err(e) => error!("couldn't create {:?}: {}", path, e),
+            Ok(mut file) => match file.write_all(to_write.as_bytes()) {
+                Err(e) => error!("Couldn't write to {:?}: {}", path, e),
+                Ok(_) => debug!("Successfully saved to file {:?}", path),
+            },
+        };
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::data_store::{
+        test_file_reader_writer::TestFileReaderWriter, DataStore, FileReaderWriter,
+    };
+    use crate::input::KeyboardType;
+
+    #[test]
+    fn test_backward_compatibility_version_1() {
+        // This test tests JSON string that will be created by the first version of data store
+        // This test SHOULD NOT be modified
+        let test_reader_writer = TestFileReaderWriter::new();
+        test_reader_writer.write(r#"{"keyboard_classifications":[{"descriptor":"descriptor","keyboard_type":{"type":"Alphabetic"},"is_finalized":true}]}"#.to_string());
+
+        let mut data_store = DataStore::new(Box::new(test_reader_writer));
+        let (keyboard_type, is_finalized) =
+            data_store.get_keyboard_type(&"descriptor".to_string()).unwrap();
+        assert_eq!(keyboard_type, KeyboardType::Alphabetic);
+        assert!(is_finalized);
+    }
+}
+
+#[cfg(test)]
+pub mod test_file_reader_writer {
+
+    use crate::data_store::FileReaderWriter;
+    use std::sync::{Arc, RwLock};
+
+    #[derive(Default)]
+    struct TestFileReaderWriterInner {
+        fs_string: String,
+    }
+
+    #[derive(Default, Clone)]
+    pub struct TestFileReaderWriter(Arc<RwLock<TestFileReaderWriterInner>>);
+
+    impl TestFileReaderWriter {
+        pub fn new() -> Self {
+            Default::default()
+        }
+    }
+
+    impl FileReaderWriter for TestFileReaderWriter {
+        fn read(&self) -> String {
+            self.0.read().unwrap().fs_string.clone()
+        }
+
+        fn write(&self, fs_string: String) {
+            self.0.write().unwrap().fs_string = fs_string;
+        }
+    }
+}
diff --git a/libs/input/rust/input.rs b/libs/input/rust/input.rs
index 564d94d..90f509d 100644
--- a/libs/input/rust/input.rs
+++ b/libs/input/rust/input.rs
@@ -19,6 +19,8 @@
 use crate::ffi::RustInputDeviceIdentifier;
 use bitflags::bitflags;
 use inputconstants::aidl::android::os::IInputConstants;
+use inputconstants::aidl::android::os::MotionEventFlag::MotionEventFlag;
+use serde::{Deserialize, Serialize};
 use std::fmt;
 
 /// The InputDevice ID.
@@ -193,31 +195,34 @@
 
 bitflags! {
     /// MotionEvent flags.
+    /// The source of truth for the flag definitions are the MotionEventFlag AIDL enum.
+    /// The flag values are redefined here as a bitflags API.
     #[derive(Debug)]
     pub struct MotionFlags: u32 {
         /// FLAG_WINDOW_IS_OBSCURED
-        const WINDOW_IS_OBSCURED = IInputConstants::MOTION_EVENT_FLAG_WINDOW_IS_OBSCURED as u32;
+        const WINDOW_IS_OBSCURED = MotionEventFlag::WINDOW_IS_OBSCURED.0 as u32;
         /// FLAG_WINDOW_IS_PARTIALLY_OBSCURED
-        const WINDOW_IS_PARTIALLY_OBSCURED = IInputConstants::MOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED as u32;
+        const WINDOW_IS_PARTIALLY_OBSCURED = MotionEventFlag::WINDOW_IS_PARTIALLY_OBSCURED.0 as u32;
         /// FLAG_HOVER_EXIT_PENDING
-        const HOVER_EXIT_PENDING = IInputConstants::MOTION_EVENT_FLAG_HOVER_EXIT_PENDING as u32;
+        const HOVER_EXIT_PENDING = MotionEventFlag::HOVER_EXIT_PENDING.0 as u32;
         /// FLAG_IS_GENERATED_GESTURE
-        const IS_GENERATED_GESTURE = IInputConstants::MOTION_EVENT_FLAG_IS_GENERATED_GESTURE as u32;
+        const IS_GENERATED_GESTURE = MotionEventFlag::IS_GENERATED_GESTURE.0 as u32;
         /// FLAG_CANCELED
-        const CANCELED = IInputConstants::INPUT_EVENT_FLAG_CANCELED as u32;
+        const CANCELED = MotionEventFlag::CANCELED.0 as u32;
         /// FLAG_NO_FOCUS_CHANGE
-        const NO_FOCUS_CHANGE = IInputConstants::MOTION_EVENT_FLAG_NO_FOCUS_CHANGE as u32;
+        const NO_FOCUS_CHANGE = MotionEventFlag::NO_FOCUS_CHANGE.0 as u32;
         /// PRIVATE_FLAG_SUPPORTS_ORIENTATION
-        const PRIVATE_SUPPORTS_ORIENTATION = IInputConstants::MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_ORIENTATION as u32;
+        const PRIVATE_FLAG_SUPPORTS_ORIENTATION =
+                MotionEventFlag::PRIVATE_FLAG_SUPPORTS_ORIENTATION.0 as u32;
         /// PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION
-        const PRIVATE_SUPPORTS_DIRECTIONAL_ORIENTATION =
-                IInputConstants::MOTION_EVENT_PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION as u32;
+        const PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION =
+                MotionEventFlag::PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION.0 as u32;
         /// FLAG_IS_ACCESSIBILITY_EVENT
-        const IS_ACCESSIBILITY_EVENT = IInputConstants::INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT as u32;
+        const IS_ACCESSIBILITY_EVENT = MotionEventFlag::IS_ACCESSIBILITY_EVENT.0 as u32;
         /// FLAG_TAINTED
-        const TAINTED = IInputConstants::INPUT_EVENT_FLAG_TAINTED as u32;
+        const TAINTED = MotionEventFlag::TAINTED.0 as u32;
         /// FLAG_TARGET_ACCESSIBILITY_FOCUS
-        const TARGET_ACCESSIBILITY_FOCUS = IInputConstants::MOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS as u32;
+        const TARGET_ACCESSIBILITY_FOCUS = MotionEventFlag::TARGET_ACCESSIBILITY_FOCUS.0 as u32;
     }
 }
 
@@ -320,9 +325,11 @@
 
 /// A rust enum representation of a Keyboard type.
 #[repr(u32)]
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
+#[serde(tag = "type")]
 pub enum KeyboardType {
     /// KEYBOARD_TYPE_NONE
+    #[default]
     None = input_bindgen::AINPUT_KEYBOARD_TYPE_NONE,
     /// KEYBOARD_TYPE_NON_ALPHABETIC
     NonAlphabetic = input_bindgen::AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC,
@@ -333,10 +340,24 @@
 #[cfg(test)]
 mod tests {
     use crate::input::SourceClass;
+    use crate::MotionFlags;
     use crate::Source;
+    use inputconstants::aidl::android::os::MotionEventFlag::MotionEventFlag;
+
     #[test]
     fn convert_source_class_pointer() {
         let source = Source::from_bits(input_bindgen::AINPUT_SOURCE_CLASS_POINTER).unwrap();
         assert!(source.is_from_class(SourceClass::Pointer));
     }
+
+    /// Ensure all MotionEventFlag constants are re-defined in rust.
+    #[test]
+    fn all_motion_event_flags_defined() {
+        for flag in MotionEventFlag::enum_values() {
+            assert!(
+                MotionFlags::from_bits(flag.0 as u32).is_some(),
+                "MotionEventFlag value {flag:?} is not redefined as a rust MotionFlags"
+            );
+        }
+    }
 }
diff --git a/libs/input/rust/keyboard_classification_config.rs b/libs/input/rust/keyboard_classification_config.rs
new file mode 100644
index 0000000..ab74efb
--- /dev/null
+++ b/libs/input/rust/keyboard_classification_config.rs
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2024 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::input::KeyboardType;
+
+// TODO(b/263559234): Categorize some of these to KeyboardType::None based on ability to produce
+//  key events at all. (Requires setup allowing InputDevice to dynamically add/remove
+//  KeyboardInputMapper based on blocklist and KeyEvents in case a KeyboardType::None device ends
+//  up producing a key event)
+pub static CLASSIFIED_DEVICES: &[(
+    /* vendorId */ u16,
+    /* productId */ u16,
+    KeyboardType,
+    /* is_finalized */ bool,
+)] = &[
+    // HP X4000 Wireless Mouse
+    (0x03f0, 0xa407, KeyboardType::NonAlphabetic, true),
+    // Microsoft Wireless Mobile Mouse 6000
+    (0x045e, 0x0745, KeyboardType::NonAlphabetic, true),
+    // Microsoft Surface Precision Mouse
+    (0x045e, 0x0821, KeyboardType::NonAlphabetic, true),
+    // Microsoft Pro IntelliMouse
+    (0x045e, 0x082a, KeyboardType::NonAlphabetic, true),
+    // Microsoft Bluetooth Mouse
+    (0x045e, 0x082f, KeyboardType::NonAlphabetic, true),
+    // Xbox One Elite Series 2 gamepad
+    (0x045e, 0x0b05, KeyboardType::NonAlphabetic, true),
+    // Logitech T400
+    (0x046d, 0x4026, KeyboardType::NonAlphabetic, true),
+    // Logitech M720 Triathlon (Unifying)
+    (0x046d, 0x405e, KeyboardType::NonAlphabetic, true),
+    // Logitech MX Master 2S (Unifying)
+    (0x046d, 0x4069, KeyboardType::NonAlphabetic, true),
+    // Logitech M585 (Unifying)
+    (0x046d, 0x406b, KeyboardType::NonAlphabetic, true),
+    // Logitech MX Anywhere 2 (Unifying)
+    (0x046d, 0x4072, KeyboardType::NonAlphabetic, true),
+    // Logitech Pebble M350
+    (0x046d, 0x4080, KeyboardType::NonAlphabetic, true),
+    // Logitech T630 Ultrathin
+    (0x046d, 0xb00d, KeyboardType::NonAlphabetic, true),
+    // Logitech M558
+    (0x046d, 0xb011, KeyboardType::NonAlphabetic, true),
+    // Logitech MX Master (Bluetooth)
+    (0x046d, 0xb012, KeyboardType::NonAlphabetic, true),
+    // Logitech MX Anywhere 2 (Bluetooth)
+    (0x046d, 0xb013, KeyboardType::NonAlphabetic, true),
+    // Logitech M720 Triathlon (Bluetooth)
+    (0x046d, 0xb015, KeyboardType::NonAlphabetic, true),
+    // Logitech M535
+    (0x046d, 0xb016, KeyboardType::NonAlphabetic, true),
+    // Logitech MX Master / Anywhere 2 (Bluetooth)
+    (0x046d, 0xb017, KeyboardType::NonAlphabetic, true),
+    // Logitech MX Master 2S (Bluetooth)
+    (0x046d, 0xb019, KeyboardType::NonAlphabetic, true),
+    // Logitech MX Anywhere 2S (Bluetooth)
+    (0x046d, 0xb01a, KeyboardType::NonAlphabetic, true),
+    // Logitech M585/M590 (Bluetooth)
+    (0x046d, 0xb01b, KeyboardType::NonAlphabetic, true),
+    // Logitech G603 Lightspeed Gaming Mouse (Bluetooth)
+    (0x046d, 0xb01c, KeyboardType::NonAlphabetic, true),
+    // Logitech MX Master (Bluetooth)
+    (0x046d, 0xb01e, KeyboardType::NonAlphabetic, true),
+    // Logitech MX Anywhere 2 (Bluetooth)
+    (0x046d, 0xb01f, KeyboardType::NonAlphabetic, true),
+    // Logitech MX Master 3 (Bluetooth)
+    (0x046d, 0xb023, KeyboardType::NonAlphabetic, true),
+    // Logitech G604 Lightspeed Gaming Mouse (Bluetooth)
+    (0x046d, 0xb024, KeyboardType::NonAlphabetic, true),
+    // Logitech Spotlight Presentation Remote (Bluetooth)
+    (0x046d, 0xb503, KeyboardType::NonAlphabetic, true),
+    // Logitech R500 (Bluetooth)
+    (0x046d, 0xb505, KeyboardType::NonAlphabetic, true),
+    // Logitech M500s
+    (0x046d, 0xc093, KeyboardType::NonAlphabetic, true),
+    // Logitech Spotlight Presentation Remote (USB dongle)
+    (0x046d, 0xc53e, KeyboardType::NonAlphabetic, true),
+    // Elecom Enelo IR LED Mouse 350
+    (0x056e, 0x0134, KeyboardType::NonAlphabetic, true),
+    // Elecom EPRIM Blue LED 5 button mouse 228
+    (0x056e, 0x0141, KeyboardType::NonAlphabetic, true),
+    // Elecom Blue LED Mouse 203
+    (0x056e, 0x0159, KeyboardType::NonAlphabetic, true),
+    // Zebra LS2208 barcode scanner
+    (0x05e0, 0x1200, KeyboardType::NonAlphabetic, true),
+    // RDing FootSwitch1F1
+    (0x0c45, 0x7403, KeyboardType::NonAlphabetic, true),
+    // SteelSeries Sensei RAW Frost Blue
+    (0x1038, 0x1369, KeyboardType::NonAlphabetic, true),
+    // SteelSeries Rival 3 Wired
+    (0x1038, 0x1824, KeyboardType::NonAlphabetic, true),
+    // SteelSeries Rival 3 Wireless (USB dongle)
+    (0x1038, 0x1830, KeyboardType::NonAlphabetic, true),
+    // Yubico.com Yubikey
+    (0x1050, 0x0010, KeyboardType::NonAlphabetic, true),
+    // Yubico.com Yubikey 4 OTP+U2F+CCID
+    (0x1050, 0x0407, KeyboardType::NonAlphabetic, true),
+    // Lenovo USB-C Wired Compact Mouse
+    (0x17ef, 0x6123, KeyboardType::NonAlphabetic, true),
+    // Corsair Katar Pro Wireless (USB dongle)
+    (0x1b1c, 0x1b94, KeyboardType::NonAlphabetic, true),
+    // Corsair Katar Pro Wireless (Bluetooth)
+    (0x1bae, 0x1b1c, KeyboardType::NonAlphabetic, true),
+    // Kensington Pro Fit Full-size
+    (0x1bcf, 0x08a0, KeyboardType::NonAlphabetic, true),
+    // Huion HS64
+    (0x256c, 0x006d, KeyboardType::NonAlphabetic, true),
+    // XP-Pen Star G640
+    (0x28bd, 0x0914, KeyboardType::NonAlphabetic, true),
+    // XP-Pen Artist 12 Pro
+    (0x28bd, 0x091f, KeyboardType::NonAlphabetic, true),
+    // XP-Pen Deco mini7W
+    (0x28bd, 0x0928, KeyboardType::NonAlphabetic, true),
+];
diff --git a/libs/input/rust/keyboard_classifier.rs b/libs/input/rust/keyboard_classifier.rs
index 1063fac..3c789b4 100644
--- a/libs/input/rust/keyboard_classifier.rs
+++ b/libs/input/rust/keyboard_classifier.rs
@@ -31,39 +31,37 @@
 //!    across multiple device connections in a time period, then change type to
 //!    KeyboardType::NonAlphabetic. Once changed, it can still change back to Alphabetic
 //!    (i.e. verified = false).
-//!
-//! TODO(b/263559234): Data store implementation to store information about past classification
 
+use crate::data_store::DataStore;
 use crate::input::{DeviceId, InputDevice, KeyboardType};
+use crate::keyboard_classification_config::CLASSIFIED_DEVICES;
 use crate::{DeviceClass, ModifierState};
 use std::collections::HashMap;
 
 /// The KeyboardClassifier is used to classify a keyboard device into non-keyboard, alphabetic
 /// keyboard or non-alphabetic keyboard
-#[derive(Default)]
 pub struct KeyboardClassifier {
     device_map: HashMap<DeviceId, KeyboardInfo>,
+    data_store: DataStore,
 }
 
 struct KeyboardInfo {
-    _device: InputDevice,
+    device: InputDevice,
     keyboard_type: KeyboardType,
     is_finalized: bool,
 }
 
 impl KeyboardClassifier {
     /// Create a new KeyboardClassifier
-    pub fn new() -> Self {
-        Default::default()
+    pub fn new(data_store: DataStore) -> Self {
+        Self { device_map: HashMap::new(), data_store }
     }
 
     /// Adds keyboard to KeyboardClassifier
     pub fn notify_keyboard_changed(&mut self, device: InputDevice) {
         let (keyboard_type, is_finalized) = self.classify_keyboard(&device);
-        self.device_map.insert(
-            device.device_id,
-            KeyboardInfo { _device: device, keyboard_type, is_finalized },
-        );
+        self.device_map
+            .insert(device.device_id, KeyboardInfo { device, keyboard_type, is_finalized });
     }
 
     /// Get keyboard type for a tracked keyboard in KeyboardClassifier
@@ -106,11 +104,16 @@
             if Self::is_alphabetic_key(&evdev_code) {
                 keyboard.keyboard_type = KeyboardType::Alphabetic;
                 keyboard.is_finalized = true;
+                self.data_store.set_keyboard_type(
+                    &keyboard.device.identifier.descriptor,
+                    keyboard.keyboard_type,
+                    keyboard.is_finalized,
+                );
             }
         }
     }
 
-    fn classify_keyboard(&self, device: &InputDevice) -> (KeyboardType, bool) {
+    fn classify_keyboard(&mut self, device: &InputDevice) -> (KeyboardType, bool) {
         // This should never happen but having keyboard device class is necessary to be classified
         // as any type of keyboard.
         if !device.classes.contains(DeviceClass::Keyboard) {
@@ -126,6 +129,21 @@
                 (KeyboardType::NonAlphabetic, true)
             };
         }
+
+        // Check in data store
+        if let Some((keyboard_type, is_finalized)) =
+            self.data_store.get_keyboard_type(&device.identifier.descriptor)
+        {
+            return (keyboard_type, is_finalized);
+        }
+
+        // Check in known device list for classification
+        for (vendor, product, keyboard_type, is_finalized) in CLASSIFIED_DEVICES.iter() {
+            if device.identifier.vendor == *vendor && device.identifier.product == *product {
+                return (*keyboard_type, *is_finalized);
+            }
+        }
+
         // Any composite device with multiple device classes should be categorized as non-alphabetic
         // keyboard initially
         if device.classes.contains(DeviceClass::Touch)
@@ -168,17 +186,20 @@
 
 #[cfg(test)]
 mod tests {
+    use crate::data_store::{test_file_reader_writer::TestFileReaderWriter, DataStore};
     use crate::input::{DeviceId, InputDevice, KeyboardType};
+    use crate::keyboard_classification_config::CLASSIFIED_DEVICES;
     use crate::keyboard_classifier::KeyboardClassifier;
     use crate::{DeviceClass, ModifierState, RustInputDeviceIdentifier};
 
     static DEVICE_ID: DeviceId = DeviceId(1);
+    static SECOND_DEVICE_ID: DeviceId = DeviceId(2);
     static KEY_A: i32 = 30;
     static KEY_1: i32 = 2;
 
     #[test]
     fn classify_external_alphabetic_keyboard() {
-        let mut classifier = KeyboardClassifier::new();
+        let mut classifier = create_classifier();
         classifier.notify_keyboard_changed(create_device(
             DeviceClass::Keyboard | DeviceClass::AlphabeticKey | DeviceClass::External,
         ));
@@ -188,7 +209,7 @@
 
     #[test]
     fn classify_external_non_alphabetic_keyboard() {
-        let mut classifier = KeyboardClassifier::new();
+        let mut classifier = create_classifier();
         classifier
             .notify_keyboard_changed(create_device(DeviceClass::Keyboard | DeviceClass::External));
         assert_eq!(classifier.get_keyboard_type(DEVICE_ID), KeyboardType::NonAlphabetic);
@@ -197,7 +218,7 @@
 
     #[test]
     fn classify_mouse_pretending_as_keyboard() {
-        let mut classifier = KeyboardClassifier::new();
+        let mut classifier = create_classifier();
         classifier.notify_keyboard_changed(create_device(
             DeviceClass::Keyboard
                 | DeviceClass::Cursor
@@ -210,7 +231,7 @@
 
     #[test]
     fn classify_touchpad_pretending_as_keyboard() {
-        let mut classifier = KeyboardClassifier::new();
+        let mut classifier = create_classifier();
         classifier.notify_keyboard_changed(create_device(
             DeviceClass::Keyboard
                 | DeviceClass::Touchpad
@@ -223,7 +244,7 @@
 
     #[test]
     fn classify_stylus_pretending_as_keyboard() {
-        let mut classifier = KeyboardClassifier::new();
+        let mut classifier = create_classifier();
         classifier.notify_keyboard_changed(create_device(
             DeviceClass::Keyboard
                 | DeviceClass::ExternalStylus
@@ -236,7 +257,7 @@
 
     #[test]
     fn classify_dpad_pretending_as_keyboard() {
-        let mut classifier = KeyboardClassifier::new();
+        let mut classifier = create_classifier();
         classifier.notify_keyboard_changed(create_device(
             DeviceClass::Keyboard
                 | DeviceClass::Dpad
@@ -249,7 +270,7 @@
 
     #[test]
     fn classify_joystick_pretending_as_keyboard() {
-        let mut classifier = KeyboardClassifier::new();
+        let mut classifier = create_classifier();
         classifier.notify_keyboard_changed(create_device(
             DeviceClass::Keyboard
                 | DeviceClass::Joystick
@@ -262,7 +283,7 @@
 
     #[test]
     fn classify_gamepad_pretending_as_keyboard() {
-        let mut classifier = KeyboardClassifier::new();
+        let mut classifier = create_classifier();
         classifier.notify_keyboard_changed(create_device(
             DeviceClass::Keyboard
                 | DeviceClass::Gamepad
@@ -275,7 +296,7 @@
 
     #[test]
     fn reclassify_keyboard_on_alphabetic_key_event() {
-        let mut classifier = KeyboardClassifier::new();
+        let mut classifier = create_classifier();
         classifier.notify_keyboard_changed(create_device(
             DeviceClass::Keyboard
                 | DeviceClass::Dpad
@@ -293,7 +314,7 @@
 
     #[test]
     fn dont_reclassify_keyboard_on_non_alphabetic_key_event() {
-        let mut classifier = KeyboardClassifier::new();
+        let mut classifier = create_classifier();
         classifier.notify_keyboard_changed(create_device(
             DeviceClass::Keyboard
                 | DeviceClass::Dpad
@@ -311,7 +332,7 @@
 
     #[test]
     fn dont_reclassify_keyboard_on_alphabetic_key_event_with_modifiers() {
-        let mut classifier = KeyboardClassifier::new();
+        let mut classifier = create_classifier();
         classifier.notify_keyboard_changed(create_device(
             DeviceClass::Keyboard
                 | DeviceClass::Dpad
@@ -326,20 +347,82 @@
         assert!(!classifier.is_finalized(DEVICE_ID));
     }
 
+    #[test]
+    fn classify_known_devices() {
+        let mut classifier = create_classifier();
+        for (vendor, product, keyboard_type, is_finalized) in CLASSIFIED_DEVICES.iter() {
+            classifier
+                .notify_keyboard_changed(create_device_with_vendor_product_ids(*vendor, *product));
+            assert_eq!(classifier.get_keyboard_type(DEVICE_ID), *keyboard_type);
+            assert_eq!(classifier.is_finalized(DEVICE_ID), *is_finalized);
+        }
+    }
+
+    #[test]
+    fn classify_previously_reclassified_devices() {
+        let test_reader_writer = TestFileReaderWriter::new();
+        {
+            let mut classifier =
+                KeyboardClassifier::new(DataStore::new(Box::new(test_reader_writer.clone())));
+            let device = create_device(
+                DeviceClass::Keyboard
+                    | DeviceClass::Dpad
+                    | DeviceClass::AlphabeticKey
+                    | DeviceClass::External,
+            );
+            classifier.notify_keyboard_changed(device);
+            classifier.process_key(DEVICE_ID, KEY_A, ModifierState::None);
+        }
+
+        // Re-create classifier and data store to mimic a reboot (but use the same file system
+        // reader writer)
+        {
+            let mut classifier =
+                KeyboardClassifier::new(DataStore::new(Box::new(test_reader_writer.clone())));
+            let device = InputDevice {
+                device_id: SECOND_DEVICE_ID,
+                identifier: create_identifier(/* vendor= */ 234, /* product= */ 345),
+                classes: DeviceClass::Keyboard
+                    | DeviceClass::Dpad
+                    | DeviceClass::AlphabeticKey
+                    | DeviceClass::External,
+            };
+            classifier.notify_keyboard_changed(device);
+            assert_eq!(classifier.get_keyboard_type(SECOND_DEVICE_ID), KeyboardType::Alphabetic);
+            assert!(classifier.is_finalized(SECOND_DEVICE_ID));
+        }
+    }
+
+    fn create_classifier() -> KeyboardClassifier {
+        KeyboardClassifier::new(DataStore::new(Box::new(TestFileReaderWriter::new())))
+    }
+
+    fn create_identifier(vendor: u16, product: u16) -> RustInputDeviceIdentifier {
+        RustInputDeviceIdentifier {
+            name: "test_device".to_string(),
+            location: "location".to_string(),
+            unique_id: "unique_id".to_string(),
+            bus: 123,
+            vendor,
+            product,
+            version: 567,
+            descriptor: "descriptor".to_string(),
+        }
+    }
+
     fn create_device(classes: DeviceClass) -> InputDevice {
         InputDevice {
             device_id: DEVICE_ID,
-            identifier: RustInputDeviceIdentifier {
-                name: "test_device".to_string(),
-                location: "location".to_string(),
-                unique_id: "unique_id".to_string(),
-                bus: 123,
-                vendor: 234,
-                product: 345,
-                version: 567,
-                descriptor: "descriptor".to_string(),
-            },
+            identifier: create_identifier(/* vendor= */ 234, /* product= */ 345),
             classes,
         }
     }
+
+    fn create_device_with_vendor_product_ids(vendor: u16, product: u16) -> InputDevice {
+        InputDevice {
+            device_id: DEVICE_ID,
+            identifier: create_identifier(vendor, product),
+            classes: DeviceClass::Keyboard | DeviceClass::AlphabeticKey | DeviceClass::External,
+        }
+    }
 }
diff --git a/libs/input/rust/lib.rs b/libs/input/rust/lib.rs
index 5010475..008f675 100644
--- a/libs/input/rust/lib.rs
+++ b/libs/input/rust/lib.rs
@@ -16,10 +16,13 @@
 
 //! The rust component of libinput.
 
+mod data_store;
 mod input;
 mod input_verifier;
+mod keyboard_classification_config;
 mod keyboard_classifier;
 
+pub use data_store::{DataStore, DefaultFileReaderWriter};
 pub use input::{
     DeviceClass, DeviceId, InputDevice, ModifierState, MotionAction, MotionFlags, Source,
 };
@@ -148,7 +151,14 @@
 }
 
 fn create_keyboard_classifier() -> Box<KeyboardClassifier> {
-    Box::new(KeyboardClassifier::new())
+    // Future design: Make this data store singleton by passing it to C++ side and making it global
+    // and pass by reference to components that need to store persistent data.
+    //
+    // Currently only used by rust keyboard classifier so keeping it here.
+    let data_store = DataStore::new(Box::new(DefaultFileReaderWriter::new(
+        "/data/system/inputflinger-data.json".to_string(),
+    )));
+    Box::new(KeyboardClassifier::new(data_store))
 }
 
 fn notify_keyboard_changed(
diff --git a/libs/input/tests/InputChannel_test.cpp b/libs/input/tests/InputChannel_test.cpp
index 02d4c07..25356cf 100644
--- a/libs/input/tests/InputChannel_test.cpp
+++ b/libs/input/tests/InputChannel_test.cpp
@@ -65,11 +65,7 @@
 
     ASSERT_EQ(OK, result) << "should have successfully opened a channel pair";
 
-    // Name
-    EXPECT_STREQ("channel name (server)", serverChannel->getName().c_str())
-            << "server channel should have suffixed name";
-    EXPECT_STREQ("channel name (client)", clientChannel->getName().c_str())
-            << "client channel should have suffixed name";
+    EXPECT_EQ(serverChannel->getName(), clientChannel->getName());
 
     // Server->Client communication
     InputMessage serverMsg = {};
@@ -78,9 +74,10 @@
     EXPECT_EQ(OK, serverChannel->sendMessage(&serverMsg))
             << "server channel should be able to send message to client channel";
 
-    InputMessage clientMsg;
-    EXPECT_EQ(OK, clientChannel->receiveMessage(&clientMsg))
+    android::base::Result<InputMessage> clientMsgResult = clientChannel->receiveMessage();
+    ASSERT_TRUE(clientMsgResult.ok())
             << "client channel should be able to receive message from server channel";
+    const InputMessage& clientMsg = *clientMsgResult;
     EXPECT_EQ(serverMsg.header.type, clientMsg.header.type)
             << "client channel should receive the correct message from server channel";
     EXPECT_EQ(serverMsg.body.key.action, clientMsg.body.key.action)
@@ -94,9 +91,10 @@
     EXPECT_EQ(OK, clientChannel->sendMessage(&clientReply))
             << "client channel should be able to send message to server channel";
 
-    InputMessage serverReply;
-    EXPECT_EQ(OK, serverChannel->receiveMessage(&serverReply))
+    android::base::Result<InputMessage> serverReplyResult = serverChannel->receiveMessage();
+    ASSERT_TRUE(serverReplyResult.ok())
             << "server channel should be able to receive message from client channel";
+    const InputMessage& serverReply = *serverReplyResult;
     EXPECT_EQ(clientReply.header.type, serverReply.header.type)
             << "server channel should receive the correct message from client channel";
     EXPECT_EQ(clientReply.header.seq, serverReply.header.seq)
@@ -134,9 +132,10 @@
             << "client channel should observe that message is available before receiving it";
 
     // Receive (consume) the message.
-    InputMessage clientMsg;
-    EXPECT_EQ(OK, receiverChannel->receiveMessage(&clientMsg))
+    android::base::Result<InputMessage> clientMsgResult = receiverChannel->receiveMessage();
+    ASSERT_TRUE(clientMsgResult.ok())
             << "client channel should be able to receive message from server channel";
+    const InputMessage& clientMsg = *clientMsgResult;
     EXPECT_EQ(serverMsg.header.type, clientMsg.header.type)
             << "client channel should receive the correct message from server channel";
     EXPECT_EQ(serverMsg.body.key.action, clientMsg.body.key.action)
@@ -156,8 +155,8 @@
     ASSERT_EQ(OK, result)
             << "should have successfully opened a channel pair";
 
-    InputMessage msg;
-    EXPECT_EQ(WOULD_BLOCK, clientChannel->receiveMessage(&msg))
+    android::base::Result<InputMessage> msgResult = clientChannel->receiveMessage();
+    EXPECT_EQ(WOULD_BLOCK, msgResult.error().code())
             << "receiveMessage should have returned WOULD_BLOCK";
 }
 
@@ -172,8 +171,8 @@
 
     serverChannel.reset(); // close server channel
 
-    InputMessage msg;
-    EXPECT_EQ(DEAD_OBJECT, clientChannel->receiveMessage(&msg))
+    android::base::Result<InputMessage> msgResult = clientChannel->receiveMessage();
+    EXPECT_EQ(DEAD_OBJECT, msgResult.error().code())
             << "receiveMessage should have returned DEAD_OBJECT";
 }
 
@@ -207,7 +206,7 @@
         MotionClassification::DEEP_PRESS,
     };
 
-    InputMessage serverMsg = {}, clientMsg;
+    InputMessage serverMsg = {};
     serverMsg.header.type = InputMessage::Type::MOTION;
     serverMsg.header.seq = 1;
     serverMsg.body.motion.pointerCount = 1;
@@ -218,11 +217,13 @@
         EXPECT_EQ(OK, serverChannel->sendMessage(&serverMsg))
                 << "server channel should be able to send message to client channel";
 
-        EXPECT_EQ(OK, clientChannel->receiveMessage(&clientMsg))
+        android::base::Result<InputMessage> clientMsgResult = clientChannel->receiveMessage();
+        ASSERT_TRUE(clientMsgResult.ok())
                 << "client channel should be able to receive message from server channel";
+        const InputMessage& clientMsg = *clientMsgResult;
         EXPECT_EQ(serverMsg.header.type, clientMsg.header.type);
-        EXPECT_EQ(classification, clientMsg.body.motion.classification) <<
-                "Expected to receive " << motionClassificationToString(classification);
+        EXPECT_EQ(classification, clientMsg.body.motion.classification)
+                << "Expected to receive " << motionClassificationToString(classification);
     }
 }
 
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index 3717f49..a67e1ef 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -371,8 +371,8 @@
                       mTransform, 2.0f, 2.1f, AMOTION_EVENT_INVALID_CURSOR_POSITION,
                       AMOTION_EVENT_INVALID_CURSOR_POSITION, mRawTransform, ARBITRARY_DOWN_TIME,
                       ARBITRARY_EVENT_TIME, 2, mPointerProperties, mSamples[0].pointerCoords);
-    event->addSample(ARBITRARY_EVENT_TIME + 1, mSamples[1].pointerCoords);
-    event->addSample(ARBITRARY_EVENT_TIME + 2, mSamples[2].pointerCoords);
+    event->addSample(ARBITRARY_EVENT_TIME + 1, mSamples[1].pointerCoords, event->getId());
+    event->addSample(ARBITRARY_EVENT_TIME + 2, mSamples[2].pointerCoords, event->getId());
 }
 
 void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) {
@@ -591,6 +591,22 @@
     ASSERT_EQ(event.getX(0), copy.getX(0));
 }
 
+TEST_F(MotionEventTest, CheckEventIdWithHistoryIsIncremented) {
+    MotionEvent event;
+    constexpr int32_t ARBITRARY_ID = 42;
+    event.initialize(ARBITRARY_ID, 2, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, INVALID_HMAC,
+                     AMOTION_EVENT_ACTION_MOVE, 0, 0, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE,
+                     AMOTION_EVENT_BUTTON_PRIMARY, MotionClassification::NONE, mTransform, 0, 0,
+                     AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+                     mRawTransform, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME, 2,
+                     mPointerProperties, mSamples[0].pointerCoords);
+    ASSERT_EQ(event.getId(), ARBITRARY_ID);
+    event.addSample(ARBITRARY_EVENT_TIME + 1, mSamples[1].pointerCoords, ARBITRARY_ID + 1);
+    ASSERT_EQ(event.getId(), ARBITRARY_ID + 1);
+    event.addSample(ARBITRARY_EVENT_TIME + 2, mSamples[2].pointerCoords, ARBITRARY_ID + 2);
+    ASSERT_EQ(event.getId(), ARBITRARY_ID + 2);
+}
+
 TEST_F(MotionEventTest, SplitPointerDown) {
     MotionEvent event = MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
                                 .downTime(ARBITRARY_DOWN_TIME)
diff --git a/libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp b/libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp
index f49469c..e710613 100644
--- a/libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp
+++ b/libs/input/tests/InputPublisherAndConsumerNoResampling_test.cpp
@@ -52,7 +52,7 @@
     const int32_t action;
     const nsecs_t downTime;
     const uint32_t seq;
-    const int32_t eventId;
+    int32_t eventId;
     const int32_t deviceId = 1;
     const uint32_t source = AINPUT_SOURCE_TOUCHSCREEN;
     const ui::LogicalDisplayId displayId = ui::LogicalDisplayId::DEFAULT;
@@ -291,6 +291,7 @@
     void publishAndConsumeKeyEvent();
     void publishAndConsumeMotionStream();
     void publishAndConsumeMotionDown(nsecs_t downTime);
+    void publishAndConsumeSinglePointerMultipleSamples(const size_t nSamples);
     void publishAndConsumeBatchedMotionMove(nsecs_t downTime);
     void publishAndConsumeFocusEvent();
     void publishAndConsumeCaptureEvent();
@@ -298,6 +299,7 @@
     void publishAndConsumeTouchModeEvent();
     void publishAndConsumeMotionEvent(int32_t action, nsecs_t downTime,
                                       const std::vector<Pointer>& pointers);
+
     void TearDown() override {
         // Destroy the consumer, flushing any of the pending ack's.
         sendMessage(LooperMessage::DESTROY_CONSUMER);
@@ -519,6 +521,123 @@
                                  {Pointer{.id = 0, .x = 20, .y = 30}});
 }
 
+/*
+ * Decompose a potential multi-sampled MotionEvent into multiple MotionEvents
+ * with a single sample.
+ */
+std::vector<MotionEvent> splitBatchedMotionEvent(const MotionEvent& batchedMotionEvent) {
+    std::vector<MotionEvent> singleMotionEvents;
+    const size_t batchSize = batchedMotionEvent.getHistorySize() + 1;
+    for (size_t i = 0; i < batchSize; ++i) {
+        MotionEvent singleMotionEvent;
+        singleMotionEvent
+                .initialize(batchedMotionEvent.getId(), batchedMotionEvent.getDeviceId(),
+                            batchedMotionEvent.getSource(), batchedMotionEvent.getDisplayId(),
+                            batchedMotionEvent.getHmac(), batchedMotionEvent.getAction(),
+                            batchedMotionEvent.getActionButton(), batchedMotionEvent.getFlags(),
+                            batchedMotionEvent.getEdgeFlags(), batchedMotionEvent.getMetaState(),
+                            batchedMotionEvent.getButtonState(),
+                            batchedMotionEvent.getClassification(),
+                            batchedMotionEvent.getTransform(), batchedMotionEvent.getXPrecision(),
+                            batchedMotionEvent.getYPrecision(),
+                            batchedMotionEvent.getRawXCursorPosition(),
+                            batchedMotionEvent.getRawYCursorPosition(),
+                            batchedMotionEvent.getRawTransform(), batchedMotionEvent.getDownTime(),
+                            batchedMotionEvent.getHistoricalEventTime(/*historicalIndex=*/i),
+                            batchedMotionEvent.getPointerCount(),
+                            batchedMotionEvent.getPointerProperties(),
+                            (batchedMotionEvent.getSamplePointerCoords() + i));
+        singleMotionEvents.push_back(singleMotionEvent);
+    }
+    return singleMotionEvents;
+}
+
+/*
+ * Simulates a single pointer touching the screen and leaving it there for a period of time.
+ * Publishes a DOWN event and consumes it right away. Then, publishes a sequence of MOVE
+ * samples for the same pointer, and waits until it has been consumed. Splits batched MotionEvents
+ * into individual samples. Checks the consumed MotionEvents against the published ones.
+ * This test is non-deterministic because it depends on the timing of arrival of events to the
+ * socket.
+ *
+ * @param nSamples The number of MOVE samples to publish before attempting consumption.
+ */
+void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeSinglePointerMultipleSamples(
+        const size_t nSamples) {
+    const nsecs_t downTime = systemTime(SYSTEM_TIME_MONOTONIC);
+    const Pointer pointer(0, 20, 30);
+
+    const PublishMotionArgs argsDown(AMOTION_EVENT_ACTION_DOWN, downTime, {pointer}, mSeq);
+    const nsecs_t publishTimeOfDown = systemTime(SYSTEM_TIME_MONOTONIC);
+    publishMotionEvent(*mPublisher, argsDown);
+
+    // Consume the DOWN event.
+    ASSERT_TRUE(mMotionEvents.popWithTimeout(TIMEOUT).has_value());
+
+    verifyFinishedSignal(*mPublisher, mSeq, publishTimeOfDown);
+
+    std::vector<nsecs_t> publishTimes;
+    std::vector<PublishMotionArgs> argsMoves;
+    std::queue<uint32_t> publishedSequenceNumbers;
+
+    // Block Looper to increase the chance of batching events
+    {
+        std::scoped_lock l(mLock);
+        mLooperMayProceed = false;
+    }
+    sendMessage(LooperMessage::BLOCK_LOOPER);
+    {
+        std::unique_lock l(mLock);
+        mNotifyLooperWaiting.wait(l, [this] { return mLooperIsBlocked; });
+    }
+
+    uint32_t firstSampleId;
+    for (size_t i = 0; i < nSamples; ++i) {
+        publishedSequenceNumbers.push(++mSeq);
+        PublishMotionArgs argsMove(AMOTION_EVENT_ACTION_MOVE, downTime, {pointer}, mSeq);
+        // A batched MotionEvent only has a single event id, currently determined when the
+        // MotionEvent is initialized. Therefore, to pass the eventId comparisons inside
+        // verifyArgsEqualToEvent, we need to override the event id of the published args to match
+        // the event id of the first sample inside the MotionEvent.
+        if (i == 0) {
+            firstSampleId = argsMove.eventId;
+        }
+        argsMove.eventId = firstSampleId;
+        publishTimes.push_back(systemTime(SYSTEM_TIME_MONOTONIC));
+        argsMoves.push_back(argsMove);
+        publishMotionEvent(*mPublisher, argsMove);
+    }
+
+    std::vector<MotionEvent> singleSampledMotionEvents;
+
+    // Unblock Looper
+    {
+        std::scoped_lock l(mLock);
+        mLooperMayProceed = true;
+    }
+    mNotifyLooperMayProceed.notify_all();
+
+    // We have no control over the socket behavior, so the consumer can receive
+    // the motion as a batched event, or as a sequence of multiple single-sample MotionEvents (or a
+    // mix of those)
+    while (singleSampledMotionEvents.size() != nSamples) {
+        const std::optional<std::unique_ptr<MotionEvent>> batchedMotionEvent =
+                mMotionEvents.popWithTimeout(TIMEOUT);
+        // The events received by these calls are never null
+        std::vector<MotionEvent> splitMotionEvents = splitBatchedMotionEvent(**batchedMotionEvent);
+        singleSampledMotionEvents.insert(singleSampledMotionEvents.end(), splitMotionEvents.begin(),
+                                         splitMotionEvents.end());
+    }
+
+    // Consumer can choose to finish events in any order. For simplicity,
+    // we verify the events in sequence (since that is how the test is implemented).
+    for (size_t i = 0; i < nSamples; ++i) {
+        verifyArgsEqualToEvent(argsMoves[i], singleSampledMotionEvents[i]);
+        verifyFinishedSignal(*mPublisher, publishedSequenceNumbers.front(), publishTimes[i]);
+        publishedSequenceNumbers.pop();
+    }
+}
+
 void InputPublisherAndConsumerNoResamplingTest::publishAndConsumeBatchedMotionMove(
         nsecs_t downTime) {
     uint32_t seq = mSeq++;
@@ -814,4 +933,8 @@
     ASSERT_NO_FATAL_FAILURE(publishAndConsumeTouchModeEvent());
 }
 
+TEST_F(InputPublisherAndConsumerNoResamplingTest, PublishAndConsumeSinglePointer) {
+    publishAndConsumeSinglePointerMultipleSamples(3);
+}
+
 } // namespace android
diff --git a/libs/input/tests/MotionPredictorMetricsManager_test.cpp b/libs/input/tests/MotionPredictorMetricsManager_test.cpp
index cc41eeb..0542f39 100644
--- a/libs/input/tests/MotionPredictorMetricsManager_test.cpp
+++ b/libs/input/tests/MotionPredictorMetricsManager_test.cpp
@@ -167,7 +167,8 @@
                         .y(predictionPoints[i].position[0])
                         .axis(AMOTION_EVENT_AXIS_PRESSURE, predictionPoints[i].pressure)
                         .buildCoords();
-        predictionEvent.addSample(predictionPoints[i].targetTimestamp, &coords);
+        predictionEvent.addSample(predictionPoints[i].targetTimestamp, &coords,
+                                  predictionEvent.getId());
     }
     return predictionEvent;
 }
diff --git a/libs/input/tests/MotionPredictor_test.cpp b/libs/input/tests/MotionPredictor_test.cpp
index d077760..5bd5794 100644
--- a/libs/input/tests/MotionPredictor_test.cpp
+++ b/libs/input/tests/MotionPredictor_test.cpp
@@ -88,6 +88,7 @@
 
 TEST(JerkTrackerTest, JerkCalculationNormalizedDtTrue) {
     JerkTracker jerkTracker(true);
+    jerkTracker.setForgetFactor(.5);
     jerkTracker.pushSample(/*timestamp=*/0, 20, 50);
     jerkTracker.pushSample(/*timestamp=*/1, 25, 53);
     jerkTracker.pushSample(/*timestamp=*/2, 30, 60);
@@ -118,11 +119,14 @@
      * y'':  3 -> -15
      * y''': -18
      */
-    EXPECT_FLOAT_EQ(jerkTracker.jerkMagnitude().value(), std::hypot(-50, -18));
+    const float newJerk = (1 - jerkTracker.getForgetFactor()) * std::hypot(10, -1) +
+            jerkTracker.getForgetFactor() * std::hypot(-50, -18);
+    EXPECT_FLOAT_EQ(jerkTracker.jerkMagnitude().value(), newJerk);
 }
 
 TEST(JerkTrackerTest, JerkCalculationNormalizedDtFalse) {
     JerkTracker jerkTracker(false);
+    jerkTracker.setForgetFactor(.5);
     jerkTracker.pushSample(/*timestamp=*/0, 20, 50);
     jerkTracker.pushSample(/*timestamp=*/10, 25, 53);
     jerkTracker.pushSample(/*timestamp=*/20, 30, 60);
@@ -153,7 +157,9 @@
      * y'':  .03 -> -.125 (delta above, divide by 10)
      * y''': -.0155 (delta above, divide by 10)
      */
-    EXPECT_FLOAT_EQ(jerkTracker.jerkMagnitude().value(), std::hypot(-.0375, -.0155));
+    const float newJerk = (1 - jerkTracker.getForgetFactor()) * std::hypot(.01, -.001) +
+            jerkTracker.getForgetFactor() * std::hypot(-.0375, -.0155);
+    EXPECT_FLOAT_EQ(jerkTracker.jerkMagnitude().value(), newJerk);
 }
 
 TEST(JerkTrackerTest, JerkCalculationAfterReset) {
@@ -291,15 +297,19 @@
     MotionPredictor predictor(/*predictionTimestampOffsetNanos=*/0,
                               []() { return true /*enable prediction*/; });
 
-    // Jerk is medium (1.05 normalized, which is halfway between LOW_JANK and HIGH_JANK)
-    predictor.record(getMotionEvent(DOWN, 0, 5.2, 20ms));
-    predictor.record(getMotionEvent(MOVE, 0, 11.5, 30ms));
-    predictor.record(getMotionEvent(MOVE, 0, 22, 40ms));
-    predictor.record(getMotionEvent(MOVE, 0, 37.75, 50ms));
-    predictor.record(getMotionEvent(MOVE, 0, 59.8, 60ms));
+    const float mediumJerk =
+            (predictor.getModelConfig().lowJerk + predictor.getModelConfig().highJerk) / 2;
+    const float a = 3; // initial acceleration
+    const float b = 4; // initial velocity
+    const float c = 5; // initial position
+    predictor.record(getMotionEvent(DOWN, 0, c, 20ms));
+    predictor.record(getMotionEvent(MOVE, 0, c + b, 30ms));
+    predictor.record(getMotionEvent(MOVE, 0, c + 2 * b + a, 40ms));
+    predictor.record(getMotionEvent(MOVE, 0, c + 3 * b + 3 * a + mediumJerk, 50ms));
+    predictor.record(getMotionEvent(MOVE, 0, c + 4 * b + 6 * a + 4 * mediumJerk, 60ms));
     std::unique_ptr<MotionEvent> predicted = predictor.predict(82 * NSEC_PER_MSEC);
     EXPECT_NE(nullptr, predicted);
-    // Halfway between LOW_JANK and HIGH_JANK means that half of the predictions
+    // Halfway between LOW_JERK and HIGH_JERK means that half of the predictions
     // will be pruned. If model prediction window is close enough to predict()
     // call time window, then half of the model predictions (5/2 -> 2) will be
     // ouputted.
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 5261287..dd78049 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -300,7 +300,9 @@
       if (result == 0) {
         outPlanes->planeCount = 3;
         outPlanes->planes[0].data = yuvData.y;
-        if (format == AHARDWAREBUFFER_FORMAT_YCbCr_P010) {
+        // P010 is word-aligned 10-bit semiplaner, and YCbCr_422_I is a single interleaved plane
+        if (format == AHARDWAREBUFFER_FORMAT_YCbCr_P010 ||
+            format == AHARDWAREBUFFER_FORMAT_YCbCr_422_I) {
             outPlanes->planes[0].pixelStride = 2;
         } else {
             outPlanes->planes[0].pixelStride = 1;
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 6fcb3a4..d05ff34 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -326,7 +326,7 @@
      * COMPOSER_OVERLAY, the system will try to prioritize the buffer receiving
      * an overlay plane & avoid caching it in intermediate composition buffers.
      */
-    AHARDWAREBUFFER_USAGE_FRONT_BUFFER = 1UL << 32,
+    AHARDWAREBUFFER_USAGE_FRONT_BUFFER = 1ULL << 32,
 
     AHARDWAREBUFFER_USAGE_VENDOR_0  = 1ULL << 28,
     AHARDWAREBUFFER_USAGE_VENDOR_1  = 1ULL << 29,
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index 4a04467..ecf98c6 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -105,6 +105,7 @@
         "skia/filters/LinearEffect.cpp",
         "skia/filters/MouriMap.cpp",
         "skia/filters/StretchShaderFactory.cpp",
+        "skia/filters/EdgeExtensionShaderFactory.cpp",
     ],
 }
 
diff --git a/libs/renderengine/ExternalTexture.cpp b/libs/renderengine/ExternalTexture.cpp
index 6f2a96a..8d0fbba 100644
--- a/libs/renderengine/ExternalTexture.cpp
+++ b/libs/renderengine/ExternalTexture.cpp
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
+#include <common/trace.h>
 #include <log/log.h>
 #include <renderengine/RenderEngine.h>
 #include <renderengine/impl/ExternalTexture.h>
 #include <ui/GraphicBuffer.h>
-#include <utils/Trace.h>
 
 namespace android::renderengine::impl {
 
@@ -35,7 +35,7 @@
 }
 
 void ExternalTexture::remapBuffer() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     {
         auto buf = mBuffer;
         mRenderEngine.unmapExternalTextureBuffer(std::move(buf));
diff --git a/libs/renderengine/benchmark/Android.bp b/libs/renderengine/benchmark/Android.bp
index e1a6f6a..f84db0b 100644
--- a/libs/renderengine/benchmark/Android.bp
+++ b/libs/renderengine/benchmark/Android.bp
@@ -57,6 +57,7 @@
         "libui",
         "libutils",
         "server_configurable_flags",
+        "libtracing_perfetto",
     ],
 
     data: ["resources/*"],
diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h
index 8ac0af4..859ae8b 100644
--- a/libs/renderengine/include/renderengine/LayerSettings.h
+++ b/libs/renderengine/include/renderengine/LayerSettings.h
@@ -31,6 +31,7 @@
 #include <ui/ShadowSettings.h>
 #include <ui/StretchEffect.h>
 #include <ui/Transform.h>
+#include "ui/EdgeExtensionEffect.h"
 
 #include <iosfwd>
 
@@ -134,6 +135,7 @@
     mat4 blurRegionTransform = mat4();
 
     StretchEffect stretchEffect;
+    EdgeExtensionEffect edgeExtensionEffect;
 
     // Name associated with the layer for debugging purposes.
     std::string name;
@@ -183,7 +185,9 @@
             lhs.skipContentDraw == rhs.skipContentDraw && lhs.shadow == rhs.shadow &&
             lhs.backgroundBlurRadius == rhs.backgroundBlurRadius &&
             lhs.blurRegionTransform == rhs.blurRegionTransform &&
-            lhs.stretchEffect == rhs.stretchEffect && lhs.whitePointNits == rhs.whitePointNits;
+            lhs.stretchEffect == rhs.stretchEffect &&
+            lhs.edgeExtensionEffect == rhs.edgeExtensionEffect &&
+            lhs.whitePointNits == rhs.whitePointNits;
 }
 
 static inline void PrintTo(const Buffer& settings, ::std::ostream* os) {
@@ -254,6 +258,10 @@
     *os << "\n}";
 }
 
+static inline void PrintTo(const EdgeExtensionEffect& effect, ::std::ostream* os) {
+    *os << effect;
+}
+
 static inline void PrintTo(const LayerSettings& settings, ::std::ostream* os) {
     *os << "LayerSettings for '" << settings.name.c_str() << "' {";
     *os << "\n    .geometry = ";
@@ -285,6 +293,10 @@
         *os << "\n    .stretchEffect = ";
         PrintTo(settings.stretchEffect, os);
     }
+
+    if (settings.edgeExtensionEffect.hasEffect()) {
+        *os << "\n    .edgeExtensionEffect = " << settings.edgeExtensionEffect;
+    }
     *os << "\n    .whitePointNits = " << settings.whitePointNits;
     *os << "\n}";
 }
diff --git a/libs/renderengine/skia/AutoBackendTexture.cpp b/libs/renderengine/skia/AutoBackendTexture.cpp
index 8aeef9f..b7b7a4d 100644
--- a/libs/renderengine/skia/AutoBackendTexture.cpp
+++ b/libs/renderengine/skia/AutoBackendTexture.cpp
@@ -25,8 +25,8 @@
 
 #include "compat/SkiaBackendTexture.h"
 
+#include <common/trace.h>
 #include <log/log_main.h>
-#include <utils/Trace.h>
 
 namespace android {
 namespace renderengine {
@@ -63,7 +63,7 @@
 }
 
 sk_sp<SkImage> AutoBackendTexture::makeImage(ui::Dataspace dataspace, SkAlphaType alphaType) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     sk_sp<SkImage> image = mBackendTexture->makeImage(alphaType, dataspace, releaseImageProc, this);
     // The following ref will be counteracted by releaseProc, when SkImage is discarded.
@@ -75,7 +75,7 @@
 }
 
 sk_sp<SkSurface> AutoBackendTexture::getOrCreateSurface(ui::Dataspace dataspace) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     LOG_ALWAYS_FATAL_IF(!mBackendTexture->isOutputBuffer(),
                         "You can't generate an SkSurface for a read-only texture");
     if (!mSurface.get() || mDataspace != dataspace) {
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index d246870..59b0656 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -729,8 +729,7 @@
         const auto externalTexture =
                 std::make_shared<impl::ExternalTexture>(externalBuffer, *renderengine,
                                                         impl::ExternalTexture::Usage::READABLE);
-        std::vector<const std::shared_ptr<ExternalTexture>> textures =
-            {srcTexture, externalTexture};
+        std::vector<std::shared_ptr<ExternalTexture>> textures = {srcTexture, externalTexture};
 
         // 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.
diff --git a/libs/renderengine/skia/GaneshVkRenderEngine.cpp b/libs/renderengine/skia/GaneshVkRenderEngine.cpp
index 68798bf..a3a43e2 100644
--- a/libs/renderengine/skia/GaneshVkRenderEngine.cpp
+++ b/libs/renderengine/skia/GaneshVkRenderEngine.cpp
@@ -21,9 +21,9 @@
 
 #include <include/gpu/ganesh/vk/GrVkBackendSemaphore.h>
 
+#include <common/trace.h>
 #include <log/log_main.h>
 #include <sync/sync.h>
-#include <utils/Trace.h>
 
 namespace android::renderengine::skia {
 
@@ -78,7 +78,7 @@
                                                      sk_sp<SkSurface> dstSurface) {
     sk_sp<GrDirectContext> grContext = context->grDirectContext();
     {
-        ATRACE_NAME("flush surface");
+        SFTRACE_NAME("flush surface");
         // TODO: Investigate feasibility of combining this "surface flush" into the "context flush"
         // below.
         context->grDirectContext()->flush(dstSurface.get());
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 48270e1..af24600 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -28,12 +28,11 @@
 #include <GrContextOptions.h>
 #include <GrTypes.h>
 #include <android-base/stringprintf.h>
+#include <common/trace.h>
 #include <gl/GrGLInterface.h>
 #include <include/gpu/ganesh/gl/GrGLDirectContext.h>
-#include <gui/TraceUtils.h>
 #include <sync/sync.h>
 #include <ui/DebugUtils.h>
-#include <utils/Trace.h>
 
 #include <cmath>
 #include <cstdint>
@@ -332,7 +331,7 @@
 
 void SkiaGLRenderEngine::waitFence(SkiaGpuContext*, base::borrowed_fd fenceFd) {
     if (fenceFd.get() >= 0 && !waitGpuFence(fenceFd)) {
-        ATRACE_NAME("SkiaGLRenderEngine::waitFence");
+        SFTRACE_NAME("SkiaGLRenderEngine::waitFence");
         sync_wait(fenceFd.get(), -1);
     }
 }
@@ -341,19 +340,19 @@
                                                    sk_sp<SkSurface> dstSurface) {
     sk_sp<GrDirectContext> grContext = context->grDirectContext();
     {
-        ATRACE_NAME("flush surface");
+        SFTRACE_NAME("flush surface");
         grContext->flush(dstSurface.get());
     }
     base::unique_fd drawFence = flushGL();
 
     bool requireSync = drawFence.get() < 0;
     if (requireSync) {
-        ATRACE_BEGIN("Submit(sync=true)");
+        SFTRACE_BEGIN("Submit(sync=true)");
     } else {
-        ATRACE_BEGIN("Submit(sync=false)");
+        SFTRACE_BEGIN("Submit(sync=false)");
     }
     bool success = grContext->submit(requireSync ? GrSyncCpu::kYes : GrSyncCpu::kNo);
-    ATRACE_END();
+    SFTRACE_END();
     if (!success) {
         ALOGE("Failed to flush RenderEngine commands");
         // Chances are, something illegal happened (Skia's internal GPU object
@@ -400,7 +399,7 @@
 }
 
 base::unique_fd SkiaGLRenderEngine::flushGL() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     if (!GLExtensions::getInstance().hasNativeFenceSync()) {
         return base::unique_fd();
     }
diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp
index e62640e..9709cd1 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaRenderEngine.cpp
@@ -54,8 +54,8 @@
 #include <SkTileMode.h>
 #include <android-base/stringprintf.h>
 #include <common/FlagManager.h>
+#include <common/trace.h>
 #include <gui/FenceMonitor.h>
-#include <gui/TraceUtils.h>
 #include <include/gpu/ganesh/SkSurfaceGanesh.h>
 #include <pthread.h>
 #include <src/core/SkTraceEventCommon.h>
@@ -64,7 +64,6 @@
 #include <ui/DebugUtils.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/HdrRenderTypeUtils.h>
-#include <utils/Trace.h>
 
 #include <cmath>
 #include <cstdint>
@@ -261,7 +260,7 @@
                                                const SkString& description) {
     mShadersCachedSinceLastCall++;
     mTotalShadersCompiled++;
-    ATRACE_FORMAT("SF cache: %i shaders", mTotalShadersCompiled);
+    SFTRACE_FORMAT("SF cache: %i shaders", mTotalShadersCompiled);
 }
 
 int SkiaRenderEngine::reportShadersCompiled() {
@@ -416,7 +415,7 @@
     if (isProtectedBuffer || isProtected() || !isGpuSampleable) {
         return;
     }
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     // If we were to support caching protected buffers then we will need to switch the
     // currently bound context if we are not already using the protected context (and subsequently
@@ -441,7 +440,7 @@
 }
 
 void SkiaRenderEngine::unmapExternalTextureBuffer(sp<GraphicBuffer>&& buffer) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::lock_guard<std::mutex> lock(mRenderingMutex);
     if (const auto& iter = mGraphicBufferExternalRefs.find(buffer->getId());
         iter != mGraphicBufferExternalRefs.end()) {
@@ -498,7 +497,7 @@
 }
 
 void SkiaRenderEngine::cleanupPostRender() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::lock_guard<std::mutex> lock(mRenderingMutex);
     mTextureCleanupMgr.cleanup();
 }
@@ -507,16 +506,24 @@
         const RuntimeEffectShaderParameters& parameters) {
     // The given surface will be stretched by HWUI via matrix transformation
     // which gets similar results for most surfaces
-    // Determine later on if we need to leverage the stertch shader within
+    // Determine later on if we need to leverage the stretch shader within
     // surface flinger
     const auto& stretchEffect = parameters.layer.stretchEffect;
     const auto& targetBuffer = parameters.layer.source.buffer.buffer;
+    const auto graphicBuffer = targetBuffer ? targetBuffer->getBuffer() : nullptr;
+
     auto shader = parameters.shader;
-    if (stretchEffect.hasEffect()) {
-        const auto graphicBuffer = targetBuffer ? targetBuffer->getBuffer() : nullptr;
-        if (graphicBuffer && parameters.shader) {
+    if (graphicBuffer && parameters.shader) {
+        if (stretchEffect.hasEffect()) {
             shader = mStretchShaderFactory.createSkShader(shader, stretchEffect);
         }
+        // The given surface requires to be filled outside of its buffer bounds if the edge
+        // extension is required
+        const auto& edgeExtensionEffect = parameters.layer.edgeExtensionEffect;
+        if (edgeExtensionEffect.hasEffect()) {
+            shader = mEdgeExtensionShaderFactory.createSkShader(shader, parameters.layer,
+                                                                parameters.imageBounds);
+        }
     }
 
     if (parameters.requiresLinearEffect) {
@@ -525,21 +532,26 @@
                           static_cast<ui::PixelFormat>(targetBuffer->getPixelFormat()))
                 : std::nullopt;
 
-        if (parameters.display.tonemapStrategy == DisplaySettings::TonemapStrategy::Local) {
-            // TODO: Handle color matrix transforms in linear space.
-            SkImage* image = parameters.shader->isAImage((SkMatrix*)nullptr, (SkTileMode*)nullptr);
-            if (image) {
-                static MouriMap kMapper;
-                const float ratio = getHdrRenderType(parameters.layer.sourceDataspace, format) ==
-                                HdrRenderType::GENERIC_HDR
-                        ? 1.0f
-                        : parameters.layerDimmingRatio;
-                return kMapper.mouriMap(getActiveContext(), parameters.shader, ratio);
-            }
+        const auto hdrType = getHdrRenderType(parameters.layer.sourceDataspace, format,
+                                              parameters.layerDimmingRatio);
+
+        const auto usingLocalTonemap =
+                parameters.display.tonemapStrategy == DisplaySettings::TonemapStrategy::Local &&
+                hdrType != HdrRenderType::SDR &&
+                shader->isAImage((SkMatrix*)nullptr, (SkTileMode*)nullptr);
+
+        if (usingLocalTonemap) {
+            static MouriMap kMapper;
+            const float ratio =
+                    hdrType == HdrRenderType::GENERIC_HDR ? 1.0f : parameters.layerDimmingRatio;
+            shader = kMapper.mouriMap(getActiveContext(), shader, ratio);
         }
 
+        // disable tonemapping if we already locally tonemapped
+        auto inputDataspace =
+                usingLocalTonemap ? parameters.outputDataSpace : parameters.layer.sourceDataspace;
         auto effect =
-                shaders::LinearEffect{.inputDataspace = parameters.layer.sourceDataspace,
+                shaders::LinearEffect{.inputDataspace = inputDataspace,
                                       .outputDataspace = parameters.outputDataSpace,
                                       .undoPremultipliedAlpha = parameters.undoPremultipliedAlpha,
                                       .fakeOutputDataspace = parameters.fakeOutputDataspace};
@@ -555,20 +567,20 @@
 
         mat4 colorTransform = parameters.layer.colorTransform;
 
-        colorTransform *=
-                mat4::scale(vec4(parameters.layerDimmingRatio, parameters.layerDimmingRatio,
-                                 parameters.layerDimmingRatio, 1.f));
+        if (!usingLocalTonemap) {
+            colorTransform *=
+                    mat4::scale(vec4(parameters.layerDimmingRatio, parameters.layerDimmingRatio,
+                                     parameters.layerDimmingRatio, 1.f));
+        }
 
-        const auto targetBuffer = parameters.layer.source.buffer.buffer;
-        const auto graphicBuffer = targetBuffer ? targetBuffer->getBuffer() : nullptr;
         const auto hardwareBuffer = graphicBuffer ? graphicBuffer->toAHardwareBuffer() : nullptr;
-        return createLinearEffectShader(parameters.shader, effect, runtimeEffect,
-                                        std::move(colorTransform), parameters.display.maxLuminance,
+        return createLinearEffectShader(shader, effect, runtimeEffect, std::move(colorTransform),
+                                        parameters.display.maxLuminance,
                                         parameters.display.currentLuminanceNits,
                                         parameters.layer.source.buffer.maxLuminanceNits,
                                         hardwareBuffer, parameters.display.renderIntent);
     }
-    return parameters.shader;
+    return shader;
 }
 
 void SkiaRenderEngine::initCanvas(SkCanvas* canvas, const DisplaySettings& display) {
@@ -683,7 +695,7 @@
         const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
         const DisplaySettings& display, const std::vector<LayerSettings>& layers,
         const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) {
-    ATRACE_FORMAT("%s for %s", __func__, display.namePlusId.c_str());
+    SFTRACE_FORMAT("%s for %s", __func__, display.namePlusId.c_str());
 
     std::lock_guard<std::mutex> lock(mRenderingMutex);
 
@@ -775,7 +787,7 @@
         logSettings(display);
     }
     for (const auto& layer : layers) {
-        ATRACE_FORMAT("DrawLayer: %s", layer.name.c_str());
+        SFTRACE_FORMAT("DrawLayer: %s", layer.name.c_str());
 
         if (kPrintLayerSettings) {
             logSettings(layer);
@@ -869,7 +881,7 @@
             // TODO(b/182216890): Filter out empty layers earlier
             if (blurRect.width() > 0 && blurRect.height() > 0) {
                 if (layer.backgroundBlurRadius > 0) {
-                    ATRACE_NAME("BackgroundBlur");
+                    SFTRACE_NAME("BackgroundBlur");
                     auto blurredImage = mBlurFilter->generate(context, layer.backgroundBlurRadius,
                                                               blurInput, blurRect);
 
@@ -882,7 +894,7 @@
                 canvas->concat(getSkM44(layer.blurRegionTransform).asM33());
                 for (auto region : layer.blurRegions) {
                     if (cachedBlurs[region.blurRadius] == nullptr) {
-                        ATRACE_NAME("BlurRegion");
+                        SFTRACE_NAME("BlurRegion");
                         cachedBlurs[region.blurRadius] =
                                 mBlurFilter->generate(context, region.blurRadius, blurInput,
                                                       blurRect);
@@ -965,7 +977,7 @@
 
         SkPaint paint;
         if (layer.source.buffer.buffer) {
-            ATRACE_NAME("DrawImage");
+            SFTRACE_NAME("DrawImage");
             validateInputBufferUsage(layer.source.buffer.buffer->getBuffer());
             const auto& item = layer.source.buffer;
             auto imageTextureRef = getOrCreateBackendTexture(item.buffer->getBuffer(), false);
@@ -1032,18 +1044,20 @@
                                                            toSkColorSpace(layerDataspace)));
             }
 
-            paint.setShader(createRuntimeEffectShader(
-                    RuntimeEffectShaderParameters{.shader = shader,
-                                                  .layer = layer,
-                                                  .display = display,
-                                                  .undoPremultipliedAlpha = !item.isOpaque &&
-                                                          item.usePremultipliedAlpha,
-                                                  .requiresLinearEffect = requiresLinearEffect,
-                                                  .layerDimmingRatio = dimInLinearSpace
-                                                          ? layerDimmingRatio
-                                                          : 1.f,
-                                                  .outputDataSpace = display.outputDataspace,
-                                                  .fakeOutputDataspace = fakeDataspace}));
+            SkRect imageBounds;
+            matrix.mapRect(&imageBounds, SkRect::Make(image->bounds()));
+
+            paint.setShader(createRuntimeEffectShader(RuntimeEffectShaderParameters{
+                    .shader = shader,
+                    .layer = layer,
+                    .display = display,
+                    .undoPremultipliedAlpha = !item.isOpaque && item.usePremultipliedAlpha,
+                    .requiresLinearEffect = requiresLinearEffect,
+                    .layerDimmingRatio = dimInLinearSpace ? layerDimmingRatio : 1.f,
+                    .outputDataSpace = display.outputDataspace,
+                    .fakeOutputDataspace = fakeDataspace,
+                    .imageBounds = imageBounds,
+            }));
 
             // Turn on dithering when dimming beyond this (arbitrary) threshold...
             static constexpr float kDimmingThreshold = 0.9f;
@@ -1096,7 +1110,7 @@
                 paint.setColorFilter(SkColorFilters::Matrix(colorMatrix));
             }
         } else {
-            ATRACE_NAME("DrawColor");
+            SFTRACE_NAME("DrawColor");
             const auto color = layer.source.solidColor;
             sk_sp<SkShader> shader = SkShaders::Color(SkColor4f{.fR = color.r,
                                                                 .fG = color.g,
@@ -1111,7 +1125,8 @@
                                                   .requiresLinearEffect = requiresLinearEffect,
                                                   .layerDimmingRatio = layerDimmingRatio,
                                                   .outputDataSpace = display.outputDataspace,
-                                                  .fakeOutputDataspace = fakeDataspace}));
+                                                  .fakeOutputDataspace = fakeDataspace,
+                                                  .imageBounds = SkRect::MakeEmpty()}));
         }
 
         if (layer.disableBlending) {
@@ -1152,7 +1167,7 @@
             canvas->drawRect(bounds.rect(), paint);
         }
         if (kGaneshFlushAfterEveryLayer) {
-            ATRACE_NAME("flush surface");
+            SFTRACE_NAME("flush surface");
             // No-op in Graphite. If "flushing" Skia's drawing commands after each layer is desired
             // in Graphite, then a graphite::Recording would need to be snapped and tracked for each
             // layer, which is likely possible but adds non-trivial complexity (in both bookkeeping
@@ -1167,7 +1182,7 @@
     LOG_ALWAYS_FATAL_IF(activeSurface != dstSurface);
     auto drawFence = sp<Fence>::make(flushAndSubmit(context, dstSurface));
 
-    if (ATRACE_ENABLED()) {
+    if (SFTRACE_ENABLED()) {
         static gui::FenceMonitor sMonitor("RE Completion");
         sMonitor.queueFence(drawFence);
     }
@@ -1185,7 +1200,7 @@
 void SkiaRenderEngine::drawShadow(SkCanvas* canvas,
                                   const SkRRect& casterRRect,
                                   const ShadowSettings& settings) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     const float casterZ = settings.length / 2.0f;
     const auto flags =
             settings.casterIsTranslucent ? kTransparentOccluder_ShadowFlag : kNone_ShadowFlag;
diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h
index c8f9241..224a1ca 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.h
+++ b/libs/renderengine/skia/SkiaRenderEngine.h
@@ -38,6 +38,7 @@
 #include "compat/SkiaGpuContext.h"
 #include "debug/SkiaCapture.h"
 #include "filters/BlurFilter.h"
+#include "filters/EdgeExtensionShaderFactory.h"
 #include "filters/LinearEffect.h"
 #include "filters/StretchShaderFactory.h"
 
@@ -156,6 +157,7 @@
         float layerDimmingRatio;
         const ui::Dataspace outputDataSpace;
         const ui::Dataspace fakeOutputDataspace;
+        const SkRect& imageBounds;
     };
     sk_sp<SkShader> createRuntimeEffectShader(const RuntimeEffectShaderParameters&);
 
@@ -175,6 +177,7 @@
     AutoBackendTexture::CleanupManager mTextureCleanupMgr GUARDED_BY(mRenderingMutex);
 
     StretchShaderFactory mStretchShaderFactory;
+    EdgeExtensionShaderFactory mEdgeExtensionShaderFactory;
 
     sp<Fence> mLastDrawFence;
     BlurFilter* mBlurFilter = nullptr;
diff --git a/libs/renderengine/skia/SkiaVkRenderEngine.cpp b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
index bd50107..d89e818 100644
--- a/libs/renderengine/skia/SkiaVkRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
@@ -29,13 +29,11 @@
 #include <GrDirectContext.h>
 #include <include/gpu/ganesh/vk/GrVkBackendSemaphore.h>
 #include <include/gpu/ganesh/vk/GrVkDirectContext.h>
-#include <vk/GrVkExtensions.h>
 #include <vk/GrVkTypes.h>
 
 #include <android-base/stringprintf.h>
-#include <gui/TraceUtils.h>
+#include <common/trace.h>
 #include <sync/sync.h>
-#include <utils/Trace.h>
 
 #include <memory>
 #include <string>
diff --git a/libs/renderengine/skia/SkiaVkRenderEngine.h b/libs/renderengine/skia/SkiaVkRenderEngine.h
index 0a2f9b2..d2bb3d5 100644
--- a/libs/renderengine/skia/SkiaVkRenderEngine.h
+++ b/libs/renderengine/skia/SkiaVkRenderEngine.h
@@ -17,8 +17,6 @@
 #ifndef SF_SKIAVKRENDERENGINE_H_
 #define SF_SKIAVKRENDERENGINE_H_
 
-#include <vk/GrVkBackendContext.h>
-
 #include "SkiaRenderEngine.h"
 #include "VulkanInterface.h"
 #include "compat/SkiaGpuContext.h"
diff --git a/libs/renderengine/skia/VulkanInterface.cpp b/libs/renderengine/skia/VulkanInterface.cpp
index 5e756b0..37b69f6 100644
--- a/libs/renderengine/skia/VulkanInterface.cpp
+++ b/libs/renderengine/skia/VulkanInterface.cpp
@@ -32,21 +32,8 @@
 namespace renderengine {
 namespace skia {
 
-GrVkBackendContext VulkanInterface::getGaneshBackendContext() {
-    GrVkBackendContext backendContext;
-    backendContext.fInstance = mInstance;
-    backendContext.fPhysicalDevice = mPhysicalDevice;
-    backendContext.fDevice = mDevice;
-    backendContext.fQueue = mQueue;
-    backendContext.fGraphicsQueueIndex = mQueueIndex;
-    backendContext.fMaxAPIVersion = mApiVersion;
-    backendContext.fVkExtensions = &mGrExtensions;
-    backendContext.fDeviceFeatures2 = mPhysicalDeviceFeatures2;
-    backendContext.fGetProc = mGrGetProc;
-    backendContext.fProtectedContext = mIsProtected ? Protected::kYes : Protected::kNo;
-    backendContext.fDeviceLostContext = this; // VulkanInterface is long-lived
-    backendContext.fDeviceLostProc = onVkDeviceFault;
-    return backendContext;
+VulkanBackendContext VulkanInterface::getGaneshBackendContext() {
+    return this->getGraphiteBackendContext();
 };
 
 VulkanBackendContext VulkanInterface::getGraphiteBackendContext() {
@@ -57,7 +44,7 @@
     backendContext.fQueue = mQueue;
     backendContext.fGraphicsQueueIndex = mQueueIndex;
     backendContext.fMaxAPIVersion = mApiVersion;
-    backendContext.fVkExtensions = &mGrExtensions;
+    backendContext.fVkExtensions = &mVulkanExtensions;
     backendContext.fDeviceFeatures2 = mPhysicalDeviceFeatures2;
     backendContext.fGetProc = mGrGetProc;
     backendContext.fProtectedContext = mIsProtected ? Protected::kYes : Protected::kNo;
@@ -429,11 +416,11 @@
         mDeviceExtensionNames.push_back(devExt.extensionName);
     }
 
-    mGrExtensions.init(sGetProc, instance, physicalDevice, enabledInstanceExtensionNames.size(),
-                       enabledInstanceExtensionNames.data(), enabledDeviceExtensionNames.size(),
-                       enabledDeviceExtensionNames.data());
+    mVulkanExtensions.init(sGetProc, instance, physicalDevice, enabledInstanceExtensionNames.size(),
+                           enabledInstanceExtensionNames.data(), enabledDeviceExtensionNames.size(),
+                           enabledDeviceExtensionNames.data());
 
-    if (!mGrExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)) {
+    if (!mVulkanExtensions.hasExtension(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, 1)) {
         BAIL("Vulkan driver doesn't support external semaphore fd");
     }
 
@@ -458,7 +445,7 @@
         tailPnext = &mProtectedMemoryFeatures->pNext;
     }
 
-    if (mGrExtensions.hasExtension(VK_EXT_DEVICE_FAULT_EXTENSION_NAME, 1)) {
+    if (mVulkanExtensions.hasExtension(VK_EXT_DEVICE_FAULT_EXTENSION_NAME, 1)) {
         mDeviceFaultFeatures = new VkPhysicalDeviceFaultFeaturesEXT;
         mDeviceFaultFeatures->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT;
         mDeviceFaultFeatures->pNext = nullptr;
@@ -484,7 +471,7 @@
             queuePriority,
     };
 
-    if (mGrExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) {
+    if (mVulkanExtensions.hasExtension(VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME, 2)) {
         queueNextPtr = &queuePriorityCreateInfo;
     }
 
@@ -606,7 +593,7 @@
     mQueue = VK_NULL_HANDLE;          // Implicitly destroyed by destroying mDevice.
     mQueueIndex = 0;
     mApiVersion = 0;
-    mGrExtensions = skgpu::VulkanExtensions();
+    mVulkanExtensions = skgpu::VulkanExtensions();
     mGrGetProc = nullptr;
     mIsProtected = false;
     mIsRealtimePriority = false;
diff --git a/libs/renderengine/skia/VulkanInterface.h b/libs/renderengine/skia/VulkanInterface.h
index f20b002..d0fe4d1 100644
--- a/libs/renderengine/skia/VulkanInterface.h
+++ b/libs/renderengine/skia/VulkanInterface.h
@@ -16,7 +16,7 @@
 
 #pragma once
 
-#include <include/gpu/vk/GrVkBackendContext.h>
+#include <include/gpu/vk/VulkanBackendContext.h>
 #include <include/gpu/vk/VulkanExtensions.h>
 #include <include/gpu/vk/VulkanTypes.h>
 
@@ -24,10 +24,6 @@
 
 using namespace skgpu;
 
-namespace skgpu {
-struct VulkanBackendContext;
-} // namespace skgpu
-
 namespace android {
 namespace renderengine {
 namespace skia {
@@ -48,7 +44,8 @@
     bool takeOwnership();
     void teardown();
 
-    GrVkBackendContext getGaneshBackendContext();
+    // TODO(b/309785258) Combine these into one now that they are the same implementation.
+    VulkanBackendContext getGaneshBackendContext();
     VulkanBackendContext getGraphiteBackendContext();
     VkSemaphore createExportableSemaphore();
     VkSemaphore importSemaphoreFromSyncFd(int syncFd);
@@ -86,7 +83,7 @@
     VkQueue mQueue = VK_NULL_HANDLE;
     int mQueueIndex = 0;
     uint32_t mApiVersion = 0;
-    skgpu::VulkanExtensions mGrExtensions;
+    skgpu::VulkanExtensions mVulkanExtensions;
     VkPhysicalDeviceFeatures2* mPhysicalDeviceFeatures2 = nullptr;
     VkPhysicalDeviceSamplerYcbcrConversionFeatures* mSamplerYcbcrConversionFeatures = nullptr;
     VkPhysicalDeviceProtectedMemoryFeatures* mProtectedMemoryFeatures = nullptr;
diff --git a/libs/renderengine/skia/compat/GaneshBackendTexture.cpp b/libs/renderengine/skia/compat/GaneshBackendTexture.cpp
index d246466..3fbc6ca 100644
--- a/libs/renderengine/skia/compat/GaneshBackendTexture.cpp
+++ b/libs/renderengine/skia/compat/GaneshBackendTexture.cpp
@@ -32,15 +32,15 @@
 #include "skia/compat/SkiaBackendTexture.h"
 
 #include <android/hardware_buffer.h>
+#include <common/trace.h>
 #include <log/log_main.h>
-#include <utils/Trace.h>
 
 namespace android::renderengine::skia {
 
 GaneshBackendTexture::GaneshBackendTexture(sk_sp<GrDirectContext> grContext,
                                            AHardwareBuffer* buffer, bool isOutputBuffer)
       : SkiaBackendTexture(buffer, isOutputBuffer), mGrContext(grContext) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     AHardwareBuffer_Desc desc;
     AHardwareBuffer_describe(buffer, &desc);
     const bool createProtectedImage = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
diff --git a/libs/renderengine/skia/compat/GaneshGpuContext.cpp b/libs/renderengine/skia/compat/GaneshGpuContext.cpp
index b2eae00..b121fe8 100644
--- a/libs/renderengine/skia/compat/GaneshGpuContext.cpp
+++ b/libs/renderengine/skia/compat/GaneshGpuContext.cpp
@@ -25,7 +25,7 @@
 #include <include/gpu/ganesh/gl/GrGLDirectContext.h>
 #include <include/gpu/ganesh/vk/GrVkDirectContext.h>
 #include <include/gpu/gl/GrGLInterface.h>
-#include <include/gpu/vk/GrVkBackendContext.h>
+#include <include/gpu/vk/VulkanBackendContext.h>
 
 #include "../AutoBackendTexture.h"
 #include "GaneshBackendTexture.h"
@@ -56,10 +56,10 @@
 }
 
 std::unique_ptr<SkiaGpuContext> SkiaGpuContext::MakeVulkan_Ganesh(
-        const GrVkBackendContext& grVkBackendContext,
+        const skgpu::VulkanBackendContext& vkBackendContext,
         GrContextOptions::PersistentCache& skSLCacheMonitor) {
     return std::make_unique<GaneshGpuContext>(
-            GrDirectContexts::MakeVulkan(grVkBackendContext, ganeshOptions(skSLCacheMonitor)));
+            GrDirectContexts::MakeVulkan(vkBackendContext, ganeshOptions(skSLCacheMonitor)));
 }
 
 GaneshGpuContext::GaneshGpuContext(sk_sp<GrDirectContext> grContext) : mGrContext(grContext) {
diff --git a/libs/renderengine/skia/compat/GraphiteBackendTexture.cpp b/libs/renderengine/skia/compat/GraphiteBackendTexture.cpp
index 3dd9ed2..a6e93ba 100644
--- a/libs/renderengine/skia/compat/GraphiteBackendTexture.cpp
+++ b/libs/renderengine/skia/compat/GraphiteBackendTexture.cpp
@@ -28,16 +28,16 @@
 #include "skia/ColorSpaces.h"
 
 #include <android/hardware_buffer.h>
+#include <common/trace.h>
 #include <inttypes.h>
 #include <log/log_main.h>
-#include <utils/Trace.h>
 
 namespace android::renderengine::skia {
 
 GraphiteBackendTexture::GraphiteBackendTexture(std::shared_ptr<skgpu::graphite::Recorder> recorder,
                                                AHardwareBuffer* buffer, bool isOutputBuffer)
       : SkiaBackendTexture(buffer, isOutputBuffer), mRecorder(std::move(recorder)) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     AHardwareBuffer_Desc desc;
     AHardwareBuffer_describe(buffer, &desc);
     const bool createProtectedImage = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
diff --git a/libs/renderengine/skia/compat/SkiaGpuContext.h b/libs/renderengine/skia/compat/SkiaGpuContext.h
index 282dfe7..9fa6fb8 100644
--- a/libs/renderengine/skia/compat/SkiaGpuContext.h
+++ b/libs/renderengine/skia/compat/SkiaGpuContext.h
@@ -23,7 +23,6 @@
 #include <include/gpu/GrDirectContext.h>
 #include <include/gpu/gl/GrGLInterface.h>
 #include <include/gpu/graphite/Context.h>
-#include <include/gpu/vk/GrVkBackendContext.h>
 #include "include/gpu/vk/VulkanBackendContext.h"
 
 #include "SkiaBackendTexture.h"
@@ -52,10 +51,10 @@
             GrContextOptions::PersistentCache& skSLCacheMonitor);
 
     /**
-     * grVkBackendContext must remain valid until after SkiaGpuContext is destroyed.
+     * vkBackendContext must remain valid until after SkiaGpuContext is destroyed.
      */
     static std::unique_ptr<SkiaGpuContext> MakeVulkan_Ganesh(
-            const GrVkBackendContext& grVkBackendContext,
+            const skgpu::VulkanBackendContext& vkBackendContext,
             GrContextOptions::PersistentCache& skSLCacheMonitor);
 
     // TODO: b/293371537 - Need shader / pipeline monitoring support in Graphite.
diff --git a/libs/renderengine/skia/debug/CommonPool.cpp b/libs/renderengine/skia/debug/CommonPool.cpp
index bf15300..9d7c69b 100644
--- a/libs/renderengine/skia/debug/CommonPool.cpp
+++ b/libs/renderengine/skia/debug/CommonPool.cpp
@@ -20,8 +20,8 @@
 #define LOG_TAG "RenderEngine"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
+#include <common/trace.h>
 #include <sys/resource.h>
-#include <utils/Trace.h>
 
 #include <system/thread_defs.h>
 #include <array>
@@ -31,7 +31,7 @@
 namespace skia {
 
 CommonPool::CommonPool() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     CommonPool* pool = this;
     // Create 2 workers
diff --git a/libs/renderengine/skia/debug/SkiaCapture.cpp b/libs/renderengine/skia/debug/SkiaCapture.cpp
index e778884..e6a0e22 100644
--- a/libs/renderengine/skia/debug/SkiaCapture.cpp
+++ b/libs/renderengine/skia/debug/SkiaCapture.cpp
@@ -22,9 +22,9 @@
 
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
+#include <common/trace.h>
 #include <log/log.h>
 #include <renderengine/RenderEngine.h>
-#include <utils/Trace.h>
 
 #include "CommonPool.h"
 #include "SkCanvas.h"
@@ -48,7 +48,7 @@
 }
 
 SkCanvas* SkiaCapture::tryCapture(SkSurface* surface) NO_THREAD_SAFETY_ANALYSIS {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     // If we are not running yet, set up.
     if (CC_LIKELY(!mCaptureRunning)) {
@@ -86,7 +86,7 @@
 }
 
 void SkiaCapture::endCapture() NO_THREAD_SAFETY_ANALYSIS {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     // Don't end anything if we are not running.
     if (CC_LIKELY(!mCaptureRunning)) {
         return;
@@ -102,7 +102,7 @@
 }
 
 SkCanvas* SkiaCapture::tryOffscreenCapture(SkSurface* surface, OffscreenState* state) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     // Don't start anything if we are not running.
     if (CC_LIKELY(!mCaptureRunning)) {
         return surface->getCanvas();
@@ -122,7 +122,7 @@
 }
 
 uint64_t SkiaCapture::endOffscreenCapture(OffscreenState* state) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     // Don't end anything if we are not running.
     if (CC_LIKELY(!mCaptureRunning)) {
         return 0;
@@ -151,7 +151,7 @@
 }
 
 void SkiaCapture::writeToFile() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     // Pass mMultiPic and mOpenMultiPicStream to a background thread, which will
     // handle the heavyweight serialization work and destroy them.
     // mOpenMultiPicStream is released to a bare pointer because keeping it in
@@ -169,7 +169,7 @@
 }
 
 bool SkiaCapture::setupMultiFrameCapture() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGD("Set up multi-frame capture, ms = %llu", mTimerInterval.count());
     base::SetProperty(PROPERTY_DEBUG_RENDERENGINE_CAPTURE_FILENAME, "");
 
diff --git a/libs/renderengine/skia/filters/BlurFilter.cpp b/libs/renderengine/skia/filters/BlurFilter.cpp
index 1e0c4cf..cd1bd71 100644
--- a/libs/renderengine/skia/filters/BlurFilter.cpp
+++ b/libs/renderengine/skia/filters/BlurFilter.cpp
@@ -25,8 +25,8 @@
 #include <SkString.h>
 #include <SkSurface.h>
 #include <SkTileMode.h>
+#include <common/trace.h>
 #include <log/log.h>
-#include <utils/Trace.h>
 
 namespace android {
 namespace renderengine {
@@ -79,7 +79,7 @@
                                 const uint32_t blurRadius, const float blurAlpha,
                                 const SkRect& blurRect, sk_sp<SkImage> blurredImage,
                                 sk_sp<SkImage> input) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     SkPaint paint;
     paint.setAlphaf(blurAlpha);
diff --git a/libs/renderengine/skia/filters/EdgeExtensionShaderFactory.cpp b/libs/renderengine/skia/filters/EdgeExtensionShaderFactory.cpp
new file mode 100644
index 0000000..1dbcc29
--- /dev/null
+++ b/libs/renderengine/skia/filters/EdgeExtensionShaderFactory.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2024 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 "EdgeExtensionShaderFactory.h"
+#include <SkPoint.h>
+#include <SkRuntimeEffect.h>
+#include <SkStream.h>
+#include <SkString.h>
+#include "log/log_main.h"
+
+namespace android::renderengine::skia {
+
+static const SkString edgeShader = SkString(R"(
+    uniform shader uContentTexture;
+    uniform vec2 uImgSize;
+
+    // TODO(b/214232209) oobTolerance is temporary and will be removed when the scrollbar will be
+    // hidden during the animation
+    const float oobTolerance = 15;
+    const int blurRadius = 3;
+    const float blurArea = float((2 * blurRadius + 1) * (2 * blurRadius + 1));
+
+    vec4 boxBlur(vec2 p) {
+        vec4 sumColors = vec4(0);
+
+        for (int i = -blurRadius; i <= blurRadius; i++) {
+            for (int j = -blurRadius; j <= blurRadius; j++) {
+                sumColors += uContentTexture.eval(p + vec2(i, j));
+            }
+        }
+        return sumColors / blurArea;
+    }
+
+    vec4 main(vec2 coord) {
+        vec2 nearestTexturePoint = clamp(coord, vec2(0, 0), uImgSize);
+        if (coord == nearestTexturePoint) {
+            return uContentTexture.eval(coord);
+        } else {
+            vec2 samplePoint = nearestTexturePoint + oobTolerance * normalize(
+                                    nearestTexturePoint - coord);
+            return boxBlur(samplePoint);
+        }
+    }
+)");
+
+sk_sp<SkShader> EdgeExtensionShaderFactory::createSkShader(const sk_sp<SkShader>& inputShader,
+                                                           const LayerSettings& layer,
+                                                           const SkRect& imageBounds) {
+    if (mBuilder == nullptr) {
+        const static SkRuntimeEffect::Result instance = SkRuntimeEffect::MakeForShader(edgeShader);
+        if (!instance.errorText.isEmpty()) {
+            ALOGE("EdgeExtensionShaderFactory terminated with an error: %s",
+                  instance.errorText.c_str());
+            return nullptr;
+        }
+        mBuilder = std::make_unique<SkRuntimeShaderBuilder>(instance.effect);
+    }
+    mBuilder->child("uContentTexture") = inputShader;
+    if (imageBounds.isEmpty()) {
+        mBuilder->uniform("uImgSize") = SkPoint{layer.geometry.boundaries.getWidth(),
+                                                layer.geometry.boundaries.getHeight()};
+    } else {
+        mBuilder->uniform("uImgSize") = SkPoint{imageBounds.width(), imageBounds.height()};
+    }
+    return mBuilder->makeShader();
+}
+} // namespace android::renderengine::skia
\ No newline at end of file
diff --git a/libs/renderengine/skia/filters/EdgeExtensionShaderFactory.h b/libs/renderengine/skia/filters/EdgeExtensionShaderFactory.h
new file mode 100644
index 0000000..b0a8a93
--- /dev/null
+++ b/libs/renderengine/skia/filters/EdgeExtensionShaderFactory.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 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 <SkImage.h>
+#include <SkRect.h>
+#include <SkRuntimeEffect.h>
+#include <SkShader.h>
+#include <renderengine/LayerSettings.h>
+#include <ui/EdgeExtensionEffect.h>
+
+namespace android::renderengine::skia {
+
+/**
+ * This shader is designed to prolong the texture of a surface whose bounds have been extended over
+ * the size of the texture. This shader is similar to the default clamp, but adds a blur effect and
+ * samples from close to the edge (compared to on the edge) to avoid weird artifacts when elements
+ * (in particular, scrollbars) touch the edge.
+ */
+class EdgeExtensionShaderFactory {
+public:
+    sk_sp<SkShader> createSkShader(const sk_sp<SkShader>& inputShader, const LayerSettings& layer,
+                                   const SkRect& imageBounds);
+
+private:
+    std::unique_ptr<SkRuntimeShaderBuilder> mBuilder;
+};
+} // namespace android::renderengine::skia
diff --git a/libs/renderengine/skia/filters/GaussianBlurFilter.cpp b/libs/renderengine/skia/filters/GaussianBlurFilter.cpp
index c9499cb..8c52c57 100644
--- a/libs/renderengine/skia/filters/GaussianBlurFilter.cpp
+++ b/libs/renderengine/skia/filters/GaussianBlurFilter.cpp
@@ -19,18 +19,18 @@
 #include "GaussianBlurFilter.h"
 #include <SkBlendMode.h>
 #include <SkCanvas.h>
+#include <SkImageFilters.h>
 #include <SkPaint.h>
 #include <SkRRect.h>
 #include <SkRuntimeEffect.h>
-#include <SkImageFilters.h>
 #include <SkSize.h>
 #include <SkString.h>
 #include <SkSurface.h>
 #include <SkTileMode.h>
+#include <common/trace.h>
 #include <include/gpu/ganesh/SkSurfaceGanesh.h>
-#include "include/gpu/GpuTypes.h" // from Skia
 #include <log/log.h>
-#include <utils/Trace.h>
+#include "include/gpu/GpuTypes.h" // from Skia
 
 namespace android {
 namespace renderengine {
diff --git a/libs/renderengine/skia/filters/KawaseBlurFilter.cpp b/libs/renderengine/skia/filters/KawaseBlurFilter.cpp
index 7a070d7..defaf6e 100644
--- a/libs/renderengine/skia/filters/KawaseBlurFilter.cpp
+++ b/libs/renderengine/skia/filters/KawaseBlurFilter.cpp
@@ -29,10 +29,10 @@
 #include <SkString.h>
 #include <SkSurface.h>
 #include <SkTileMode.h>
+#include <common/trace.h>
 #include <include/gpu/GpuTypes.h>
 #include <include/gpu/ganesh/SkSurfaceGanesh.h>
 #include <log/log.h>
-#include <utils/Trace.h>
 
 namespace android {
 namespace renderengine {
diff --git a/libs/renderengine/skia/filters/LinearEffect.cpp b/libs/renderengine/skia/filters/LinearEffect.cpp
index f7dcd3a..3bc3564 100644
--- a/libs/renderengine/skia/filters/LinearEffect.cpp
+++ b/libs/renderengine/skia/filters/LinearEffect.cpp
@@ -19,9 +19,9 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #include <SkString.h>
+#include <common/trace.h>
 #include <log/log.h>
 #include <shaders/shaders.h>
-#include <utils/Trace.h>
 
 #include <math/mat4.h>
 
@@ -30,7 +30,7 @@
 namespace skia {
 
 sk_sp<SkRuntimeEffect> buildRuntimeEffect(const shaders::LinearEffect& linearEffect) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     SkString shaderString = SkString(shaders::buildLinearEffectSkSL(linearEffect));
 
     auto [shader, error] = SkRuntimeEffect::MakeForShader(shaderString);
@@ -45,7 +45,7 @@
         sk_sp<SkRuntimeEffect> runtimeEffect, const mat4& colorTransform, float maxDisplayLuminance,
         float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer,
         aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     SkRuntimeShaderBuilder effectBuilder(runtimeEffect);
 
     effectBuilder.child("child") = shader;
diff --git a/libs/renderengine/skia/filters/MouriMap.cpp b/libs/renderengine/skia/filters/MouriMap.cpp
index 7d8b8a5..b458939 100644
--- a/libs/renderengine/skia/filters/MouriMap.cpp
+++ b/libs/renderengine/skia/filters/MouriMap.cpp
@@ -35,7 +35,7 @@
         float maximum = 0.0;
         for (int y = 0; y < 16; y++) {
             for (int x = 0; x < 16; x++) {
-                float3 linear = toLinearSrgb(bitmap.eval(xy * 16 + vec2(x, y)).rgb) * hdrSdrRatio;
+                float3 linear = toLinearSrgb(bitmap.eval((xy - 0.5) * 16 + 0.5 + vec2(x, y)).rgb) * hdrSdrRatio;
                 float maxRGB = max(linear.r, max(linear.g, linear.b));
                 maximum = max(maximum, log2(max(maxRGB, 1.0)));
             }
@@ -49,7 +49,7 @@
         float maximum = 0.0;
         for (int y = 0; y < 8; y++) {
             for (int x = 0; x < 8; x++) {
-                maximum = max(maximum, bitmap.eval(xy * 8 + vec2(x, y)).r);
+                maximum = max(maximum, bitmap.eval((xy - 0.5) * 8 + 0.5 + vec2(x, y)).r);
             }
         }
         return float4(float3(maximum), 1.0);
@@ -84,13 +84,13 @@
         float3 linear = toLinearSrgb(rgba.rgb) * hdrSdrRatio;
 
         if (localMax <= 1.0) {
-            return float4(fromLinearSrgb(linear), 1.0);
+            return float4(fromLinearSrgb(linear), rgba.a);
         }
 
         float maxRGB = max(linear.r, max(linear.g, linear.b));
         localMax = max(localMax, maxRGB);
         float gain = (1 + maxRGB / (localMax * localMax)) / (1 + maxRGB);
-        return float4(fromLinearSrgb(linear * gain), 1.0);
+        return float4(fromLinearSrgb(linear * gain), rgba.a);
     }
 )");
 
diff --git a/libs/renderengine/tests/Android.bp b/libs/renderengine/tests/Android.bp
index 0783714..7fbbf49 100644
--- a/libs/renderengine/tests/Android.bp
+++ b/libs/renderengine/tests/Android.bp
@@ -66,5 +66,6 @@
         "libutils",
         "server_configurable_flags",
         "libaconfig_storage_read_api_cc",
+        "libtracing_perfetto",
     ],
 }
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index a8a9823..b5cc65f 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -34,9 +34,12 @@
 #include <ui/ColorSpace.h>
 #include <ui/PixelFormat.h>
 
+#include <algorithm>
 #include <chrono>
 #include <condition_variable>
+#include <filesystem>
 #include <fstream>
+#include <system_error>
 
 #include "../skia/SkiaGLRenderEngine.h"
 #include "../skia/SkiaVkRenderEngine.h"
@@ -259,22 +262,51 @@
 
     ~RenderEngineTest() {
         if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
-            writeBufferToFile("/data/texture_out_");
+            writeBufferToFile("/data/local/tmp/RenderEngineTest/");
         }
         const ::testing::TestInfo* const test_info =
                 ::testing::UnitTest::GetInstance()->current_test_info();
         ALOGI("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
     }
 
-    void writeBufferToFile(const char* basename) {
-        std::string filename(basename);
-        filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
-        filename.append(".ppm");
-        std::ofstream file(filename.c_str(), std::ios::binary);
+    // If called during e.g.
+    // `PerRenderEngineType/RenderEngineTest#drawLayers_fillBufferCheckersRotate90_colorSource/0`
+    // with a directory of `/data/local/tmp/RenderEngineTest`, then mBuffer will be dumped to
+    // `/data/local/tmp/RenderEngineTest/drawLayers_fillBufferCheckersRotate90_colorSource-0.ppm`
+    //
+    // Note: if `directory` does not exist, then its full path will be recursively created with 777
+    // permissions. If `directory` already exists but does not grant the executing user write
+    // permissions, then saving the buffer will fail.
+    //
+    // Since this is test-only code, no security considerations are made.
+    void writeBufferToFile(const filesystem::path& directory) {
+        const auto currentTestInfo = ::testing::UnitTest::GetInstance()->current_test_info();
+        LOG_ALWAYS_FATAL_IF(!currentTestInfo,
+                            "writeBufferToFile must be called during execution of a test");
+
+        std::string fileName(currentTestInfo->name());
+        // Test names may include the RenderEngine variant separated by '/', which would separate
+        // the file name into a subdirectory if not corrected.
+        std::replace(fileName.begin(), fileName.end(), '/', '-');
+        fileName.append(".ppm");
+
+        std::error_code err;
+        filesystem::create_directories(directory, err);
+        if (err.value()) {
+            ALOGE("Unable to create directory %s for writing %s (%d: %s)", directory.c_str(),
+                  fileName.c_str(), err.value(), err.message().c_str());
+            return;
+        }
+
+        // Append operator ("/") ensures exactly one "/" directly before the argument.
+        const filesystem::path filePath = directory / fileName;
+        std::ofstream file(filePath.c_str(), std::ios::binary);
         if (!file.is_open()) {
-            ALOGE("Unable to open file: %s", filename.c_str());
-            ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
-                  "surfaceflinger to write debug images");
+            ALOGE("Unable to open file: %s", filePath.c_str());
+            ALOGE("You may need to do: \"adb shell setenforce 0\" to enable surfaceflinger to "
+                  "write debug images, or the %s directory might not give the executing user write "
+                  "permission",
+                  directory.c_str());
             return;
         }
 
@@ -304,6 +336,7 @@
             }
         }
         file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
+        ALOGI("Image of incorrect output written to %s", filePath.c_str());
         mBuffer->getBuffer()->unlock();
     }
 
@@ -3147,6 +3180,214 @@
     expectBufferColor(Rect(0, 0, 1, 1), 0,  70, 0, 255);
 }
 
+TEST_P(RenderEngineTest, localTonemap_preservesFullscreenSdr) {
+    if (!GetParam()->apiSupported()) {
+        GTEST_SKIP();
+    }
+
+    initializeRenderEngine();
+
+    mBuffer = std::make_shared<
+            renderengine::impl::
+                    ExternalTexture>(sp<GraphicBuffer>::make(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1,
+                                                             GRALLOC_USAGE_SW_READ_OFTEN |
+                                                                     GRALLOC_USAGE_SW_WRITE_OFTEN |
+                                                                     GRALLOC_USAGE_HW_RENDER |
+                                                                     GRALLOC_USAGE_HW_TEXTURE,
+                                                             "output"),
+                                     *mRE,
+                                     renderengine::impl::ExternalTexture::Usage::READABLE |
+                                             renderengine::impl::ExternalTexture::Usage::WRITEABLE);
+    ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
+
+    const auto whiteBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(51, 51, 51, 255));
+
+    const auto rect = Rect(0, 0, 1, 1);
+    const renderengine::DisplaySettings display{
+            .physicalDisplay = rect,
+            .clip = rect,
+            .outputDataspace = ui::Dataspace::SRGB,
+            .targetLuminanceNits = 40,
+            .tonemapStrategy = renderengine::DisplaySettings::TonemapStrategy::Local,
+    };
+
+    const renderengine::LayerSettings whiteLayer{
+            .geometry.boundaries = rect.toFloatRect(),
+            .source =
+                    renderengine::PixelSource{
+                            .buffer =
+                                    renderengine::Buffer{
+                                            .buffer = whiteBuffer,
+                                    },
+                    },
+            .alpha = 1.0f,
+            .sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR,
+            .whitePointNits = 200,
+    };
+
+    std::vector<renderengine::LayerSettings> layers{whiteLayer};
+    invokeDraw(display, layers);
+
+    expectBufferColor(Rect(0, 0, 1, 1), 255, 255, 255, 255);
+}
+
+TEST_P(RenderEngineTest, localTonemap_preservesFarawaySdrRegions) {
+    if (!GetParam()->apiSupported()) {
+        GTEST_SKIP();
+    }
+
+    initializeRenderEngine();
+
+    const auto blockWidth = 256;
+    const auto width = blockWidth * 4;
+
+    const auto buffer = allocateSourceBuffer(width, 1);
+
+    mBuffer = std::make_shared<
+            renderengine::impl::
+                    ExternalTexture>(sp<GraphicBuffer>::make(width, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+                                                             1,
+                                                             GRALLOC_USAGE_SW_READ_OFTEN |
+                                                                     GRALLOC_USAGE_SW_WRITE_OFTEN |
+                                                                     GRALLOC_USAGE_HW_RENDER |
+                                                                     GRALLOC_USAGE_HW_TEXTURE,
+                                                             "output"),
+                                     *mRE,
+                                     renderengine::impl::ExternalTexture::Usage::READABLE |
+                                             renderengine::impl::ExternalTexture::Usage::WRITEABLE);
+
+    {
+        uint8_t* pixels;
+        buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                                  reinterpret_cast<void**>(&pixels));
+        uint8_t* dst = pixels;
+        for (uint32_t i = 0; i < width; i++) {
+            uint8_t value = 0;
+            if (i < blockWidth) {
+                value = 51;
+            } else if (i >= blockWidth * 3) {
+                value = 255;
+            }
+            dst[0] = value;
+            dst[1] = value;
+            dst[2] = value;
+            dst[3] = 255;
+            dst += 4;
+        }
+        buffer->getBuffer()->unlock();
+    }
+
+    const auto rect = Rect(0, 0, width, 1);
+    const renderengine::DisplaySettings display{
+            .physicalDisplay = rect,
+            .clip = rect,
+            .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
+            .targetLuminanceNits = 40,
+            .tonemapStrategy = renderengine::DisplaySettings::TonemapStrategy::Local,
+    };
+
+    const renderengine::LayerSettings whiteLayer{
+            .geometry.boundaries = rect.toFloatRect(),
+            .source =
+                    renderengine::PixelSource{
+                            .buffer =
+                                    renderengine::Buffer{
+                                            .buffer = buffer,
+                                    },
+                    },
+            .alpha = 1.0f,
+            .sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR,
+            .whitePointNits = 200,
+    };
+
+    std::vector<renderengine::LayerSettings> layers{whiteLayer};
+    invokeDraw(display, layers);
+
+    // SDR regions are boosted to preserve SDR detail.
+    expectBufferColor(Rect(0, 0, blockWidth, 1), 255, 255, 255, 255);
+    expectBufferColor(Rect(blockWidth, 0, blockWidth * 2, 1), 0, 0, 0, 255);
+    expectBufferColor(Rect(blockWidth * 2, 0, blockWidth * 3, 1), 0, 0, 0, 255);
+    expectBufferColor(Rect(blockWidth * 3, 0, blockWidth * 4, 1), 255, 255, 255, 255);
+}
+
+TEST_P(RenderEngineTest, localTonemap_tonemapsNearbySdrRegions) {
+    if (!GetParam()->apiSupported()) {
+        GTEST_SKIP();
+    }
+
+    initializeRenderEngine();
+
+    const auto blockWidth = 2;
+    const auto width = blockWidth * 2;
+
+    mBuffer = std::make_shared<
+            renderengine::impl::
+                    ExternalTexture>(sp<GraphicBuffer>::make(width, 1, HAL_PIXEL_FORMAT_RGBA_8888,
+                                                             1,
+                                                             GRALLOC_USAGE_SW_READ_OFTEN |
+                                                                     GRALLOC_USAGE_SW_WRITE_OFTEN |
+                                                                     GRALLOC_USAGE_HW_RENDER |
+                                                                     GRALLOC_USAGE_HW_TEXTURE,
+                                                             "output"),
+                                     *mRE,
+                                     renderengine::impl::ExternalTexture::Usage::READABLE |
+                                             renderengine::impl::ExternalTexture::Usage::WRITEABLE);
+
+    const auto buffer = allocateSourceBuffer(width, 1);
+
+    {
+        uint8_t* pixels;
+        buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                                  reinterpret_cast<void**>(&pixels));
+        uint8_t* dst = pixels;
+        for (uint32_t i = 0; i < width; i++) {
+            uint8_t value = 0;
+            if (i < blockWidth) {
+                value = 51;
+            } else if (i >= blockWidth) {
+                value = 255;
+            }
+            dst[0] = value;
+            dst[1] = value;
+            dst[2] = value;
+            dst[3] = 255;
+            dst += 4;
+        }
+        buffer->getBuffer()->unlock();
+    }
+
+    const auto rect = Rect(0, 0, width, 1);
+    const renderengine::DisplaySettings display{
+            .physicalDisplay = rect,
+            .clip = rect,
+            .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
+            .targetLuminanceNits = 40,
+            .tonemapStrategy = renderengine::DisplaySettings::TonemapStrategy::Local,
+    };
+
+    const renderengine::LayerSettings whiteLayer{
+            .geometry.boundaries = rect.toFloatRect(),
+            .source =
+                    renderengine::PixelSource{
+                            .buffer =
+                                    renderengine::Buffer{
+                                            .buffer = buffer,
+                                    },
+                    },
+            .alpha = 1.0f,
+            .sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR,
+            .whitePointNits = 200,
+    };
+
+    std::vector<renderengine::LayerSettings> layers{whiteLayer};
+    invokeDraw(display, layers);
+
+    // SDR regions remain "dimmed", but preserve detail with a roll-off curve.
+    expectBufferColor(Rect(0, 0, blockWidth, 1), 132, 132, 132, 255, 2);
+    // HDR regions are not dimmed.
+    expectBufferColor(Rect(blockWidth, 0, blockWidth * 2, 1), 255, 255, 255, 255);
+}
+
 TEST_P(RenderEngineTest, primeShaderCache) {
     // TODO: b/331447071 - Fix in Graphite and re-enable.
     if (GetParam()->skiaBackend() == renderengine::RenderEngine::SkiaBackend::GRAPHITE) {
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index d27c151..f5a90fd 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -23,9 +23,9 @@
 #include <future>
 
 #include <android-base/stringprintf.h>
+#include <common/trace.h>
 #include <private/gui/SyncFeatures.h>
 #include <processgroup/processgroup.h>
-#include <utils/Trace.h>
 
 using namespace std::chrono_literals;
 
@@ -39,7 +39,7 @@
 
 RenderEngineThreaded::RenderEngineThreaded(CreateInstanceFactory factory)
       : RenderEngine(Threaded::YES) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::lock_guard lockThread(mThreadMutex);
     mThread = std::thread(&RenderEngineThreaded::threadMain, this, factory);
@@ -76,7 +76,7 @@
 
 // NO_THREAD_SAFETY_ANALYSIS is because std::unique_lock presently lacks thread safety annotations.
 void RenderEngineThreaded::threadMain(CreateInstanceFactory factory) NO_THREAD_SAFETY_ANALYSIS {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (!SetTaskProfiles(0, {"SFRenderEnginePolicy"})) {
         ALOGW("Failed to set render-engine task profile!");
@@ -133,13 +133,13 @@
 std::future<void> RenderEngineThreaded::primeCache(PrimeCacheConfig config) {
     const auto resultPromise = std::make_shared<std::promise<void>>();
     std::future<void> resultFuture = resultPromise->get_future();
-    ATRACE_CALL();
+    SFTRACE_CALL();
     // This function is designed so it can run asynchronously, so we do not need to wait
     // for the futures.
     {
         std::lock_guard lock(mThreadMutex);
         mFunctionCalls.push([resultPromise, config](renderengine::RenderEngine& instance) {
-            ATRACE_NAME("REThreaded::primeCache");
+            SFTRACE_NAME("REThreaded::primeCache");
             if (setSchedFifo(false) != NO_ERROR) {
                 ALOGW("Couldn't set SCHED_OTHER for primeCache");
             }
@@ -163,7 +163,7 @@
     {
         std::lock_guard lock(mThreadMutex);
         mFunctionCalls.push([&resultPromise, &result](renderengine::RenderEngine& instance) {
-            ATRACE_NAME("REThreaded::dump");
+            SFTRACE_NAME("REThreaded::dump");
             std::string localResult = result;
             instance.dump(localResult);
             resultPromise.set_value(std::move(localResult));
@@ -176,13 +176,13 @@
 
 void RenderEngineThreaded::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
                                                     bool isRenderable) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     // This function is designed so it can run asynchronously, so we do not need to wait
     // for the futures.
     {
         std::lock_guard lock(mThreadMutex);
         mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
-            ATRACE_NAME("REThreaded::mapExternalTextureBuffer");
+            SFTRACE_NAME("REThreaded::mapExternalTextureBuffer");
             instance.mapExternalTextureBuffer(buffer, isRenderable);
         });
     }
@@ -190,14 +190,14 @@
 }
 
 void RenderEngineThreaded::unmapExternalTextureBuffer(sp<GraphicBuffer>&& buffer) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     // This function is designed so it can run asynchronously, so we do not need to wait
     // for the futures.
     {
         std::lock_guard lock(mThreadMutex);
         mFunctionCalls.push(
                 [=, buffer = std::move(buffer)](renderengine::RenderEngine& instance) mutable {
-                    ATRACE_NAME("REThreaded::unmapExternalTextureBuffer");
+                    SFTRACE_NAME("REThreaded::unmapExternalTextureBuffer");
                     instance.unmapExternalTextureBuffer(std::move(buffer));
                 });
     }
@@ -229,7 +229,7 @@
     {
         std::lock_guard lock(mThreadMutex);
         mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
-            ATRACE_NAME("REThreaded::cleanupPostRender");
+            SFTRACE_NAME("REThreaded::cleanupPostRender");
             instance.cleanupPostRender();
         });
         mNeedsPostRenderCleanup = false;
@@ -252,7 +252,7 @@
 ftl::Future<FenceResult> RenderEngineThreaded::drawLayers(
         const DisplaySettings& display, const std::vector<LayerSettings>& layers,
         const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     const auto resultPromise = std::make_shared<std::promise<FenceResult>>();
     std::future<FenceResult> resultFuture = resultPromise->get_future();
     int fd = bufferFence.release();
@@ -261,7 +261,7 @@
         mNeedsPostRenderCleanup = true;
         mFunctionCalls.push(
                 [resultPromise, display, layers, buffer, fd](renderengine::RenderEngine& instance) {
-                    ATRACE_NAME("REThreaded::drawLayers");
+                    SFTRACE_NAME("REThreaded::drawLayers");
                     instance.updateProtectedContext(layers, buffer);
                     instance.drawLayersInternal(std::move(resultPromise), display, layers, buffer,
                                                 base::unique_fd(fd));
@@ -277,7 +277,7 @@
     {
         std::lock_guard lock(mThreadMutex);
         mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
-            ATRACE_NAME("REThreaded::getContextPriority");
+            SFTRACE_NAME("REThreaded::getContextPriority");
             int priority = instance.getContextPriority();
             resultPromise.set_value(priority);
         });
@@ -297,7 +297,7 @@
     {
         std::lock_guard lock(mThreadMutex);
         mFunctionCalls.push([size](renderengine::RenderEngine& instance) {
-            ATRACE_NAME("REThreaded::onActiveDisplaySizeChanged");
+            SFTRACE_NAME("REThreaded::onActiveDisplaySizeChanged");
             instance.onActiveDisplaySizeChanged(size);
         });
     }
@@ -324,7 +324,7 @@
     {
         std::lock_guard lock(mThreadMutex);
         mFunctionCalls.push([tracingEnabled](renderengine::RenderEngine& instance) {
-            ATRACE_NAME("REThreaded::setEnableTracing");
+            SFTRACE_NAME("REThreaded::setEnableTracing");
             instance.setEnableTracing(tracingEnabled);
         });
     }
diff --git a/libs/sensor/Android.bp b/libs/sensor/Android.bp
index 7fa47b4..659666d 100644
--- a/libs/sensor/Android.bp
+++ b/libs/sensor/Android.bp
@@ -63,6 +63,8 @@
         "libhardware",
         "libpermission",
         "android.companion.virtual.virtualdevice_aidl-cpp",
+        "libaconfig_storage_read_api_cc",
+        "server_configurable_flags",
     ],
 
     static_libs: [
diff --git a/libs/sensor/SensorEventQueue.cpp b/libs/sensor/SensorEventQueue.cpp
index 4438d45..84852ea 100644
--- a/libs/sensor/SensorEventQueue.cpp
+++ b/libs/sensor/SensorEventQueue.cpp
@@ -15,31 +15,40 @@
  */
 
 #define LOG_TAG "Sensors"
-
-#include <sensor/SensorEventQueue.h>
-
-#include <algorithm>
-#include <sys/socket.h>
-
-#include <utils/RefBase.h>
-#include <utils/Looper.h>
-
-#include <sensor/Sensor.h>
-#include <sensor/BitTube.h>
-#include <sensor/ISensorEventConnection.h>
+#define ATRACE_TAG ATRACE_TAG_SYSTEM_SERVER
 
 #include <android/sensor.h>
+#include <com_android_hardware_libsensor_flags.h>
+#include <cutils/trace.h>
 #include <hardware/sensors-base.h>
+#include <sensor/BitTube.h>
+#include <sensor/ISensorEventConnection.h>
+#include <sensor/Sensor.h>
+#include <sensor/SensorEventQueue.h>
+#include <sensor/SensorManager.h>
+#include <sys/socket.h>
+#include <utils/Looper.h>
+#include <utils/RefBase.h>
+
+#include <algorithm>
+#include <cinttypes>
+#include <string>
 
 using std::min;
+namespace libsensor_flags = com::android::hardware::libsensor::flags;
 
 // ----------------------------------------------------------------------------
 namespace android {
 // ----------------------------------------------------------------------------
 
-SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
-    : mSensorEventConnection(connection), mRecBuffer(nullptr), mAvailable(0), mConsumed(0),
-      mNumAcksToSend(0) {
+SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection,
+                                   SensorManager& sensorManager)
+      : mSensorEventConnection(connection),
+        mRecBuffer(nullptr),
+        mSensorManager(sensorManager),
+        mAvailable(0),
+        mConsumed(0),
+        mNumAcksToSend(0) {
     mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT];
 }
 
@@ -65,8 +74,8 @@
 
 ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
     if (mAvailable == 0) {
-        ssize_t err = BitTube::recvObjects(mSensorChannel,
-                mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
+        ssize_t err =
+                BitTube::recvObjects(mSensorChannel, mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
         if (err < 0) {
             return err;
         }
@@ -75,6 +84,20 @@
     }
     size_t count = min(numEvents, mAvailable);
     memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));
+
+    if (CC_UNLIKELY(ATRACE_ENABLED()) &&
+        libsensor_flags::sensor_event_queue_report_sensor_usage_in_tracing()) {
+        for (size_t i = 0; i < count; i++) {
+            std::optional<std::string_view> sensorName =
+                    mSensorManager.getSensorNameByHandle(events->sensor);
+            if (sensorName.has_value()) {
+                char buffer[UINT8_MAX];
+                std::snprintf(buffer, sizeof(buffer), "Sensor event from %s",
+                              sensorName.value().data());
+                ATRACE_INSTANT_FOR_TRACK(LOG_TAG, buffer);
+            }
+        }
+    }
     mAvailable -= count;
     mConsumed += count;
     return static_cast<ssize_t>(count);
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index 9411e20..3ca6f0f 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -38,6 +38,7 @@
 #include <sensor/SensorEventQueue.h>
 
 #include <com_android_hardware_libsensor_flags.h>
+namespace libsensor_flags = com::android::hardware::libsensor::flags;
 
 // ----------------------------------------------------------------------------
 namespace android {
@@ -78,6 +79,21 @@
     return DEVICE_ID_DEFAULT;
 }
 
+bool findSensorNameInList(int32_t handle, const Vector<Sensor>& sensorList,
+                          std::string* outString) {
+    for (auto& sensor : sensorList) {
+        if (sensor.getHandle() == handle) {
+            std::ostringstream oss;
+            oss << sensor.getStringType() << ":" << sensor.getName();
+            if (outString) {
+                *outString = std::move(oss.str());
+            }
+            return true;
+        }
+    }
+    return false;
+}
+
 }  // namespace
 
 Mutex SensorManager::sLock;
@@ -355,6 +371,25 @@
     return nullptr;
 }
 
+std::optional<std::string_view> SensorManager::getSensorNameByHandle(int32_t handle) {
+    std::lock_guard<std::mutex> lock(mSensorHandleToNameMutex);
+    auto iterator = mSensorHandleToName.find(handle);
+    if (iterator != mSensorHandleToName.end()) {
+        return iterator->second;
+    }
+
+    std::string sensorName;
+    if (!findSensorNameInList(handle, mSensors, &sensorName) &&
+        !findSensorNameInList(handle, mDynamicSensors, &sensorName)) {
+        ALOGW("Cannot find sensor with handle %d", handle);
+        return std::nullopt;
+    }
+
+    mSensorHandleToName[handle] = std::move(sensorName);
+
+    return mSensorHandleToName[handle];
+}
+
 sp<SensorEventQueue> SensorManager::createEventQueue(
     String8 packageName, int mode, String16 attributionTag) {
     sp<SensorEventQueue> queue;
@@ -368,7 +403,7 @@
             ALOGE("createEventQueue: connection is NULL.");
             return nullptr;
         }
-        queue = new SensorEventQueue(connection);
+        queue = new SensorEventQueue(connection, *this);
         break;
     }
     return queue;
diff --git a/libs/sensor/include/sensor/SensorEventQueue.h b/libs/sensor/include/sensor/SensorEventQueue.h
index 8c3fde0..0bcaadc 100644
--- a/libs/sensor/include/sensor/SensorEventQueue.h
+++ b/libs/sensor/include/sensor/SensorEventQueue.h
@@ -42,6 +42,7 @@
 // ----------------------------------------------------------------------------
 
 class ISensorEventConnection;
+class SensorManager;
 class Sensor;
 class Looper;
 
@@ -65,7 +66,8 @@
     // Default sensor sample period
     static constexpr int32_t SENSOR_DELAY_NORMAL = 200000;
 
-    explicit SensorEventQueue(const sp<ISensorEventConnection>& connection);
+    explicit SensorEventQueue(const sp<ISensorEventConnection>& connection,
+                              SensorManager& sensorManager);
     virtual ~SensorEventQueue();
     virtual void onFirstRef();
 
@@ -107,6 +109,7 @@
     mutable Mutex mLock;
     mutable sp<Looper> mLooper;
     ASensorEvent* mRecBuffer;
+    SensorManager& mSensorManager;
     size_t mAvailable;
     size_t mConsumed;
     uint32_t mNumAcksToSend;
diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h
index 49f050a..8d7237d 100644
--- a/libs/sensor/include/sensor/SensorManager.h
+++ b/libs/sensor/include/sensor/SensorManager.h
@@ -17,22 +17,20 @@
 #ifndef ANDROID_GUI_SENSOR_MANAGER_H
 #define ANDROID_GUI_SENSOR_MANAGER_H
 
-#include <map>
-#include <unordered_map>
-
-#include <stdint.h>
-#include <sys/types.h>
-
 #include <binder/IBinder.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
-
+#include <sensor/SensorEventQueue.h>
+#include <stdint.h>
+#include <sys/types.h>
 #include <utils/Errors.h>
+#include <utils/String8.h>
 #include <utils/StrongPointer.h>
 #include <utils/Vector.h>
-#include <utils/String8.h>
 
-#include <sensor/SensorEventQueue.h>
+#include <map>
+#include <string>
+#include <unordered_map>
 
 // ----------------------------------------------------------------------------
 // Concrete types for the NDK
@@ -66,6 +64,7 @@
     sp<SensorEventQueue> createEventQueue(
         String8 packageName = String8(""), int mode = 0, String16 attributionTag = String16(""));
     bool isDataInjectionEnabled();
+    std::optional<std::string_view> getSensorNameByHandle(int32_t handle);
     bool isReplayDataInjectionEnabled();
     bool isHalBypassReplayDataInjectionEnabled();
     int createDirectChannel(size_t size, int channelType, const native_handle_t *channelData);
@@ -97,6 +96,9 @@
     const String16 mOpPackageName;
     const int mDeviceId;
     std::unordered_map<int, sp<ISensorEventConnection>> mDirectConnection;
+
+    std::mutex mSensorHandleToNameMutex;
+    std::unordered_map<int32_t, std::string> mSensorHandleToName;
     int32_t mDirectConnectionHandle;
 };
 
diff --git a/libs/tracing_perfetto/Android.bp b/libs/tracing_perfetto/Android.bp
index 3a4c869..b5c56c5 100644
--- a/libs/tracing_perfetto/Android.bp
+++ b/libs/tracing_perfetto/Android.bp
@@ -40,6 +40,7 @@
     ],
 
     shared_libs: [
+        "libbase",
         "libcutils",
         "libperfetto_c",
         "android.os.flags-aconfig-cc-host",
diff --git a/libs/tracing_perfetto/include/tracing_perfetto.h b/libs/tracing_perfetto/include/tracing_perfetto.h
index 2c1c2a4..59c43d6 100644
--- a/libs/tracing_perfetto/include/tracing_perfetto.h
+++ b/libs/tracing_perfetto/include/tracing_perfetto.h
@@ -14,40 +14,40 @@
  * limitations under the License.
  */
 
-#ifndef TRACING_PERFETTO_H
-#define TRACING_PERFETTO_H
+#pragma once
 
 #include <stdint.h>
 
-#include "trace_result.h"
-
 namespace tracing_perfetto {
 
 void registerWithPerfetto(bool test = false);
 
-Result traceBegin(uint64_t category, const char* name);
+void traceBegin(uint64_t category, const char* name);
 
-Result traceEnd(uint64_t category);
+void traceEnd(uint64_t category);
 
-Result traceAsyncBegin(uint64_t category, const char* name, int32_t cookie);
+void traceAsyncBegin(uint64_t category, const char* name, int32_t cookie);
 
-Result traceAsyncEnd(uint64_t category, const char* name, int32_t cookie);
+void traceFormatBegin(uint64_t category, const char* fmt, ...);
 
-Result traceAsyncBeginForTrack(uint64_t category, const char* name,
+void traceAsyncEnd(uint64_t category, const char* name, int32_t cookie);
+
+void traceAsyncBeginForTrack(uint64_t category, const char* name,
                                const char* trackName, int32_t cookie);
 
-Result traceAsyncEndForTrack(uint64_t category, const char* trackName,
+void traceAsyncEndForTrack(uint64_t category, const char* trackName,
                              int32_t cookie);
 
-Result traceInstant(uint64_t category, const char* name);
+void traceInstant(uint64_t category, const char* name);
 
-Result traceInstantForTrack(uint64_t category, const char* trackName,
+void traceFormatInstant(uint64_t category, const char* fmt, ...);
+
+void traceInstantForTrack(uint64_t category, const char* trackName,
                             const char* name);
 
-Result traceCounter(uint64_t category, const char* name, int64_t value);
+void traceCounter(uint64_t category, const char* name, int64_t value);
+
+void traceCounter32(uint64_t category, const char* name, int32_t value);
 
 bool isTagEnabled(uint64_t category);
-
 }  // namespace tracing_perfetto
-
-#endif  // TRACING_PERFETTO_H
diff --git a/libs/tracing_perfetto/tests/Android.bp b/libs/tracing_perfetto/tests/Android.bp
index a35b0e0..d203467 100644
--- a/libs/tracing_perfetto/tests/Android.bp
+++ b/libs/tracing_perfetto/tests/Android.bp
@@ -26,6 +26,7 @@
     static_libs: [
         "libflagtest",
         "libgmock",
+        "perfetto_trace_protos",
     ],
     cflags: [
         "-Wall",
@@ -35,6 +36,8 @@
         "android.os.flags-aconfig-cc-host",
         "libbase",
         "libperfetto_c",
+        "liblog",
+        "libprotobuf-cpp-lite",
         "libtracing_perfetto",
     ],
     srcs: [
diff --git a/libs/tracing_perfetto/tests/tracing_perfetto_test.cpp b/libs/tracing_perfetto/tests/tracing_perfetto_test.cpp
index 7716b9a..e9fee2e 100644
--- a/libs/tracing_perfetto/tests/tracing_perfetto_test.cpp
+++ b/libs/tracing_perfetto/tests/tracing_perfetto_test.cpp
@@ -16,10 +16,10 @@
 
 #include "tracing_perfetto.h"
 
-#include <thread>
-
 #include <android_os.h>
 #include <flag_macros.h>
+#include <thread>
+#include <unistd.h>
 
 #include "gtest/gtest.h"
 #include "perfetto/public/abi/data_source_abi.h"
@@ -45,67 +45,182 @@
 #include "trace_categories.h"
 #include "utils.h"
 
+#include "protos/perfetto/trace/trace.pb.h"
+#include "protos/perfetto/trace/trace_packet.pb.h"
+#include "protos/perfetto/trace/interned_data/interned_data.pb.h"
+
+#include <fstream>
+#include <iterator>
 namespace tracing_perfetto {
 
-using ::perfetto::shlib::test_utils::AllFieldsWithId;
-using ::perfetto::shlib::test_utils::FieldView;
-using ::perfetto::shlib::test_utils::IdFieldView;
-using ::perfetto::shlib::test_utils::MsgField;
-using ::perfetto::shlib::test_utils::PbField;
-using ::perfetto::shlib::test_utils::StringField;
+using ::perfetto::protos::Trace;
+using ::perfetto::protos::TracePacket;
+using ::perfetto::protos::EventCategory;
+using ::perfetto::protos::EventName;
+using ::perfetto::protos::FtraceEvent;
+using ::perfetto::protos::FtraceEventBundle;
+using ::perfetto::protos::InternedData;
+
 using ::perfetto::shlib::test_utils::TracingSession;
-using ::perfetto::shlib::test_utils::VarIntField;
-using ::testing::_;
-using ::testing::ElementsAre;
-using ::testing::UnorderedElementsAre;
 
 const auto PERFETTO_SDK_TRACING = ACONFIG_FLAG(android::os, perfetto_sdk_tracing);
 
+// TODO(b/303199244): Add tests for all the library functions.
 class TracingPerfettoTest : public testing::Test {
  protected:
   void SetUp() override {
-    tracing_perfetto::registerWithPerfetto(true /* test */);
+    tracing_perfetto::registerWithPerfetto(false /* test */);
   }
 };
 
-// TODO(b/303199244): Add tests for all the library functions.
-
-TEST_F_WITH_FLAGS(TracingPerfettoTest, traceInstant,
-                  REQUIRES_FLAGS_ENABLED(PERFETTO_SDK_TRACING)) {
-  TracingSession tracing_session =
-      TracingSession::Builder().set_data_source_name("track_event").Build();
-  tracing_perfetto::traceInstant(TRACE_CATEGORY_INPUT, "");
-
+Trace stopSession(TracingSession& tracing_session) {
+  tracing_session.FlushBlocking(5000);
   tracing_session.StopBlocking();
   std::vector<uint8_t> data = tracing_session.ReadBlocking();
+  std::string data_string(data.begin(), data.end());
+
+  perfetto::protos::Trace trace;
+  trace.ParseFromString(data_string);
+
+  return trace;
+}
+
+void verifyTrackEvent(const Trace& trace, const std::string expected_category,
+                      const std::string& expected_name) {
   bool found = false;
-  for (struct PerfettoPbDecoderField trace_field : FieldView(data)) {
-    ASSERT_THAT(trace_field, PbField(perfetto_protos_Trace_packet_field_number,
-                                     MsgField(_)));
-    IdFieldView track_event(
-        trace_field, perfetto_protos_TracePacket_track_event_field_number);
-    if (track_event.size() == 0) {
-      continue;
+  for (const TracePacket& packet: trace.packet()) {
+    if (packet.has_track_event() && packet.has_interned_data()) {
+
+      const InternedData& interned_data = packet.interned_data();
+      if (interned_data.event_categories_size() > 0) {
+        const EventCategory& event_category = packet.interned_data().event_categories(0);
+        if (event_category.name() == expected_category) {
+          found = true;
+        }
+      }
+
+      if (interned_data.event_names_size() > 0) {
+        const EventName& event_name = packet.interned_data().event_names(0);
+        if (event_name.name() == expected_name) {
+          found &= true;
+        }
+      }
+
+      if (found) {
+        break;
+      }
     }
-    found = true;
-    IdFieldView cat_iid_fields(
-        track_event.front(),
-        perfetto_protos_TrackEvent_category_iids_field_number);
-    ASSERT_THAT(cat_iid_fields, ElementsAre(VarIntField(_)));
-    uint64_t cat_iid = cat_iid_fields.front().value.integer64;
-    EXPECT_THAT(
-        trace_field,
-        AllFieldsWithId(
-            perfetto_protos_TracePacket_interned_data_field_number,
-            ElementsAre(AllFieldsWithId(
-                perfetto_protos_InternedData_event_categories_field_number,
-                ElementsAre(MsgField(UnorderedElementsAre(
-                    PbField(perfetto_protos_EventCategory_iid_field_number,
-                            VarIntField(cat_iid)),
-                    PbField(perfetto_protos_EventCategory_name_field_number,
-                            StringField("input")))))))));
   }
   EXPECT_TRUE(found);
 }
 
-}  // namespace tracing_perfetto
\ No newline at end of file
+void verifyAtraceEvent(const Trace& trace, const std::string& expected_name) {
+  std::string expected_print_buf = "I|" + std::to_string(gettid()) + "|" + expected_name + "\n";
+
+  bool found = false;
+  for (const TracePacket& packet: trace.packet()) {
+    if (packet.has_ftrace_events()) {
+      const FtraceEventBundle& ftrace_events_bundle = packet.ftrace_events();
+
+      if (ftrace_events_bundle.event_size() > 0) {
+        const FtraceEvent& ftrace_event = ftrace_events_bundle.event(0);
+        if (ftrace_event.has_print() && (ftrace_event.print().buf() == expected_print_buf)) {
+          found = true;
+          break;
+        }
+      }
+    }
+  }
+  EXPECT_TRUE(found);
+}
+
+TEST_F_WITH_FLAGS(TracingPerfettoTest, traceInstantWithPerfetto,
+                  REQUIRES_FLAGS_ENABLED(PERFETTO_SDK_TRACING)) {
+  std::string event_category = "input";
+  std::string event_name = "traceInstantWithPerfetto";
+
+  TracingSession tracing_session =
+      TracingSession::Builder().add_enabled_category(event_category).Build();
+
+  tracing_perfetto::traceInstant(TRACE_CATEGORY_INPUT, event_name.c_str());
+
+  Trace trace = stopSession(tracing_session);
+
+  verifyTrackEvent(trace, event_category, event_name);
+}
+
+TEST_F_WITH_FLAGS(TracingPerfettoTest, traceInstantWithAtrace,
+                  REQUIRES_FLAGS_ENABLED(PERFETTO_SDK_TRACING)) {
+  std::string event_category = "input";
+  std::string event_name = "traceInstantWithAtrace";
+
+  TracingSession tracing_session =
+      TracingSession::Builder().add_atrace_category(event_category).Build();
+
+  tracing_perfetto::traceInstant(TRACE_CATEGORY_INPUT, event_name.c_str());
+
+  Trace trace = stopSession(tracing_session);
+
+  verifyAtraceEvent(trace, event_name);
+}
+
+TEST_F_WITH_FLAGS(TracingPerfettoTest, traceInstantWithPerfettoAndAtrace,
+                  REQUIRES_FLAGS_ENABLED(PERFETTO_SDK_TRACING)) {
+  std::string event_category = "input";
+  std::string event_name = "traceInstantWithPerfettoAndAtrace";
+
+  TracingSession tracing_session =
+      TracingSession::Builder()
+      .add_atrace_category(event_category)
+      .add_enabled_category(event_category).Build();
+
+  tracing_perfetto::traceInstant(TRACE_CATEGORY_INPUT, event_name.c_str());
+
+  Trace trace = stopSession(tracing_session);
+
+  verifyAtraceEvent(trace, event_name);
+}
+
+TEST_F_WITH_FLAGS(TracingPerfettoTest, traceInstantWithPerfettoAndAtraceAndPreferTrackEvent,
+                  REQUIRES_FLAGS_ENABLED(PERFETTO_SDK_TRACING)) {
+  std::string event_category = "input";
+  std::string event_name = "traceInstantWithPerfettoAndAtraceAndPreferTrackEvent";
+
+  TracingSession tracing_session =
+      TracingSession::Builder()
+      .add_atrace_category(event_category)
+      .add_atrace_category_prefer_sdk(event_category)
+      .add_enabled_category(event_category).Build();
+
+  tracing_perfetto::traceInstant(TRACE_CATEGORY_INPUT, event_name.c_str());
+
+  Trace trace = stopSession(tracing_session);
+
+  verifyTrackEvent(trace, event_category, event_name);
+}
+
+TEST_F_WITH_FLAGS(TracingPerfettoTest, traceInstantWithPerfettoAndAtraceConcurrently,
+                  REQUIRES_FLAGS_ENABLED(PERFETTO_SDK_TRACING)) {
+  std::string event_category = "input";
+  std::string event_name = "traceInstantWithPerfettoAndAtraceConcurrently";
+
+  TracingSession perfetto_tracing_session =
+      TracingSession::Builder()
+      .add_atrace_category(event_category)
+      .add_atrace_category_prefer_sdk(event_category)
+      .add_enabled_category(event_category).Build();
+
+  TracingSession atrace_tracing_session =
+      TracingSession::Builder()
+      .add_atrace_category(event_category)
+      .add_enabled_category(event_category).Build();
+
+  tracing_perfetto::traceInstant(TRACE_CATEGORY_INPUT, event_name.c_str());
+
+  Trace atrace_trace = stopSession(atrace_tracing_session);
+  Trace perfetto_trace = stopSession(perfetto_tracing_session);
+
+  verifyAtraceEvent(atrace_trace, event_name);
+  verifyAtraceEvent(perfetto_trace, event_name);
+}
+}  // namespace tracing_perfetto
diff --git a/libs/tracing_perfetto/tests/utils.cpp b/libs/tracing_perfetto/tests/utils.cpp
index 9c42028..8c4d4a8 100644
--- a/libs/tracing_perfetto/tests/utils.cpp
+++ b/libs/tracing_perfetto/tests/utils.cpp
@@ -26,6 +26,11 @@
 #include "perfetto/public/protos/config/track_event/track_event_config.pzc.h"
 #include "perfetto/public/tracing_session.h"
 
+#include "protos/perfetto/config/ftrace/ftrace_config.pb.h"
+#include "protos/perfetto/config/track_event/track_event_config.pb.h"
+#include "protos/perfetto/config/data_source_config.pb.h"
+#include "protos/perfetto/config/trace_config.pb.h"
+
 namespace perfetto {
 namespace shlib {
 namespace test_utils {
@@ -44,63 +49,54 @@
 }  // namespace
 
 TracingSession TracingSession::Builder::Build() {
-  struct PerfettoPbMsgWriter writer;
-  struct PerfettoHeapBuffer* hb = PerfettoHeapBufferCreate(&writer.writer);
+  perfetto::protos::TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(1024);
 
-  struct perfetto_protos_TraceConfig cfg;
-  PerfettoPbMsgInit(&cfg.msg, &writer);
+  auto* track_event_ds_config = trace_config.add_data_sources()->mutable_config();
+  auto* ftrace_ds_config = trace_config.add_data_sources()->mutable_config();
+
+  track_event_ds_config->set_name("track_event");
+  track_event_ds_config->set_target_buffer(0);
+
+  ftrace_ds_config->set_name("linux.ftrace");
+  ftrace_ds_config->set_target_buffer(0);
 
   {
-    struct perfetto_protos_TraceConfig_BufferConfig buffers;
-    perfetto_protos_TraceConfig_begin_buffers(&cfg, &buffers);
-
-    perfetto_protos_TraceConfig_BufferConfig_set_size_kb(&buffers, 1024);
-
-    perfetto_protos_TraceConfig_end_buffers(&cfg, &buffers);
-  }
-
-  {
-    struct perfetto_protos_TraceConfig_DataSource data_sources;
-    perfetto_protos_TraceConfig_begin_data_sources(&cfg, &data_sources);
-
-    {
-      struct perfetto_protos_DataSourceConfig ds_cfg;
-      perfetto_protos_TraceConfig_DataSource_begin_config(&data_sources,
-                                                          &ds_cfg);
-
-      perfetto_protos_DataSourceConfig_set_cstr_name(&ds_cfg,
-                                                     data_source_name_.c_str());
-      if (!enabled_categories_.empty() && !disabled_categories_.empty()) {
-        perfetto_protos_TrackEventConfig te_cfg;
-        perfetto_protos_DataSourceConfig_begin_track_event_config(&ds_cfg,
-                                                                  &te_cfg);
-        for (const std::string& cat : enabled_categories_) {
-          perfetto_protos_TrackEventConfig_set_enabled_categories(
-              &te_cfg, cat.data(), cat.size());
-        }
-        for (const std::string& cat : disabled_categories_) {
-          perfetto_protos_TrackEventConfig_set_disabled_categories(
-              &te_cfg, cat.data(), cat.size());
-        }
-        perfetto_protos_DataSourceConfig_end_track_event_config(&ds_cfg,
-                                                                &te_cfg);
+    auto* ftrace_config = ftrace_ds_config->mutable_ftrace_config();
+    if (!atrace_categories_.empty()) {
+      ftrace_config->add_ftrace_events("ftrace/print");
+      for (const std::string& cat : atrace_categories_) {
+        ftrace_config->add_atrace_categories(cat);
       }
 
-      perfetto_protos_TraceConfig_DataSource_end_config(&data_sources, &ds_cfg);
+      for (const std::string& cat : atrace_categories_prefer_sdk_) {
+        ftrace_config->add_atrace_categories_prefer_sdk(cat);
+      }
     }
-
-    perfetto_protos_TraceConfig_end_data_sources(&cfg, &data_sources);
   }
-  size_t cfg_size = PerfettoStreamWriterGetWrittenSize(&writer.writer);
-  std::unique_ptr<uint8_t[]> ser(new uint8_t[cfg_size]);
-  PerfettoHeapBufferCopyInto(hb, &writer.writer, ser.get(), cfg_size);
-  PerfettoHeapBufferDestroy(hb, &writer.writer);
+
+  {
+    auto* track_event_config = track_event_ds_config->mutable_track_event_config();
+    if (!enabled_categories_.empty() || !disabled_categories_.empty()) {
+      for (const std::string& cat : enabled_categories_) {
+        track_event_config->add_enabled_categories(cat);
+      }
+
+      for (const std::string& cat : disabled_categories_) {
+        track_event_config->add_disabled_categories(cat);
+      }
+    }
+  }
 
   struct PerfettoTracingSessionImpl* ts =
-      PerfettoTracingSessionCreate(PERFETTO_BACKEND_IN_PROCESS);
+      PerfettoTracingSessionCreate(PERFETTO_BACKEND_SYSTEM);
 
-  PerfettoTracingSessionSetup(ts, ser.get(), cfg_size);
+  std::string trace_config_string;
+  trace_config.SerializeToString(&trace_config_string);
 
+  PerfettoTracingSessionSetup(ts, trace_config_string.data(), trace_config_string.length());
+
+  // Fails to start here
   PerfettoTracingSessionStartBlocking(ts);
 
   return TracingSession::Adopt(ts);
diff --git a/libs/tracing_perfetto/tests/utils.h b/libs/tracing_perfetto/tests/utils.h
index 4353554..8edb414 100644
--- a/libs/tracing_perfetto/tests/utils.h
+++ b/libs/tracing_perfetto/tests/utils.h
@@ -74,10 +74,6 @@
   class Builder {
    public:
     Builder() = default;
-    Builder& set_data_source_name(std::string data_source_name) {
-      data_source_name_ = std::move(data_source_name);
-      return *this;
-    }
     Builder& add_enabled_category(std::string category) {
       enabled_categories_.push_back(std::move(category));
       return *this;
@@ -86,12 +82,21 @@
       disabled_categories_.push_back(std::move(category));
       return *this;
     }
+    Builder& add_atrace_category(std::string category) {
+      atrace_categories_.push_back(std::move(category));
+      return *this;
+    }
+    Builder& add_atrace_category_prefer_sdk(std::string category) {
+      atrace_categories_prefer_sdk_.push_back(std::move(category));
+      return *this;
+    }
     TracingSession Build();
 
    private:
-    std::string data_source_name_;
     std::vector<std::string> enabled_categories_;
     std::vector<std::string> disabled_categories_;
+    std::vector<std::string> atrace_categories_;
+    std::vector<std::string> atrace_categories_prefer_sdk_;
   };
 
   static TracingSession Adopt(struct PerfettoTracingSessionImpl*);
diff --git a/libs/tracing_perfetto/tracing_perfetto.cpp b/libs/tracing_perfetto/tracing_perfetto.cpp
index 6f716ee..c35e078 100644
--- a/libs/tracing_perfetto/tracing_perfetto.cpp
+++ b/libs/tracing_perfetto/tracing_perfetto.cpp
@@ -17,6 +17,7 @@
 #include "tracing_perfetto.h"
 
 #include <cutils/trace.h>
+#include <cstdarg>
 
 #include "perfetto/public/te_category_macros.h"
 #include "trace_categories.h"
@@ -28,116 +29,172 @@
   internal::registerWithPerfetto(test);
 }
 
-Result traceBegin(uint64_t category, const char* name) {
+void traceBegin(uint64_t category, const char* name) {
   struct PerfettoTeCategory* perfettoTeCategory =
       internal::toPerfettoCategory(category);
-  if (perfettoTeCategory != nullptr) {
-    return internal::perfettoTraceBegin(*perfettoTeCategory, name);
-  } else {
+
+  if (internal::shouldPreferAtrace(perfettoTeCategory, category)) {
     atrace_begin(category, name);
-    return Result::SUCCESS;
+  } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) {
+    internal::perfettoTraceBegin(*perfettoTeCategory, name);
   }
 }
 
-Result traceEnd(uint64_t category) {
+void traceFormatBegin(uint64_t category, const char* fmt, ...) {
   struct PerfettoTeCategory* perfettoTeCategory =
       internal::toPerfettoCategory(category);
-  if (perfettoTeCategory != nullptr) {
-    return internal::perfettoTraceEnd(*perfettoTeCategory);
-  } else {
+  const bool preferAtrace = internal::shouldPreferAtrace(perfettoTeCategory, category);
+  const bool preferPerfetto = internal::isPerfettoCategoryEnabled(perfettoTeCategory);
+  if (CC_LIKELY(!(preferAtrace || preferPerfetto))) {
+    return;
+  }
+
+  const int BUFFER_SIZE = 256;
+  va_list ap;
+  char buf[BUFFER_SIZE];
+
+  va_start(ap, fmt);
+  vsnprintf(buf, BUFFER_SIZE, fmt, ap);
+  va_end(ap);
+
+
+  if (preferAtrace) {
+    atrace_begin(category, buf);
+  } else if (preferPerfetto) {
+    internal::perfettoTraceBegin(*perfettoTeCategory, buf);
+  }
+}
+
+void traceEnd(uint64_t category) {
+  struct PerfettoTeCategory* perfettoTeCategory =
+      internal::toPerfettoCategory(category);
+
+  if (internal::shouldPreferAtrace(perfettoTeCategory, category)) {
     atrace_end(category);
-    return Result::SUCCESS;
+  } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) {
+    internal::perfettoTraceEnd(*perfettoTeCategory);
   }
 }
 
-Result traceAsyncBegin(uint64_t category, const char* name, int32_t cookie) {
+void traceAsyncBegin(uint64_t category, const char* name, int32_t cookie) {
   struct PerfettoTeCategory* perfettoTeCategory =
       internal::toPerfettoCategory(category);
-  if (perfettoTeCategory != nullptr) {
-    return internal::perfettoTraceAsyncBegin(*perfettoTeCategory, name, cookie);
-  } else {
+
+  if (internal::shouldPreferAtrace(perfettoTeCategory, category)) {
     atrace_async_begin(category, name, cookie);
-    return Result::SUCCESS;
+  } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) {
+    internal::perfettoTraceAsyncBegin(*perfettoTeCategory, name, cookie);
   }
 }
 
-Result traceAsyncEnd(uint64_t category, const char* name, int32_t cookie) {
+void traceAsyncEnd(uint64_t category, const char* name, int32_t cookie) {
   struct PerfettoTeCategory* perfettoTeCategory =
       internal::toPerfettoCategory(category);
-  if (perfettoTeCategory != nullptr) {
-    return internal::perfettoTraceAsyncEnd(*perfettoTeCategory, name, cookie);
-  } else {
+
+  if (internal::shouldPreferAtrace(perfettoTeCategory, category)) {
     atrace_async_end(category, name, cookie);
-    return Result::SUCCESS;
+  } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) {
+    internal::perfettoTraceAsyncEnd(*perfettoTeCategory, name, cookie);
   }
 }
 
-Result traceAsyncBeginForTrack(uint64_t category, const char* name,
+void traceAsyncBeginForTrack(uint64_t category, const char* name,
                                const char* trackName, int32_t cookie) {
   struct PerfettoTeCategory* perfettoTeCategory =
       internal::toPerfettoCategory(category);
-  if (perfettoTeCategory != nullptr) {
-    return internal::perfettoTraceAsyncBeginForTrack(*perfettoTeCategory, name, trackName, cookie);
-  } else {
+
+  if (internal::shouldPreferAtrace(perfettoTeCategory, category)) {
     atrace_async_for_track_begin(category, trackName, name, cookie);
-    return Result::SUCCESS;
+  } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) {
+    internal::perfettoTraceAsyncBeginForTrack(*perfettoTeCategory, name, trackName, cookie);
   }
 }
 
-Result traceAsyncEndForTrack(uint64_t category, const char* trackName,
+void traceAsyncEndForTrack(uint64_t category, const char* trackName,
                              int32_t cookie) {
   struct PerfettoTeCategory* perfettoTeCategory =
       internal::toPerfettoCategory(category);
-  if (perfettoTeCategory != nullptr) {
-    return internal::perfettoTraceAsyncEndForTrack(*perfettoTeCategory, trackName, cookie);
-  } else {
+
+  if (internal::shouldPreferAtrace(perfettoTeCategory, category)) {
     atrace_async_for_track_end(category, trackName, cookie);
-    return Result::SUCCESS;
+  } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) {
+    internal::perfettoTraceAsyncEndForTrack(*perfettoTeCategory, trackName, cookie);
   }
 }
 
-Result traceInstant(uint64_t category, const char* name) {
+void traceInstant(uint64_t category, const char* name) {
   struct PerfettoTeCategory* perfettoTeCategory =
       internal::toPerfettoCategory(category);
-  if (perfettoTeCategory != nullptr) {
-    return internal::perfettoTraceInstant(*perfettoTeCategory, name);
-  } else {
+
+  if (internal::shouldPreferAtrace(perfettoTeCategory, category)) {
     atrace_instant(category, name);
-    return Result::SUCCESS;
+  } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) {
+    internal::perfettoTraceInstant(*perfettoTeCategory, name);
   }
 }
 
-Result traceInstantForTrack(uint64_t category, const char* trackName,
+void traceFormatInstant(uint64_t category, const char* fmt, ...) {
+  struct PerfettoTeCategory* perfettoTeCategory =
+      internal::toPerfettoCategory(category);
+  const bool preferAtrace = internal::shouldPreferAtrace(perfettoTeCategory, category);
+  const bool preferPerfetto = internal::isPerfettoCategoryEnabled(perfettoTeCategory);
+  if (CC_LIKELY(!(preferAtrace || preferPerfetto))) {
+    return;
+  }
+
+  const int BUFFER_SIZE = 256;
+  va_list ap;
+  char buf[BUFFER_SIZE];
+
+  va_start(ap, fmt);
+  vsnprintf(buf, BUFFER_SIZE, fmt, ap);
+  va_end(ap);
+
+  if (preferAtrace) {
+    atrace_instant(category, buf);
+  } else if (preferPerfetto) {
+    internal::perfettoTraceInstant(*perfettoTeCategory, buf);
+  }
+}
+
+void traceInstantForTrack(uint64_t category, const char* trackName,
                             const char* name) {
   struct PerfettoTeCategory* perfettoTeCategory =
       internal::toPerfettoCategory(category);
-  if (perfettoTeCategory != nullptr) {
-    return internal::perfettoTraceInstantForTrack(*perfettoTeCategory, trackName, name);
-  } else {
+
+  if (internal::shouldPreferAtrace(perfettoTeCategory, category)) {
     atrace_instant_for_track(category, trackName, name);
-    return Result::SUCCESS;
+  } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) {
+    internal::perfettoTraceInstantForTrack(*perfettoTeCategory, trackName, name);
   }
 }
 
-Result traceCounter(uint64_t category, const char* name, int64_t value) {
+void traceCounter(uint64_t category, const char* name, int64_t value) {
   struct PerfettoTeCategory* perfettoTeCategory =
       internal::toPerfettoCategory(category);
-  if (perfettoTeCategory != nullptr) {
-    return internal::perfettoTraceCounter(*perfettoTeCategory, name, value);
-  } else {
+
+  if (internal::shouldPreferAtrace(perfettoTeCategory, category)) {
     atrace_int64(category, name, value);
-    return Result::SUCCESS;
+  } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) {
+    internal::perfettoTraceCounter(*perfettoTeCategory, name, value);
+  }
+}
+
+void traceCounter32(uint64_t category, const char* name, int32_t value) {
+  struct PerfettoTeCategory* perfettoTeCategory = internal::toPerfettoCategory(category);
+  if (internal::shouldPreferAtrace(perfettoTeCategory, category)) {
+    atrace_int(category, name, value);
+  } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) {
+    internal::perfettoTraceCounter(*perfettoTeCategory, name,
+                                          static_cast<int64_t>(value));
   }
 }
 
 bool isTagEnabled(uint64_t category) {
   struct PerfettoTeCategory* perfettoTeCategory =
       internal::toPerfettoCategory(category);
-  if (perfettoTeCategory != nullptr) {
-    return true;
-  } else {
-    return (atrace_get_enabled_tags() & category) != 0;
-  }
+  return internal::isPerfettoCategoryEnabled(perfettoTeCategory)
+      || atrace_is_tag_enabled(category);
 }
 
 }  // namespace tracing_perfetto
diff --git a/libs/tracing_perfetto/tracing_perfetto_internal.cpp b/libs/tracing_perfetto/tracing_perfetto_internal.cpp
index 758ace6..9a0042a 100644
--- a/libs/tracing_perfetto/tracing_perfetto_internal.cpp
+++ b/libs/tracing_perfetto/tracing_perfetto_internal.cpp
@@ -44,13 +44,13 @@
   C(rro, "rro", "RRO category")                                  \
   C(thermal, "thermal", "Thermal category")
 
-#include "tracing_perfetto_internal.h"
-
-#include <inttypes.h>
-
+#include <atomic>
 #include <mutex>
 
 #include <android_os.h>
+#include <android-base/properties.h>
+#include <cutils/trace.h>
+#include <inttypes.h>
 
 #include "perfetto/public/compiler.h"
 #include "perfetto/public/producer.h"
@@ -58,19 +58,42 @@
 #include "perfetto/public/te_macros.h"
 #include "perfetto/public/track_event.h"
 #include "trace_categories.h"
-#include "trace_result.h"
+#include "tracing_perfetto_internal.h"
+
+#ifdef __BIONIC__
+#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#include <sys/_system_properties.h>
+#endif
 
 namespace tracing_perfetto {
 
 namespace internal {
 
 namespace {
-
 PERFETTO_TE_CATEGORIES_DECLARE(FRAMEWORK_CATEGORIES);
 
 PERFETTO_TE_CATEGORIES_DEFINE(FRAMEWORK_CATEGORIES);
 
-std::atomic_bool is_perfetto_registered = false;
+static constexpr char kPreferFlagProperty[] = "debug.atrace.prefer_sdk";
+static std::atomic<const prop_info*> prefer_property_info = nullptr;
+static std::atomic_uint32_t last_prefer_seq_num = 0;
+static std::atomic_uint64_t prefer_flags = 0;
+
+static const prop_info* system_property_find(const char* name [[maybe_unused]]) {
+  #ifdef __BIONIC__
+  return __system_property_find(name);
+  #endif
+
+  return nullptr;
+}
+
+static uint32_t system_property_serial(const prop_info* pi [[maybe_unused]]) {
+  #ifdef __BIONIC__
+  return __system_property_serial(pi);
+  #endif
+
+  return last_prefer_seq_num;
+}
 
 struct PerfettoTeCategory* toCategory(uint64_t inCategory) {
   switch (inCategory) {
@@ -137,8 +160,60 @@
 
 }  // namespace
 
-bool isPerfettoRegistered() {
-  return is_perfetto_registered;
+bool isPerfettoCategoryEnabled(PerfettoTeCategory* category) {
+  return category != nullptr;
+}
+
+/**
+ * Updates the cached |prefer_flags|.
+ *
+ * We cache the prefer_flags because reading it on every trace event is expensive.
+ * The cache is invalidated when a sys_prop sequence number changes.
+ */
+void updatePreferFlags() {
+  if (!prefer_property_info.load(std::memory_order_acquire)) {
+    auto* new_prefer_property_info = system_property_find(kPreferFlagProperty);
+    prefer_flags.store(android::base::GetIntProperty(kPreferFlagProperty, 0),
+                       std::memory_order_relaxed);
+
+    if (!new_prefer_property_info) {
+      // This should never happen. If it does, we fail gracefully and end up reading the property
+      // traced event.
+      return;
+    }
+
+    last_prefer_seq_num = system_property_serial(new_prefer_property_info);
+    prefer_property_info.store(new_prefer_property_info, std::memory_order_release);
+  }
+
+  uint32_t prefer_seq_num =  system_property_serial(prefer_property_info);
+  if (prefer_seq_num != last_prefer_seq_num.load(std::memory_order_acquire)) {
+    prefer_flags.store(android::base::GetIntProperty(kPreferFlagProperty, 0),
+                       std::memory_order_relaxed);
+    last_prefer_seq_num.store(prefer_seq_num, std::memory_order_release);
+  }
+}
+
+bool shouldPreferAtrace(PerfettoTeCategory *perfettoCategory, uint64_t atraceCategory) {
+  // There are 3 cases:
+  // 1. Atrace is not enabled.
+  if (!atrace_is_tag_enabled(atraceCategory)) {
+    return false;
+  }
+
+  // 2. Atrace is enabled but perfetto is not enabled.
+  if (!isPerfettoCategoryEnabled(perfettoCategory)) {
+    return true;
+  }
+
+  // Update prefer_flags before checking it below
+  updatePreferFlags();
+
+  // 3. Atrace and perfetto are enabled.
+  // Even though this category is enabled for track events, the config mandates that we downgrade
+  // it to atrace if the same atrace category is currently enabled. This prevents missing the
+  // event from a concurrent session that needs the same category in atrace.
+  return (atraceCategory & prefer_flags.load(std::memory_order_relaxed)) == 0;
 }
 
 struct PerfettoTeCategory* toPerfettoCategory(uint64_t category) {
@@ -148,7 +223,7 @@
   }
 
   bool enabled = PERFETTO_UNLIKELY(PERFETTO_ATOMIC_LOAD_EXPLICIT(
-      (*perfettoCategory).enabled, PERFETTO_MEMORY_ORDER_RELAXED));
+       (*perfettoCategory).enabled, PERFETTO_MEMORY_ORDER_RELAXED));
   return enabled ? perfettoCategory : nullptr;
 }
 
@@ -164,70 +239,57 @@
     PerfettoProducerInit(args);
     PerfettoTeInit();
     PERFETTO_TE_REGISTER_CATEGORIES(FRAMEWORK_CATEGORIES);
-    is_perfetto_registered = true;
   });
 }
 
-Result perfettoTraceBegin(const struct PerfettoTeCategory& category, const char* name) {
+void perfettoTraceBegin(const struct PerfettoTeCategory& category, const char* name) {
   PERFETTO_TE(category, PERFETTO_TE_SLICE_BEGIN(name));
-  return Result::SUCCESS;
 }
 
-Result perfettoTraceEnd(const struct PerfettoTeCategory& category) {
+void perfettoTraceEnd(const struct PerfettoTeCategory& category) {
   PERFETTO_TE(category, PERFETTO_TE_SLICE_END());
-  return Result::SUCCESS;
 }
 
-Result perfettoTraceAsyncBeginForTrack(const struct PerfettoTeCategory& category, const char* name,
+void perfettoTraceAsyncBeginForTrack(const struct PerfettoTeCategory& category, const char* name,
                                        const char* trackName, uint64_t cookie) {
   PERFETTO_TE(
       category, PERFETTO_TE_SLICE_BEGIN(name),
       PERFETTO_TE_NAMED_TRACK(trackName, cookie, PerfettoTeProcessTrackUuid()));
-  return Result::SUCCESS;
 }
 
-Result perfettoTraceAsyncEndForTrack(const struct PerfettoTeCategory& category,
+void perfettoTraceAsyncEndForTrack(const struct PerfettoTeCategory& category,
                                      const char* trackName, uint64_t cookie) {
   PERFETTO_TE(
       category, PERFETTO_TE_SLICE_END(),
       PERFETTO_TE_NAMED_TRACK(trackName, cookie, PerfettoTeProcessTrackUuid()));
-  return Result::SUCCESS;
 }
 
-Result perfettoTraceAsyncBegin(const struct PerfettoTeCategory& category, const char* name,
+void perfettoTraceAsyncBegin(const struct PerfettoTeCategory& category, const char* name,
                                uint64_t cookie) {
-  return perfettoTraceAsyncBeginForTrack(category, name, name, cookie);
+  perfettoTraceAsyncBeginForTrack(category, name, name, cookie);
 }
 
-Result perfettoTraceAsyncEnd(const struct PerfettoTeCategory& category, const char* name,
+void perfettoTraceAsyncEnd(const struct PerfettoTeCategory& category, const char* name,
                              uint64_t cookie) {
-  return perfettoTraceAsyncEndForTrack(category, name, cookie);
+  perfettoTraceAsyncEndForTrack(category, name, cookie);
 }
 
-Result perfettoTraceInstant(const struct PerfettoTeCategory& category, const char* name) {
+void perfettoTraceInstant(const struct PerfettoTeCategory& category, const char* name) {
   PERFETTO_TE(category, PERFETTO_TE_INSTANT(name));
-  return Result::SUCCESS;
 }
 
-Result perfettoTraceInstantForTrack(const struct PerfettoTeCategory& category,
+void perfettoTraceInstantForTrack(const struct PerfettoTeCategory& category,
                                     const char* trackName, const char* name) {
   PERFETTO_TE(
       category, PERFETTO_TE_INSTANT(name),
       PERFETTO_TE_NAMED_TRACK(trackName, 1, PerfettoTeProcessTrackUuid()));
-  return Result::SUCCESS;
 }
 
-Result perfettoTraceCounter(const struct PerfettoTeCategory& category,
+void perfettoTraceCounter(const struct PerfettoTeCategory& category,
                             [[maybe_unused]] const char* name, int64_t value) {
   PERFETTO_TE(category, PERFETTO_TE_COUNTER(),
               PERFETTO_TE_INT_COUNTER(value));
-  return Result::SUCCESS;
 }
-
-uint64_t getDefaultCategories() {
-  return TRACE_CATEGORIES;
-}
-
 }  // namespace internal
 
 }  // namespace tracing_perfetto
diff --git a/libs/tracing_perfetto/tracing_perfetto_internal.h b/libs/tracing_perfetto/tracing_perfetto_internal.h
index 79e4b8f..3e1ac2a 100644
--- a/libs/tracing_perfetto/tracing_perfetto_internal.h
+++ b/libs/tracing_perfetto/tracing_perfetto_internal.h
@@ -19,7 +19,6 @@
 
 #include <stdint.h>
 
-#include "include/trace_result.h"
 #include "perfetto/public/te_category_macros.h"
 
 namespace tracing_perfetto {
@@ -32,31 +31,33 @@
 
 void registerWithPerfetto(bool test = false);
 
-Result perfettoTraceBegin(const struct PerfettoTeCategory& category, const char* name);
+void perfettoTraceBegin(const struct PerfettoTeCategory& category, const char* name);
 
-Result perfettoTraceEnd(const struct PerfettoTeCategory& category);
+void perfettoTraceEnd(const struct PerfettoTeCategory& category);
 
-Result perfettoTraceAsyncBegin(const struct PerfettoTeCategory& category, const char* name,
+void perfettoTraceAsyncBegin(const struct PerfettoTeCategory& category, const char* name,
                                uint64_t cookie);
 
-Result perfettoTraceAsyncEnd(const struct PerfettoTeCategory& category, const char* name,
+void perfettoTraceAsyncEnd(const struct PerfettoTeCategory& category, const char* name,
                              uint64_t cookie);
 
-Result perfettoTraceAsyncBeginForTrack(const struct PerfettoTeCategory& category, const char* name,
+void perfettoTraceAsyncBeginForTrack(const struct PerfettoTeCategory& category, const char* name,
                                        const char* trackName, uint64_t cookie);
 
-Result perfettoTraceAsyncEndForTrack(const struct PerfettoTeCategory& category,
+void perfettoTraceAsyncEndForTrack(const struct PerfettoTeCategory& category,
                                      const char* trackName, uint64_t cookie);
 
-Result perfettoTraceInstant(const struct PerfettoTeCategory& category, const char* name);
+void perfettoTraceInstant(const struct PerfettoTeCategory& category, const char* name);
 
-Result perfettoTraceInstantForTrack(const struct PerfettoTeCategory& category,
+void perfettoTraceInstantForTrack(const struct PerfettoTeCategory& category,
                                     const char* trackName, const char* name);
 
-Result perfettoTraceCounter(const struct PerfettoTeCategory& category, const char* name,
+void perfettoTraceCounter(const struct PerfettoTeCategory& category, const char* name,
                             int64_t value);
 
-uint64_t getDefaultCategories();
+bool isPerfettoCategoryEnabled(PerfettoTeCategory *perfettoTeCategory);
+
+bool shouldPreferAtrace(PerfettoTeCategory *perfettoTeCategory, uint64_t category);
 
 }  // namespace internal
 
diff --git a/libs/ui/Gralloc5.cpp b/libs/ui/Gralloc5.cpp
index f14a5cf..c9ec036 100644
--- a/libs/ui/Gralloc5.cpp
+++ b/libs/ui/Gralloc5.cpp
@@ -91,8 +91,7 @@
         }
 
         void* so = nullptr;
-        // TODO(b/322384429) switch this to __ANDROID_API_V__ when V is finalized
-        if API_LEVEL_AT_LEAST(__ANDROID_API_FUTURE__, 202404) {
+        if API_LEVEL_AT_LEAST (__ANDROID_API_V__, 202404) {
             so = AServiceManager_openDeclaredPassthroughHal("mapper", mapperSuffix.c_str(),
                                                             RTLD_LOCAL | RTLD_NOW);
         } else {
diff --git a/libs/ui/include/ui/BufferHubDefs.h b/libs/ui/include/ui/BufferHubDefs.h
deleted file mode 100644
index 10f274f..0000000
--- a/libs/ui/include/ui/BufferHubDefs.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_BUFFER_HUB_DEFS_H_
-#define ANDROID_BUFFER_HUB_DEFS_H_
-
-#include <atomic>
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpacked"
-// TODO(b/118893702): remove dependency once DvrNativeBufferMetadata moved out of libdvr
-#include <dvr/dvr_api.h>
-#pragma clang diagnostic pop
-
-namespace android {
-
-namespace BufferHubDefs {
-
-// Single buffer clients (up to 16) ownership signal.
-// 32-bit atomic unsigned int.
-// Each client takes 2 bits. The first bit locates in the first 16 bits of
-// bufferState; the second bit locates in the last 16 bits of bufferState.
-// Client states:
-// Gained state 11. Exclusive write state.
-// Posted state 10.
-// Acquired state 01. Shared read state.
-// Released state 00.
-//
-//  MSB                        LSB
-//   |                          |
-//   v                          v
-// [C15|...|C1|C0|C15| ... |C1|C0]
-
-// Maximum number of clients a buffer can have.
-static constexpr int kMaxNumberOfClients = 16;
-
-// Definition of bit masks.
-//  MSB                            LSB
-//   | kHighBitsMask | kLowbitsMask |
-//   v               v              v
-// [b31|   ...   |b16|b15|   ...  |b0]
-
-// The location of lower 16 bits in the 32-bit buffer state.
-static constexpr uint32_t kLowbitsMask = (1U << kMaxNumberOfClients) - 1U;
-
-// The location of higher 16 bits in the 32-bit buffer state.
-static constexpr uint32_t kHighBitsMask = ~kLowbitsMask;
-
-// The client bit mask of the first client.
-static constexpr uint32_t kFirstClientBitMask = (1U << kMaxNumberOfClients) + 1U;
-
-// Returns true if any of the client is in gained state.
-static inline bool isAnyClientGained(uint32_t state) {
-    uint32_t highBits = state >> kMaxNumberOfClients;
-    uint32_t lowBits = state & kLowbitsMask;
-    return highBits == lowBits && lowBits != 0U;
-}
-
-// Returns true if the input client is in gained state.
-static inline bool isClientGained(uint32_t state, uint32_t client_bit_mask) {
-    return state == client_bit_mask;
-}
-
-// Returns true if any of the client is in posted state.
-static inline bool isAnyClientPosted(uint32_t state) {
-    uint32_t highBits = state >> kMaxNumberOfClients;
-    uint32_t lowBits = state & kLowbitsMask;
-    uint32_t postedOrAcquired = highBits ^ lowBits;
-    return postedOrAcquired & highBits;
-}
-
-// Returns true if the input client is in posted state.
-static inline bool isClientPosted(uint32_t state, uint32_t client_bit_mask) {
-    uint32_t clientBits = state & client_bit_mask;
-    if (clientBits == 0U) return false;
-    uint32_t lowBits = clientBits & kLowbitsMask;
-    return lowBits == 0U;
-}
-
-// Return true if any of the client is in acquired state.
-static inline bool isAnyClientAcquired(uint32_t state) {
-    uint32_t highBits = state >> kMaxNumberOfClients;
-    uint32_t lowBits = state & kLowbitsMask;
-    uint32_t postedOrAcquired = highBits ^ lowBits;
-    return postedOrAcquired & lowBits;
-}
-
-// Return true if the input client is in acquired state.
-static inline bool isClientAcquired(uint32_t state, uint32_t client_bit_mask) {
-    uint32_t clientBits = state & client_bit_mask;
-    if (clientBits == 0U) return false;
-    uint32_t highBits = clientBits & kHighBitsMask;
-    return highBits == 0U;
-}
-
-// Returns true if the input client is in released state.
-static inline bool isClientReleased(uint32_t state, uint32_t client_bit_mask) {
-    return (state & client_bit_mask) == 0U;
-}
-
-// Returns the next available buffer client's client_state_masks.
-// @params union_bits. Union of all existing clients' client_state_masks.
-static inline uint32_t findNextAvailableClientStateMask(uint32_t union_bits) {
-    uint32_t lowUnion = union_bits & kLowbitsMask;
-    if (lowUnion == kLowbitsMask) return 0U;
-    uint32_t incremented = lowUnion + 1U;
-    uint32_t difference = incremented ^ lowUnion;
-    uint32_t newLowBit = (difference + 1U) >> 1;
-    return newLowBit + (newLowBit << kMaxNumberOfClients);
-}
-
-struct __attribute__((aligned(8))) MetadataHeader {
-    // Internal data format, which can be updated as long as the size, padding and field alignment
-    // of the struct is consistent within the same ABI. As this part is subject for future updates,
-    // it's not stable cross Android version, so don't have it visible from outside of the Android
-    // platform (include Apps and vendor HAL).
-
-    // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
-    // bufferState.
-    std::atomic<uint32_t> bufferState;
-
-    // Every client takes up one bit in fenceState. Only the lower 32 bits are valid. The upper 32
-    // bits are there for easier manipulation, but the value should be ignored.
-    std::atomic<uint32_t> fenceState;
-
-    // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
-    // activeClientsBitMask.
-    std::atomic<uint32_t> activeClientsBitMask;
-
-    // Explicit padding 4 bytes.
-    uint32_t padding;
-
-    // The index of the buffer queue where the buffer belongs to.
-    uint64_t queueIndex;
-
-    // Public data format, which should be updated with caution. See more details in dvr_api.h
-    DvrNativeBufferMetadata metadata;
-};
-
-static_assert(sizeof(MetadataHeader) == 128, "Unexpected MetadataHeader size");
-static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader);
-
-/**
- * android.frameworks.bufferhub@1.0::BufferTraits.bufferInfo is an opaque handle. See
- * https://cs.corp.google.com/android/frameworks/hardware/interfaces/bufferhub/1.0/types.hal for
- * more details about android.frameworks.bufferhub@1.0::BufferTraits.
- *
- * This definition could be changed, but implementation of BufferHubService::buildBufferInfo
- * (frameworks/native/services/bufferhub), VtsHalBufferHubV1_0TargetTest
- * (frameworks/hardware/interfaces/bufferhub) and BufferHubBuffer::readBufferTraits (libui) will
- * also need to be updated.
- *
- * It's definition should follow the following format:
- * {
- *   NumFds = 2,
- *   NumInts = 3,
- *   data[0] = Ashmem fd for BufferHubMetadata,
- *   data[1] = event fd,
- *   data[2] = buffer id,
- *   data[3] = client state bit mask,
- *   data[4] = user metadata size,
- * }
- */
-static constexpr int kBufferInfoNumFds = 2;
-static constexpr int kBufferInfoNumInts = 3;
-
-} // namespace BufferHubDefs
-
-} // namespace android
-
-#endif // ANDROID_BUFFER_HUB_DEFS_H_
diff --git a/libs/ui/include/ui/EdgeExtensionEffect.h b/libs/ui/include/ui/EdgeExtensionEffect.h
new file mode 100644
index 0000000..02126b1
--- /dev/null
+++ b/libs/ui/include/ui/EdgeExtensionEffect.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2024 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
+
+/**
+ * Stores the edge that will be extended
+ */
+namespace android {
+
+enum CanonicalDirections { NONE = 0, LEFT = 1, RIGHT = 2, TOP = 4, BOTTOM = 8 };
+
+inline std::string to_string(CanonicalDirections direction) {
+    switch (direction) {
+        case LEFT:
+            return "LEFT";
+        case RIGHT:
+            return "RIGHT";
+        case TOP:
+            return "TOP";
+        case BOTTOM:
+            return "BOTTOM";
+        case NONE:
+            return "NONE";
+    }
+}
+
+struct EdgeExtensionEffect {
+    EdgeExtensionEffect(bool left, bool right, bool top, bool bottom) {
+        extensionEdges = NONE;
+        if (left) {
+            extensionEdges |= LEFT;
+        }
+        if (right) {
+            extensionEdges |= RIGHT;
+        }
+        if (top) {
+            extensionEdges |= TOP;
+        }
+        if (bottom) {
+            extensionEdges |= BOTTOM;
+        }
+    }
+
+    EdgeExtensionEffect() { EdgeExtensionEffect(false, false, false, false); }
+
+    bool extendsEdge(CanonicalDirections edge) const { return extensionEdges & edge; }
+
+    bool hasEffect() const { return extensionEdges != NONE; };
+
+    void reset() { extensionEdges = NONE; }
+
+    bool operator==(const EdgeExtensionEffect& other) const {
+        return extensionEdges == other.extensionEdges;
+    }
+
+    bool operator!=(const EdgeExtensionEffect& other) const { return !(*this == other); }
+
+private:
+    int extensionEdges;
+};
+
+inline std::string to_string(const EdgeExtensionEffect& effect) {
+    std::string s = "EdgeExtensionEffect={edges=[";
+    if (effect.hasEffect()) {
+        for (CanonicalDirections edge : {LEFT, RIGHT, TOP, BOTTOM}) {
+            if (effect.extendsEdge(edge)) {
+                s += to_string(edge) + ", ";
+            }
+        }
+    } else {
+        s += to_string(NONE);
+    }
+    s += "]}";
+    return s;
+}
+
+inline std::ostream& operator<<(std::ostream& os, const EdgeExtensionEffect effect) {
+    os << to_string(effect);
+    return os;
+}
+} // namespace android
diff --git a/libs/vr/.clang-format b/libs/vr/.clang-format
deleted file mode 100644
index 04d7970..0000000
--- a/libs/vr/.clang-format
+++ /dev/null
@@ -1,5 +0,0 @@
-BasedOnStyle: Google
-DerivePointerAlignment: false
-PointerAlignment: Left
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
diff --git a/libs/vr/CPPLINT.cfg b/libs/vr/CPPLINT.cfg
deleted file mode 100644
index 87fb641..0000000
--- a/libs/vr/CPPLINT.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-set noparent
-filter=-build/include_order,-legal/copyright,-build/include,-build/c++11,+build/include_alpha
diff --git a/libs/vr/OWNERS b/libs/vr/OWNERS
deleted file mode 100644
index 098c80e..0000000
--- a/libs/vr/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-hendrikw@google.com
-jwcai@google.com
-steventhomas@google.com
-patplunkett@google.com
diff --git a/libs/vr/libbroadcastring/Android.bp b/libs/vr/libbroadcastring/Android.bp
deleted file mode 100644
index e72ca74..0000000
--- a/libs/vr/libbroadcastring/Android.bp
+++ /dev/null
@@ -1,43 +0,0 @@
-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_library_static {
-    name: "libbroadcastring",
-
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-    export_include_dirs: ["include"],
-    shared_libs: [
-        "libbase",
-    ],
-    export_shared_lib_headers: [
-        "libbase",
-    ],
-}
-
-cc_test {
-    name: "broadcast_ring_tests",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-    srcs: [
-        "broadcast_ring_test.cc",
-    ],
-    static_libs: [
-        "libbroadcastring",
-    ],
-    shared_libs: [
-        "libbase",
-    ],
-}
diff --git a/libs/vr/libbroadcastring/broadcast_ring_test.cc b/libs/vr/libbroadcastring/broadcast_ring_test.cc
deleted file mode 100644
index dfdd4ef..0000000
--- a/libs/vr/libbroadcastring/broadcast_ring_test.cc
+++ /dev/null
@@ -1,866 +0,0 @@
-#include "libbroadcastring/broadcast_ring.h"
-
-#include <stdlib.h>
-#include <memory>
-#include <thread>  // NOLINT
-#include <sys/mman.h>
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace dvr {
-namespace {
-
-template <uint32_t N>
-struct alignas(8) Aligned {
-  char v[N];
-};
-
-template <uint32_t N>
-struct alignas(8) Sized {
-  Sized() { Clear(); }
-  explicit Sized(char c) { Fill(c); }
-  char v[sizeof(Aligned<N>)];
-  void Clear() { memset(v, 0, sizeof(v)); }
-  void Fill(char c) { memset(v, c, sizeof(v)); }
-  static Sized Pattern(uint8_t c) {
-    Sized sized;
-    for (size_t i = 0; i < sizeof(v); ++i) {
-      sized.v[i] = static_cast<char>(c + i);
-    }
-    return sized;
-  }
-  bool operator==(const Sized& right) const {
-    static_assert(sizeof(*this) == sizeof(v), "Size mismatch");
-    return !memcmp(v, right.v, sizeof(v));
-  }
-  template <typename SmallerSized>
-  SmallerSized Truncate() const {
-    SmallerSized val;
-    static_assert(sizeof(val.v) <= sizeof(v), "Cannot truncate to larger size");
-    memcpy(val.v, v, sizeof(val.v));
-    return val;
-  }
-};
-
-char FillChar(int val) { return static_cast<char>(val); }
-
-struct FakeMmap {
-  explicit FakeMmap(size_t size) : size(size), data(new char[size]) {}
-  size_t size;
-  std::unique_ptr<char[]> data;
-  void* mmap() { return static_cast<void*>(data.get()); }
-};
-
-template <typename Ring>
-FakeMmap CreateRing(Ring* ring, uint32_t count) {
-  FakeMmap mmap(Ring::MemorySize(count));
-  *ring = Ring::Create(mmap.mmap(), mmap.size, count);
-  return mmap;
-}
-
-template <typename RecordType, bool StaticSize = false,
-          uint32_t StaticCount = 0, uint32_t MaxReserved = 1,
-          uint32_t MinAvailable = 0>
-struct Traits {
-  using Record = RecordType;
-  static constexpr bool kUseStaticRecordSize = StaticSize;
-  static constexpr uint32_t kStaticRecordCount = StaticCount;
-  static constexpr uint32_t kMaxReservedRecords = MaxReserved;
-  static constexpr uint32_t kMinAvailableRecords = MinAvailable;
-  static constexpr uint32_t kMinRecordCount = MaxReserved + MinAvailable;
-};
-
-template <typename Record, bool StaticSize = false, uint32_t MaxReserved = 1,
-          uint32_t MinAvailable = 7>
-struct TraitsDynamic
-    : public Traits<Record, StaticSize, 0, MaxReserved, MinAvailable> {
-  using Ring = BroadcastRing<Record, TraitsDynamic>;
-  static uint32_t MinCount() { return MaxReserved + MinAvailable; }
-};
-
-template <typename Record, uint32_t StaticCount = 1, bool StaticSize = true,
-          uint32_t MaxReserved = 1, uint32_t MinAvailable = 0>
-struct TraitsStatic
-    : public Traits<Record, true, StaticCount, MaxReserved, MinAvailable> {
-  using Ring = BroadcastRing<Record, TraitsStatic>;
-  static uint32_t MinCount() { return StaticCount; }
-};
-
-using Dynamic_8_NxM = TraitsDynamic<Sized<8>>;
-using Dynamic_16_NxM = TraitsDynamic<Sized<16>>;
-using Dynamic_32_NxM = TraitsDynamic<Sized<32>>;
-using Dynamic_32_32xM = TraitsDynamic<Sized<32>, true>;
-using Dynamic_16_NxM_1plus0 = TraitsDynamic<Sized<16>, false, 1, 0>;
-using Dynamic_16_NxM_1plus1 = TraitsDynamic<Sized<16>, false, 1, 1>;
-using Dynamic_16_NxM_5plus11 = TraitsDynamic<Sized<16>, false, 5, 11>;
-using Dynamic_256_NxM_1plus0 = TraitsDynamic<Sized<256>, false, 1, 0>;
-
-using Static_8_8x1 = TraitsStatic<Sized<8>, 1>;
-using Static_8_8x16 = TraitsStatic<Sized<8>, 16>;
-using Static_16_16x8 = TraitsStatic<Sized<16>, 8>;
-using Static_16_16x16 = TraitsStatic<Sized<16>, 16>;
-using Static_16_16x32 = TraitsStatic<Sized<16>, 32>;
-using Static_32_Nx8 = TraitsStatic<Sized<32>, 8, false>;
-
-using TraitsList = ::testing::Types<Dynamic_8_NxM,           //
-                                    Dynamic_16_NxM,          //
-                                    Dynamic_32_NxM,          //
-                                    Dynamic_32_32xM,         //
-                                    Dynamic_16_NxM_1plus0,   //
-                                    Dynamic_16_NxM_1plus1,   //
-                                    Dynamic_16_NxM_5plus11,  //
-                                    Dynamic_256_NxM_1plus0,  //
-                                    Static_8_8x1,            //
-                                    Static_8_8x16,           //
-                                    Static_16_16x8,          //
-                                    Static_16_16x16,         //
-                                    Static_16_16x32,         //
-                                    Static_32_Nx8>;
-
-}  // namespace
-
-template <typename T>
-class BroadcastRingTest : public ::testing::Test {};
-
-TYPED_TEST_CASE(BroadcastRingTest, TraitsList);
-
-TYPED_TEST(BroadcastRingTest, Geometry) {
-  using Record = typename TypeParam::Record;
-  using Ring = typename TypeParam::Ring;
-  Ring ring;
-  auto mmap = CreateRing(&ring, Ring::Traits::MinCount());
-  EXPECT_EQ(Ring::Traits::MinCount(), ring.record_count());
-  EXPECT_EQ(sizeof(Record), ring.record_size());
-}
-
-TYPED_TEST(BroadcastRingTest, PutGet) {
-  using Record = typename TypeParam::Record;
-  using Ring = typename TypeParam::Ring;
-  Ring ring;
-  auto mmap = CreateRing(&ring, Ring::Traits::MinCount());
-  const uint32_t oldest_sequence_at_start = ring.GetOldestSequence();
-  const uint32_t next_sequence_at_start = ring.GetNextSequence();
-  {
-    uint32_t sequence = oldest_sequence_at_start;
-    Record record;
-    EXPECT_FALSE(ring.Get(&sequence, &record));
-    EXPECT_EQ(oldest_sequence_at_start, sequence);
-    EXPECT_EQ(Record(), record);
-  }
-  const Record original_record(0x1a);
-  ring.Put(original_record);
-  {
-    uint32_t sequence = next_sequence_at_start;
-    Record record;
-    EXPECT_TRUE(ring.Get(&sequence, &record));
-    EXPECT_EQ(next_sequence_at_start, sequence);
-    EXPECT_EQ(original_record, record);
-  }
-  {
-    uint32_t sequence = next_sequence_at_start + 1;
-    Record record;
-    EXPECT_FALSE(ring.Get(&sequence, &record));
-    EXPECT_EQ(next_sequence_at_start + 1, sequence);
-    EXPECT_EQ(Record(), record);
-  }
-}
-
-TYPED_TEST(BroadcastRingTest, FillOnce) {
-  using Record = typename TypeParam::Record;
-  using Ring = typename TypeParam::Ring;
-  Ring ring;
-  auto mmap = CreateRing(&ring, Ring::Traits::MinCount());
-  const uint32_t next_sequence_at_start = ring.GetNextSequence();
-  for (uint32_t i = 0; i < ring.record_count(); ++i)
-    ring.Put(Record(FillChar(i)));
-  for (uint32_t i = 0; i < ring.record_count(); ++i) {
-    const uint32_t expected_sequence = next_sequence_at_start + i;
-    const Record expected_record(FillChar(i));
-    {
-      uint32_t sequence = ring.GetOldestSequence() + i;
-      Record record;
-      EXPECT_TRUE(ring.Get(&sequence, &record));
-      EXPECT_EQ(expected_sequence, sequence);
-      EXPECT_EQ(expected_record, record);
-    }
-  }
-  {
-    uint32_t sequence = ring.GetOldestSequence() + ring.record_count();
-    Record record;
-    EXPECT_FALSE(ring.Get(&sequence, &record));
-  }
-}
-
-TYPED_TEST(BroadcastRingTest, FillTwice) {
-  using Record = typename TypeParam::Record;
-  using Ring = typename TypeParam::Ring;
-  Ring ring;
-  auto mmap = CreateRing(&ring, Ring::Traits::MinCount());
-  const uint32_t next_sequence_at_start = ring.GetNextSequence();
-  for (uint32_t i = 0; i < 2 * ring.record_count(); ++i) {
-    const Record newest_record(FillChar(i));
-    ring.Put(newest_record);
-
-    const uint32_t newest_sequence = next_sequence_at_start + i;
-    const uint32_t records_available = std::min(i + 1, ring.record_count());
-    const uint32_t oldest_sequence = newest_sequence - records_available + 1;
-    EXPECT_EQ(newest_sequence, ring.GetNewestSequence());
-    EXPECT_EQ(oldest_sequence, ring.GetOldestSequence());
-    EXPECT_EQ(newest_sequence + 1, ring.GetNextSequence());
-
-    for (uint32_t j = 0; j < records_available; ++j) {
-      const uint32_t sequence_jth_newest = newest_sequence - j;
-      const Record record_jth_newest(FillChar(i - j));
-
-      {
-        uint32_t sequence = sequence_jth_newest;
-        Record record;
-        EXPECT_TRUE(ring.Get(&sequence, &record));
-        EXPECT_EQ(sequence_jth_newest, sequence);
-        EXPECT_EQ(record_jth_newest, record);
-      }
-
-      {
-        uint32_t sequence = sequence_jth_newest;
-        Record record;
-        EXPECT_TRUE(ring.GetNewest(&sequence, &record));
-        EXPECT_EQ(newest_sequence, sequence);
-        EXPECT_EQ(newest_record, record);
-      }
-    }
-
-    const Record oldest_record(
-        FillChar(i + (oldest_sequence - newest_sequence)));
-    const uint32_t sequence_0th_overwritten = oldest_sequence - 1;
-    const uint32_t sequence_0th_future = newest_sequence + 1;
-    const uint32_t sequence_1st_future = newest_sequence + 2;
-
-    {
-      uint32_t sequence = sequence_0th_overwritten;
-      Record record;
-      EXPECT_TRUE(ring.Get(&sequence, &record));
-      EXPECT_EQ(oldest_sequence, sequence);
-      EXPECT_EQ(oldest_record, record);
-    }
-
-    {
-      uint32_t sequence = sequence_0th_overwritten;
-      Record record;
-      EXPECT_TRUE(ring.GetNewest(&sequence, &record));
-      EXPECT_EQ(newest_sequence, sequence);
-      EXPECT_EQ(newest_record, record);
-    }
-
-    {
-      uint32_t sequence = sequence_0th_future;
-      Record record;
-      EXPECT_FALSE(ring.Get(&sequence, &record));
-      EXPECT_EQ(sequence_0th_future, sequence);
-      EXPECT_EQ(Record(), record);
-    }
-
-    {
-      uint32_t sequence = sequence_0th_future;
-      Record record;
-      EXPECT_FALSE(ring.GetNewest(&sequence, &record));
-      EXPECT_EQ(sequence_0th_future, sequence);
-      EXPECT_EQ(Record(), record);
-    }
-
-    {
-      uint32_t sequence = sequence_1st_future;
-      Record record;
-      EXPECT_TRUE(ring.Get(&sequence, &record));
-      EXPECT_EQ(oldest_sequence, sequence);
-      EXPECT_EQ(oldest_record, record);
-    }
-
-    {
-      uint32_t sequence = sequence_1st_future;
-      Record record;
-      EXPECT_TRUE(ring.GetNewest(&sequence, &record));
-      EXPECT_EQ(newest_sequence, sequence);
-      EXPECT_EQ(newest_record, record);
-    }
-  }
-}
-
-TYPED_TEST(BroadcastRingTest, Import) {
-  using Record = typename TypeParam::Record;
-  using Ring = typename TypeParam::Ring;
-  Ring ring;
-  auto mmap = CreateRing(&ring, Ring::Traits::MinCount());
-
-  const uint32_t sequence_0 = ring.GetNextSequence();
-  const uint32_t sequence_1 = ring.GetNextSequence() + 1;
-  const Record record_0 = Record::Pattern(0x00);
-  const Record record_1 = Record::Pattern(0x80);
-  ring.Put(record_0);
-  ring.Put(record_1);
-
-  {
-    Ring imported_ring;
-    bool import_ok;
-    std::tie(imported_ring, import_ok) = Ring::Import(mmap.mmap(), mmap.size);
-    EXPECT_TRUE(import_ok);
-    EXPECT_EQ(ring.record_size(), imported_ring.record_size());
-    EXPECT_EQ(ring.record_count(), imported_ring.record_count());
-
-    if (ring.record_count() != 1) {
-      uint32_t sequence = sequence_0;
-      Record imported_record;
-      EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
-      EXPECT_EQ(sequence_0, sequence);
-      EXPECT_EQ(record_0, imported_record);
-    }
-
-    {
-      uint32_t sequence = sequence_1;
-      Record imported_record;
-      EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
-      EXPECT_EQ(sequence_1, sequence);
-      EXPECT_EQ(record_1, imported_record);
-    }
-  }
-}
-
-TEST(BroadcastRingTest, ShouldFailImportIfStaticSizeMismatch) {
-  using OriginalRing = typename Static_16_16x16::Ring;
-  using RecordSizeMismatchRing = typename Static_8_8x16::Ring;
-  using RecordCountMismatchRing = typename Static_16_16x8::Ring;
-
-  OriginalRing original_ring;
-  auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount());
-
-  {
-    using ImportedRing = RecordSizeMismatchRing;
-    ImportedRing imported_ring;
-    bool import_ok;
-    std::tie(imported_ring, import_ok) =
-        ImportedRing::Import(mmap.mmap(), mmap.size);
-    EXPECT_FALSE(import_ok);
-    auto mmap_imported =
-        CreateRing(&imported_ring, ImportedRing::Traits::MinCount());
-    EXPECT_NE(original_ring.record_size(), imported_ring.record_size());
-    EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
-  }
-
-  {
-    using ImportedRing = RecordCountMismatchRing;
-    ImportedRing imported_ring;
-    bool import_ok;
-    std::tie(imported_ring, import_ok) =
-        ImportedRing::Import(mmap.mmap(), mmap.size);
-    EXPECT_FALSE(import_ok);
-    auto mmap_imported =
-        CreateRing(&imported_ring, ImportedRing::Traits::MinCount());
-    EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
-    EXPECT_NE(original_ring.record_count(), imported_ring.record_count());
-  }
-}
-
-TEST(BroadcastRingTest, ShouldFailImportIfDynamicSizeGrows) {
-  using OriginalRing = typename Dynamic_8_NxM::Ring;
-  using RecordSizeGrowsRing = typename Dynamic_16_NxM::Ring;
-
-  OriginalRing original_ring;
-  auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount());
-
-  {
-    using ImportedRing = RecordSizeGrowsRing;
-    ImportedRing imported_ring;
-    bool import_ok;
-    std::tie(imported_ring, import_ok) =
-        ImportedRing::Import(mmap.mmap(), mmap.size);
-    EXPECT_FALSE(import_ok);
-    auto mmap_imported =
-        CreateRing(&imported_ring, ImportedRing::Traits::MinCount());
-    EXPECT_LT(original_ring.record_size(), imported_ring.record_size());
-    EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
-  }
-}
-
-TEST(BroadcastRingTest, ShouldFailImportIfCountTooSmall) {
-  using OriginalRing = typename Dynamic_16_NxM_1plus0::Ring;
-  using MinCountRing = typename Dynamic_16_NxM_1plus1::Ring;
-
-  OriginalRing original_ring;
-  auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount());
-
-  {
-    using ImportedRing = MinCountRing;
-    ImportedRing imported_ring;
-    bool import_ok;
-    std::tie(imported_ring, import_ok) =
-        ImportedRing::Import(mmap.mmap(), mmap.size);
-    EXPECT_FALSE(import_ok);
-    auto mmap_imported =
-        CreateRing(&imported_ring, ImportedRing::Traits::MinCount());
-    EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
-    EXPECT_LT(original_ring.record_count(), imported_ring.record_count());
-  }
-}
-
-TEST(BroadcastRingTest, ShouldFailImportIfMmapTooSmall) {
-  using OriginalRing = typename Dynamic_16_NxM::Ring;
-
-  OriginalRing original_ring;
-  auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount());
-
-  {
-    using ImportedRing = OriginalRing;
-    ImportedRing imported_ring;
-    bool import_ok;
-    const size_t kMinSize =
-        ImportedRing::MemorySize(original_ring.record_count());
-    std::tie(imported_ring, import_ok) = ImportedRing::Import(mmap.mmap(), 0);
-    EXPECT_FALSE(import_ok);
-    std::tie(imported_ring, import_ok) =
-        ImportedRing::Import(mmap.mmap(), kMinSize - 1);
-    EXPECT_FALSE(import_ok);
-    std::tie(imported_ring, import_ok) =
-        ImportedRing::Import(mmap.mmap(), kMinSize);
-    EXPECT_TRUE(import_ok);
-    EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
-    EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
-  }
-}
-
-TEST(BroadcastRingTest, ShouldImportIfDynamicSizeShrinks) {
-  using OriginalRing = typename Dynamic_16_NxM::Ring;
-  using RecordSizeShrinksRing = typename Dynamic_8_NxM::Ring;
-
-  OriginalRing original_ring;
-  auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount());
-
-  using OriginalRecord = typename OriginalRing::Record;
-  const uint32_t original_sequence_0 = original_ring.GetNextSequence();
-  const uint32_t original_sequence_1 = original_ring.GetNextSequence() + 1;
-  const OriginalRecord original_record_0 = OriginalRecord::Pattern(0x00);
-  const OriginalRecord original_record_1 = OriginalRecord::Pattern(0x80);
-  original_ring.Put(original_record_0);
-  original_ring.Put(original_record_1);
-
-  {
-    using ImportedRing = RecordSizeShrinksRing;
-    using ImportedRecord = typename ImportedRing::Record;
-    ImportedRing imported_ring;
-    bool import_ok;
-    std::tie(imported_ring, import_ok) =
-        ImportedRing::Import(mmap.mmap(), mmap.size);
-    EXPECT_TRUE(import_ok);
-    EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
-    EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
-    EXPECT_GT(sizeof(OriginalRecord), sizeof(ImportedRecord));
-
-    {
-      uint32_t sequence = original_sequence_0;
-      ImportedRecord shrunk_record;
-      EXPECT_TRUE(imported_ring.Get(&sequence, &shrunk_record));
-      EXPECT_EQ(original_sequence_0, sequence);
-      EXPECT_EQ(original_record_0.Truncate<ImportedRecord>(), shrunk_record);
-    }
-
-    {
-      uint32_t sequence = original_sequence_1;
-      ImportedRecord shrunk_record;
-      EXPECT_TRUE(imported_ring.Get(&sequence, &shrunk_record));
-      EXPECT_EQ(original_sequence_1, sequence);
-      EXPECT_EQ(original_record_1.Truncate<ImportedRecord>(), shrunk_record);
-    }
-  }
-}
-
-TEST(BroadcastRingTest, ShouldImportIfCompatibleDynamicToStatic) {
-  using OriginalRing = typename Dynamic_16_NxM::Ring;
-  using ImportedRing = typename Static_16_16x16::Ring;
-  using OriginalRecord = typename OriginalRing::Record;
-  using ImportedRecord = typename ImportedRing::Record;
-  using StaticRing = ImportedRing;
-
-  OriginalRing original_ring;
-  auto mmap = CreateRing(&original_ring, StaticRing::Traits::MinCount());
-
-  const uint32_t original_sequence_0 = original_ring.GetNextSequence();
-  const uint32_t original_sequence_1 = original_ring.GetNextSequence() + 1;
-  const OriginalRecord original_record_0 = OriginalRecord::Pattern(0x00);
-  const OriginalRecord original_record_1 = OriginalRecord::Pattern(0x80);
-  original_ring.Put(original_record_0);
-  original_ring.Put(original_record_1);
-
-  {
-    ImportedRing imported_ring;
-    bool import_ok;
-    std::tie(imported_ring, import_ok) =
-        ImportedRing::Import(mmap.mmap(), mmap.size);
-    EXPECT_TRUE(import_ok);
-    EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
-    EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
-
-    {
-      uint32_t sequence = original_sequence_0;
-      ImportedRecord imported_record;
-      EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
-      EXPECT_EQ(original_sequence_0, sequence);
-      EXPECT_EQ(original_record_0, imported_record);
-    }
-
-    {
-      uint32_t sequence = original_sequence_1;
-      ImportedRecord imported_record;
-      EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
-      EXPECT_EQ(original_sequence_1, sequence);
-      EXPECT_EQ(original_record_1, imported_record);
-    }
-  }
-}
-
-TEST(BroadcastRingTest, ShouldImportIfCompatibleStaticToDynamic) {
-  using OriginalRing = typename Static_16_16x16::Ring;
-  using ImportedRing = typename Dynamic_16_NxM::Ring;
-  using OriginalRecord = typename OriginalRing::Record;
-  using ImportedRecord = typename ImportedRing::Record;
-  using StaticRing = OriginalRing;
-
-  OriginalRing original_ring;
-  auto mmap = CreateRing(&original_ring, StaticRing::Traits::MinCount());
-
-  const uint32_t original_sequence_0 = original_ring.GetNextSequence();
-  const uint32_t original_sequence_1 = original_ring.GetNextSequence() + 1;
-  const OriginalRecord original_record_0 = OriginalRecord::Pattern(0x00);
-  const OriginalRecord original_record_1 = OriginalRecord::Pattern(0x80);
-  original_ring.Put(original_record_0);
-  original_ring.Put(original_record_1);
-
-  {
-    ImportedRing imported_ring;
-    bool import_ok;
-    std::tie(imported_ring, import_ok) =
-        ImportedRing::Import(mmap.mmap(), mmap.size);
-    EXPECT_TRUE(import_ok);
-    EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
-    EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
-
-    {
-      uint32_t sequence = original_sequence_0;
-      ImportedRecord imported_record;
-      EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
-      EXPECT_EQ(original_sequence_0, sequence);
-      EXPECT_EQ(original_record_0, imported_record);
-    }
-
-    {
-      uint32_t sequence = original_sequence_1;
-      ImportedRecord imported_record;
-      EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
-      EXPECT_EQ(original_sequence_1, sequence);
-      EXPECT_EQ(original_record_1, imported_record);
-    }
-  }
-}
-
-TEST(BroadcastRingTest, ShouldImportIfReadonlyMmap) {
-  using Ring = Dynamic_32_NxM::Ring;
-  using Record = Ring::Record;
-
-  uint32_t record_count = Ring::Traits::MinCount();
-  size_t ring_size = Ring::MemorySize(record_count);
-
-  size_t page_size = sysconf(_SC_PAGESIZE);
-  size_t mmap_size = (ring_size + (page_size - 1)) & ~(page_size - 1);
-  ASSERT_GE(mmap_size, ring_size);
-
-  void* mmap_base = mmap(nullptr, mmap_size, PROT_READ | PROT_WRITE,
-                         MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
-  ASSERT_NE(MAP_FAILED, mmap_base);
-
-  Ring ring = Ring::Create(mmap_base, mmap_size, record_count);
-  for (uint32_t i = 0; i < record_count; ++i) ring.Put(Record(FillChar(i)));
-
-  ASSERT_EQ(0, mprotect(mmap_base, mmap_size, PROT_READ));
-
-  {
-    Ring imported_ring;
-    bool import_ok;
-    std::tie(imported_ring, import_ok) = Ring::Import(mmap_base, mmap_size);
-    EXPECT_TRUE(import_ok);
-    EXPECT_EQ(ring.record_size(), imported_ring.record_size());
-    EXPECT_EQ(ring.record_count(), imported_ring.record_count());
-
-    uint32_t oldest_sequence = imported_ring.GetOldestSequence();
-    for (uint32_t i = 0; i < record_count; ++i) {
-      uint32_t sequence = oldest_sequence + i;
-      Record record;
-      EXPECT_TRUE(imported_ring.Get(&sequence, &record));
-      EXPECT_EQ(Record(FillChar(i)), record);
-    }
-  }
-
-  ASSERT_EQ(0, munmap(mmap_base, mmap_size));
-}
-
-TEST(BroadcastRingTest, ShouldDieIfPutReadonlyMmap) {
-  using Ring = Dynamic_32_NxM::Ring;
-  using Record = Ring::Record;
-
-  uint32_t record_count = Ring::Traits::MinCount();
-  size_t ring_size = Ring::MemorySize(record_count);
-
-  size_t page_size = sysconf(_SC_PAGESIZE);
-  size_t mmap_size = (ring_size + (page_size - 1)) & ~(page_size - 1);
-  ASSERT_GE(mmap_size, ring_size);
-
-  void* mmap_base = mmap(nullptr, mmap_size, PROT_READ | PROT_WRITE,
-                         MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
-  ASSERT_NE(MAP_FAILED, mmap_base);
-
-  Ring ring = Ring::Create(mmap_base, mmap_size, record_count);
-  for (uint32_t i = 0; i < record_count; ++i) ring.Put(Record(FillChar(i)));
-
-  ASSERT_EQ(0, mprotect(mmap_base, mmap_size, PROT_READ));
-
-  EXPECT_DEATH_IF_SUPPORTED({ ring.Put(Record(7)); }, "");
-
-  ASSERT_EQ(0, munmap(mmap_base, mmap_size));
-}
-
-TEST(BroadcastRingTest, ShouldDieIfCreationMmapTooSmall) {
-  using Ring = Dynamic_32_NxM::Ring;
-  using Record = Ring::Record;
-
-  uint32_t record_count = Ring::Traits::MinCount();
-  size_t ring_size = Ring::MemorySize(record_count);
-  FakeMmap mmap(ring_size);
-
-  EXPECT_DEATH_IF_SUPPORTED({
-    Ring ring = Ring::Create(mmap.mmap(), ring_size - 1, record_count);
-  }, "");
-
-  Ring ring = Ring::Create(mmap.mmap(), ring_size, record_count);
-
-  ring.Put(Record(3));
-
-  {
-    uint32_t sequence = ring.GetNewestSequence();
-    Record record;
-    EXPECT_TRUE(ring.Get(&sequence, &record));
-    EXPECT_EQ(Record(3), record);
-  }
-}
-
-TEST(BroadcastRingTest, ShouldDieIfCreationMmapMisaligned) {
-  using Ring = Static_8_8x1::Ring;
-  using Record = Ring::Record;
-
-  constexpr int kAlign = Ring::mmap_alignment();
-  constexpr int kMisalign = kAlign / 2;
-  size_t ring_size = Ring::MemorySize();
-  std::unique_ptr<char[]> buf(new char[ring_size + kMisalign]);
-
-  EXPECT_DEATH_IF_SUPPORTED(
-      { Ring ring = Ring::Create(buf.get() + kMisalign, ring_size); }, "");
-
-  Ring ring = Ring::Create(buf.get(), ring_size);
-
-  ring.Put(Record(3));
-
-  {
-    uint32_t sequence = ring.GetNewestSequence();
-    Record record;
-    EXPECT_TRUE(ring.Get(&sequence, &record));
-    EXPECT_EQ(Record(3), record);
-  }
-}
-
-template <typename Ring>
-std::unique_ptr<std::thread> CopyTask(std::atomic<bool>* quit, void* in_base,
-                                      size_t in_size, void* out_base,
-                                      size_t out_size) {
-  return std::unique_ptr<std::thread>(
-      new std::thread([quit, in_base, in_size, out_base, out_size]() {
-        using Record = typename Ring::Record;
-
-        bool import_ok;
-        Ring in_ring;
-        Ring out_ring;
-        std::tie(in_ring, import_ok) = Ring::Import(in_base, in_size);
-        ASSERT_TRUE(import_ok);
-        std::tie(out_ring, import_ok) = Ring::Import(out_base, out_size);
-        ASSERT_TRUE(import_ok);
-
-        uint32_t sequence = in_ring.GetOldestSequence();
-        while (!std::atomic_load_explicit(quit, std::memory_order_relaxed)) {
-          Record record;
-          if (in_ring.Get(&sequence, &record)) {
-            out_ring.Put(record);
-            sequence++;
-          }
-        }
-      }));
-}
-
-TEST(BroadcastRingTest, ThreadedCopySingle) {
-  using Ring = Dynamic_32_NxM::Ring;
-  using Record = Ring::Record;
-  Ring in_ring;
-  auto in_mmap = CreateRing(&in_ring, Ring::Traits::MinCount());
-
-  Ring out_ring;
-  auto out_mmap = CreateRing(&out_ring, Ring::Traits::MinCount());
-
-  std::atomic<bool> quit(false);
-  std::unique_ptr<std::thread> copy_task = CopyTask<Ring>(
-      &quit, out_mmap.mmap(), out_mmap.size, in_mmap.mmap(), in_mmap.size);
-
-  const Record out_record(0x1c);
-  out_ring.Put(out_record);
-
-  uint32_t in_sequence = in_ring.GetOldestSequence();
-  Record in_record;
-  while (!in_ring.Get(&in_sequence, &in_record)) {
-    // Do nothing.
-  }
-
-  EXPECT_EQ(out_record, in_record);
-  std::atomic_store_explicit(&quit, true, std::memory_order_relaxed);
-  copy_task->join();
-}
-
-TEST(BroadcastRingTest, ThreadedCopyLossless) {
-  using Ring = Dynamic_32_NxM::Ring;
-  using Record = Ring::Record;
-  Ring in_ring;
-  auto in_mmap = CreateRing(&in_ring, Ring::Traits::MinCount());
-
-  Ring out_ring;
-  auto out_mmap = CreateRing(&out_ring, Ring::Traits::MinCount());
-
-  std::atomic<bool> quit(false);
-  std::unique_ptr<std::thread> copy_task = CopyTask<Ring>(
-      &quit, out_mmap.mmap(), out_mmap.size, in_mmap.mmap(), in_mmap.size);
-
-  constexpr uint32_t kRecordsToProcess = 10000;
-  uint32_t out_records = 0;
-  uint32_t in_records = 0;
-  uint32_t in_sequence = in_ring.GetNextSequence();
-  while (out_records < kRecordsToProcess || in_records < kRecordsToProcess) {
-    if (out_records < kRecordsToProcess &&
-        out_records - in_records < out_ring.record_count()) {
-      const Record out_record(FillChar(out_records));
-      out_ring.Put(out_record);
-      out_records++;
-    }
-
-    Record in_record;
-    while (in_ring.Get(&in_sequence, &in_record)) {
-      EXPECT_EQ(Record(FillChar(in_records)), in_record);
-      in_records++;
-      in_sequence++;
-    }
-  }
-
-  EXPECT_EQ(kRecordsToProcess, out_records);
-  EXPECT_EQ(kRecordsToProcess, in_records);
-
-  std::atomic_store_explicit(&quit, true, std::memory_order_relaxed);
-  copy_task->join();
-}
-
-TEST(BroadcastRingTest, ThreadedCopyLossy) {
-  using Ring = Dynamic_32_NxM::Ring;
-  using Record = Ring::Record;
-  Ring in_ring;
-  auto in_mmap = CreateRing(&in_ring, Ring::Traits::MinCount());
-
-  Ring out_ring;
-  auto out_mmap = CreateRing(&out_ring, Ring::Traits::MinCount());
-
-  std::atomic<bool> quit(false);
-  std::unique_ptr<std::thread> copy_task = CopyTask<Ring>(
-      &quit, out_mmap.mmap(), out_mmap.size, in_mmap.mmap(), in_mmap.size);
-
-  constexpr uint32_t kRecordsToProcess = 100000;
-  uint32_t out_records = 0;
-  uint32_t in_records = 0;
-  uint32_t in_sequence = in_ring.GetNextSequence();
-  while (out_records < kRecordsToProcess) {
-    const Record out_record(FillChar(out_records));
-    out_ring.Put(out_record);
-    out_records++;
-
-    Record in_record;
-    if (in_ring.GetNewest(&in_sequence, &in_record)) {
-      EXPECT_EQ(Record(in_record.v[0]), in_record);
-      in_records++;
-      in_sequence++;
-    }
-  }
-
-  EXPECT_EQ(kRecordsToProcess, out_records);
-  EXPECT_GE(kRecordsToProcess, in_records);
-
-  std::atomic_store_explicit(&quit, true, std::memory_order_relaxed);
-  copy_task->join();
-}
-
-template <typename Ring>
-std::unique_ptr<std::thread> CheckFillTask(std::atomic<bool>* quit,
-                                           void* in_base, size_t in_size) {
-  return std::unique_ptr<std::thread>(
-      new std::thread([quit, in_base, in_size]() {
-        using Record = typename Ring::Record;
-
-        bool import_ok;
-        Ring in_ring;
-        std::tie(in_ring, import_ok) = Ring::Import(in_base, in_size);
-        ASSERT_TRUE(import_ok);
-
-        uint32_t sequence = in_ring.GetOldestSequence();
-        while (!std::atomic_load_explicit(quit, std::memory_order_relaxed)) {
-          Record record;
-          if (in_ring.Get(&sequence, &record)) {
-            ASSERT_EQ(Record(record.v[0]), record);
-            sequence++;
-          }
-        }
-      }));
-}
-
-template <typename Ring>
-void ThreadedOverwriteTorture() {
-  using Record = typename Ring::Record;
-
-  // Maximize overwrites by having few records.
-  const int kMinRecordCount = 1;
-  const int kMaxRecordCount = 4;
-
-  for (int count = kMinRecordCount; count <= kMaxRecordCount; count *= 2) {
-    Ring out_ring;
-    auto out_mmap = CreateRing(&out_ring, count);
-
-    std::atomic<bool> quit(false);
-    std::unique_ptr<std::thread> check_task =
-        CheckFillTask<Ring>(&quit, out_mmap.mmap(), out_mmap.size);
-
-    constexpr int kIterations = 10000;
-    for (int i = 0; i < kIterations; ++i) {
-      const Record record(FillChar(i));
-      out_ring.Put(record);
-    }
-
-    std::atomic_store_explicit(&quit, true, std::memory_order_relaxed);
-    check_task->join();
-  }
-}
-
-TEST(BroadcastRingTest, ThreadedOverwriteTortureSmall) {
-  ThreadedOverwriteTorture<Dynamic_16_NxM_1plus0::Ring>();
-}
-
-TEST(BroadcastRingTest, ThreadedOverwriteTortureLarge) {
-  ThreadedOverwriteTorture<Dynamic_256_NxM_1plus0::Ring>();
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libbroadcastring/include/libbroadcastring/broadcast_ring.h b/libs/vr/libbroadcastring/include/libbroadcastring/broadcast_ring.h
deleted file mode 100644
index f2e5034..0000000
--- a/libs/vr/libbroadcastring/include/libbroadcastring/broadcast_ring.h
+++ /dev/null
@@ -1,692 +0,0 @@
-#ifndef ANDROID_DVR_BROADCAST_RING_H_
-#define ANDROID_DVR_BROADCAST_RING_H_
-
-#include <inttypes.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <atomic>
-#include <limits>
-#include <tuple>
-#include <type_traits>
-#include <utility>
-
-#include "android-base/logging.h"
-
-#if ATOMIC_LONG_LOCK_FREE != 2 || ATOMIC_INT_LOCK_FREE != 2
-#error "This file requires lock free atomic uint32_t and long"
-#endif
-
-namespace android {
-namespace dvr {
-
-struct DefaultRingTraits {
-  // Set this to false to allow compatibly expanding the record size.
-  static constexpr bool kUseStaticRecordSize = false;
-
-  // Set this to a nonzero value to fix the number of records in the ring.
-  static constexpr uint32_t kStaticRecordCount = 0;
-
-  // Set this to the max number of records that can be written simultaneously.
-  static constexpr uint32_t kMaxReservedRecords = 1;
-
-  // Set this to the min number of records that must be readable.
-  static constexpr uint32_t kMinAvailableRecords = 1;
-};
-
-// Nonblocking ring suitable for concurrent single-writer, multi-reader access.
-//
-// Readers never block the writer and thus this is a nondeterministically lossy
-// transport in the absence of external synchronization. Don't use this as a
-// transport when deterministic behavior is required.
-//
-// Readers may have a read-only mapping; each reader's state is a single local
-// sequence number.
-//
-// The implementation takes care to avoid data races on record access.
-// Inconsistent data can only be returned if at least 2^32 records are written
-// during the read-side critical section.
-//
-// In addition, both readers and the writer are careful to avoid accesses
-// outside the bounds of the mmap area passed in during initialization even if
-// there is a misbehaving or malicious task with write access to the mmap area.
-//
-// When dynamic record size is enabled, readers use the record size in the ring
-// header when indexing the ring, so that it is possible to extend the record
-// type without breaking the read-side ABI.
-//
-// Avoid calling Put() in a tight loop; there should be significantly more time
-// between successive puts than it takes to read one record from memory to
-// ensure Get() completes quickly. This requirement should not be difficult to
-// achieve for most practical uses; 4kB puts at 10,000Hz is well below the
-// scaling limit on current mobile chips.
-//
-// Example Writer Usage:
-//
-//   using Record = MyRecordType;
-//   using Ring = BroadcastRing<Record>;
-//
-//   uint32_t record_count = kMyDesiredCount;
-//   uint32_t ring_size = Ring::MemorySize(record_count);
-//
-//   size_t page_size = sysconf(_SC_PAGESIZE);
-//   uint32_t mmap_size = (ring_size + (page_size - 1)) & ~(page_size - 1);
-//
-//   // Allocate & map via your preferred mechanism, e.g.
-//   int fd = open("/dev/shm/ring_test", O_CREAT|O_RDWR|O_CLOEXEC, 0600);
-//   CHECK(fd >= 0);
-//   CHECK(!ftruncate(fd, ring_size));
-//   void *mmap_base = mmap(nullptr, mmap_size, PROT_READ|PROT_WRITE,
-//                          MAP_SHARED, fd, 0);
-//   CHECK(mmap_base != MAP_FAILED);
-//   close(fd);
-//
-//   Ring ring = Ring::Create(mmap_base, mmap_size, record_count);
-//
-//   while (!done)
-//     ring.Put(BuildNextRecordBlocking());
-//
-//   CHECK(!munmap(mmap_base, mmap_size));
-//
-// Example Reader Usage:
-//
-//   using Record = MyRecordType;
-//   using Ring = BroadcastRing<Record>;
-//
-//   // Map via your preferred mechanism, e.g.
-//   int fd = open("/dev/shm/ring_test", O_RDONLY|O_CLOEXEC);
-//   CHECK(fd >= 0);
-//   struct stat st;
-//   CHECK(!fstat(fd, &st));
-//   size_t mmap_size = st.st_size;
-//   void *mmap_base = mmap(nullptr, mmap_size, PROT_READ,
-//                          MAP_SHARED, fd, 0);
-//   CHECK(mmap_base != MAP_FAILED);
-//   close(fd);
-//
-//   Ring ring;
-//   bool import_ok;
-//   std::tie(ring, import_ok) = Ring::Import(mmap_base, mmap_size);
-//   CHECK(import_ok);
-//
-//   uint32_t sequence;
-//
-//   // Choose starting point (using "0" is unpredictable but not dangerous)
-//   sequence = ring.GetOldestSequence();  // The oldest available
-//   sequence = ring.GetNewestSequence();  // The newest available
-//   sequence = ring.GetNextSequence();    // The next one produced
-//
-//   while (!done) {
-//     Record record;
-//
-//     if (you_want_to_process_all_available_records) {
-//       while (ring.Get(&sequence, &record)) {
-//         ProcessRecord(sequence, record);
-//         sequence++;
-//       }
-//     } else if (you_want_to_skip_to_the_newest_record) {
-//       if (ring.GetNewest(&sequence, &record)) {
-//         ProcessRecord(sequence, record);
-//         sequence++;
-//       }
-//     }
-//
-//     DoSomethingExpensiveOrBlocking();
-//   }
-//
-//   CHECK(!munmap(mmap_base, mmap_size));
-//
-template <typename RecordType, typename BaseTraits = DefaultRingTraits>
-class BroadcastRing {
- public:
-  using Record = RecordType;
-  struct Traits : public BaseTraits {
-    // Must have enough space for writers, plus enough space for readers.
-    static constexpr int kMinRecordCount =
-        BaseTraits::kMaxReservedRecords + BaseTraits::kMinAvailableRecords;
-
-    // Count of zero means dynamic, non-zero means static.
-    static constexpr bool kUseStaticRecordCount =
-        (BaseTraits::kStaticRecordCount != 0);
-
-    // If both record size and count are static then the overall size is too.
-    static constexpr bool kIsStaticSize =
-        BaseTraits::kUseStaticRecordSize && kUseStaticRecordCount;
-  };
-
-  static constexpr bool IsPowerOfTwo(uint32_t size) {
-    return (size & (size - 1)) == 0;
-  }
-
-  // Sanity check the options provided in Traits.
-  static_assert(Traits::kMinRecordCount >= 1, "Min record count too small");
-  static_assert(!Traits::kUseStaticRecordCount ||
-                    Traits::kStaticRecordCount >= Traits::kMinRecordCount,
-                "Static record count is too small");
-  static_assert(!Traits::kStaticRecordCount ||
-                    IsPowerOfTwo(Traits::kStaticRecordCount),
-                "Static record count is not a power of two");
-  static_assert(std::is_standard_layout<Record>::value,
-                "Record type must be standard layout");
-
-  BroadcastRing() {}
-
-  // Creates a new ring at |mmap| with |record_count| records.
-  //
-  // There must be at least |MemorySize(record_count)| bytes of space already
-  // allocated at |mmap|. The ring does not take ownership.
-  static BroadcastRing Create(void* mmap, size_t mmap_size,
-                              uint32_t record_count) {
-    BroadcastRing ring(mmap);
-    CHECK(ring.ValidateGeometry(mmap_size, sizeof(Record), record_count));
-    ring.InitializeHeader(sizeof(Record), record_count);
-    return ring;
-  }
-
-  // Creates a new ring at |mmap|.
-  //
-  // There must be at least |MemorySize()| bytes of space already allocated at
-  // |mmap|. The ring does not take ownership.
-  static BroadcastRing Create(void* mmap, size_t mmap_size) {
-    return Create(mmap, mmap_size,
-                  Traits::kUseStaticRecordCount
-                      ? Traits::kStaticRecordCount
-                      : BroadcastRing::GetRecordCount(mmap_size));
-  }
-
-  // Imports an existing ring at |mmap|.
-  //
-  // Import may fail if the ring parameters in the mmap header are not sensible.
-  // In this case the returned boolean is false; make sure to check this value.
-  static std::tuple<BroadcastRing, bool> Import(void* mmap, size_t mmap_size) {
-    BroadcastRing ring(mmap);
-    uint32_t record_size = 0;
-    uint32_t record_count = 0;
-    if (mmap_size >= sizeof(Header)) {
-      record_size = std::atomic_load_explicit(&ring.header_mmap()->record_size,
-                                              std::memory_order_relaxed);
-      record_count = std::atomic_load_explicit(
-          &ring.header_mmap()->record_count, std::memory_order_relaxed);
-    }
-    bool ok = ring.ValidateGeometry(mmap_size, record_size, record_count);
-    return std::make_tuple(ring, ok);
-  }
-
-  ~BroadcastRing() {}
-
-  // Calculates the space necessary for a ring of size |record_count|.
-  //
-  // Use this function for dynamically sized rings.
-  static constexpr size_t MemorySize(uint32_t record_count) {
-    return sizeof(Header) + sizeof(Record) * record_count;
-  }
-
-  // Calculates the space necessary for a statically sized ring.
-  //
-  // Use this function for statically sized rings.
-  static constexpr size_t MemorySize() {
-    static_assert(
-        Traits::kUseStaticRecordCount,
-        "Wrong MemorySize() function called for dynamic record count");
-    return MemorySize(Traits::kStaticRecordCount);
-  }
-
-  static uint32_t NextPowerOf2(uint32_t n) {
-    if (n == 0)
-      return 0;
-    n -= 1;
-    n |= n >> 16;
-    n |= n >> 8;
-    n |= n >> 4;
-    n |= n >> 2;
-    n |= n >> 1;
-    return n + 1;
-  }
-
-  // Gets the biggest power of 2 record count that can fit into this mmap.
-  //
-  // The header size has been taken into account.
-  static uint32_t GetRecordCount(size_t mmap_size) {
-    if (mmap_size <= sizeof(Header)) {
-      return 0;
-    }
-    uint32_t count =
-        static_cast<uint32_t>((mmap_size - sizeof(Header)) / sizeof(Record));
-    return IsPowerOfTwo(count) ? count : (NextPowerOf2(count) / 2);
-  }
-
-  // Writes a record to the ring.
-  //
-  // The oldest record is overwritten unless the ring is not already full.
-  void Put(const Record& record) {
-    const int kRecordCount = 1;
-    Reserve(kRecordCount);
-    Geometry geometry = GetGeometry();
-    PutRecordInternal(&record, record_mmap_writer(geometry.tail_index));
-    Publish(kRecordCount);
-  }
-
-  // Gets sequence number of the oldest currently available record.
-  uint32_t GetOldestSequence() const {
-    return std::atomic_load_explicit(&header_mmap()->head,
-                                     std::memory_order_relaxed);
-  }
-
-  // Gets sequence number of the first future record.
-  //
-  // If the returned value is passed to Get() and there is no concurrent Put(),
-  // Get() will return false.
-  uint32_t GetNextSequence() const {
-    return std::atomic_load_explicit(&header_mmap()->tail,
-                                     std::memory_order_relaxed);
-  }
-
-  // Gets sequence number of the newest currently available record.
-  uint32_t GetNewestSequence() const { return GetNextSequence() - 1; }
-
-  // Copies the oldest available record with sequence at least |*sequence| to
-  // |record|.
-  //
-  // Returns false if there is no recent enough record available.
-  //
-  // Updates |*sequence| with the sequence number of the record returned. To get
-  // the following record, increment this number by one.
-  //
-  // This function synchronizes with two other operations:
-  //
-  //    (1) Load-Acquire of |tail|
-  //
-  //        Together with the store-release in Publish(), this load-acquire
-  //        ensures each store to a record in PutRecordInternal() happens-before
-  //        any corresponding load in GetRecordInternal().
-  //
-  //        i.e. the stores for the records with sequence numbers < |tail| have
-  //        completed from our perspective
-  //
-  //    (2) Acquire Fence between record access & final load of |head|
-  //
-  //        Together with the release fence in Reserve(), this ensures that if
-  //        GetRecordInternal() loads a value stored in some execution of
-  //        PutRecordInternal(), then the store of |head| in the Reserve() that
-  //        preceeded it happens-before our final load of |head|.
-  //
-  //        i.e. if we read a record with sequence number >= |final_head| then
-  //        no later store to that record has completed from our perspective
-  bool Get(uint32_t* sequence /*inout*/, Record* record /*out*/) const {
-    for (;;) {
-      uint32_t tail = std::atomic_load_explicit(&header_mmap()->tail,
-                                                std::memory_order_acquire);
-      uint32_t head = std::atomic_load_explicit(&header_mmap()->head,
-                                                std::memory_order_relaxed);
-
-      if (tail - head > record_count())
-        continue;  // Concurrent modification; re-try.
-
-      if (*sequence - head > tail - head)
-        *sequence = head;  // Out of window, skip forward to first available.
-
-      if (*sequence == tail) return false;  // No new records available.
-
-      Geometry geometry =
-          CalculateGeometry(record_count(), record_size(), *sequence, tail);
-
-      // Compute address explicitly in case record_size > sizeof(Record).
-      RecordStorage* record_storage = record_mmap_reader(geometry.head_index);
-
-      GetRecordInternal(record_storage, record);
-
-      // NB: It is not sufficient to change this to a load-acquire of |head|.
-      std::atomic_thread_fence(std::memory_order_acquire);
-
-      uint32_t final_head = std::atomic_load_explicit(
-          &header_mmap()->head, std::memory_order_relaxed);
-
-      if (final_head - head > *sequence - head)
-        continue;  // Concurrent modification; re-try.
-
-      // Note: Combining the above 4 comparisons gives:
-      // 0 <= final_head - head <= sequence - head < tail - head <= record_count
-      //
-      // We can also write this as:
-      // head <=* final_head <=* sequence <* tail <=* head + record_count
-      //
-      // where <* orders by difference from head: x <* y if x - head < y - head.
-      // This agrees with the order of sequence updates during "put" operations.
-      return true;
-    }
-  }
-
-  // Copies the newest available record with sequence at least |*sequence| to
-  // |record|.
-  //
-  // Returns false if there is no recent enough record available.
-  //
-  // Updates |*sequence| with the sequence number of the record returned. To get
-  // the following record, increment this number by one.
-  bool GetNewest(uint32_t* sequence, Record* record) const {
-    uint32_t newest_sequence = GetNewestSequence();
-    if (*sequence == newest_sequence + 1) return false;
-    *sequence = newest_sequence;
-    return Get(sequence, record);
-  }
-
-  // Returns true if this instance has been created or imported.
-  bool is_valid() const { return !!data_.mmap; }
-
-  uint32_t record_count() const { return record_count_internal(); }
-  uint32_t record_size() const { return record_size_internal(); }
-  static constexpr uint32_t mmap_alignment() { return alignof(Mmap); }
-
- private:
-  struct Header {
-    // Record size for reading out of the ring. Writers always write the full
-    // length; readers may need to read a prefix of each record.
-    std::atomic<uint32_t> record_size;
-
-    // Number of records in the ring.
-    std::atomic<uint32_t> record_count;
-
-    // Readable region is [head % record_count, tail % record_count).
-    //
-    // The region in [tail % record_count, head % record_count) was either never
-    // populated or is being updated.
-    //
-    // These are sequences numbers, not indexes - indexes should be computed
-    // with a modulus.
-    //
-    // To ensure consistency:
-    //
-    // (1) Writes advance |head| past any updated records before writing to
-    //     them, and advance |tail| after they are written.
-    // (2) Readers check |tail| before reading data and |head| after,
-    //     making sure to discard any data that was written to concurrently.
-    std::atomic<uint32_t> head;
-    std::atomic<uint32_t> tail;
-  };
-
-  // Store using the standard word size.
-  using StorageType = long;  // NOLINT
-
-  // Always require 8 byte alignment so that the same record sizes are legal on
-  // 32 and 64 bit builds.
-  static constexpr size_t kRecordAlignment = 8;
-  static_assert(kRecordAlignment % sizeof(StorageType) == 0,
-                "Bad record alignment");
-
-  struct RecordStorage {
-    // This is accessed with relaxed atomics to prevent data races on the
-    // contained data, which would be undefined behavior.
-    std::atomic<StorageType> data[sizeof(Record) / sizeof(StorageType)];
-  };
-
-  static_assert(sizeof(StorageType) *
-                        std::extent<decltype(RecordStorage::data)>() ==
-                    sizeof(Record),
-                "Record length must be a multiple of sizeof(StorageType)");
-
-  struct Geometry {
-    // Static geometry.
-    uint32_t record_count;
-    uint32_t record_size;
-
-    // Copy of atomic sequence counts.
-    uint32_t head;
-    uint32_t tail;
-
-    // First index of readable region.
-    uint32_t head_index;
-
-    // First index of writable region.
-    uint32_t tail_index;
-
-    // Number of records in readable region.
-    uint32_t count;
-
-    // Number of records in writable region.
-    uint32_t space;
-  };
-
-  // Mmap area layout.
-  //
-  // Readers should not index directly into |records| as this is not valid when
-  // dynamic record sizes are used; use record_mmap_reader() instead.
-  struct Mmap {
-    Header header;
-    RecordStorage records[];
-  };
-
-  static_assert(std::is_standard_layout<Mmap>::value,
-                "Mmap must be standard layout");
-  static_assert(sizeof(std::atomic<uint32_t>) == sizeof(uint32_t),
-                "Lockless atomics contain extra state");
-  static_assert(sizeof(std::atomic<StorageType>) == sizeof(StorageType),
-                "Lockless atomics contain extra state");
-
-  explicit BroadcastRing(void* mmap) {
-    CHECK_EQ(0U, reinterpret_cast<uintptr_t>(mmap) % alignof(Mmap));
-    data_.mmap = reinterpret_cast<Mmap*>(mmap);
-  }
-
-  // Initializes the mmap area header for a new ring.
-  void InitializeHeader(uint32_t record_size, uint32_t record_count) {
-    constexpr uint32_t kInitialSequence = -256;  // Force an early wrap.
-    std::atomic_store_explicit(&header_mmap()->record_size, record_size,
-                               std::memory_order_relaxed);
-    std::atomic_store_explicit(&header_mmap()->record_count, record_count,
-                               std::memory_order_relaxed);
-    std::atomic_store_explicit(&header_mmap()->head, kInitialSequence,
-                               std::memory_order_relaxed);
-    std::atomic_store_explicit(&header_mmap()->tail, kInitialSequence,
-                               std::memory_order_relaxed);
-  }
-
-  // Validates ring geometry.
-  //
-  // Ring geometry is validated carefully on import and then cached. This allows
-  // us to avoid out-of-range accesses even if the parameters in the header are
-  // later changed.
-  bool ValidateGeometry(size_t mmap_size, uint32_t header_record_size,
-                        uint32_t header_record_count) {
-    set_record_size(header_record_size);
-    set_record_count(header_record_count);
-
-    if (record_size() != header_record_size) return false;
-    if (record_count() != header_record_count) return false;
-    if (record_count() < Traits::kMinRecordCount) return false;
-    if (record_size() < sizeof(Record)) return false;
-    if (record_size() % kRecordAlignment != 0) return false;
-    if (!IsPowerOfTwo(record_count())) return false;
-
-    size_t memory_size = record_count() * record_size();
-    if (memory_size / record_size() != record_count()) return false;
-    if (memory_size + sizeof(Header) < memory_size) return false;
-    if (memory_size + sizeof(Header) > mmap_size) return false;
-
-    return true;
-  }
-
-  // Copies a record into the ring.
-  //
-  // This is done with relaxed atomics because otherwise it is racy according to
-  // the C++ memory model. This is very low overhead once optimized.
-  static inline void PutRecordInternal(const Record* in, RecordStorage* out) {
-    StorageType data[sizeof(Record) / sizeof(StorageType)];
-    memcpy(data, in, sizeof(*in));
-    for (size_t i = 0; i < std::extent<decltype(data)>(); ++i) {
-      std::atomic_store_explicit(&out->data[i], data[i],
-                                 std::memory_order_relaxed);
-    }
-  }
-
-  // Copies a record out of the ring.
-  //
-  // This is done with relaxed atomics because otherwise it is racy according to
-  // the C++ memory model. This is very low overhead once optimized.
-  static inline void GetRecordInternal(RecordStorage* in, Record* out) {
-    StorageType data[sizeof(Record) / sizeof(StorageType)];
-    for (size_t i = 0; i < std::extent<decltype(data)>(); ++i) {
-      data[i] =
-          std::atomic_load_explicit(&in->data[i], std::memory_order_relaxed);
-    }
-    memcpy(out, &data, sizeof(*out));
-  }
-
-  // Converts a record's sequence number into a storage index.
-  static uint32_t SequenceToIndex(uint32_t sequence, uint32_t record_count) {
-    return sequence & (record_count - 1);
-  }
-
-  // Computes readable & writable ranges from ring parameters.
-  static Geometry CalculateGeometry(uint32_t record_count, uint32_t record_size,
-                                    uint32_t head, uint32_t tail) {
-    Geometry geometry;
-    geometry.record_count = record_count;
-    geometry.record_size = record_size;
-    DCHECK_EQ(0U, geometry.record_size % kRecordAlignment);
-    geometry.head = head;
-    geometry.tail = tail;
-    geometry.head_index = SequenceToIndex(head, record_count);
-    geometry.tail_index = SequenceToIndex(tail, record_count);
-    geometry.count = geometry.tail - geometry.head;
-    DCHECK_LE(geometry.count, record_count);
-    geometry.space = geometry.record_count - geometry.count;
-    return geometry;
-  }
-
-  // Gets the current ring readable & writable regions.
-  //
-  // This this is always safe from the writing thread since it is the only
-  // thread allowed to update the header.
-  Geometry GetGeometry() const {
-    return CalculateGeometry(
-        record_count(), record_size(),
-        std::atomic_load_explicit(&header_mmap()->head,
-                                  std::memory_order_relaxed),
-        std::atomic_load_explicit(&header_mmap()->tail,
-                                  std::memory_order_relaxed));
-  }
-
-  // Makes space for at least |reserve_count| records.
-  //
-  // There is nothing to prevent overwriting records that have concurrent
-  // readers. We do however ensure that this situation can be detected: the
-  // fence ensures the |head| update will be the first update seen by readers,
-  // and readers check this value after reading and discard data that may have
-  // been concurrently modified.
-  void Reserve(uint32_t reserve_count) {
-    Geometry geometry = GetGeometry();
-    DCHECK_LE(reserve_count, Traits::kMaxReservedRecords);
-    uint32_t needed =
-        (geometry.space >= reserve_count ? 0 : reserve_count - geometry.space);
-
-    std::atomic_store_explicit(&header_mmap()->head, geometry.head + needed,
-                               std::memory_order_relaxed);
-
-    // NB: It is not sufficient to change this to a store-release of |head|.
-    std::atomic_thread_fence(std::memory_order_release);
-  }
-
-  // Makes |publish_count| records visible to readers.
-  //
-  // Space must have been reserved by a previous call to Reserve().
-  void Publish(uint32_t publish_count) {
-    Geometry geometry = GetGeometry();
-    DCHECK_LE(publish_count, geometry.space);
-    std::atomic_store_explicit(&header_mmap()->tail,
-                               geometry.tail + publish_count,
-                               std::memory_order_release);
-  }
-
-  // Helpers to compute addresses in mmap area.
-  Mmap* mmap() const { return data_.mmap; }
-  Header* header_mmap() const { return &data_.mmap->header; }
-  RecordStorage* record_mmap_writer(uint32_t index) const {
-    DCHECK_EQ(sizeof(Record), record_size());
-    return &data_.mmap->records[index];
-  }
-  RecordStorage* record_mmap_reader(uint32_t index) const {
-    if (Traits::kUseStaticRecordSize) {
-      return &data_.mmap->records[index];
-    } else {
-      // Calculate the location of a record in the ring without assuming that
-      // sizeof(Record) == record_size.
-      return reinterpret_cast<RecordStorage*>(
-          reinterpret_cast<char*>(data_.mmap->records) + index * record_size());
-    }
-  }
-
-  // The following horrifying template gunk enables us to store just the mmap
-  // base pointer for compile-time statically sized rings. Dynamically sized
-  // rings also store the validated copy of the record size & count.
-  //
-  // This boils down to: use a compile time constant if available, and otherwise
-  // load the value that was validated on import from a member variable.
-  template <typename T = Traits>
-  typename std::enable_if<T::kUseStaticRecordSize, uint32_t>::type
-  record_size_internal() const {
-    return sizeof(Record);
-  }
-
-  template <typename T = Traits>
-  typename std::enable_if<!T::kUseStaticRecordSize, uint32_t>::type
-  record_size_internal() const {
-    return data_.record_size;
-  }
-
-  template <typename T = Traits>
-  typename std::enable_if<T::kUseStaticRecordSize, void>::type set_record_size(
-      uint32_t /*record_size*/) {}
-
-  template <typename T = Traits>
-  typename std::enable_if<!T::kUseStaticRecordSize, void>::type set_record_size(
-      uint32_t record_size) {
-    data_.record_size = record_size;
-  }
-
-  template <typename T = Traits>
-  typename std::enable_if<T::kUseStaticRecordCount, uint32_t>::type
-  record_count_internal() const {
-    return Traits::kStaticRecordCount;
-  }
-
-  template <typename T = Traits>
-  typename std::enable_if<!T::kUseStaticRecordCount, uint32_t>::type
-  record_count_internal() const {
-    return data_.record_count;
-  }
-
-  template <typename T = Traits>
-  typename std::enable_if<T::kUseStaticRecordCount, void>::type
-  set_record_count(uint32_t /*record_count*/) const {}
-
-  template <typename T = Traits>
-  typename std::enable_if<!T::kUseStaticRecordCount, void>::type
-  set_record_count(uint32_t record_count) {
-    data_.record_count = record_count;
-  }
-
-  // Data we need to store for statically sized rings.
-  struct DataStaticSize {
-    Mmap* mmap = nullptr;
-  };
-
-  // Data we need to store for dynamically sized rings.
-  struct DataDynamicSize {
-    Mmap* mmap = nullptr;
-
-    // These are cached to make sure misbehaving writers cannot cause
-    // out-of-bounds memory accesses by updating the values in the mmap header.
-    uint32_t record_size = 0;
-    uint32_t record_count = 0;
-  };
-
-  using DataStaticOrDynamic =
-      typename std::conditional<Traits::kIsStaticSize, DataStaticSize,
-                                DataDynamicSize>::type;
-
-  DataStaticOrDynamic data_;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_BROADCAST_RING_H_
diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp
deleted file mode 100644
index 583ad1d..0000000
--- a/libs/vr/libbufferhub/Android.bp
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) 2016 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_library_headers {
-    name: "libbufferhub_headers",
-    export_include_dirs: ["include"],
-    vendor_available: true,  // TODO(b/112338314): Does shouldn't be available to vendor.
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.media",
-        "com.android.media.swcodec",
-    ],
-    min_sdk_version: "29",
-}
-
-sourceFiles = [
-    "buffer_hub_base.cpp",
-    "buffer_hub_rpc.cpp",
-    "consumer_buffer.cpp",
-    "ion_buffer.cpp",
-    "producer_buffer.cpp",
-]
-
-sharedLibraries = [
-    "libbase",
-    "libcutils",
-    "liblog",
-    "libui",
-    "libutils",
-    "libpdx_default_transport",
-]
-
-headerLibraries = [
-    "libbufferhub_headers",
-    "libdvr_headers",
-    "libnativebase_headers",
-]
-
-cc_library {
-    srcs: sourceFiles,
-    cflags: [
-        "-DLOG_TAG=\"libbufferhub\"",
-        "-DTRACE=0",
-        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
-        "-Wall",
-        "-Werror",
-    ],
-    shared_libs: sharedLibraries,
-    header_libs: headerLibraries,
-    name: "libbufferhub",
-    export_header_lib_headers: [
-        "libbufferhub_headers",
-        "libnativebase_headers",
-    ],
-}
-
-cc_test {
-    srcs: ["buffer_hub-test.cpp"],
-    static_libs: ["libbufferhub"],
-    shared_libs: sharedLibraries,
-    header_libs: headerLibraries,
-    name: "buffer_hub-test",
-}
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
deleted file mode 100644
index 27ab024..0000000
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ /dev/null
@@ -1,906 +0,0 @@
-#include <gtest/gtest.h>
-#include <poll.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/consumer_buffer.h>
-#include <private/dvr/producer_buffer.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-#include <ui/BufferHubDefs.h>
-
-#include <mutex>
-#include <thread>
-
-namespace {
-#define RETRY_EINTR(fnc_call)                 \
-  ([&]() -> decltype(fnc_call) {              \
-    decltype(fnc_call) result;                \
-    do {                                      \
-      result = (fnc_call);                    \
-    } while (result == -1 && errno == EINTR); \
-    return result;                            \
-  })()
-
-using android::BufferHubDefs::isAnyClientAcquired;
-using android::BufferHubDefs::isAnyClientGained;
-using android::BufferHubDefs::isAnyClientPosted;
-using android::BufferHubDefs::isClientAcquired;
-using android::BufferHubDefs::isClientPosted;
-using android::BufferHubDefs::isClientReleased;
-using android::BufferHubDefs::kFirstClientBitMask;
-using android::dvr::ConsumerBuffer;
-using android::dvr::ProducerBuffer;
-using android::pdx::LocalHandle;
-using android::pdx::Status;
-using LibBufferHubTest = ::testing::Test;
-
-const int kWidth = 640;
-const int kHeight = 480;
-const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-const int kUsage = 0;
-// Maximum number of consumers for the buffer that only has one producer in the
-// test.
-const size_t kMaxConsumerCount =
-    android::BufferHubDefs::kMaxNumberOfClients - 1;
-const int kPollTimeoutMs = 100;
-
-// Helper function to poll the eventfd in BufferHubBase.
-template <class BufferHubBase>
-int PollBufferEvent(const std::unique_ptr<BufferHubBase>& buffer,
-                    int timeout_ms = kPollTimeoutMs) {
-  pollfd p = {buffer->event_fd(), POLLIN, 0};
-  return poll(&p, 1, timeout_ms);
-}
-
-}  // namespace
-
-TEST_F(LibBufferHubTest, TestBasicUsage) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c1 =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c1.get() != nullptr);
-  // Check that consumers can spawn other consumers.
-  std::unique_ptr<ConsumerBuffer> c2 =
-      ConsumerBuffer::Import(c1->CreateConsumer());
-  ASSERT_TRUE(c2.get() != nullptr);
-
-  // Checks the state masks of client p, c1 and c2.
-  EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask);
-  EXPECT_EQ(c1->client_state_mask(), kFirstClientBitMask << 1);
-  EXPECT_EQ(c2->client_state_mask(), kFirstClientBitMask << 2);
-
-  // Initial state: producer not available, consumers not available.
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
-
-  EXPECT_EQ(0, p->GainAsync());
-  EXPECT_EQ(0, p->Post(LocalHandle()));
-
-  // New state: producer not available, consumers available.
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
-  EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c1)));
-  EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c2)));
-
-  LocalHandle fence;
-  EXPECT_EQ(0, c1->Acquire(&fence));
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
-  EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c2)));
-
-  EXPECT_EQ(0, c2->Acquire(&fence));
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
-
-  EXPECT_EQ(0, c1->Release(LocalHandle()));
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
-  EXPECT_EQ(0, c2->Discard());
-  EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(p)));
-
-  EXPECT_EQ(0, p->Gain(&fence));
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
-}
-
-TEST_F(LibBufferHubTest, TestEpoll) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-
-  LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
-  ASSERT_TRUE(epoll_fd.IsValid());
-
-  epoll_event event;
-  std::array<epoll_event, 64> events;
-
-  auto event_sources = p->GetEventSources();
-  ASSERT_LT(event_sources.size(), events.size());
-
-  for (const auto& event_source : event_sources) {
-    event = {.events = event_source.event_mask | EPOLLET,
-             .data = {.fd = p->event_fd()}};
-    ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
-                           &event));
-  }
-
-  event_sources = c->GetEventSources();
-  ASSERT_LT(event_sources.size(), events.size());
-
-  for (const auto& event_source : event_sources) {
-    event = {.events = event_source.event_mask | EPOLLET,
-             .data = {.fd = c->event_fd()}};
-    ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
-                           &event));
-  }
-
-  // No events should be signaled initially.
-  ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
-
-  // Gain and post the producer and check for consumer signal.
-  EXPECT_EQ(0, p->GainAsync());
-  EXPECT_EQ(0, p->Post({}));
-  ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
-                          kPollTimeoutMs));
-  ASSERT_TRUE(events[0].events & EPOLLIN);
-  ASSERT_EQ(c->event_fd(), events[0].data.fd);
-
-  // Save the event bits to translate later.
-  event = events[0];
-
-  // Check for events again. Edge-triggered mode should prevent any.
-  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
-                          kPollTimeoutMs));
-  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
-                          kPollTimeoutMs));
-  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
-                          kPollTimeoutMs));
-  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
-                          kPollTimeoutMs));
-
-  // Translate the events.
-  auto event_status = c->GetEventMask(event.events);
-  ASSERT_TRUE(event_status);
-  ASSERT_TRUE(event_status.get() & EPOLLIN);
-
-  // Check for events again. Edge-triggered mode should prevent any.
-  EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
-                          kPollTimeoutMs));
-}
-
-TEST_F(LibBufferHubTest, TestStateMask) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-
-  // It's ok to create up to kMaxConsumerCount consumer buffers.
-  uint32_t client_state_masks = p->client_state_mask();
-  std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
-  for (size_t i = 0; i < kMaxConsumerCount; i++) {
-    cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
-    ASSERT_TRUE(cs[i].get() != nullptr);
-    // Expect all buffers have unique state mask.
-    EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
-    client_state_masks |= cs[i]->client_state_mask();
-  }
-  EXPECT_EQ(client_state_masks, ~0U);
-
-  // The 64th creation will fail with out-of-memory error.
-  auto state = p->CreateConsumer();
-  EXPECT_EQ(state.error(), E2BIG);
-
-  // Release any consumer should allow us to re-create.
-  for (size_t i = 0; i < kMaxConsumerCount; i++) {
-    client_state_masks &= ~cs[i]->client_state_mask();
-    cs[i] = nullptr;
-    cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
-    ASSERT_TRUE(cs[i].get() != nullptr);
-    // The released state mask will be reused.
-    EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
-    client_state_masks |= cs[i]->client_state_mask();
-  }
-}
-
-TEST_F(LibBufferHubTest, TestStateTransitions) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-
-  LocalHandle fence;
-  EXPECT_EQ(0, p->GainAsync());
-
-  // Acquire in gained state should fail.
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
-
-  // Post in gained state should succeed.
-  EXPECT_EQ(0, p->Post(LocalHandle()));
-
-  // Post and gain in posted state should fail.
-  EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
-  EXPECT_EQ(-EBUSY, p->Gain(&fence));
-
-  // Acquire in posted state should succeed.
-  EXPECT_EQ(0, c->Acquire(&fence));
-
-  // Acquire, post, and gain in acquired state should fail.
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
-  EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
-  EXPECT_EQ(-EBUSY, p->Gain(&fence));
-
-  // Release in acquired state should succeed.
-  EXPECT_EQ(0, c->Release(LocalHandle()));
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
-
-  // Acquire and post in released state should fail.
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
-  EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
-
-  // Gain in released state should succeed.
-  EXPECT_EQ(0, p->Gain(&fence));
-
-  // Acquire in gained state should fail.
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
-}
-
-TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-
-  DvrNativeBufferMetadata metadata;
-  LocalHandle invalid_fence;
-  EXPECT_EQ(0, p->GainAsync());
-
-  // Acquire in gained state should fail.
-  EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
-  EXPECT_FALSE(invalid_fence.IsValid());
-  EXPECT_FALSE(invalid_fence.IsValid());
-
-  // Post in gained state should succeed.
-  EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_EQ(p->buffer_state(), c->buffer_state());
-  EXPECT_TRUE(isAnyClientPosted(p->buffer_state()));
-
-  // Post and gain in posted state should fail.
-  EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
-  EXPECT_FALSE(invalid_fence.IsValid());
-
-  // Acquire in posted state should succeed.
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
-  EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
-  EXPECT_FALSE(invalid_fence.IsValid());
-  EXPECT_EQ(p->buffer_state(), c->buffer_state());
-  EXPECT_TRUE(isAnyClientAcquired(p->buffer_state()));
-
-  // Acquire, post, and gain in acquired state should fail.
-  EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
-  EXPECT_FALSE(invalid_fence.IsValid());
-  EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
-  EXPECT_FALSE(invalid_fence.IsValid());
-
-  // Release in acquired state should succeed.
-  EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
-  EXPECT_EQ(p->buffer_state(), c->buffer_state());
-  EXPECT_TRUE(p->is_released());
-
-  // Acquire and post in released state should fail.
-  EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
-  EXPECT_FALSE(invalid_fence.IsValid());
-  EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
-
-  // Gain in released state should succeed.
-  EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
-  EXPECT_FALSE(invalid_fence.IsValid());
-  EXPECT_EQ(p->buffer_state(), c->buffer_state());
-  EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
-
-  // Acquire and gain in gained state should fail.
-  EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
-  EXPECT_FALSE(invalid_fence.IsValid());
-}
-
-TEST_F(LibBufferHubTest, TestGainTwiceByTheSameProducer) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-
-  ASSERT_EQ(0, p->GainAsync());
-  ASSERT_EQ(0, p->GainAsync());
-}
-
-TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-  ASSERT_EQ(0, p->GainAsync());
-  ASSERT_EQ(0, p->Post(LocalHandle()));
-  ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
-
-  // Gain in posted state should only succeed with gain_posted_buffer = true.
-  LocalHandle invalid_fence;
-  EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
-  EXPECT_EQ(0, p->Gain(&invalid_fence, true));
-}
-
-TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-  ASSERT_EQ(0, p->GainAsync());
-  ASSERT_EQ(0, p->Post(LocalHandle()));
-  ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
-
-  // GainAsync in posted state should only succeed with gain_posted_buffer
-  // equals true.
-  DvrNativeBufferMetadata metadata;
-  LocalHandle invalid_fence;
-  EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
-  EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
-}
-
-TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  ASSERT_EQ(0, p->GainAsync());
-  ASSERT_EQ(0, p->Post(LocalHandle()));
-  // Producer state bit is in released state after post, other clients shall be
-  // in posted state although there is no consumer of this buffer yet.
-  ASSERT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask()));
-  ASSERT_TRUE(p->is_released());
-  ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
-
-  // Gain in released state should succeed.
-  LocalHandle invalid_fence;
-  EXPECT_EQ(0, p->Gain(&invalid_fence, false));
-}
-
-TEST_F(LibBufferHubTest, TestMaxConsumers) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  uint32_t producer_state_mask = p->client_state_mask();
-
-  std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
-  for (size_t i = 0; i < kMaxConsumerCount; ++i) {
-    cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
-    ASSERT_TRUE(cs[i].get() != nullptr);
-    EXPECT_TRUE(cs[i]->is_released());
-    EXPECT_NE(producer_state_mask, cs[i]->client_state_mask());
-  }
-
-  EXPECT_EQ(0, p->GainAsync());
-  DvrNativeBufferMetadata metadata;
-  LocalHandle invalid_fence;
-
-  // Post the producer should trigger all consumers to be available.
-  EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask()));
-  for (size_t i = 0; i < kMaxConsumerCount; ++i) {
-    EXPECT_TRUE(
-        isClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
-    EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(cs[i])));
-    EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
-    EXPECT_TRUE(
-        isClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
-  }
-
-  // All consumers have to release before the buffer is considered to be
-  // released.
-  for (size_t i = 0; i < kMaxConsumerCount; i++) {
-    EXPECT_FALSE(p->is_released());
-    EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
-  }
-
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
-  EXPECT_TRUE(p->is_released());
-
-  // Buffer state cross all clients must be consistent.
-  for (size_t i = 0; i < kMaxConsumerCount; i++) {
-    EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
-  }
-}
-
-TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  EXPECT_EQ(0, p->GainAsync());
-  EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
-
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_TRUE(isAnyClientGained(c->buffer_state()));
-
-  DvrNativeBufferMetadata metadata;
-  LocalHandle invalid_fence;
-
-  // Post the gained buffer should signal already created consumer.
-  EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_TRUE(isAnyClientPosted(p->buffer_state()));
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
-  EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
-  EXPECT_TRUE(isAnyClientAcquired(c->buffer_state()));
-}
-
-TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  EXPECT_EQ(0, p->GainAsync());
-  EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
-
-  DvrNativeBufferMetadata metadata;
-  LocalHandle invalid_fence;
-
-  // Post the gained buffer before any consumer gets created.
-  EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_TRUE(p->is_released());
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
-
-  // Newly created consumer will be signalled for the posted buffer although it
-  // is created after producer posting.
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_TRUE(isClientPosted(c->buffer_state(), c->client_state_mask()));
-  EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
-}
-
-TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-
-  std::unique_ptr<ConsumerBuffer> c1 =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c1.get() != nullptr);
-
-  EXPECT_EQ(0, p->GainAsync());
-  DvrNativeBufferMetadata metadata;
-  LocalHandle invalid_fence;
-
-  // Post, acquire, and release the buffer..
-  EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
-  EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
-  EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
-
-  // Note that the next PDX call is on the producer channel, which may be
-  // executed before Release impulse gets executed by bufferhubd. Thus, here we
-  // need to wait until the releasd is confirmed before creating another
-  // consumer.
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
-  EXPECT_TRUE(p->is_released());
-
-  // Create another consumer immediately after the release, should not make the
-  // buffer un-released.
-  std::unique_ptr<ConsumerBuffer> c2 =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c2.get() != nullptr);
-
-  EXPECT_TRUE(p->is_released());
-  EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
-  EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
-}
-
-TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
-  struct Metadata {
-    int64_t field1;
-    int64_t field2;
-  };
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_EQ(0, p->GainAsync());
-  Metadata m = {1, 3};
-  EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
-  EXPECT_LE(0, RETRY_EINTR(PollBufferEvent(c)));
-  LocalHandle fence;
-  Metadata m2 = {};
-  EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
-  EXPECT_EQ(m.field1, m2.field1);
-  EXPECT_EQ(m.field2, m2.field2);
-  EXPECT_EQ(0, c->Release(LocalHandle()));
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p, /*timeout_ms=*/0)));
-}
-
-TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
-  struct Metadata {
-    int64_t field1;
-    int64_t field2;
-  };
-  struct OverSizedMetadata {
-    int64_t field1;
-    int64_t field2;
-    int64_t field3;
-  };
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_EQ(0, p->GainAsync());
-
-  // It is illegal to post metadata larger than originally requested during
-  // buffer allocation.
-  OverSizedMetadata evil_meta = {};
-  EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
-  EXPECT_GE(0, RETRY_EINTR(PollBufferEvent(c)));
-
-  // It is ok to post metadata smaller than originally requested during
-  // buffer allocation.
-  EXPECT_EQ(0, p->Post(LocalHandle()));
-}
-
-TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
-  struct Metadata {
-    int64_t field1;
-    int64_t field2;
-  };
-  struct OverSizedMetadata {
-    int64_t field1;
-    int64_t field2;
-    int64_t field3;
-  };
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_EQ(0, p->GainAsync());
-
-  Metadata m = {1, 3};
-  EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
-
-  LocalHandle fence;
-  int64_t sequence;
-  OverSizedMetadata e;
-
-  // It is illegal to acquire metadata larger than originally requested during
-  // buffer allocation.
-  EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
-
-  // It is ok to acquire metadata smaller than originally requested during
-  // buffer allocation.
-  EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
-  EXPECT_EQ(m.field1, sequence);
-}
-
-TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_EQ(0, p->GainAsync());
-
-  int64_t sequence = 3;
-  EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
-
-  LocalHandle fence;
-  EXPECT_EQ(0, c->Acquire(&fence));
-}
-
-TEST_F(LibBufferHubTest, TestWithNoMeta) {
-  std::unique_ptr<ProducerBuffer> p =
-      ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_EQ(0, p->GainAsync());
-
-  LocalHandle fence;
-
-  EXPECT_EQ(0, p->Post(LocalHandle()));
-  EXPECT_EQ(0, c->Acquire(&fence));
-}
-
-TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
-  std::unique_ptr<ProducerBuffer> p =
-      ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_EQ(0, p->GainAsync());
-
-  int64_t sequence = 3;
-  EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
-}
-
-namespace {
-
-int PollFd(int fd, int timeout_ms) {
-  pollfd p = {fd, POLLIN, 0};
-  return poll(&p, 1, timeout_ms);
-}
-
-}  // namespace
-
-TEST_F(LibBufferHubTest, TestAcquireFence) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_EQ(0, p->GainAsync());
-
-  DvrNativeBufferMetadata meta;
-  LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-
-  // Post with unsignaled fence.
-  EXPECT_EQ(0, p->PostAsync(&meta, f1));
-
-  // Should acquire a valid fence.
-  LocalHandle f2;
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
-  EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
-  EXPECT_TRUE(f2.IsValid());
-  // The original fence and acquired fence should have different fd number.
-  EXPECT_NE(f1.Get(), f2.Get());
-  EXPECT_GE(0, PollFd(f2.Get(), 0));
-
-  // Signal the original fence will trigger the new fence.
-  eventfd_write(f1.Get(), 1);
-  // Now the original FD has been signaled.
-  EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
-
-  // Release the consumer with an invalid fence.
-  EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
-
-  // Should gain an invalid fence.
-  LocalHandle f3;
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
-  EXPECT_EQ(0, p->GainAsync(&meta, &f3));
-  EXPECT_FALSE(f3.IsValid());
-
-  // Post with a signaled fence.
-  EXPECT_EQ(0, p->PostAsync(&meta, f1));
-
-  // Should acquire a valid fence and it's already signalled.
-  LocalHandle f4;
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
-  EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
-  EXPECT_TRUE(f4.IsValid());
-  EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
-
-  // Release with an unsignalled fence and signal it immediately after release
-  // without producer gainning.
-  LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-  EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
-  eventfd_write(f5.Get(), 1);
-
-  // Should gain a valid fence, which is already signaled.
-  LocalHandle f6;
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
-  EXPECT_EQ(0, p->GainAsync(&meta, &f6));
-  EXPECT_TRUE(f6.IsValid());
-  EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
-}
-
-TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c1 =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c1.get() != nullptr);
-  const uint32_t client_state_mask1 = c1->client_state_mask();
-
-  EXPECT_EQ(0, p->GainAsync());
-  DvrNativeBufferMetadata meta;
-  EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
-
-  LocalHandle fence;
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
-  EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence));
-
-  // Destroy the consumer who has acquired but not released the buffer.
-  c1 = nullptr;
-
-  // The buffer is now available for the producer to gain.
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
-
-  // Newly added consumer is not able to acquire the buffer.
-  std::unique_ptr<ConsumerBuffer> c2 =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c2.get() != nullptr);
-  const uint32_t client_state_mask2 = c2->client_state_mask();
-  EXPECT_NE(client_state_mask1, client_state_mask2);
-  EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
-  EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
-
-  // Producer should be able to gain.
-  EXPECT_EQ(0, p->GainAsync(&meta, &fence, false));
-}
-
-TEST_F(LibBufferHubTest, TestAcquireLastPosted) {
-  std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p.get() != nullptr);
-  std::unique_ptr<ConsumerBuffer> c1 =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c1.get() != nullptr);
-  const uint32_t client_state_mask1 = c1->client_state_mask();
-
-  EXPECT_EQ(0, p->GainAsync());
-  DvrNativeBufferMetadata meta;
-  EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
-
-  // c2 is created when the buffer is in posted state. buffer state for c1 is
-  // posted. Thus, c2 should be automatically set to posted and able to acquire.
-  std::unique_ptr<ConsumerBuffer> c2 =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c2.get() != nullptr);
-  const uint32_t client_state_mask2 = c2->client_state_mask();
-  EXPECT_NE(client_state_mask1, client_state_mask2);
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c2)));
-  LocalHandle invalid_fence;
-  EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence));
-
-  EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence));
-
-  // c3 is created when the buffer is in acquired state. buffer state for c1 and
-  // c2 are acquired. Thus, c3 should be automatically set to posted and able to
-  // acquire.
-  std::unique_ptr<ConsumerBuffer> c3 =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c3.get() != nullptr);
-  const uint32_t client_state_mask3 = c3->client_state_mask();
-  EXPECT_NE(client_state_mask1, client_state_mask3);
-  EXPECT_NE(client_state_mask2, client_state_mask3);
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c3)));
-  EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence));
-
-  // Releasing c2 and c3 in normal ways.
-  EXPECT_EQ(0, c2->Release(LocalHandle()));
-  EXPECT_EQ(0, c3->ReleaseAsync(&meta, LocalHandle()));
-
-  // Destroy the c1 who has not released the buffer.
-  c1 = nullptr;
-
-  // The buffer is now available for the producer to gain.
-  EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
-
-  // C4 is created in released state. Thus, it cannot gain the just posted
-  // buffer.
-  std::unique_ptr<ConsumerBuffer> c4 =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(c4.get() != nullptr);
-  const uint32_t client_state_mask4 = c4->client_state_mask();
-  EXPECT_NE(client_state_mask3, client_state_mask4);
-  EXPECT_GE(0, RETRY_EINTR(PollBufferEvent(c3)));
-  EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
-
-  // Producer should be able to gain.
-  EXPECT_EQ(0, p->GainAsync(&meta, &invalid_fence));
-}
-
-TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
-  // TODO(b/112338294) rewrite test after migration
-  return;
-
-  /* std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  std::unique_ptr<ConsumerBuffer> c =
-      ConsumerBuffer::Import(p->CreateConsumer());
-  ASSERT_TRUE(p.get() != nullptr);
-  ASSERT_TRUE(c.get() != nullptr);
-
-  DvrNativeBufferMetadata metadata;
-  LocalHandle invalid_fence;
-  int p_id = p->id();
-
-  // Detach in posted state should fail.
-  EXPECT_EQ(0, p->GainAsync());
-  EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_GT(RETRY_EINTR(PollBufferEvent(c)), 0);
-  auto s1 = p->Detach();
-  EXPECT_FALSE(s1);
-
-  // Detach in acquired state should fail.
-  EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
-  s1 = p->Detach();
-  EXPECT_FALSE(s1);
-
-  // Detach in released state should fail.
-  EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
-  EXPECT_GT(RETRY_EINTR(PollBufferEvent(p)), 0);
-  s1 = p->Detach();
-  EXPECT_FALSE(s1);
-
-  // Detach in gained state should succeed.
-  EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
-  s1 = p->Detach();
-  EXPECT_TRUE(s1);
-
-  LocalChannelHandle handle = s1.take();
-  EXPECT_TRUE(handle.valid());
-
-  // Both producer and consumer should have hangup.
-  EXPECT_GT(RETRY_EINTR(PollBufferEvent(p)), 0);
-  auto s2 = p->GetEventMask(POLLHUP);
-  EXPECT_TRUE(s2);
-  EXPECT_EQ(s2.get(), POLLHUP);
-
-  EXPECT_GT(RETRY_EINTR(PollBufferEvent(c)), 0);
-  s2 = p->GetEventMask(POLLHUP);
-  EXPECT_TRUE(s2);
-  EXPECT_EQ(s2.get(), POLLHUP);
-
-  auto s3 = p->CreateConsumer();
-  EXPECT_FALSE(s3);
-  // Note that here the expected error code is EOPNOTSUPP as the socket towards
-  // ProducerChannel has been teared down.
-  EXPECT_EQ(s3.error(), EOPNOTSUPP);
-
-  s3 = c->CreateConsumer();
-  EXPECT_FALSE(s3);
-  // Note that here the expected error code is EPIPE returned from
-  // ConsumerChannel::HandleMessage as the socket is still open but the producer
-  // is gone.
-  EXPECT_EQ(s3.error(), EPIPE);
-
-  // Detached buffer handle can be use to construct a new BufferHubBuffer
-  // object.
-  auto d = BufferHubBuffer::Import(std::move(handle));
-  EXPECT_FALSE(handle.valid());
-  EXPECT_TRUE(d->IsConnected());
-  EXPECT_TRUE(d->IsValid());
-
-  EXPECT_EQ(d->id(), p_id); */
-}
-
-TEST_F(LibBufferHubTest, TestDetach) {
-  // TODO(b/112338294) rewrite test after migration
-  return;
-
-  /* std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
-      kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
-  ASSERT_TRUE(p1.get() != nullptr);
-  int p1_id = p1->id();
-
-  // Detached the producer from gained state.
-  EXPECT_EQ(0, p1->GainAsync());
-  auto status_or_handle = p1->Detach();
-  EXPECT_TRUE(status_or_handle.ok());
-  LocalChannelHandle h1 = status_or_handle.take();
-  EXPECT_TRUE(h1.valid());
-
-  // Detached buffer handle can be use to construct a new BufferHubBuffer
-  // object.
-  auto b1 = BufferHubBuffer::Import(std::move(h1));
-  EXPECT_FALSE(h1.valid());
-  EXPECT_TRUE(b1->IsValid());
-  int b1_id = b1->id();
-  EXPECT_EQ(b1_id, p1_id); */
-}
diff --git a/libs/vr/libbufferhub/buffer_hub_base.cpp b/libs/vr/libbufferhub/buffer_hub_base.cpp
deleted file mode 100644
index 17930b4..0000000
--- a/libs/vr/libbufferhub/buffer_hub_base.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-#include <poll.h>
-#include <sys/epoll.h>
-
-#include <pdx/default_transport/client_channel.h>
-#include <pdx/default_transport/client_channel_factory.h>
-#include <private/dvr/buffer_hub_base.h>
-
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Status;
-using android::pdx::default_transport::ClientChannel;
-using android::pdx::default_transport::ClientChannelFactory;
-
-namespace android {
-namespace dvr {
-
-BufferHubBase::BufferHubBase(LocalChannelHandle channel_handle)
-    : Client{pdx::default_transport::ClientChannel::Create(
-          std::move(channel_handle))},
-      id_(-1),
-      cid_(-1) {}
-BufferHubBase::BufferHubBase(const std::string& endpoint_path)
-    : Client{pdx::default_transport::ClientChannelFactory::Create(
-          endpoint_path)},
-      id_(-1),
-      cid_(-1) {}
-
-BufferHubBase::~BufferHubBase() {
-  // buffer_state and fence_state are not reset here. They will be used to
-  // clean up epoll fd if necessary in ProducerChannel::RemoveConsumer method.
-  if (metadata_header_ != nullptr) {
-    metadata_buffer_.Unlock();
-  }
-}
-
-Status<LocalChannelHandle> BufferHubBase::CreateConsumer() {
-  Status<LocalChannelHandle> status =
-      InvokeRemoteMethod<BufferHubRPC::NewConsumer>();
-  ALOGE_IF(!status,
-           "BufferHub::CreateConsumer: Failed to create consumer channel: %s",
-           status.GetErrorMessage().c_str());
-  return status;
-}
-
-int BufferHubBase::ImportBuffer() {
-  ATRACE_NAME("BufferHubBase::ImportBuffer");
-
-  Status<BufferDescription<LocalHandle>> status =
-      InvokeRemoteMethod<BufferHubRPC::GetBuffer>();
-  if (!status) {
-    ALOGE("BufferHubBase::ImportBuffer: Failed to get buffer: %s",
-          status.GetErrorMessage().c_str());
-    return -status.error();
-  } else if (status.get().id() < 0) {
-    ALOGE("BufferHubBase::ImportBuffer: Received an invalid id!");
-    return -EIO;
-  }
-
-  auto buffer_desc = status.take();
-
-  // Stash the buffer id to replace the value in id_.
-  const int new_id = buffer_desc.id();
-
-  // Import the buffer.
-  IonBuffer ion_buffer;
-  ALOGD_IF(TRACE, "BufferHubBase::ImportBuffer: id=%d.", buffer_desc.id());
-
-  if (const int ret = buffer_desc.ImportBuffer(&ion_buffer))
-    return ret;
-
-  // Import the metadata.
-  IonBuffer metadata_buffer;
-  if (const int ret = buffer_desc.ImportMetadata(&metadata_buffer)) {
-    ALOGE("Failed to import metadata buffer, error=%d", ret);
-    return ret;
-  }
-  size_t metadata_buf_size = metadata_buffer.width();
-  if (metadata_buf_size < BufferHubDefs::kMetadataHeaderSize) {
-    ALOGE("BufferHubBase::ImportBuffer: metadata buffer too small: %zu",
-          metadata_buf_size);
-    return -ENOMEM;
-  }
-
-  // If all imports succee, replace the previous buffer and id.
-  buffer_ = std::move(ion_buffer);
-  metadata_buffer_ = std::move(metadata_buffer);
-  metadata_buf_size_ = metadata_buf_size;
-  user_metadata_size_ = metadata_buf_size_ - BufferHubDefs::kMetadataHeaderSize;
-
-  void* metadata_ptr = nullptr;
-  if (const int ret =
-          metadata_buffer_.Lock(BufferHubDefs::kMetadataUsage, /*x=*/0,
-                                /*y=*/0, metadata_buf_size_,
-                                /*height=*/1, &metadata_ptr)) {
-    ALOGE("BufferHubBase::ImportBuffer: Failed to lock metadata.");
-    return ret;
-  }
-
-  // Set up shared fences.
-  shared_acquire_fence_ = buffer_desc.take_acquire_fence();
-  shared_release_fence_ = buffer_desc.take_release_fence();
-  if (!shared_acquire_fence_ || !shared_release_fence_) {
-    ALOGE("BufferHubBase::ImportBuffer: Failed to import shared fences.");
-    return -EIO;
-  }
-
-  metadata_header_ =
-      reinterpret_cast<BufferHubDefs::MetadataHeader*>(metadata_ptr);
-  if (user_metadata_size_) {
-    user_metadata_ptr_ =
-        reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(metadata_ptr) +
-                                BufferHubDefs::kMetadataHeaderSize);
-  } else {
-    user_metadata_ptr_ = nullptr;
-  }
-
-  id_ = new_id;
-  cid_ = buffer_desc.buffer_cid();
-  client_state_mask_ = buffer_desc.client_state_mask();
-
-  // Note that here the buffer_state, fence_state and active_clients_bit_mask
-  // are mapped from shared memory as an atomic object. The std::atomic's
-  // constructor will not be called so that the original value stored in the
-  // memory region will be preserved.
-  buffer_state_ = &metadata_header_->bufferState;
-  ALOGD_IF(TRACE,
-           "BufferHubBase::ImportBuffer: id=%d, buffer_state=%" PRIx32 ".",
-           id(), buffer_state_->load(std::memory_order_acquire));
-  fence_state_ = &metadata_header_->fenceState;
-  ALOGD_IF(TRACE,
-           "BufferHubBase::ImportBuffer: id=%d, fence_state=%" PRIx32 ".", id(),
-           fence_state_->load(std::memory_order_acquire));
-  active_clients_bit_mask_ = &metadata_header_->activeClientsBitMask;
-  ALOGD_IF(
-      TRACE,
-      "BufferHubBase::ImportBuffer: id=%d, active_clients_bit_mask=%" PRIx32
-      ".",
-      id(), active_clients_bit_mask_->load(std::memory_order_acquire));
-
-  return 0;
-}
-
-int BufferHubBase::CheckMetadata(size_t user_metadata_size) const {
-  if (user_metadata_size && !user_metadata_ptr_) {
-    ALOGE("BufferHubBase::CheckMetadata: doesn't support custom metadata.");
-    return -EINVAL;
-  }
-  if (user_metadata_size > user_metadata_size_) {
-    ALOGE("BufferHubBase::CheckMetadata: too big: %zu, maximum: %zu.",
-          user_metadata_size, user_metadata_size_);
-    return -E2BIG;
-  }
-  return 0;
-}
-
-int BufferHubBase::UpdateSharedFence(const LocalHandle& new_fence,
-                                     const LocalHandle& shared_fence) {
-  if (pending_fence_fd_.Get() != new_fence.Get()) {
-    // First, replace the old fd if there was already one. Skipping if the new
-    // one is the same as the old.
-    if (pending_fence_fd_.IsValid()) {
-      const int ret = epoll_ctl(shared_fence.Get(), EPOLL_CTL_DEL,
-                                pending_fence_fd_.Get(), nullptr);
-      ALOGW_IF(ret,
-               "BufferHubBase::UpdateSharedFence: failed to remove old fence "
-               "fd from epoll set, error: %s.",
-               strerror(errno));
-    }
-
-    if (new_fence.IsValid()) {
-      // If ready fence is valid, we put that into the epoll set.
-      epoll_event event;
-      event.events = EPOLLIN;
-      event.data.u32 = client_state_mask();
-      pending_fence_fd_ = new_fence.Duplicate();
-      if (epoll_ctl(shared_fence.Get(), EPOLL_CTL_ADD, pending_fence_fd_.Get(),
-                    &event) < 0) {
-        const int error = errno;
-        ALOGE(
-            "BufferHubBase::UpdateSharedFence: failed to add new fence fd "
-            "into epoll set, error: %s.",
-            strerror(error));
-        return -error;
-      }
-      // Set bit in fence state to indicate that there is a fence from this
-      // producer or consumer.
-      fence_state_->fetch_or(client_state_mask());
-    } else {
-      // Unset bit in fence state to indicate that there is no fence, so that
-      // when consumer to acquire or producer to acquire, it knows no need to
-      // check fence for this buffer.
-      fence_state_->fetch_and(~client_state_mask());
-    }
-  }
-
-  return 0;
-}
-
-int BufferHubBase::Lock(int usage, int x, int y, int width, int height,
-                        void** address) {
-  return buffer_.Lock(usage, x, y, width, height, address);
-}
-
-int BufferHubBase::Unlock() { return buffer_.Unlock(); }
-
-int BufferHubBase::GetBlobReadWritePointer(size_t size, void** addr) {
-  int width = static_cast<int>(size);
-  int height = 1;
-  int ret = Lock(usage(), 0, 0, width, height, addr);
-  if (ret == 0)
-    Unlock();
-  return ret;
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libbufferhub/buffer_hub_rpc.cpp b/libs/vr/libbufferhub/buffer_hub_rpc.cpp
deleted file mode 100644
index 9a67faa..0000000
--- a/libs/vr/libbufferhub/buffer_hub_rpc.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "include/private/dvr/bufferhub_rpc.h"
-
-namespace android {
-namespace dvr {
-
-constexpr char BufferHubRPC::kClientPath[];
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libbufferhub/consumer_buffer.cpp b/libs/vr/libbufferhub/consumer_buffer.cpp
deleted file mode 100644
index 7823e36..0000000
--- a/libs/vr/libbufferhub/consumer_buffer.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-#include <private/dvr/consumer_buffer.h>
-
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Status;
-
-namespace android {
-namespace dvr {
-
-ConsumerBuffer::ConsumerBuffer(LocalChannelHandle channel)
-    : BASE(std::move(channel)) {
-  const int ret = ImportBuffer();
-  if (ret < 0) {
-    ALOGE("ConsumerBuffer::ConsumerBuffer: Failed to import buffer: %s",
-          strerror(-ret));
-    Close(ret);
-  }
-}
-
-std::unique_ptr<ConsumerBuffer> ConsumerBuffer::Import(
-    LocalChannelHandle channel) {
-  ATRACE_NAME("ConsumerBuffer::Import");
-  ALOGD_IF(TRACE, "ConsumerBuffer::Import: channel=%d", channel.value());
-  return ConsumerBuffer::Create(std::move(channel));
-}
-
-std::unique_ptr<ConsumerBuffer> ConsumerBuffer::Import(
-    Status<LocalChannelHandle> status) {
-  return Import(status ? status.take()
-                       : LocalChannelHandle{nullptr, -status.error()});
-}
-
-int ConsumerBuffer::LocalAcquire(DvrNativeBufferMetadata* out_meta,
-                                 LocalHandle* out_fence) {
-  if (!out_meta)
-    return -EINVAL;
-
-  // The buffer can be acquired iff the buffer state for this client is posted.
-  uint32_t current_buffer_state =
-      buffer_state_->load(std::memory_order_acquire);
-  if (!BufferHubDefs::isClientPosted(current_buffer_state,
-                                     client_state_mask())) {
-    ALOGE(
-        "%s: Failed to acquire the buffer. The buffer is not posted, id=%d "
-        "state=%" PRIx32 " client_state_mask=%" PRIx32 ".",
-        __FUNCTION__, id(), current_buffer_state, client_state_mask());
-    return -EBUSY;
-  }
-
-  // Change the buffer state for this consumer from posted to acquired.
-  uint32_t updated_buffer_state = current_buffer_state ^ client_state_mask();
-  while (!buffer_state_->compare_exchange_weak(
-      current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
-      std::memory_order_acquire)) {
-    if (!BufferHubDefs::isClientPosted(current_buffer_state,
-                                       client_state_mask())) {
-      ALOGE(
-          "%s: Failed to acquire the buffer. The buffer is no longer posted, "
-          "id=%d state=%" PRIx32 " client_state_mask=%" PRIx32 ".",
-          __FUNCTION__, id(), current_buffer_state, client_state_mask());
-      return -EBUSY;
-    }
-    // The failure of compare_exchange_weak updates current_buffer_state.
-    updated_buffer_state = current_buffer_state ^ client_state_mask();
-  }
-
-  // Copy the canonical metadata.
-  void* metadata_ptr = reinterpret_cast<void*>(&metadata_header_->metadata);
-  memcpy(out_meta, metadata_ptr, sizeof(DvrNativeBufferMetadata));
-  // Fill in the user_metadata_ptr in address space of the local process.
-  if (out_meta->user_metadata_size) {
-    out_meta->user_metadata_ptr =
-        reinterpret_cast<uint64_t>(user_metadata_ptr_);
-  } else {
-    out_meta->user_metadata_ptr = 0;
-  }
-
-  uint32_t fence_state = fence_state_->load(std::memory_order_acquire);
-  // If there is an acquire fence from producer, we need to return it.
-  // The producer state bit mask is kFirstClientBitMask for now.
-  if (fence_state & BufferHubDefs::kFirstClientBitMask) {
-    *out_fence = shared_acquire_fence_.Duplicate();
-  }
-
-  return 0;
-}
-
-int ConsumerBuffer::Acquire(LocalHandle* ready_fence) {
-  return Acquire(ready_fence, nullptr, 0);
-}
-
-int ConsumerBuffer::Acquire(LocalHandle* ready_fence, void* meta,
-                            size_t user_metadata_size) {
-  ATRACE_NAME("ConsumerBuffer::Acquire");
-
-  if (const int error = CheckMetadata(user_metadata_size))
-    return error;
-
-  DvrNativeBufferMetadata canonical_meta;
-  if (const int error = LocalAcquire(&canonical_meta, ready_fence))
-    return error;
-
-  if (meta && user_metadata_size) {
-    void* metadata_src =
-        reinterpret_cast<void*>(canonical_meta.user_metadata_ptr);
-    if (metadata_src) {
-      memcpy(meta, metadata_src, user_metadata_size);
-    } else {
-      ALOGW("ConsumerBuffer::Acquire: no user-defined metadata.");
-    }
-  }
-
-  auto status = InvokeRemoteMethod<BufferHubRPC::ConsumerAcquire>();
-  if (!status)
-    return -status.error();
-  return 0;
-}
-
-int ConsumerBuffer::AcquireAsync(DvrNativeBufferMetadata* out_meta,
-                                 LocalHandle* out_fence) {
-  ATRACE_NAME("ConsumerBuffer::AcquireAsync");
-
-  if (const int error = LocalAcquire(out_meta, out_fence))
-    return error;
-
-  auto status = SendImpulse(BufferHubRPC::ConsumerAcquire::Opcode);
-  if (!status)
-    return -status.error();
-  return 0;
-}
-
-int ConsumerBuffer::LocalRelease(const DvrNativeBufferMetadata* meta,
-                                 const LocalHandle& release_fence) {
-  if (const int error = CheckMetadata(meta->user_metadata_size))
-    return error;
-
-  // Set the buffer state of this client to released if it is not already in
-  // released state.
-  uint32_t current_buffer_state =
-      buffer_state_->load(std::memory_order_acquire);
-  if (BufferHubDefs::isClientReleased(current_buffer_state,
-                                      client_state_mask())) {
-    return 0;
-  }
-  uint32_t updated_buffer_state = current_buffer_state & (~client_state_mask());
-  while (!buffer_state_->compare_exchange_weak(
-      current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
-      std::memory_order_acquire)) {
-    // The failure of compare_exchange_weak updates current_buffer_state.
-    updated_buffer_state = current_buffer_state & (~client_state_mask());
-  }
-
-  // On release, only the user requested metadata is copied back into the shared
-  // memory for metadata. Since there are multiple consumers, it doesn't make
-  // sense to send the canonical metadata back to the producer. However, one of
-  // the consumer can still choose to write up to user_metadata_size bytes of
-  // data into user_metadata_ptr.
-  if (meta->user_metadata_ptr && meta->user_metadata_size) {
-    void* metadata_src = reinterpret_cast<void*>(meta->user_metadata_ptr);
-    memcpy(user_metadata_ptr_, metadata_src, meta->user_metadata_size);
-  }
-
-  // Send out the release fence through the shared epoll fd. Note that during
-  // releasing the producer is not expected to be polling on the fence.
-  if (const int error = UpdateSharedFence(release_fence, shared_release_fence_))
-    return error;
-
-  return 0;
-}
-
-int ConsumerBuffer::Release(const LocalHandle& release_fence) {
-  ATRACE_NAME("ConsumerBuffer::Release");
-
-  DvrNativeBufferMetadata meta;
-  if (const int error = LocalRelease(&meta, release_fence))
-    return error;
-
-  return ReturnStatusOrError(InvokeRemoteMethod<BufferHubRPC::ConsumerRelease>(
-      BorrowedFence(release_fence.Borrow())));
-}
-
-int ConsumerBuffer::ReleaseAsync() {
-  DvrNativeBufferMetadata meta;
-  return ReleaseAsync(&meta, LocalHandle());
-}
-
-int ConsumerBuffer::ReleaseAsync(const DvrNativeBufferMetadata* meta,
-                                 const LocalHandle& release_fence) {
-  ATRACE_NAME("ConsumerBuffer::ReleaseAsync");
-
-  if (const int error = LocalRelease(meta, release_fence))
-    return error;
-
-  return ReturnStatusOrError(
-      SendImpulse(BufferHubRPC::ConsumerRelease::Opcode));
-}
-
-int ConsumerBuffer::Discard() { return Release(LocalHandle()); }
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
deleted file mode 100644
index 8a490d9..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
+++ /dev/null
@@ -1,169 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_HUB_BASE_H_
-#define ANDROID_DVR_BUFFER_HUB_BASE_H_
-
-#include <vector>
-
-#include <private/dvr/bufferhub_rpc.h>
-
-namespace android {
-namespace dvr {
-
-// Base class of two types of BufferHub clients: dvr::ProducerBuffer and
-// dvr::ConsumerBuffer.
-class BufferHubBase : public pdx::Client {
- public:
-  using LocalHandle = pdx::LocalHandle;
-  using LocalChannelHandle = pdx::LocalChannelHandle;
-  template <typename T>
-  using Status = pdx::Status<T>;
-
-  // Create a new consumer channel that is attached to the producer. Returns
-  // a file descriptor for the new channel or a negative error code.
-  Status<LocalChannelHandle> CreateConsumer();
-
-  // Gets a blob buffer that was created with ProducerBuffer::CreateBlob.
-  // Locking and Unlocking is handled internally. There's no need to Unlock
-  // after calling this method.
-  int GetBlobReadWritePointer(size_t size, void** addr);
-
-  // Returns a dup'd file descriptor for accessing the blob shared memory. The
-  // caller takes ownership of the file descriptor and must close it or pass on
-  // ownership. Some GPU API extensions can take file descriptors to bind shared
-  // memory gralloc buffers to GPU buffer objects.
-  LocalHandle GetBlobFd() const {
-    // Current GPU vendor puts the buffer allocation in one FD. If we change GPU
-    // vendors and this is the wrong fd, late-latching and EDS will very clearly
-    // stop working and we will need to correct this. The alternative is to use
-    // a GL context in the pose service to allocate this buffer or to use the
-    // ION API directly instead of gralloc.
-    return LocalHandle(dup(native_handle()->data[0]));
-  }
-
-  using Client::event_fd;
-
-  Status<int> GetEventMask(int events) {
-    if (auto* client_channel = GetChannel()) {
-      return client_channel->GetEventMask(events);
-    } else {
-      return pdx::ErrorStatus(EINVAL);
-    }
-  }
-
-  std::vector<pdx::ClientChannel::EventSource> GetEventSources() const {
-    if (auto* client_channel = GetChannel()) {
-      return client_channel->GetEventSources();
-    } else {
-      return {};
-    }
-  }
-
-  native_handle_t* native_handle() const {
-    return const_cast<native_handle_t*>(buffer_.handle());
-  }
-
-  IonBuffer* buffer() { return &buffer_; }
-  const IonBuffer* buffer() const { return &buffer_; }
-
-  // Gets ID of the buffer client. All BufferHub clients derived from the same
-  // buffer in bufferhubd share the same buffer id.
-  int id() const { return id_; }
-
-  // Gets the channel id of the buffer client. Each BufferHub client has its
-  // system unique channel id.
-  int cid() const { return cid_; }
-
-  // Returns the buffer buffer state.
-  uint32_t buffer_state() {
-    return buffer_state_->load(std::memory_order_acquire);
-  };
-
-  // Returns whether the buffer is already released by all current clients.
-  bool is_released() {
-    return (buffer_state() &
-            active_clients_bit_mask_->load(std::memory_order_acquire)) == 0;
-  }
-
-  // A state mask which is unique to a buffer hub client among all its siblings
-  // sharing the same concrete graphic buffer.
-  uint32_t client_state_mask() const { return client_state_mask_; }
-
-  // The following methods return settings of the first buffer. Currently,
-  // it is only possible to create multi-buffer BufferHubBases with the same
-  // settings.
-  uint32_t width() const { return buffer_.width(); }
-  uint32_t height() const { return buffer_.height(); }
-  uint32_t stride() const { return buffer_.stride(); }
-  uint32_t format() const { return buffer_.format(); }
-  uint32_t usage() const { return buffer_.usage(); }
-  uint32_t layer_count() const { return buffer_.layer_count(); }
-
-  uint64_t GetQueueIndex() const { return metadata_header_->queueIndex; }
-  void SetQueueIndex(uint64_t index) { metadata_header_->queueIndex = index; }
-
- protected:
-  explicit BufferHubBase(LocalChannelHandle channel);
-  explicit BufferHubBase(const std::string& endpoint_path);
-  virtual ~BufferHubBase();
-
-  // Initialization helper.
-  int ImportBuffer();
-
-  // Check invalid metadata operation. Returns 0 if requested metadata is valid.
-  int CheckMetadata(size_t user_metadata_size) const;
-
-  // Send out the new fence by updating the shared fence (shared_release_fence
-  // for producer and shared_acquire_fence for consumer). Note that during this
-  // should only be used in LocalPost() or LocalRelease, and the shared fence
-  // shouldn't be poll'ed by the other end.
-  int UpdateSharedFence(const LocalHandle& new_fence,
-                        const LocalHandle& shared_fence);
-
-  // Locks the area specified by (x, y, width, height) for a specific usage. If
-  // the usage is software then |addr| will be updated to point to the address
-  // of the buffer in virtual memory. The caller should only access/modify the
-  // pixels in the specified area. anything else is undefined behavior.
-  int Lock(int usage, int x, int y, int width, int height, void** addr);
-
-  // Must be called after Lock() when the caller has finished changing the
-  // buffer.
-  int Unlock();
-
-  // IonBuffer that is shared between bufferhubd, producer, and consumers.
-  size_t metadata_buf_size_{0};
-  size_t user_metadata_size_{0};
-  BufferHubDefs::MetadataHeader* metadata_header_ = nullptr;
-  void* user_metadata_ptr_ = nullptr;
-  std::atomic<uint32_t>* buffer_state_ = nullptr;
-  std::atomic<uint32_t>* fence_state_ = nullptr;
-  std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
-
-  LocalHandle shared_acquire_fence_;
-  LocalHandle shared_release_fence_;
-
-  // A local fence fd that holds the ownership of the fence fd on Post (for
-  // producer) and Release (for consumer).
-  LocalHandle pending_fence_fd_;
-
- private:
-  BufferHubBase(const BufferHubBase&) = delete;
-  void operator=(const BufferHubBase&) = delete;
-
-  // Global id for the buffer that is consistent across processes. It is meant
-  // for logging and debugging purposes only and should not be used for lookup
-  // or any other functional purpose as a security precaution.
-  int id_;
-
-  // Channel id.
-  int cid_;
-
-  // Client bit mask which indicates the locations of this client object in the
-  // buffer_state_.
-  uint32_t client_state_mask_{0U};
-  IonBuffer buffer_;
-  IonBuffer metadata_buffer_;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_BUFFER_HUB_BASE_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
deleted file mode 100644
index e610e18..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
+++ /dev/null
@@ -1,164 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_HUB_DEFS_H_
-#define ANDROID_DVR_BUFFER_HUB_DEFS_H_
-
-#include <dvr/dvr_api.h>
-#include <hardware/gralloc.h>
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/rpc/serializable.h>
-#include <private/dvr/native_handle_wrapper.h>
-#include <ui/BufferHubDefs.h>
-
-namespace android {
-namespace dvr {
-
-namespace BufferHubDefs {
-
-static constexpr uint32_t kMetadataFormat = HAL_PIXEL_FORMAT_BLOB;
-static constexpr uint32_t kMetadataUsage =
-    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
-
-// See more details in libs/ui/include/ui/BufferHubDefs.h
-static constexpr int kMaxNumberOfClients =
-    android::BufferHubDefs::kMaxNumberOfClients;
-static constexpr uint32_t kLowbitsMask = android::BufferHubDefs::kLowbitsMask;
-static constexpr uint32_t kHighBitsMask = android::BufferHubDefs::kHighBitsMask;
-static constexpr uint32_t kFirstClientBitMask =
-    android::BufferHubDefs::kFirstClientBitMask;
-
-static inline bool isAnyClientGained(uint32_t state) {
-  return android::BufferHubDefs::isAnyClientGained(state);
-}
-
-static inline bool isClientGained(uint32_t state, uint32_t client_bit_mask) {
-  return android::BufferHubDefs::isClientGained(state, client_bit_mask);
-}
-
-static inline bool isAnyClientPosted(uint32_t state) {
-  return android::BufferHubDefs::isAnyClientPosted(state);
-}
-
-static inline bool isClientPosted(uint32_t state, uint32_t client_bit_mask) {
-  return android::BufferHubDefs::isClientPosted(state, client_bit_mask);
-}
-
-static inline bool isAnyClientAcquired(uint32_t state) {
-  return android::BufferHubDefs::isAnyClientAcquired(state);
-}
-
-static inline bool isClientAcquired(uint32_t state, uint32_t client_bit_mask) {
-  return android::BufferHubDefs::isClientAcquired(state, client_bit_mask);
-}
-
-static inline bool isClientReleased(uint32_t state, uint32_t client_bit_mask) {
-  return android::BufferHubDefs::isClientReleased(state, client_bit_mask);
-}
-
-// Returns the next available buffer client's client_state_masks.
-// @params union_bits. Union of all existing clients' client_state_masks.
-static inline uint32_t findNextAvailableClientStateMask(uint32_t union_bits) {
-  return android::BufferHubDefs::findNextAvailableClientStateMask(union_bits);
-}
-
-using MetadataHeader = android::BufferHubDefs::MetadataHeader;
-static constexpr size_t kMetadataHeaderSize =
-    android::BufferHubDefs::kMetadataHeaderSize;
-
-}  // namespace BufferHubDefs
-
-template <typename FileHandleType>
-class BufferTraits {
- public:
-  BufferTraits() = default;
-  BufferTraits(const native_handle_t* buffer_handle,
-               const FileHandleType& metadata_handle, int id,
-               uint32_t client_state_mask, uint64_t metadata_size,
-               uint32_t width, uint32_t height, uint32_t layer_count,
-               uint32_t format, uint64_t usage, uint32_t stride,
-               const FileHandleType& acquire_fence_fd,
-               const FileHandleType& release_fence_fd)
-      : id_(id),
-        client_state_mask_(client_state_mask),
-        metadata_size_(metadata_size),
-        width_(width),
-        height_(height),
-        layer_count_(layer_count),
-        format_(format),
-        usage_(usage),
-        stride_(stride),
-        buffer_handle_(buffer_handle),
-        metadata_handle_(metadata_handle.Borrow()),
-        acquire_fence_fd_(acquire_fence_fd.Borrow()),
-        release_fence_fd_(release_fence_fd.Borrow()) {}
-
-  BufferTraits(BufferTraits&& other) = default;
-  BufferTraits& operator=(BufferTraits&& other) = default;
-
-  // ID of the buffer client. All BufferHubBuffer clients derived from the same
-  // buffer in bufferhubd share the same buffer id.
-  int id() const { return id_; }
-
-  // State mask of the buffer client. Each BufferHubBuffer client backed by the
-  // same buffer channel has uniqued state bit among its siblings. For a
-  // producer buffer the bit must be kFirstClientBitMask; for a consumer the bit
-  // must be one of the kConsumerStateMask.
-  uint32_t client_state_mask() const { return client_state_mask_; }
-  uint64_t metadata_size() const { return metadata_size_; }
-
-  uint32_t width() { return width_; }
-  uint32_t height() { return height_; }
-  uint32_t layer_count() { return layer_count_; }
-  uint32_t format() { return format_; }
-  uint64_t usage() { return usage_; }
-  uint32_t stride() { return stride_; }
-
-  const NativeHandleWrapper<FileHandleType>& buffer_handle() const {
-    return buffer_handle_;
-  }
-
-  NativeHandleWrapper<FileHandleType> take_buffer_handle() {
-    return std::move(buffer_handle_);
-  }
-  FileHandleType take_metadata_handle() { return std::move(metadata_handle_); }
-  FileHandleType take_acquire_fence() { return std::move(acquire_fence_fd_); }
-  FileHandleType take_release_fence() { return std::move(release_fence_fd_); }
-
- private:
-  // BufferHub specific traits.
-  int id_ = -1;
-  uint32_t client_state_mask_;
-  uint64_t metadata_size_;
-
-  // Traits for a GraphicBuffer.
-  uint32_t width_;
-  uint32_t height_;
-  uint32_t layer_count_;
-  uint32_t format_;
-  uint64_t usage_;
-  uint32_t stride_;
-
-  // Native handle for the graphic buffer.
-  NativeHandleWrapper<FileHandleType> buffer_handle_;
-
-  // File handle of an ashmem that holds buffer metadata.
-  FileHandleType metadata_handle_;
-
-  // Pamameters for shared fences.
-  FileHandleType acquire_fence_fd_;
-  FileHandleType release_fence_fd_;
-
-  PDX_SERIALIZABLE_MEMBERS(BufferTraits<FileHandleType>, id_,
-                           client_state_mask_, metadata_size_, stride_, width_,
-                           height_, layer_count_, format_, usage_,
-                           buffer_handle_, metadata_handle_, acquire_fence_fd_,
-                           release_fence_fd_);
-
-  BufferTraits(const BufferTraits&) = delete;
-  void operator=(const BufferTraits&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_BUFFER_HUB_DEFS_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
deleted file mode 100644
index f1cd0b4..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
+++ /dev/null
@@ -1,377 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUB_RPC_H_
-#define ANDROID_DVR_BUFFERHUB_RPC_H_
-
-#include "buffer_hub_defs.h"
-
-#include <cutils/native_handle.h>
-#include <ui/BufferQueueDefs.h>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/rpc/serializable.h>
-#include <private/dvr/ion_buffer.h>
-
-namespace android {
-namespace dvr {
-
-template <typename FileHandleType>
-class NativeBufferHandle {
- public:
-  NativeBufferHandle() { Clear(); }
-  NativeBufferHandle(const IonBuffer& buffer, int id)
-      : id_(id),
-        stride_(buffer.stride()),
-        width_(buffer.width()),
-        height_(buffer.height()),
-        layer_count_(buffer.layer_count()),
-        format_(buffer.format()),
-        usage_(buffer.usage()) {
-    // Populate the fd and int vectors: native_handle->data[] is an array of fds
-    // followed by an array of opaque ints.
-    const int fd_count = buffer.handle()->numFds;
-    const int int_count = buffer.handle()->numInts;
-    for (int i = 0; i < fd_count; i++) {
-      fds_.emplace_back(FileHandleType::AsDuplicate(buffer.handle()->data[i]));
-    }
-    for (int i = 0; i < int_count; i++) {
-      opaque_ints_.push_back(buffer.handle()->data[fd_count + i]);
-    }
-  }
-  NativeBufferHandle(NativeBufferHandle&& other) noexcept = default;
-  NativeBufferHandle& operator=(NativeBufferHandle&& other) noexcept = default;
-
-  // Imports the native handle into the given IonBuffer instance.
-  int Import(IonBuffer* buffer) {
-    // This is annoying, but we need to convert the vector of FileHandles into a
-    // vector of ints for the Import API.
-    std::vector<int> fd_ints;
-    for (const auto& fd : fds_)
-      fd_ints.push_back(fd.Get());
-
-    const int ret =
-        buffer->Import(fd_ints.data(), fd_ints.size(), opaque_ints_.data(),
-                       opaque_ints_.size(), width_, height_, layer_count_,
-                       stride_, format_, usage_);
-    if (ret < 0)
-      return ret;
-
-    // Import succeeded, release the file handles which are now owned by the
-    // IonBuffer and clear members.
-    for (auto& fd : fds_)
-      fd.Release();
-    opaque_ints_.clear();
-    Clear();
-
-    return 0;
-  }
-
-  int id() const { return id_; }
-  size_t IntCount() const { return opaque_ints_.size(); }
-  size_t FdCount() const { return fds_.size(); }
-
- private:
-  int id_;
-  uint32_t stride_;
-  uint32_t width_;
-  uint32_t height_;
-  uint32_t layer_count_;
-  uint32_t format_;
-  uint64_t usage_;
-  std::vector<int> opaque_ints_;
-  std::vector<FileHandleType> fds_;
-
-  void Clear() {
-    id_ = -1;
-    stride_ = width_ = height_ = format_ = usage_ = 0;
-  }
-
-  PDX_SERIALIZABLE_MEMBERS(NativeBufferHandle<FileHandleType>, id_, stride_,
-                           width_, height_, layer_count_, format_, usage_,
-                           opaque_ints_, fds_);
-
-  NativeBufferHandle(const NativeBufferHandle&) = delete;
-  void operator=(const NativeBufferHandle&) = delete;
-};
-
-template <typename FileHandleType>
-class BufferDescription {
- public:
-  BufferDescription() = default;
-  BufferDescription(const IonBuffer& buffer, const IonBuffer& metadata, int id,
-                    int buffer_cid, uint32_t client_state_mask,
-                    const FileHandleType& acquire_fence_fd,
-                    const FileHandleType& release_fence_fd)
-      : id_(id),
-        buffer_cid_(buffer_cid),
-        client_state_mask_(client_state_mask),
-        buffer_(buffer, id),
-        metadata_(metadata, id),
-        acquire_fence_fd_(acquire_fence_fd.Borrow()),
-        release_fence_fd_(release_fence_fd.Borrow()) {}
-
-  BufferDescription(BufferDescription&& other) noexcept = default;
-  BufferDescription& operator=(BufferDescription&& other) noexcept = default;
-
-  // ID of the buffer client. All BufferHub clients derived from the same buffer
-  // in bufferhubd share the same buffer id.
-  int id() const { return id_; }
-
-  // Channel ID of the buffer client. Each BufferHub client has its system
-  // unique channel id.
-  int buffer_cid() const { return buffer_cid_; }
-
-  // State mask of the buffer client. Each BufferHub client backed by the
-  // same buffer channel has uniqued state bit among its siblings.
-  uint32_t client_state_mask() const { return client_state_mask_; }
-  FileHandleType take_acquire_fence() { return std::move(acquire_fence_fd_); }
-  FileHandleType take_release_fence() { return std::move(release_fence_fd_); }
-
-  int ImportBuffer(IonBuffer* buffer) { return buffer_.Import(buffer); }
-  int ImportMetadata(IonBuffer* metadata) { return metadata_.Import(metadata); }
-
- private:
-  int id_{-1};
-  int buffer_cid_{-1};
-  uint32_t client_state_mask_{0U};
-  // Two IonBuffers: one for the graphic buffer and one for metadata.
-  NativeBufferHandle<FileHandleType> buffer_;
-  NativeBufferHandle<FileHandleType> metadata_;
-
-  // Pamameters for shared fences.
-  FileHandleType acquire_fence_fd_;
-  FileHandleType release_fence_fd_;
-
-  PDX_SERIALIZABLE_MEMBERS(BufferDescription<FileHandleType>, id_, buffer_cid_,
-                           client_state_mask_, buffer_, metadata_,
-                           acquire_fence_fd_, release_fence_fd_);
-
-  BufferDescription(const BufferDescription&) = delete;
-  void operator=(const BufferDescription&) = delete;
-};
-
-using BorrowedNativeBufferHandle = NativeBufferHandle<pdx::BorrowedHandle>;
-using LocalNativeBufferHandle = NativeBufferHandle<pdx::LocalHandle>;
-
-template <typename FileHandleType>
-class FenceHandle {
- public:
-  FenceHandle() = default;
-  explicit FenceHandle(int fence) : fence_{fence} {}
-  explicit FenceHandle(FileHandleType&& fence) : fence_{std::move(fence)} {}
-  FenceHandle(FenceHandle&&) noexcept = default;
-  FenceHandle& operator=(FenceHandle&&) noexcept = default;
-
-  explicit operator bool() const { return fence_.IsValid(); }
-
-  const FileHandleType& get() const { fence_; }
-  FileHandleType&& take() { return std::move(fence_); }
-
-  int get_fd() const { return fence_.Get(); }
-  void close() { fence_.Close(); }
-
-  FenceHandle<pdx::BorrowedHandle> borrow() const {
-    return FenceHandle<pdx::BorrowedHandle>(fence_.Borrow());
-  }
-
- private:
-  FileHandleType fence_;
-
-  PDX_SERIALIZABLE_MEMBERS(FenceHandle<FileHandleType>, fence_);
-
-  FenceHandle(const FenceHandle&) = delete;
-  void operator=(const FenceHandle&) = delete;
-};
-
-using LocalFence = FenceHandle<pdx::LocalHandle>;
-using BorrowedFence = FenceHandle<pdx::BorrowedHandle>;
-
-struct ProducerQueueConfig {
-  // Whether the buffer queue is operating in Async mode.
-  // From GVR's perspective of view, this means a buffer can be acquired
-  // asynchronously by the compositor.
-  // From Android Surface's perspective of view, this is equivalent to
-  // IGraphicBufferProducer's async mode. When in async mode, a producer
-  // will never block even if consumer is running slow.
-  bool is_async;
-
-  // Default buffer width that is set during ProducerQueue's creation.
-  uint32_t default_width;
-
-  // Default buffer height that is set during ProducerQueue's creation.
-  uint32_t default_height;
-
-  // Default buffer format that is set during ProducerQueue's creation.
-  uint32_t default_format;
-
-  // Size of the meta data associated with all the buffers allocated from the
-  // queue.
-  size_t user_metadata_size;
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(ProducerQueueConfig, is_async, default_width,
-                           default_height, default_format, user_metadata_size);
-};
-
-class ProducerQueueConfigBuilder {
- public:
-  // Build a ProducerQueueConfig object.
-  ProducerQueueConfig Build() {
-    return {is_async_, default_width_, default_height_, default_format_,
-            user_metadata_size_};
-  }
-
-  ProducerQueueConfigBuilder& SetIsAsync(bool is_async) {
-    is_async_ = is_async;
-    return *this;
-  }
-
-  ProducerQueueConfigBuilder& SetDefaultWidth(uint32_t width) {
-    default_width_ = width;
-    return *this;
-  }
-
-  ProducerQueueConfigBuilder& SetDefaultHeight(uint32_t height) {
-    default_height_ = height;
-    return *this;
-  }
-
-  ProducerQueueConfigBuilder& SetDefaultFormat(uint32_t format) {
-    default_format_ = format;
-    return *this;
-  }
-
-  template <typename Meta>
-  ProducerQueueConfigBuilder& SetMetadata() {
-    user_metadata_size_ = sizeof(Meta);
-    return *this;
-  }
-
-  ProducerQueueConfigBuilder& SetMetadataSize(size_t user_metadata_size) {
-    user_metadata_size_ = user_metadata_size;
-    return *this;
-  }
-
- private:
-  bool is_async_{false};
-  uint32_t default_width_{1};
-  uint32_t default_height_{1};
-  uint32_t default_format_{1};  // PIXEL_FORMAT_RGBA_8888
-  size_t user_metadata_size_{0};
-};
-
-// Explicit specializations of ProducerQueueConfigBuilder::Build for void
-// metadata type.
-template <>
-inline ProducerQueueConfigBuilder&
-ProducerQueueConfigBuilder::SetMetadata<void>() {
-  user_metadata_size_ = 0;
-  return *this;
-}
-
-struct QueueInfo {
-  ProducerQueueConfig producer_config;
-  int id;
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(QueueInfo, producer_config, id);
-};
-
-struct UsagePolicy {
-  uint64_t usage_set_mask{0};
-  uint64_t usage_clear_mask{0};
-  uint64_t usage_deny_set_mask{0};
-  uint64_t usage_deny_clear_mask{0};
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(UsagePolicy, usage_set_mask, usage_clear_mask,
-                           usage_deny_set_mask, usage_deny_clear_mask);
-};
-
-// BufferHub Service RPC interface. Defines the endpoints, op codes, and method
-// type signatures supported by bufferhubd.
-struct BufferHubRPC {
-  // Service path.
-  static constexpr char kClientPath[] = "system/buffer_hub/client";
-
-  // |BufferHubQueue| will keep track of at most this value of buffers.
-  // Attempts at runtime to increase the number of buffers past this
-  // will fail. Note that the value is in sync with |android::BufferQueue|, so
-  // that slot id can be shared between |android::dvr::BufferHubQueueProducer|
-  // and |android::BufferQueueProducer| which both implements the same
-  // interface: |android::IGraphicBufferProducer|.
-  static constexpr size_t kMaxQueueCapacity =
-      android::BufferQueueDefs::NUM_BUFFER_SLOTS;
-
-  // Op codes.
-  enum {
-    kOpCreateBuffer = 0,
-    kOpGetBuffer,
-    kOpNewConsumer,
-    kOpProducerPost,
-    kOpProducerGain,
-    kOpConsumerAcquire,
-    kOpConsumerRelease,
-    kOpConsumerBufferDetach,
-    kOpCreateProducerQueue,
-    kOpCreateConsumerQueue,
-    kOpGetQueueInfo,
-    kOpProducerQueueAllocateBuffers,
-    kOpProducerQueueInsertBuffer,
-    kOpProducerQueueRemoveBuffer,
-    kOpConsumerQueueImportBuffers,
-    // TODO(b/77153033): Separate all those RPC operations into subclasses.
-  };
-
-  // Aliases.
-  using LocalChannelHandle = pdx::LocalChannelHandle;
-  using LocalHandle = pdx::LocalHandle;
-  using Void = pdx::rpc::Void;
-
-  // Methods.
-  PDX_REMOTE_METHOD(CreateBuffer, kOpCreateBuffer,
-                    void(uint32_t width, uint32_t height, uint32_t format,
-                         uint64_t usage, size_t user_metadata_size));
-  PDX_REMOTE_METHOD(GetBuffer, kOpGetBuffer,
-                    BufferDescription<LocalHandle>(Void));
-  PDX_REMOTE_METHOD(NewConsumer, kOpNewConsumer, LocalChannelHandle(Void));
-  PDX_REMOTE_METHOD(ProducerPost, kOpProducerPost,
-                    void(LocalFence acquire_fence));
-  PDX_REMOTE_METHOD(ProducerGain, kOpProducerGain, LocalFence(Void));
-  PDX_REMOTE_METHOD(ConsumerAcquire, kOpConsumerAcquire, LocalFence(Void));
-  PDX_REMOTE_METHOD(ConsumerRelease, kOpConsumerRelease,
-                    void(LocalFence release_fence));
-
-  // Detaches a ConsumerBuffer from an existing producer/consumer set. Can only
-  // be called when the consumer is the only consumer and it has exclusive
-  // access to the buffer (i.e. in the acquired'ed state). On the successful
-  // return of the IPC call, a new DetachedBufferChannel handle will be returned
-  // and all existing producer and consumer channels will be closed. Further
-  // IPCs towards those channels will return error.
-  PDX_REMOTE_METHOD(ConsumerBufferDetach, kOpConsumerBufferDetach,
-                    LocalChannelHandle(Void));
-
-  // Buffer Queue Methods.
-  PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue,
-                    QueueInfo(const ProducerQueueConfig& producer_config,
-                              const UsagePolicy& usage_policy));
-  PDX_REMOTE_METHOD(CreateConsumerQueue, kOpCreateConsumerQueue,
-                    LocalChannelHandle(bool silent_queue));
-  PDX_REMOTE_METHOD(GetQueueInfo, kOpGetQueueInfo, QueueInfo(Void));
-  PDX_REMOTE_METHOD(ProducerQueueAllocateBuffers,
-                    kOpProducerQueueAllocateBuffers,
-                    std::vector<std::pair<LocalChannelHandle, size_t>>(
-                        uint32_t width, uint32_t height, uint32_t layer_count,
-                        uint32_t format, uint64_t usage, size_t buffer_count));
-  PDX_REMOTE_METHOD(ProducerQueueInsertBuffer, kOpProducerQueueInsertBuffer,
-                    size_t(int buffer_cid));
-  PDX_REMOTE_METHOD(ProducerQueueRemoveBuffer, kOpProducerQueueRemoveBuffer,
-                    void(size_t slot));
-  PDX_REMOTE_METHOD(ConsumerQueueImportBuffers, kOpConsumerQueueImportBuffers,
-                    std::vector<std::pair<LocalChannelHandle, size_t>>(Void));
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_BUFFERHUB_RPC_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h b/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
deleted file mode 100644
index 726f035..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef ANDROID_DVR_CONSUMER_BUFFER_H_
-#define ANDROID_DVR_CONSUMER_BUFFER_H_
-
-#include <private/dvr/buffer_hub_base.h>
-
-namespace android {
-namespace dvr {
-
-// This is a connection to a producer buffer, which can be located in another
-// application. When that buffer is Post()ed, this fd will be signaled and
-// Acquire allows read access. The user is responsible for making sure that
-// Acquire is called with the correct metadata structure. The only guarantee the
-// API currently provides is that an Acquire() with metadata of the wrong size
-// will fail.
-class ConsumerBuffer : public pdx::ClientBase<ConsumerBuffer, BufferHubBase> {
- public:
-  // This call assumes ownership of |fd|.
-  static std::unique_ptr<ConsumerBuffer> Import(LocalChannelHandle channel);
-  static std::unique_ptr<ConsumerBuffer> Import(
-      Status<LocalChannelHandle> status);
-
-  // Attempt to retrieve a post event from buffer hub. If successful,
-  // |ready_fence| will be set to a fence to wait on until the buffer is ready.
-  // This call will only succeed after the fd is signalled. This call may be
-  // performed as an alternative to the Acquire() with metadata. In such cases
-  // the metadata is not read.
-  //
-  // This returns zero or negative unix error code.
-  int Acquire(LocalHandle* ready_fence);
-
-  // Attempt to retrieve a post event from buffer hub. If successful,
-  // |ready_fence| is set to a fence signaling that the contents of the buffer
-  // are available. This call will only succeed if the buffer is in the posted
-  // state.
-  // Returns zero on success, or a negative errno code otherwise.
-  int Acquire(LocalHandle* ready_fence, void* meta, size_t user_metadata_size);
-
-  // Asynchronously acquires a bufer.
-  int AcquireAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
-
-  // Releases the buffer from any buffer state. If the fence is valid the fence
-  // determines the buffer usage, otherwise the buffer is released immediately.
-  // This returns zero or a negative unix error code.
-  int Release(const LocalHandle& release_fence);
-  int ReleaseAsync();
-
-  // Asynchronously releases a buffer. Similar to the synchronous version above,
-  // except that it does not wait for BufferHub to reply with success or error.
-  // The fence and metadata are passed to consumer via shared fd and shared
-  // memory.
-  int ReleaseAsync(const DvrNativeBufferMetadata* meta,
-                   const LocalHandle& release_fence);
-
-  // May be called after or instead of Acquire to indicate that the consumer
-  // does not need to access the buffer this cycle. This returns zero or a
-  // negative unix error code.
-  int Discard();
-
- private:
-  friend BASE;
-
-  explicit ConsumerBuffer(LocalChannelHandle channel);
-
-  // Local state transition helpers.
-  int LocalAcquire(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
-  int LocalRelease(const DvrNativeBufferMetadata* meta,
-                   const LocalHandle& release_fence);
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_CONSUMER_BUFFER_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h b/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
deleted file mode 100644
index ed38e7f..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef ANDROID_DVR_ION_BUFFER_H_
-#define ANDROID_DVR_ION_BUFFER_H_
-
-#include <hardware/gralloc.h>
-#include <log/log.h>
-#include <ui/GraphicBuffer.h>
-
-namespace android {
-namespace dvr {
-
-// IonBuffer is an abstraction of Ion/Gralloc buffers.
-class IonBuffer {
- public:
-  IonBuffer();
-  IonBuffer(uint32_t width, uint32_t height, uint32_t format, uint64_t usage);
-  IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
-            uint32_t stride, uint32_t format, uint64_t usage);
-  IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
-            uint32_t layer_count, uint32_t stride, uint32_t format,
-            uint64_t usage);
-  ~IonBuffer();
-
-  IonBuffer(IonBuffer&& other) noexcept;
-  IonBuffer& operator=(IonBuffer&& other) noexcept;
-
-  // Returns check this IonBuffer holds a valid Gralloc buffer.
-  bool IsValid() const { return buffer_ && buffer_->initCheck() == OK; }
-
-  // Frees the underlying native handle and leaves the instance initialized to
-  // empty.
-  void FreeHandle();
-
-  // Allocates a new native handle with the given parameters, freeing the
-  // previous native handle if necessary. Returns 0 on success or a negative
-  // errno code otherwise. If allocation fails the previous native handle is
-  // left intact.
-  int Alloc(uint32_t width, uint32_t height, uint32_t layer_count,
-            uint32_t format, uint64_t usage);
-
-  // Resets the underlying native handle and parameters, freeing the previous
-  // native handle if necessary.
-  void Reset(buffer_handle_t handle, uint32_t width, uint32_t height,
-             uint32_t layer_count, uint32_t stride, uint32_t format,
-             uint64_t usage);
-
-  // Like Reset but also registers the native handle, which is necessary for
-  // native handles received over IPC. Returns 0 on success or a negative errno
-  // code otherwise. If import fails the previous native handle is left intact.
-  int Import(buffer_handle_t handle, uint32_t width, uint32_t height,
-             uint32_t layer_count, uint32_t stride, uint32_t format,
-             uint64_t usage);
-
-  // Like Reset but imports a native handle from raw fd and int arrays. Returns
-  // 0 on success or a negative errno code otherwise. If import fails the
-  // previous native handle is left intact.
-  int Import(const int* fd_array, int fd_count, const int* int_array,
-             int int_count, uint32_t width, uint32_t height,
-             uint32_t layer_count, uint32_t stride, uint32_t format,
-             uint64_t usage);
-
-  // Duplicates the native handle underlying |other| and then imports it. This
-  // is useful for creating multiple, independent views of the same Ion/Gralloc
-  // buffer. Returns 0 on success or a negative errno code otherwise. If
-  // duplication or import fail the previous native handle is left intact.
-  int Duplicate(const IonBuffer* other);
-
-  int Lock(uint32_t usage, int x, int y, int width, int height, void** address);
-  int LockYUV(uint32_t usage, int x, int y, int width, int height,
-              struct android_ycbcr* yuv);
-  int Unlock();
-
-  sp<GraphicBuffer>& buffer() { return buffer_; }
-  const sp<GraphicBuffer>& buffer() const { return buffer_; }
-  buffer_handle_t handle() const {
-    return buffer_.get() ? buffer_->handle : nullptr;
-  }
-  uint32_t width() const { return buffer_.get() ? buffer_->getWidth() : 0; }
-  uint32_t height() const { return buffer_.get() ? buffer_->getHeight() : 0; }
-  uint32_t layer_count() const {
-    return buffer_.get() ? buffer_->getLayerCount() : 0;
-  }
-  uint32_t stride() const { return buffer_.get() ? buffer_->getStride() : 0; }
-  uint32_t format() const {
-    return buffer_.get() ? buffer_->getPixelFormat() : 0;
-  }
-  uint64_t usage() const {
-    return buffer_.get() ? static_cast<uint64_t>(buffer_->getUsage()) : 0;
-  }
-
- private:
-  sp<GraphicBuffer> buffer_;
-
-  IonBuffer(const IonBuffer&) = delete;
-  void operator=(const IonBuffer&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_ION_BUFFER_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/native_handle_wrapper.h b/libs/vr/libbufferhub/include/private/dvr/native_handle_wrapper.h
deleted file mode 100644
index a5c6ca2..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/native_handle_wrapper.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef ANDROID_DVR_NATIVE_HANDLE_WRAPPER_H_
-#define ANDROID_DVR_NATIVE_HANDLE_WRAPPER_H_
-
-#include <cutils/native_handle.h>
-#include <log/log.h>
-#include <pdx/rpc/serializable.h>
-
-#include <vector>
-
-namespace android {
-namespace dvr {
-
-// A PDX-friendly wrapper to maintain the life cycle of a native_handle_t
-// object.
-//
-// See https://source.android.com/devices/architecture/hidl/types#handle_t for
-// more information about native_handle_t.
-template <typename FileHandleType>
-class NativeHandleWrapper {
- public:
-  NativeHandleWrapper() = default;
-  NativeHandleWrapper(NativeHandleWrapper&& other) = default;
-  NativeHandleWrapper& operator=(NativeHandleWrapper&& other) = default;
-
-  // Create a new NativeHandleWrapper by duplicating the handle.
-  explicit NativeHandleWrapper(const native_handle_t* handle) {
-    const int fd_count = handle->numFds;
-    const int int_count = handle->numInts;
-
-    // Populate the fd and int vectors: native_handle->data[] is an array of fds
-    // followed by an array of opaque ints.
-    for (int i = 0; i < fd_count; i++) {
-      fds_.emplace_back(FileHandleType::AsDuplicate(handle->data[i]));
-    }
-    for (int i = 0; i < int_count; i++) {
-      ints_.push_back(handle->data[fd_count + i]);
-    }
-  }
-
-  size_t int_count() const { return ints_.size(); }
-  size_t fd_count() const { return fds_.size(); }
-  bool IsValid() const { return ints_.size() != 0 || fds_.size() != 0; }
-
-  // Duplicate a native handle from the wrapper.
-  native_handle_t* DuplicateHandle() const {
-    if (!IsValid()) {
-      return nullptr;
-    }
-
-    // numFds + numInts ints.
-    std::vector<FileHandleType> fds;
-    for (const auto& fd : fds_) {
-      if (!fd.IsValid()) {
-        return nullptr;
-      }
-      fds.emplace_back(fd.Duplicate());
-    }
-
-    return FromFdsAndInts(std::move(fds), ints_);
-  }
-
-  // Takes the native handle out of the wrapper.
-  native_handle_t* TakeHandle() {
-    if (!IsValid()) {
-      return nullptr;
-    }
-
-    return FromFdsAndInts(std::move(fds_), std::move(ints_));
-  }
-
- private:
-  NativeHandleWrapper(const NativeHandleWrapper&) = delete;
-  void operator=(const NativeHandleWrapper&) = delete;
-
-  static native_handle_t* FromFdsAndInts(std::vector<FileHandleType> fds,
-                                         std::vector<int> ints) {
-    native_handle_t* handle = native_handle_create(fds.size(), ints.size());
-    if (!handle) {
-      ALOGE("NativeHandleWrapper::TakeHandle: Failed to create new handle.");
-      return nullptr;
-    }
-
-    // numFds + numInts ints.
-    for (int i = 0; i < handle->numFds; i++) {
-      handle->data[i] = fds[i].Release();
-    }
-    memcpy(&handle->data[handle->numFds], ints.data(),
-           sizeof(int) * handle->numInts);
-
-    return handle;
-  }
-
-  std::vector<int> ints_;
-  std::vector<FileHandleType> fds_;
-
-  PDX_SERIALIZABLE_MEMBERS(NativeHandleWrapper<FileHandleType>, ints_, fds_);
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_NATIVE_HANDLE_WRAPPER_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h b/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
deleted file mode 100644
index 7ec345c..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef ANDROID_DVR_PRODUCER_BUFFER_H_
-#define ANDROID_DVR_PRODUCER_BUFFER_H_
-
-#include <private/dvr/buffer_hub_base.h>
-
-namespace android {
-namespace dvr {
-
-// This represents a writable buffer. Calling Post notifies all clients and
-// makes the buffer read-only. Call Gain to acquire write access. A buffer
-// may have many consumers.
-//
-// The user of ProducerBuffer is responsible with making sure that the Post() is
-// done with the correct metadata type and size. The user is also responsible
-// for making sure that remote ends (ConsumerBuffers) are also using the correct
-// metadata when acquiring the buffer. The API guarantees that a Post() with a
-// metadata of wrong size will fail. However, it currently does not do any
-// type checking.
-// The API also assumes that metadata is a serializable type (plain old data).
-class ProducerBuffer : public pdx::ClientBase<ProducerBuffer, BufferHubBase> {
- public:
-  // Imports a bufferhub producer channel, assuming ownership of its handle.
-  static std::unique_ptr<ProducerBuffer> Import(LocalChannelHandle channel);
-  static std::unique_ptr<ProducerBuffer> Import(
-      Status<LocalChannelHandle> status);
-
-  // Asynchronously posts a buffer. The fence and metadata are passed to
-  // consumer via shared fd and shared memory.
-  int PostAsync(const DvrNativeBufferMetadata* meta,
-                const LocalHandle& ready_fence);
-
-  // Post this buffer, passing |ready_fence| to the consumers. The bytes in
-  // |meta| are passed unaltered to the consumers. The producer must not modify
-  // the buffer until it is re-gained.
-  // This returns zero or a negative unix error code.
-  int Post(const LocalHandle& ready_fence, const void* meta,
-           size_t user_metadata_size);
-
-  int Post(const LocalHandle& ready_fence) {
-    return Post(ready_fence, nullptr, 0);
-  }
-
-  // Attempt to re-gain the buffer for writing. If |release_fence| is valid, it
-  // must be waited on before using the buffer. If it is not valid then the
-  // buffer is free for immediate use. This call will succeed if the buffer
-  // is in the released state, or in posted state and gain_posted_buffer is
-  // true.
-  //
-  // @param release_fence output fence.
-  // @param gain_posted_buffer whether to gain posted buffer or not.
-  // @return This returns zero or a negative unix error code.
-  int Gain(LocalHandle* release_fence, bool gain_posted_buffer = false);
-
-  // Asynchronously marks a released buffer as gained. This method is similar to
-  // the synchronous version above, except that it does not wait for BufferHub
-  // to acknowledge success or failure. Because of the asynchronous nature of
-  // the underlying message, no error is returned if this method is called when
-  // the buffer is in an incorrect state. Returns zero if sending the message
-  // succeeded, or a negative errno code if local error check fails.
-  // TODO(b/112007999): gain_posted_buffer true is only used to prevent
-  // libdvrtracking from starving when there are non-responding clients. This
-  // gain_posted_buffer param can be removed once libdvrtracking start to use
-  // the new AHardwareBuffer API.
-  int GainAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence,
-                bool gain_posted_buffer = false);
-  int GainAsync();
-
-  // Detaches a ProducerBuffer from an existing producer/consumer set. Can only
-  // be called when a producer buffer has exclusive access to the buffer (i.e.
-  // in the gain'ed state). On the successful return of the IPC call, a new
-  // LocalChannelHandle representing a detached buffer will be returned and all
-  // existing producer and consumer channels will be closed. Further IPCs
-  // towards those channels will return error.
-  Status<LocalChannelHandle> Detach();
-
- private:
-  friend BASE;
-
-  // Constructors are automatically exposed through ProducerBuffer::Create(...)
-  // static template methods inherited from ClientBase, which take the same
-  // arguments as the constructors.
-
-  // Constructs a buffer with the given geometry and parameters.
-  ProducerBuffer(uint32_t width, uint32_t height, uint32_t format,
-                 uint64_t usage, size_t metadata_size = 0);
-
-  // Constructs a blob (flat) buffer with the given usage flags.
-  ProducerBuffer(uint64_t usage, size_t size);
-
-  // Imports the given file handle to a producer channel, taking ownership.
-  explicit ProducerBuffer(LocalChannelHandle channel);
-
-  // Local state transition helpers.
-  int LocalGain(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence,
-                bool gain_posted_buffer = false);
-  int LocalPost(const DvrNativeBufferMetadata* meta,
-                const LocalHandle& ready_fence);
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_PRODUCER_BUFFER_H_
diff --git a/libs/vr/libbufferhub/ion_buffer.cpp b/libs/vr/libbufferhub/ion_buffer.cpp
deleted file mode 100644
index 1965410..0000000
--- a/libs/vr/libbufferhub/ion_buffer.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-#include <private/dvr/ion_buffer.h>
-
-#include <log/log.h>
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
-
-#include <mutex>
-
-namespace {
-
-constexpr uint32_t kDefaultGraphicBufferLayerCount = 1;
-
-}  // anonymous namespace
-
-namespace android {
-namespace dvr {
-
-IonBuffer::IonBuffer() : IonBuffer(nullptr, 0, 0, 0, 0, 0, 0) {}
-
-IonBuffer::IonBuffer(uint32_t width, uint32_t height, uint32_t format,
-                     uint64_t usage)
-    : IonBuffer() {
-  Alloc(width, height, kDefaultGraphicBufferLayerCount, format, usage);
-}
-
-IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
-                     uint32_t stride, uint32_t format, uint64_t usage)
-    : IonBuffer(handle, width, height, kDefaultGraphicBufferLayerCount, stride,
-                format, usage) {}
-
-IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
-                     uint32_t layer_count, uint32_t stride, uint32_t format,
-                     uint64_t usage)
-    : buffer_(nullptr) {
-  ALOGD_IF(TRACE,
-           "IonBuffer::IonBuffer: handle=%p width=%u height=%u layer_count=%u "
-           "stride=%u format=%u usage=%" PRIx64,
-           handle, width, height, layer_count, stride, format, usage);
-  if (handle != 0) {
-    Import(handle, width, height, layer_count, stride, format, usage);
-  }
-}
-
-IonBuffer::~IonBuffer() {
-  ALOGD_IF(TRACE,
-           "IonBuffer::~IonBuffer: handle=%p width=%u height=%u stride=%u "
-           "format=%u usage=%" PRIx64,
-           handle(), width(), height(), stride(), format(), usage());
-  FreeHandle();
-}
-
-IonBuffer::IonBuffer(IonBuffer&& other) noexcept : IonBuffer() {
-  *this = std::move(other);
-}
-
-IonBuffer& IonBuffer::operator=(IonBuffer&& other) noexcept {
-  ALOGD_IF(TRACE, "IonBuffer::operator=: handle_=%p other.handle_=%p", handle(),
-           other.handle());
-
-  if (this != &other) {
-    buffer_ = other.buffer_;
-    other.FreeHandle();
-  }
-  return *this;
-}
-
-void IonBuffer::FreeHandle() {
-  if (buffer_.get()) {
-    // GraphicBuffer unregisters and cleans up the handle if needed
-    buffer_ = nullptr;
-  }
-}
-
-int IonBuffer::Alloc(uint32_t width, uint32_t height, uint32_t layer_count,
-                     uint32_t format, uint64_t usage) {
-  ALOGD_IF(TRACE,
-           "IonBuffer::Alloc: width=%u height=%u layer_count=%u format=%u "
-           "usage=%" PRIx64, width, height, layer_count, format, usage);
-
-  sp<GraphicBuffer> buffer =
-      new GraphicBuffer(width, height, format, layer_count, usage);
-  if (buffer->initCheck() != OK) {
-    ALOGE("IonBuffer::Aloc: Failed to allocate buffer");
-    return -EINVAL;
-  } else {
-    buffer_ = buffer;
-    return 0;
-  }
-}
-
-void IonBuffer::Reset(buffer_handle_t handle, uint32_t width, uint32_t height,
-                      uint32_t layer_count, uint32_t stride, uint32_t format,
-                      uint64_t usage) {
-  ALOGD_IF(TRACE,
-           "IonBuffer::Reset: handle=%p width=%u height=%u layer_count=%u "
-           "stride=%u format=%u usage=%" PRIx64,
-           handle, width, height, layer_count, stride, format, usage);
-  Import(handle, width, height, layer_count, stride, format, usage);
-}
-
-int IonBuffer::Import(buffer_handle_t handle, uint32_t width, uint32_t height,
-                      uint32_t layer_count, uint32_t stride, uint32_t format,
-                      uint64_t usage) {
-  ATRACE_NAME("IonBuffer::Import1");
-  ALOGD_IF(TRACE,
-           "IonBuffer::Import: handle=%p width=%u height=%u layer_count=%u "
-           "stride=%u format=%u usage=%" PRIx64,
-           handle, width, height, layer_count, stride, format, usage);
-  FreeHandle();
-  sp<GraphicBuffer> buffer =
-      new GraphicBuffer(handle, GraphicBuffer::TAKE_UNREGISTERED_HANDLE, width,
-                        height, format, layer_count, usage, stride);
-  if (buffer->initCheck() != OK) {
-    ALOGE("IonBuffer::Import: Failed to import buffer");
-    return -EINVAL;
-  } else {
-    buffer_ = buffer;
-    return 0;
-  }
-}
-
-int IonBuffer::Import(const int* fd_array, int fd_count, const int* int_array,
-                      int int_count, uint32_t width, uint32_t height,
-                      uint32_t layer_count, uint32_t stride, uint32_t format,
-                      uint64_t usage) {
-  ATRACE_NAME("IonBuffer::Import2");
-  ALOGD_IF(TRACE,
-           "IonBuffer::Import: fd_count=%d int_count=%d width=%u height=%u "
-           "layer_count=%u stride=%u format=%u usage=%" PRIx64,
-           fd_count, int_count, width, height, layer_count, stride, format,
-           usage);
-
-  if (fd_count < 0 || int_count < 0) {
-    ALOGE("IonBuffer::Import: invalid arguments.");
-    return -EINVAL;
-  }
-
-  native_handle_t* handle = native_handle_create(fd_count, int_count);
-  if (!handle) {
-    ALOGE("IonBuffer::Import: failed to create new native handle.");
-    return -ENOMEM;
-  }
-
-  // Copy fd_array into the first part of handle->data and int_array right
-  // after it.
-  memcpy(handle->data, fd_array, sizeof(int) * fd_count);
-  memcpy(handle->data + fd_count, int_array, sizeof(int) * int_count);
-
-  const int ret =
-      Import(handle, width, height, layer_count, stride, format, usage);
-  if (ret < 0) {
-    ALOGE("IonBuffer::Import: failed to import raw native handle: %s",
-          strerror(-ret));
-    native_handle_close(handle);
-    native_handle_delete(handle);
-  }
-
-  return ret;
-}
-
-int IonBuffer::Duplicate(const IonBuffer* other) {
-  if (!other->handle())
-    return -EINVAL;
-
-  const int fd_count = other->handle()->numFds;
-  const int int_count = other->handle()->numInts;
-
-  if (fd_count < 0 || int_count < 0)
-    return -EINVAL;
-
-  native_handle_t* handle = native_handle_create(fd_count, int_count);
-  if (!handle) {
-    ALOGE("IonBuffer::Duplicate: Failed to create new native handle.");
-    return -ENOMEM;
-  }
-
-  // Duplicate the file descriptors from the other native handle.
-  for (int i = 0; i < fd_count; i++)
-    handle->data[i] = dup(other->handle()->data[i]);
-
-  // Copy the ints after the file descriptors.
-  memcpy(handle->data + fd_count, other->handle()->data + fd_count,
-         sizeof(int) * int_count);
-
-  const int ret =
-      Import(handle, other->width(), other->height(), other->layer_count(),
-             other->stride(), other->format(), other->usage());
-  if (ret < 0) {
-    ALOGE("IonBuffer::Duplicate: Failed to import duplicate native handle: %s",
-          strerror(-ret));
-    native_handle_close(handle);
-    native_handle_delete(handle);
-  }
-
-  return ret;
-}
-
-int IonBuffer::Lock(uint32_t usage, int x, int y, int width, int height,
-                    void** address) {
-  ATRACE_NAME("IonBuffer::Lock");
-  ALOGD_IF(TRACE,
-           "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d "
-           "address=%p",
-           handle(), usage, x, y, width, height, address);
-
-  status_t err =
-      buffer_->lock(usage, Rect(x, y, x + width, y + height), address);
-  if (err != OK)
-    return -EINVAL;
-  else
-    return 0;
-}
-
-int IonBuffer::LockYUV(uint32_t usage, int x, int y, int width, int height,
-                       struct android_ycbcr* yuv) {
-  ATRACE_NAME("IonBuffer::LockYUV");
-  ALOGD_IF(TRACE,
-           "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d",
-           handle(), usage, x, y, width, height);
-
-  status_t err =
-      buffer_->lockYCbCr(usage, Rect(x, y, x + width, y + height), yuv);
-  if (err != OK)
-    return -EINVAL;
-  else
-    return 0;
-}
-
-int IonBuffer::Unlock() {
-  ATRACE_NAME("IonBuffer::Unlock");
-  ALOGD_IF(TRACE, "IonBuffer::Unlock: handle=%p", handle());
-
-  status_t err = buffer_->unlock();
-  if (err != OK)
-    return -EINVAL;
-  else
-    return 0;
-}
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libbufferhub/producer_buffer.cpp b/libs/vr/libbufferhub/producer_buffer.cpp
deleted file mode 100644
index aa9d072..0000000
--- a/libs/vr/libbufferhub/producer_buffer.cpp
+++ /dev/null
@@ -1,296 +0,0 @@
-#include <private/dvr/producer_buffer.h>
-
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Status;
-
-namespace android {
-namespace dvr {
-
-ProducerBuffer::ProducerBuffer(uint32_t width, uint32_t height, uint32_t format,
-                               uint64_t usage, size_t user_metadata_size)
-    : BASE(BufferHubRPC::kClientPath) {
-  ATRACE_NAME("ProducerBuffer::ProducerBuffer");
-  ALOGD_IF(TRACE,
-           "ProducerBuffer::ProducerBuffer: fd=%d width=%u height=%u format=%u "
-           "usage=%" PRIx64 " user_metadata_size=%zu",
-           event_fd(), width, height, format, usage, user_metadata_size);
-
-  auto status = InvokeRemoteMethod<BufferHubRPC::CreateBuffer>(
-      width, height, format, usage, user_metadata_size);
-  if (!status) {
-    ALOGE(
-        "ProducerBuffer::ProducerBuffer: Failed to create producer buffer: %s",
-        status.GetErrorMessage().c_str());
-    Close(-status.error());
-    return;
-  }
-
-  const int ret = ImportBuffer();
-  if (ret < 0) {
-    ALOGE(
-        "ProducerBuffer::ProducerBuffer: Failed to import producer buffer: %s",
-        strerror(-ret));
-    Close(ret);
-  }
-}
-
-ProducerBuffer::ProducerBuffer(uint64_t usage, size_t size)
-    : BASE(BufferHubRPC::kClientPath) {
-  ATRACE_NAME("ProducerBuffer::ProducerBuffer");
-  ALOGD_IF(TRACE, "ProducerBuffer::ProducerBuffer: usage=%" PRIx64 " size=%zu",
-           usage, size);
-  const int width = static_cast<int>(size);
-  const int height = 1;
-  const int format = HAL_PIXEL_FORMAT_BLOB;
-  const size_t user_metadata_size = 0;
-
-  auto status = InvokeRemoteMethod<BufferHubRPC::CreateBuffer>(
-      width, height, format, usage, user_metadata_size);
-  if (!status) {
-    ALOGE("ProducerBuffer::ProducerBuffer: Failed to create blob: %s",
-          status.GetErrorMessage().c_str());
-    Close(-status.error());
-    return;
-  }
-
-  const int ret = ImportBuffer();
-  if (ret < 0) {
-    ALOGE(
-        "ProducerBuffer::ProducerBuffer: Failed to import producer buffer: %s",
-        strerror(-ret));
-    Close(ret);
-  }
-}
-
-ProducerBuffer::ProducerBuffer(LocalChannelHandle channel)
-    : BASE(std::move(channel)) {
-  const int ret = ImportBuffer();
-  if (ret < 0) {
-    ALOGE(
-        "ProducerBuffer::ProducerBuffer: Failed to import producer buffer: %s",
-        strerror(-ret));
-    Close(ret);
-  }
-}
-
-int ProducerBuffer::LocalPost(const DvrNativeBufferMetadata* meta,
-                              const LocalHandle& ready_fence) {
-  if (const int error = CheckMetadata(meta->user_metadata_size))
-    return error;
-
-  // The buffer can be posted iff the buffer state for this client is gained.
-  uint32_t current_buffer_state =
-      buffer_state_->load(std::memory_order_acquire);
-  if (!BufferHubDefs::isClientGained(current_buffer_state,
-                                     client_state_mask())) {
-    ALOGE("%s: not gained, id=%d state=%" PRIx32 ".", __FUNCTION__, id(),
-          current_buffer_state);
-    return -EBUSY;
-  }
-
-  // Set the producer client buffer state to released, that of all other clients
-  // (both existing and non-existing clients) to posted.
-  uint32_t updated_buffer_state =
-      (~client_state_mask()) & BufferHubDefs::kHighBitsMask;
-  while (!buffer_state_->compare_exchange_weak(
-      current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
-      std::memory_order_acquire)) {
-    if (!BufferHubDefs::isClientGained(current_buffer_state,
-                                       client_state_mask())) {
-      ALOGE(
-          "%s: Failed to post the buffer. The buffer is no longer gained, "
-          "id=%d state=%" PRIx32 ".",
-          __FUNCTION__, id(), current_buffer_state);
-      return -EBUSY;
-    }
-  }
-
-  // Copy the canonical metadata.
-  void* metadata_ptr = reinterpret_cast<void*>(&metadata_header_->metadata);
-  memcpy(metadata_ptr, meta, sizeof(DvrNativeBufferMetadata));
-  // Copy extra user requested metadata.
-  if (meta->user_metadata_ptr && meta->user_metadata_size) {
-    void* metadata_src = reinterpret_cast<void*>(meta->user_metadata_ptr);
-    memcpy(user_metadata_ptr_, metadata_src, meta->user_metadata_size);
-  }
-
-  // Send out the acquire fence through the shared epoll fd. Note that during
-  // posting no consumer is not expected to be polling on the fence.
-  if (const int error = UpdateSharedFence(ready_fence, shared_acquire_fence_))
-    return error;
-
-  return 0;
-}
-
-int ProducerBuffer::Post(const LocalHandle& ready_fence, const void* meta,
-                         size_t user_metadata_size) {
-  ATRACE_NAME("ProducerBuffer::Post");
-
-  // Populate cononical metadata for posting.
-  DvrNativeBufferMetadata canonical_meta;
-  canonical_meta.user_metadata_ptr = reinterpret_cast<uint64_t>(meta);
-  canonical_meta.user_metadata_size = user_metadata_size;
-
-  if (const int error = LocalPost(&canonical_meta, ready_fence))
-    return error;
-
-  return ReturnStatusOrError(InvokeRemoteMethod<BufferHubRPC::ProducerPost>(
-      BorrowedFence(ready_fence.Borrow())));
-}
-
-int ProducerBuffer::PostAsync(const DvrNativeBufferMetadata* meta,
-                              const LocalHandle& ready_fence) {
-  ATRACE_NAME("ProducerBuffer::PostAsync");
-
-  if (const int error = LocalPost(meta, ready_fence))
-    return error;
-
-  return ReturnStatusOrError(SendImpulse(BufferHubRPC::ProducerPost::Opcode));
-}
-
-int ProducerBuffer::LocalGain(DvrNativeBufferMetadata* out_meta,
-                              LocalHandle* out_fence, bool gain_posted_buffer) {
-  if (!out_meta)
-    return -EINVAL;
-
-  uint32_t current_buffer_state =
-      buffer_state_->load(std::memory_order_acquire);
-  ALOGD_IF(TRACE, "%s: buffer=%d, state=%" PRIx32 ".", __FUNCTION__, id(),
-           current_buffer_state);
-
-  if (BufferHubDefs::isClientGained(current_buffer_state,
-                                    client_state_mask())) {
-    ALOGV("%s: already gained id=%d.", __FUNCTION__, id());
-    return 0;
-  }
-  if (BufferHubDefs::isAnyClientAcquired(current_buffer_state) ||
-      BufferHubDefs::isAnyClientGained(current_buffer_state) ||
-      (BufferHubDefs::isAnyClientPosted(
-           current_buffer_state &
-           active_clients_bit_mask_->load(std::memory_order_acquire)) &&
-       !gain_posted_buffer)) {
-    ALOGE("%s: not released id=%d state=%" PRIx32 ".", __FUNCTION__, id(),
-          current_buffer_state);
-    return -EBUSY;
-  }
-  // Change the buffer state to gained state.
-  uint32_t updated_buffer_state = client_state_mask();
-  while (!buffer_state_->compare_exchange_weak(
-      current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
-      std::memory_order_acquire)) {
-    if (BufferHubDefs::isAnyClientAcquired(current_buffer_state) ||
-        BufferHubDefs::isAnyClientGained(current_buffer_state) ||
-        (BufferHubDefs::isAnyClientPosted(
-             current_buffer_state &
-             active_clients_bit_mask_->load(std::memory_order_acquire)) &&
-         !gain_posted_buffer)) {
-      ALOGE(
-          "%s: Failed to gain the buffer. The buffer is no longer released. "
-          "id=%d state=%" PRIx32 ".",
-          __FUNCTION__, id(), current_buffer_state);
-      return -EBUSY;
-    }
-  }
-
-  // Canonical metadata is undefined on Gain. Except for user_metadata and
-  // release_fence_mask. Fill in the user_metadata_ptr in address space of the
-  // local process.
-  if (metadata_header_->metadata.user_metadata_size && user_metadata_ptr_) {
-    out_meta->user_metadata_size =
-        metadata_header_->metadata.user_metadata_size;
-    out_meta->user_metadata_ptr =
-        reinterpret_cast<uint64_t>(user_metadata_ptr_);
-  } else {
-    out_meta->user_metadata_size = 0;
-    out_meta->user_metadata_ptr = 0;
-  }
-
-  uint32_t current_fence_state = fence_state_->load(std::memory_order_acquire);
-  uint32_t current_active_clients_bit_mask =
-      active_clients_bit_mask_->load(std::memory_order_acquire);
-  // If there are release fence(s) from consumer(s), we need to return it to the
-  // consumer(s).
-  // TODO(b/112007999) add an atomic variable in metadata header in shared
-  // memory to indicate which client is the last producer of the buffer.
-  // Currently, assume the first client is the only producer to the buffer.
-  if (current_fence_state & current_active_clients_bit_mask &
-      (~BufferHubDefs::kFirstClientBitMask)) {
-    *out_fence = shared_release_fence_.Duplicate();
-    out_meta->release_fence_mask = current_fence_state &
-                                   current_active_clients_bit_mask &
-                                   (~BufferHubDefs::kFirstClientBitMask);
-  }
-
-  return 0;
-}
-
-int ProducerBuffer::Gain(LocalHandle* release_fence, bool gain_posted_buffer) {
-  ATRACE_NAME("ProducerBuffer::Gain");
-
-  DvrNativeBufferMetadata meta;
-  if (const int error = LocalGain(&meta, release_fence, gain_posted_buffer))
-    return error;
-
-  auto status = InvokeRemoteMethod<BufferHubRPC::ProducerGain>();
-  if (!status)
-    return -status.error();
-  return 0;
-}
-
-int ProducerBuffer::GainAsync(DvrNativeBufferMetadata* out_meta,
-                              LocalHandle* release_fence,
-                              bool gain_posted_buffer) {
-  ATRACE_NAME("ProducerBuffer::GainAsync");
-
-  if (const int error = LocalGain(out_meta, release_fence, gain_posted_buffer))
-    return error;
-
-  return ReturnStatusOrError(SendImpulse(BufferHubRPC::ProducerGain::Opcode));
-}
-
-int ProducerBuffer::GainAsync() {
-  DvrNativeBufferMetadata meta;
-  LocalHandle fence;
-  return GainAsync(&meta, &fence);
-}
-
-std::unique_ptr<ProducerBuffer> ProducerBuffer::Import(
-    LocalChannelHandle channel) {
-  ALOGD_IF(TRACE, "ProducerBuffer::Import: channel=%d", channel.value());
-  return ProducerBuffer::Create(std::move(channel));
-}
-
-std::unique_ptr<ProducerBuffer> ProducerBuffer::Import(
-    Status<LocalChannelHandle> status) {
-  return Import(status ? status.take()
-                       : LocalChannelHandle{nullptr, -status.error()});
-}
-
-Status<LocalChannelHandle> ProducerBuffer::Detach() {
-  // TODO(b/112338294) remove after migrate producer buffer to binder
-  ALOGW("ProducerBuffer::Detach: not supported operation during migration");
-  return {};
-
-  // TODO(b/112338294) Keep here for reference. Remove it after new logic is
-  // written.
-  /* uint32_t buffer_state = buffer_state_->load(std::memory_order_acquire);
-  if (!BufferHubDefs::isClientGained(
-      buffer_state, BufferHubDefs::kFirstClientStateMask)) {
-    // Can only detach a ProducerBuffer when it's in gained state.
-    ALOGW("ProducerBuffer::Detach: The buffer (id=%d, state=0x%" PRIx32
-          ") is not in gained state.",
-          id(), buffer_state);
-    return {};
-  }
-
-  Status<LocalChannelHandle> status =
-      InvokeRemoteMethod<BufferHubRPC::ProducerBufferDetach>();
-  ALOGE_IF(!status,
-           "ProducerBuffer::Detach: Failed to detach buffer (id=%d): %s.", id(),
-           status.GetErrorMessage().c_str());
-  return status; */
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp
deleted file mode 100644
index 9dbeacb..0000000
--- a/libs/vr/libdvr/Android.bp
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2017 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_library_headers {
-    name: "libdvr_headers",
-    export_include_dirs: ["include"],
-    vendor_available: true,
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.media",
-        "com.android.media.swcodec",
-    ],
-    min_sdk_version: "29",
-}
diff --git a/libs/vr/libdvr/include/CPPLINT.cfg b/libs/vr/libdvr/include/CPPLINT.cfg
deleted file mode 100644
index 2f8a3c0..0000000
--- a/libs/vr/libdvr/include/CPPLINT.cfg
+++ /dev/null
@@ -1 +0,0 @@
-filter=-build/header_guard
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
deleted file mode 100644
index b7abb99..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ /dev/null
@@ -1,503 +0,0 @@
-#ifndef ANDROID_DVR_API_H_
-#define ANDROID_DVR_API_H_
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <cstdio>
-
-#include <dvr/dvr_display_types.h>
-#include <dvr/dvr_hardware_composer_types.h>
-#include <dvr/dvr_pose.h>
-#include <dvr/dvr_tracking_types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __GNUC__
-#define ALIGNED_DVR_STRUCT(x) __attribute__((packed, aligned(x)))
-#else
-#define ALIGNED_DVR_STRUCT(x)
-#endif
-
-typedef struct ANativeWindow ANativeWindow;
-
-typedef struct DvrPoseAsync DvrPoseAsync;
-
-typedef uint64_t DvrSurfaceUpdateFlags;
-typedef struct DvrDisplayManager DvrDisplayManager;
-typedef struct DvrSurfaceState DvrSurfaceState;
-typedef struct DvrPoseClient DvrPoseClient;
-typedef struct DvrPoseDataCaptureRequest DvrPoseDataCaptureRequest;
-typedef struct DvrVSyncClient DvrVSyncClient;
-typedef struct DvrVirtualTouchpad DvrVirtualTouchpad;
-
-typedef struct DvrBuffer DvrBuffer;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct AHardwareBuffer AHardwareBuffer;
-
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
-typedef struct DvrNativeBufferMetadata DvrNativeBufferMetadata;
-
-typedef struct DvrSurface DvrSurface;
-typedef uint64_t DvrSurfaceAttributeType;
-typedef int32_t DvrSurfaceAttributeKey;
-typedef int32_t DvrGlobalBufferKey;
-
-typedef struct DvrSurfaceAttributeValue DvrSurfaceAttributeValue;
-typedef struct DvrSurfaceAttribute DvrSurfaceAttribute;
-
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrTrackingCamera DvrTrackingCamera;
-typedef struct DvrTrackingFeatureExtractor DvrTrackingFeatureExtractor;
-typedef struct DvrTrackingSensors DvrTrackingSensors;
-typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
-
-// Note: To avoid breaking others during active development, only modify this
-// struct by appending elements to the end.
-// If you do feel we should to re-arrange or remove elements, please make a
-// note of it, and wait until we're about to finalize for an API release to do
-// so.
-typedef struct DvrNativeDisplayMetrics {
-  uint32_t display_width;
-  uint32_t display_height;
-  uint32_t display_x_dpi;
-  uint32_t display_y_dpi;
-  uint32_t vsync_period_ns;
-} DvrNativeDisplayMetrics;
-
-// native_handle contains the fds for the underlying ION allocations inside
-// the gralloc buffer. This is needed temporarily while GPU vendors work on
-// better support for AHardwareBuffer via glBindSharedBuffer APIs. See
-// b/37207909. For now we can declare the native_handle struct where it is
-// used for GPU late latching. See cutils/native_handle.h for the struct layout.
-struct native_handle;
-
-// Device metrics data type enums.
-enum {
-  // Request the device lens metrics protobuf. This matches cardboard protos.
-  DVR_CONFIGURATION_DATA_LENS_METRICS = 0,
-  // Request the device metrics protobuf.
-  DVR_CONFIGURATION_DATA_DEVICE_METRICS = 1,
-  // Request the per device configuration data file.
-  DVR_CONFIGURATION_DATA_DEVICE_CONFIG = 2,
-  // Request the edid data for the display.
-  DVR_CONFIGURATION_DATA_DEVICE_EDID = 3,
-};
-
-// dvr_display_manager.h
-typedef int (*DvrDisplayManagerCreatePtr)(DvrDisplayManager** client_out);
-typedef void (*DvrDisplayManagerDestroyPtr)(DvrDisplayManager* client);
-typedef int (*DvrDisplayManagerGetEventFdPtr)(DvrDisplayManager* client);
-typedef int (*DvrDisplayManagerTranslateEpollEventMaskPtr)(
-    DvrDisplayManager* client, int in_events, int* out_events);
-typedef int (*DvrDisplayManagerGetSurfaceStatePtr)(
-    DvrDisplayManager* client, DvrSurfaceState* surface_state);
-typedef int (*DvrDisplayManagerGetReadBufferQueuePtr)(
-    DvrDisplayManager* client, int surface_id, int queue_id,
-    DvrReadBufferQueue** queue_out);
-typedef int (*DvrConfigurationDataGetPtr)(int config_type, uint8_t** data,
-                                          size_t* data_size);
-typedef void (*DvrConfigurationDataDestroyPtr)(uint8_t* data);
-typedef int (*DvrSurfaceStateCreatePtr)(DvrSurfaceState** surface_state);
-typedef void (*DvrSurfaceStateDestroyPtr)(DvrSurfaceState* surface_state);
-typedef int (*DvrSurfaceStateGetSurfaceCountPtr)(DvrSurfaceState* surface_state,
-                                                 size_t* count_out);
-typedef int (*DvrSurfaceStateGetUpdateFlagsPtr)(
-    DvrSurfaceState* surface_state, size_t surface_index,
-    DvrSurfaceUpdateFlags* flags_out);
-typedef int (*DvrSurfaceStateGetSurfaceIdPtr)(DvrSurfaceState* surface_state,
-                                              size_t surface_index,
-                                              int* surface_id_out);
-typedef int (*DvrSurfaceStateGetProcessIdPtr)(DvrSurfaceState* surface_state,
-                                              size_t surface_index,
-                                              int* process_id_out);
-typedef int (*DvrSurfaceStateGetQueueCountPtr)(DvrSurfaceState* surface_state,
-                                               size_t surface_index,
-                                               size_t* count_out);
-typedef ssize_t (*DvrSurfaceStateGetQueueIdsPtr)(DvrSurfaceState* surface_state,
-                                                 size_t surface_index,
-                                                 int* queue_ids,
-                                                 size_t max_count);
-typedef int (*DvrSurfaceStateGetZOrderPtr)(DvrSurfaceState* surface_state,
-                                           size_t surface_index,
-                                           int* z_order_out);
-typedef int (*DvrSurfaceStateGetVisiblePtr)(DvrSurfaceState* surface_state,
-                                            size_t surface_index,
-                                            bool* visible_out);
-typedef int (*DvrSurfaceStateGetAttributeCountPtr)(
-    DvrSurfaceState* surface_state, size_t surface_index, size_t* count_out);
-typedef ssize_t (*DvrSurfaceStateGetAttributesPtr)(
-    DvrSurfaceState* surface_state, size_t surface_index,
-    DvrSurfaceAttribute* attributes, size_t max_attribute_count);
-
-// dvr_buffer.h
-typedef void (*DvrWriteBufferCreateEmptyPtr)(DvrWriteBuffer** write_buffer_out);
-typedef void (*DvrWriteBufferDestroyPtr)(DvrWriteBuffer* write_buffer);
-typedef int (*DvrWriteBufferIsValidPtr)(DvrWriteBuffer* write_buffer);
-typedef int (*DvrWriteBufferClearPtr)(DvrWriteBuffer* write_buffer);
-typedef int (*DvrWriteBufferGetIdPtr)(DvrWriteBuffer* write_buffer);
-typedef int (*DvrWriteBufferGetAHardwareBufferPtr)(
-    DvrWriteBuffer* write_buffer, AHardwareBuffer** hardware_buffer);
-typedef int (*DvrWriteBufferPostPtr)(DvrWriteBuffer* write_buffer,
-                                     int ready_fence_fd, const void* meta,
-                                     size_t meta_size_bytes);
-typedef int (*DvrWriteBufferGainPtr)(DvrWriteBuffer* write_buffer,
-                                     int* release_fence_fd);
-typedef int (*DvrWriteBufferGainAsyncPtr)(DvrWriteBuffer* write_buffer);
-typedef const struct native_handle* (*DvrWriteBufferGetNativeHandlePtr)(
-    DvrWriteBuffer* write_buffer);
-
-typedef void (*DvrReadBufferCreateEmptyPtr)(DvrReadBuffer** read_buffer_out);
-typedef void (*DvrReadBufferDestroyPtr)(DvrReadBuffer* read_buffer);
-typedef int (*DvrReadBufferIsValidPtr)(DvrReadBuffer* read_buffer);
-typedef int (*DvrReadBufferClearPtr)(DvrReadBuffer* read_buffer);
-typedef int (*DvrReadBufferGetIdPtr)(DvrReadBuffer* read_buffer);
-typedef int (*DvrReadBufferGetAHardwareBufferPtr)(
-    DvrReadBuffer* read_buffer, AHardwareBuffer** hardware_buffer);
-typedef int (*DvrReadBufferAcquirePtr)(DvrReadBuffer* read_buffer,
-                                       int* ready_fence_fd, void* meta,
-                                       size_t meta_size_bytes);
-typedef int (*DvrReadBufferReleasePtr)(DvrReadBuffer* read_buffer,
-                                       int release_fence_fd);
-typedef int (*DvrReadBufferReleaseAsyncPtr)(DvrReadBuffer* read_buffer);
-typedef const struct native_handle* (*DvrReadBufferGetNativeHandlePtr)(
-    DvrReadBuffer* read_buffer);
-
-typedef void (*DvrBufferDestroyPtr)(DvrBuffer* buffer);
-typedef int (*DvrBufferGetAHardwareBufferPtr)(
-    DvrBuffer* buffer, AHardwareBuffer** hardware_buffer);
-typedef int (*DvrBufferGlobalLayoutVersionGetPtr)();
-typedef const struct native_handle* (*DvrBufferGetNativeHandlePtr)(
-    DvrBuffer* buffer);
-
-// dvr_buffer_queue.h
-typedef int (*DvrWriteBufferQueueCreatePtr)(uint32_t width, uint32_t height,
-                                            uint32_t format,
-                                            uint32_t layer_count,
-                                            uint64_t usage, size_t capacity,
-                                            size_t metadata_size,
-                                            DvrWriteBufferQueue** queue_out);
-typedef void (*DvrWriteBufferQueueDestroyPtr)(DvrWriteBufferQueue* write_queue);
-typedef ssize_t (*DvrWriteBufferQueueGetCapacityPtr)(
-    DvrWriteBufferQueue* write_queue);
-typedef int (*DvrWriteBufferQueueGetIdPtr)(DvrWriteBufferQueue* write_queue);
-typedef int (*DvrWriteBufferQueueGetExternalSurfacePtr)(
-    DvrWriteBufferQueue* write_queue, ANativeWindow** out_window);
-typedef int (*DvrWriteBufferQueueGetANativeWindowPtr)(
-    DvrWriteBufferQueue* write_queue, ANativeWindow** out_window);
-typedef int (*DvrWriteBufferQueueCreateReadQueuePtr)(
-    DvrWriteBufferQueue* write_queue, DvrReadBufferQueue** out_read_queue);
-typedef int (*DvrWriteBufferQueueDequeuePtr)(DvrWriteBufferQueue* write_queue,
-                                             int timeout,
-                                             DvrWriteBuffer* out_buffer,
-                                             int* out_fence_fd);
-typedef int (*DvrWriteBufferQueueGainBufferPtr)(
-    DvrWriteBufferQueue* write_queue, int timeout,
-    DvrWriteBuffer** out_write_buffer, DvrNativeBufferMetadata* out_meta,
-    int* out_fence_fd);
-typedef int (*DvrWriteBufferQueuePostBufferPtr)(
-    DvrWriteBufferQueue* write_queue, DvrWriteBuffer* write_buffer,
-    const DvrNativeBufferMetadata* meta, int ready_fence_fd);
-typedef int (*DvrWriteBufferQueueResizeBufferPtr)(
-    DvrWriteBufferQueue* write_queue, uint32_t width, uint32_t height);
-typedef void (*DvrReadBufferQueueDestroyPtr)(DvrReadBufferQueue* read_queue);
-typedef ssize_t (*DvrReadBufferQueueGetCapacityPtr)(
-    DvrReadBufferQueue* read_queue);
-typedef int (*DvrReadBufferQueueGetIdPtr)(DvrReadBufferQueue* read_queue);
-typedef int (*DvrReadBufferQueueGetEventFdPtr)(DvrReadBufferQueue* read_queue);
-typedef int (*DvrReadBufferQueueCreateReadQueuePtr)(
-    DvrReadBufferQueue* read_queue, DvrReadBufferQueue** out_read_queue);
-typedef int (*DvrReadBufferQueueDequeuePtr)(DvrReadBufferQueue* read_queue,
-                                            int timeout,
-                                            DvrReadBuffer* out_buffer,
-                                            int* out_fence_fd, void* out_meta,
-                                            size_t meta_size_bytes);
-typedef int (*DvrReadBufferQueueAcquireBufferPtr)(
-    DvrReadBufferQueue* read_queue, int timeout,
-    DvrReadBuffer** out_read_buffer, DvrNativeBufferMetadata* out_meta,
-    int* out_fence_fd);
-typedef int (*DvrReadBufferQueueReleaseBufferPtr)(
-    DvrReadBufferQueue* read_queue, DvrReadBuffer* read_buffer,
-    const DvrNativeBufferMetadata* meta, int release_fence_fd);
-typedef void (*DvrReadBufferQueueBufferAvailableCallback)(void* context);
-typedef int (*DvrReadBufferQueueSetBufferAvailableCallbackPtr)(
-    DvrReadBufferQueue* read_queue,
-    DvrReadBufferQueueBufferAvailableCallback callback, void* context);
-typedef void (*DvrReadBufferQueueBufferRemovedCallback)(DvrReadBuffer* buffer,
-                                                        void* context);
-typedef int (*DvrReadBufferQueueSetBufferRemovedCallbackPtr)(
-    DvrReadBufferQueue* read_queue,
-    DvrReadBufferQueueBufferRemovedCallback callback, void* context);
-typedef int (*DvrReadBufferQueueHandleEventsPtr)(
-    DvrReadBufferQueue* read_queue);
-
-// dvr_surface.h
-typedef int (*DvrSetupGlobalBufferPtr)(DvrGlobalBufferKey key, size_t size,
-                                       uint64_t usage, DvrBuffer** buffer_out);
-typedef int (*DvrDeleteGlobalBufferPtr)(DvrGlobalBufferKey key);
-typedef int (*DvrGetGlobalBufferPtr)(DvrGlobalBufferKey key,
-                                     DvrBuffer** out_buffer);
-typedef int (*DvrSurfaceCreatePtr)(const DvrSurfaceAttribute* attributes,
-                                   size_t attribute_count,
-                                   DvrSurface** surface_out);
-typedef void (*DvrSurfaceDestroyPtr)(DvrSurface* surface);
-typedef int (*DvrSurfaceGetIdPtr)(DvrSurface* surface);
-typedef int (*DvrSurfaceSetAttributesPtr)(DvrSurface* surface,
-                                          const DvrSurfaceAttribute* attributes,
-                                          size_t attribute_count);
-typedef int (*DvrSurfaceCreateWriteBufferQueuePtr)(
-    DvrSurface* surface, uint32_t width, uint32_t height, uint32_t format,
-    uint32_t layer_count, uint64_t usage, size_t capacity, size_t metadata_size,
-    DvrWriteBufferQueue** queue_out);
-typedef int (*DvrGetNativeDisplayMetricsPtr)(size_t sizeof_metrics,
-                                             DvrNativeDisplayMetrics* metrics);
-
-// dvr_vsync.h
-typedef int (*DvrVSyncClientCreatePtr)(DvrVSyncClient** client_out);
-typedef void (*DvrVSyncClientDestroyPtr)(DvrVSyncClient* client);
-typedef int (*DvrVSyncClientGetSchedInfoPtr)(DvrVSyncClient* client,
-                                             int64_t* vsync_period_ns,
-                                             int64_t* next_timestamp_ns,
-                                             uint32_t* next_vsync_count);
-
-// libs/vr/libvrsensor/include/dvr/pose_client.h
-typedef DvrPoseClient* (*DvrPoseClientCreatePtr)();
-typedef void (*DvrPoseClientDestroyPtr)(DvrPoseClient* client);
-typedef int (*DvrPoseClientGetPtr)(DvrPoseClient* client, uint32_t vsync_count,
-                                   DvrPoseAsync* out_pose);
-typedef uint32_t (*DvrPoseClientGetVsyncCountPtr)(DvrPoseClient* client);
-typedef int (*DvrPoseClientGetControllerPtr)(DvrPoseClient* client,
-                                             int32_t controller_id,
-                                             uint32_t vsync_count,
-                                             DvrPoseAsync* out_pose);
-typedef int (*DvrPoseClientSensorsEnablePtr)(DvrPoseClient* client,
-                                             bool enabled);
-typedef int (*DvrPoseClientDataCapturePtr)(DvrPoseClient* client,
-    const DvrPoseDataCaptureRequest* request);
-typedef int (*DvrPoseClientDataReaderDestroyPtr)(DvrPoseClient* client,
-                                                 uint64_t data_type);
-
-// dvr_pose.h
-typedef int (*DvrPoseClientGetDataReaderPtr)(DvrPoseClient* client,
-                                             uint64_t data_type,
-                                             DvrReadBufferQueue** read_queue);
-
-// services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h
-
-// Touchpad IDs for *Touch*() and *ButtonState*() calls.
-enum {
-  DVR_VIRTUAL_TOUCHPAD_PRIMARY = 0,
-  DVR_VIRTUAL_TOUCHPAD_VIRTUAL = 1,
-};
-typedef DvrVirtualTouchpad* (*DvrVirtualTouchpadCreatePtr)();
-typedef void (*DvrVirtualTouchpadDestroyPtr)(DvrVirtualTouchpad* client);
-typedef int (*DvrVirtualTouchpadAttachPtr)(DvrVirtualTouchpad* client);
-typedef int (*DvrVirtualTouchpadDetachPtr)(DvrVirtualTouchpad* client);
-typedef int (*DvrVirtualTouchpadTouchPtr)(DvrVirtualTouchpad* client,
-                                          int touchpad, float x, float y,
-                                          float pressure);
-typedef int (*DvrVirtualTouchpadButtonStatePtr)(DvrVirtualTouchpad* client,
-                                                int touchpad, int buttons);
-typedef int (*DvrVirtualTouchpadScrollPtr)(DvrVirtualTouchpad* client,
-                                           int touchpad, float x, float y);
-
-// dvr_hardware_composer_client.h
-typedef struct DvrHwcClient DvrHwcClient;
-typedef struct DvrHwcFrame DvrHwcFrame;
-typedef int (*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
-typedef DvrHwcClient* (*DvrHwcClientCreatePtr)(DvrHwcOnFrameCallback callback,
-                                               void* client_state);
-typedef void (*DvrHwcClientDestroyPtr)(DvrHwcClient* client);
-typedef void (*DvrHwcFrameDestroyPtr)(DvrHwcFrame* frame);
-typedef DvrHwcDisplay (*DvrHwcFrameGetDisplayIdPtr)(DvrHwcFrame* frame);
-typedef int32_t (*DvrHwcFrameGetDisplayWidthPtr)(DvrHwcFrame* frame);
-typedef int32_t (*DvrHwcFrameGetDisplayHeightPtr)(DvrHwcFrame* frame);
-typedef bool (*DvrHwcFrameGetDisplayRemovedPtr)(DvrHwcFrame* frame);
-typedef size_t (*DvrHwcFrameGetLayerCountPtr)(DvrHwcFrame* frame);
-typedef DvrHwcLayer (*DvrHwcFrameGetLayerIdPtr)(DvrHwcFrame* frame,
-                                                size_t layer_index);
-typedef uint32_t (*DvrHwcFrameGetActiveConfigPtr)(DvrHwcFrame* frame);
-typedef uint32_t (*DvrHwcFrameGetColorModePtr)(DvrHwcFrame* frame);
-typedef void (*DvrHwcFrameGetColorTransformPtr)(DvrHwcFrame* frame,
-                                                float* out_matrix,
-                                                int32_t* out_hint);
-typedef uint32_t (*DvrHwcFrameGetPowerModePtr)(DvrHwcFrame* frame);
-typedef uint32_t (*DvrHwcFrameGetVsyncEnabledPtr)(DvrHwcFrame* frame);
-typedef AHardwareBuffer* (*DvrHwcFrameGetLayerBufferPtr)(DvrHwcFrame* frame,
-                                                         size_t layer_index);
-typedef int (*DvrHwcFrameGetLayerFencePtr)(DvrHwcFrame* frame,
-                                           size_t layer_index);
-typedef DvrHwcRecti (*DvrHwcFrameGetLayerDisplayFramePtr)(DvrHwcFrame* frame,
-                                                          size_t layer_index);
-typedef DvrHwcRectf (*DvrHwcFrameGetLayerCropPtr)(DvrHwcFrame* frame,
-                                                  size_t layer_index);
-typedef DvrHwcBlendMode (*DvrHwcFrameGetLayerBlendModePtr)(DvrHwcFrame* frame,
-                                                           size_t layer_index);
-typedef float (*DvrHwcFrameGetLayerAlphaPtr)(DvrHwcFrame* frame,
-                                             size_t layer_index);
-typedef uint32_t (*DvrHwcFrameGetLayerTypePtr)(DvrHwcFrame* frame,
-                                               size_t layer_index);
-typedef uint32_t (*DvrHwcFrameGetLayerApplicationIdPtr)(DvrHwcFrame* frame,
-                                                        size_t layer_index);
-typedef uint32_t (*DvrHwcFrameGetLayerZOrderPtr)(DvrHwcFrame* frame,
-                                                 size_t layer_index);
-
-typedef void (*DvrHwcFrameGetLayerCursorPtr)(DvrHwcFrame* frame,
-                                             size_t layer_index, int32_t* out_x,
-                                             int32_t* out_y);
-
-typedef uint32_t (*DvrHwcFrameGetLayerTransformPtr)(DvrHwcFrame* frame,
-                                                    size_t layer_index);
-
-typedef uint32_t (*DvrHwcFrameGetLayerDataspacePtr)(DvrHwcFrame* frame,
-                                                    size_t layer_index);
-
-typedef uint32_t (*DvrHwcFrameGetLayerColorPtr)(DvrHwcFrame* frame,
-                                                size_t layer_index);
-
-typedef uint32_t (*DvrHwcFrameGetLayerNumVisibleRegionsPtr)(DvrHwcFrame* frame,
-                                                            size_t layer_index);
-typedef DvrHwcRecti (*DvrHwcFrameGetLayerVisibleRegionPtr)(DvrHwcFrame* frame,
-                                                           size_t layer_index,
-                                                           size_t index);
-
-typedef uint32_t (*DvrHwcFrameGetLayerNumDamagedRegionsPtr)(DvrHwcFrame* frame,
-                                                            size_t layer_index);
-typedef DvrHwcRecti (*DvrHwcFrameGetLayerDamagedRegionPtr)(DvrHwcFrame* frame,
-                                                           size_t layer_index,
-                                                           size_t index);
-
-// dvr_performance.h
-typedef int (*DvrPerformanceSetSchedulerPolicyPtr)(
-    pid_t task_id, const char* scheduler_policy);
-
-// dvr_tracking.h
-typedef int (*DvrTrackingCameraCreatePtr)(DvrTrackingCamera** out_camera);
-typedef void (*DvrTrackingCameraDestroyPtr)(DvrTrackingCamera* camera);
-typedef int (*DvrTrackingCameraStartPtr)(DvrTrackingCamera* camera,
-                                         DvrWriteBufferQueue* write_queue);
-typedef int (*DvrTrackingCameraStopPtr)(DvrTrackingCamera* camera);
-
-typedef int (*DvrTrackingFeatureExtractorCreatePtr)(
-    DvrTrackingFeatureExtractor** out_extractor);
-typedef void (*DvrTrackingFeatureExtractorDestroyPtr)(
-    DvrTrackingFeatureExtractor* extractor);
-typedef void (*DvrTrackingFeatureCallback)(void* context,
-                                           const DvrTrackingFeatures* event);
-typedef int (*DvrTrackingFeatureExtractorStartPtr)(
-    DvrTrackingFeatureExtractor* extractor,
-    DvrTrackingFeatureCallback callback, void* context);
-typedef int (*DvrTrackingFeatureExtractorStopPtr)(
-    DvrTrackingFeatureExtractor* extractor);
-typedef int (*DvrTrackingFeatureExtractorProcessBufferPtr)(
-    DvrTrackingFeatureExtractor* extractor, DvrReadBuffer* buffer,
-    const DvrTrackingBufferMetadata* metadata, bool* out_skipped);
-
-typedef void (*DvrTrackingSensorEventCallback)(void* context,
-                                               DvrTrackingSensorEvent* event);
-typedef int (*DvrTrackingSensorsCreatePtr)(DvrTrackingSensors** out_sensors,
-                                           const char* mode);
-typedef void (*DvrTrackingSensorsDestroyPtr)(DvrTrackingSensors* sensors);
-typedef int (*DvrTrackingSensorsStartPtr)(
-    DvrTrackingSensors* sensors, DvrTrackingSensorEventCallback callback,
-    void* context);
-typedef int (*DvrTrackingSensorsStopPtr)(DvrTrackingSensors* sensors);
-
-// The buffer metadata that an Android Surface (a.k.a. ANativeWindow)
-// will populate. A DvrWriteBufferQueue must be created with this metadata iff
-// ANativeWindow access is needed. Please do not remove, modify, or reorder
-// existing data members. If new fields need to be added, please take extra care
-// to make sure that new data field is padded properly the size of the struct
-// stays same.
-// TODO(b/118893702): move the definition to libnativewindow or libui
-struct ALIGNED_DVR_STRUCT(8) DvrNativeBufferMetadata {
-#ifdef __cplusplus
-  DvrNativeBufferMetadata()
-      : timestamp(0),
-        is_auto_timestamp(0),
-        dataspace(0),
-        crop_left(0),
-        crop_top(0),
-        crop_right(0),
-        crop_bottom(0),
-        scaling_mode(0),
-        transform(0),
-        index(0),
-        user_metadata_size(0),
-        user_metadata_ptr(0),
-        release_fence_mask(0),
-        reserved{0} {}
-#endif
-  // Timestamp of the frame.
-  int64_t timestamp;
-
-  // Whether the buffer is using auto timestamp.
-  int32_t is_auto_timestamp;
-
-  // Must be one of the HAL_DATASPACE_XXX value defined in system/graphics.h
-  int32_t dataspace;
-
-  // Crop extracted from an ACrop or android::Crop object.
-  int32_t crop_left;
-  int32_t crop_top;
-  int32_t crop_right;
-  int32_t crop_bottom;
-
-  // Must be one of the NATIVE_WINDOW_SCALING_MODE_XXX value defined in
-  // system/window.h.
-  int32_t scaling_mode;
-
-  // Must be one of the ANATIVEWINDOW_TRANSFORM_XXX value defined in
-  // android/native_window.h
-  int32_t transform;
-
-  // The index of the frame.
-  int64_t index;
-
-  // Size of additional metadata requested by user.
-  uint64_t user_metadata_size;
-
-  // Raw memory address of the additional user defined metadata. Only valid when
-  // user_metadata_size is non-zero.
-  uint64_t user_metadata_ptr;
-
-  // Only applicable for metadata retrieved from GainAsync. This indicates which
-  // consumer has pending fence that producer should epoll on.
-  uint32_t release_fence_mask;
-
-  // Reserved bytes for so that the struct is forward compatible and padding to
-  // 104 bytes so the size is a multiple of 8.
-  int32_t reserved[9];
-};
-
-#ifdef __cplusplus
-// Warning: DvrNativeBufferMetadata is part of the DVR API and changing its size
-// will cause compatiblity issues between different DVR API releases.
-static_assert(sizeof(DvrNativeBufferMetadata) == 104,
-              "Unexpected size for DvrNativeBufferMetadata");
-#endif
-
-struct DvrApi_v1 {
-// Defines an API entry for V1 (no version suffix).
-#define DVR_V1_API_ENTRY(name) Dvr##name##Ptr name
-#define DVR_V1_API_ENTRY_DEPRECATED(name) Dvr##name##Ptr name
-
-#include "dvr_api_entries.h"
-
-// Undefine macro definitions to play nice with Google3 style rules.
-#undef DVR_V1_API_ENTRY
-#undef DVR_V1_API_ENTRY_DEPRECATED
-};
-
-int dvrGetApi(void* api, size_t struct_size, int version);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  // ANDROID_DVR_API_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_api_entries.h b/libs/vr/libdvr/include/dvr/dvr_api_entries.h
deleted file mode 100644
index 3006b61..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_api_entries.h
+++ /dev/null
@@ -1,200 +0,0 @@
-// dvr_api_entries.h
-//
-// Defines the DVR platform library API entries.
-//
-// Do not include this header directly.
-
-#ifndef DVR_V1_API_ENTRY
-#error Do not include this header directly.
-#endif
-
-#ifndef DVR_V1_API_ENTRY_DEPRECATED
-#error Do not include this header directly.
-#endif
-
-// Do not delete this line: BEGIN CODEGEN OUTPUT
-// Display manager client
-DVR_V1_API_ENTRY(DisplayManagerCreate);
-DVR_V1_API_ENTRY(DisplayManagerDestroy);
-DVR_V1_API_ENTRY(DisplayManagerGetEventFd);
-DVR_V1_API_ENTRY(DisplayManagerTranslateEpollEventMask);
-DVR_V1_API_ENTRY(DisplayManagerGetSurfaceState);
-DVR_V1_API_ENTRY(DisplayManagerGetReadBufferQueue);
-DVR_V1_API_ENTRY(ConfigurationDataGet);
-DVR_V1_API_ENTRY(ConfigurationDataDestroy);
-DVR_V1_API_ENTRY(SurfaceStateCreate);
-DVR_V1_API_ENTRY(SurfaceStateDestroy);
-DVR_V1_API_ENTRY(SurfaceStateGetSurfaceCount);
-DVR_V1_API_ENTRY(SurfaceStateGetUpdateFlags);
-DVR_V1_API_ENTRY(SurfaceStateGetSurfaceId);
-DVR_V1_API_ENTRY(SurfaceStateGetProcessId);
-DVR_V1_API_ENTRY(SurfaceStateGetQueueCount);
-DVR_V1_API_ENTRY(SurfaceStateGetQueueIds);
-DVR_V1_API_ENTRY(SurfaceStateGetZOrder);
-DVR_V1_API_ENTRY(SurfaceStateGetVisible);
-DVR_V1_API_ENTRY(SurfaceStateGetAttributeCount);
-DVR_V1_API_ENTRY(SurfaceStateGetAttributes);
-
-// Write buffer
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferCreateEmpty);
-DVR_V1_API_ENTRY(WriteBufferDestroy);
-DVR_V1_API_ENTRY(WriteBufferIsValid);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferClear);
-DVR_V1_API_ENTRY(WriteBufferGetId);
-DVR_V1_API_ENTRY(WriteBufferGetAHardwareBuffer);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferPost);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferGain);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferGainAsync);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferGetNativeHandle);
-
-// Read buffer
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferCreateEmpty);
-DVR_V1_API_ENTRY(ReadBufferDestroy);
-DVR_V1_API_ENTRY(ReadBufferIsValid);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferClear);
-DVR_V1_API_ENTRY(ReadBufferGetId);
-DVR_V1_API_ENTRY(ReadBufferGetAHardwareBuffer);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferAcquire);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferRelease);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferReleaseAsync);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferGetNativeHandle);
-
-// Buffer
-DVR_V1_API_ENTRY(BufferDestroy);
-DVR_V1_API_ENTRY(BufferGetAHardwareBuffer);
-DVR_V1_API_ENTRY_DEPRECATED(BufferGetNativeHandle);
-DVR_V1_API_ENTRY(BufferGlobalLayoutVersionGet);
-
-// Write buffer queue
-DVR_V1_API_ENTRY(WriteBufferQueueDestroy);
-DVR_V1_API_ENTRY(WriteBufferQueueGetCapacity);
-DVR_V1_API_ENTRY(WriteBufferQueueGetId);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferQueueGetExternalSurface);
-DVR_V1_API_ENTRY(WriteBufferQueueCreateReadQueue);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferQueueDequeue);
-DVR_V1_API_ENTRY(WriteBufferQueueResizeBuffer);
-
-// Read buffer queue
-DVR_V1_API_ENTRY(ReadBufferQueueDestroy);
-DVR_V1_API_ENTRY(ReadBufferQueueGetCapacity);
-DVR_V1_API_ENTRY(ReadBufferQueueGetId);
-DVR_V1_API_ENTRY(ReadBufferQueueCreateReadQueue);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferQueueDequeue);
-DVR_V1_API_ENTRY(ReadBufferQueueSetBufferAvailableCallback);
-DVR_V1_API_ENTRY(ReadBufferQueueSetBufferRemovedCallback);
-DVR_V1_API_ENTRY(ReadBufferQueueHandleEvents);
-
-// V-Sync client
-DVR_V1_API_ENTRY_DEPRECATED(VSyncClientCreate);
-DVR_V1_API_ENTRY_DEPRECATED(VSyncClientDestroy);
-DVR_V1_API_ENTRY_DEPRECATED(VSyncClientGetSchedInfo);
-
-// Display surface
-DVR_V1_API_ENTRY(SurfaceCreate);
-DVR_V1_API_ENTRY(SurfaceDestroy);
-DVR_V1_API_ENTRY(SurfaceGetId);
-DVR_V1_API_ENTRY(SurfaceSetAttributes);
-DVR_V1_API_ENTRY(SurfaceCreateWriteBufferQueue);
-DVR_V1_API_ENTRY(SetupGlobalBuffer);
-DVR_V1_API_ENTRY(DeleteGlobalBuffer);
-DVR_V1_API_ENTRY(GetGlobalBuffer);
-
-// Pose client
-DVR_V1_API_ENTRY(PoseClientCreate);
-DVR_V1_API_ENTRY(PoseClientDestroy);
-DVR_V1_API_ENTRY(PoseClientGet);
-DVR_V1_API_ENTRY(PoseClientGetVsyncCount);
-DVR_V1_API_ENTRY(PoseClientGetController);
-
-// Virtual touchpad client
-DVR_V1_API_ENTRY(VirtualTouchpadCreate);
-DVR_V1_API_ENTRY(VirtualTouchpadDestroy);
-DVR_V1_API_ENTRY(VirtualTouchpadAttach);
-DVR_V1_API_ENTRY(VirtualTouchpadDetach);
-DVR_V1_API_ENTRY(VirtualTouchpadTouch);
-DVR_V1_API_ENTRY(VirtualTouchpadButtonState);
-
-// VR HWComposer client
-DVR_V1_API_ENTRY(HwcClientCreate);
-DVR_V1_API_ENTRY(HwcClientDestroy);
-DVR_V1_API_ENTRY(HwcFrameDestroy);
-DVR_V1_API_ENTRY(HwcFrameGetDisplayId);
-DVR_V1_API_ENTRY(HwcFrameGetDisplayWidth);
-DVR_V1_API_ENTRY(HwcFrameGetDisplayHeight);
-DVR_V1_API_ENTRY(HwcFrameGetDisplayRemoved);
-DVR_V1_API_ENTRY(HwcFrameGetActiveConfig);
-DVR_V1_API_ENTRY(HwcFrameGetColorMode);
-DVR_V1_API_ENTRY(HwcFrameGetColorTransform);
-DVR_V1_API_ENTRY(HwcFrameGetPowerMode);
-DVR_V1_API_ENTRY(HwcFrameGetVsyncEnabled);
-DVR_V1_API_ENTRY(HwcFrameGetLayerCount);
-DVR_V1_API_ENTRY(HwcFrameGetLayerId);
-DVR_V1_API_ENTRY(HwcFrameGetLayerBuffer);
-DVR_V1_API_ENTRY(HwcFrameGetLayerFence);
-DVR_V1_API_ENTRY(HwcFrameGetLayerDisplayFrame);
-DVR_V1_API_ENTRY(HwcFrameGetLayerCrop);
-DVR_V1_API_ENTRY(HwcFrameGetLayerBlendMode);
-DVR_V1_API_ENTRY(HwcFrameGetLayerAlpha);
-DVR_V1_API_ENTRY(HwcFrameGetLayerType);
-DVR_V1_API_ENTRY(HwcFrameGetLayerApplicationId);
-DVR_V1_API_ENTRY(HwcFrameGetLayerZOrder);
-DVR_V1_API_ENTRY(HwcFrameGetLayerCursor);
-DVR_V1_API_ENTRY(HwcFrameGetLayerTransform);
-DVR_V1_API_ENTRY(HwcFrameGetLayerDataspace);
-DVR_V1_API_ENTRY(HwcFrameGetLayerColor);
-DVR_V1_API_ENTRY(HwcFrameGetLayerNumVisibleRegions);
-DVR_V1_API_ENTRY(HwcFrameGetLayerVisibleRegion);
-DVR_V1_API_ENTRY(HwcFrameGetLayerNumDamagedRegions);
-DVR_V1_API_ENTRY(HwcFrameGetLayerDamagedRegion);
-
-// New entries added at the end to allow the DVR platform library API
-// to be updated before updating VrCore.
-
-// Virtual touchpad client
-DVR_V1_API_ENTRY(VirtualTouchpadScroll);
-
-// Read the native display metrics from the hardware composer
-DVR_V1_API_ENTRY(GetNativeDisplayMetrics);
-
-// Performance
-DVR_V1_API_ENTRY(PerformanceSetSchedulerPolicy);
-
-// Pose client
-DVR_V1_API_ENTRY(PoseClientSensorsEnable);
-
-// Read buffer queue
-DVR_V1_API_ENTRY(ReadBufferQueueGetEventFd);
-
-// Create write buffer queue locally
-DVR_V1_API_ENTRY(WriteBufferQueueCreate);
-
-// Gets an ANativeWindow from DvrWriteBufferQueue.
-DVR_V1_API_ENTRY(WriteBufferQueueGetANativeWindow);
-
-// Dvr{Read,Write}BufferQueue API for asynchronous IPC.
-DVR_V1_API_ENTRY(WriteBufferQueueGainBuffer);
-DVR_V1_API_ENTRY(WriteBufferQueuePostBuffer);
-DVR_V1_API_ENTRY(ReadBufferQueueAcquireBuffer);
-DVR_V1_API_ENTRY(ReadBufferQueueReleaseBuffer);
-
-// Pose client
-DVR_V1_API_ENTRY(PoseClientGetDataReader);
-DVR_V1_API_ENTRY(PoseClientDataCapture);
-DVR_V1_API_ENTRY(PoseClientDataReaderDestroy);
-
-// Tracking
-DVR_V1_API_ENTRY(TrackingCameraCreate);
-DVR_V1_API_ENTRY(TrackingCameraDestroy);
-DVR_V1_API_ENTRY(TrackingCameraStart);
-DVR_V1_API_ENTRY(TrackingCameraStop);
-
-DVR_V1_API_ENTRY(TrackingFeatureExtractorCreate);
-DVR_V1_API_ENTRY(TrackingFeatureExtractorDestroy);
-DVR_V1_API_ENTRY(TrackingFeatureExtractorStart);
-DVR_V1_API_ENTRY(TrackingFeatureExtractorStop);
-DVR_V1_API_ENTRY(TrackingFeatureExtractorProcessBuffer);
-
-DVR_V1_API_ENTRY(TrackingSensorsCreate);
-DVR_V1_API_ENTRY(TrackingSensorsDestroy);
-DVR_V1_API_ENTRY(TrackingSensorsStart);
-DVR_V1_API_ENTRY(TrackingSensorsStop);
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer.h b/libs/vr/libdvr/include/dvr/dvr_buffer.h
deleted file mode 100644
index 4234844..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_buffer.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_H_
-#define ANDROID_DVR_BUFFER_H_
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-#include <memory>
-
-__BEGIN_DECLS
-
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrBuffer DvrBuffer;
-typedef struct AHardwareBuffer AHardwareBuffer;
-struct native_handle;
-
-// Destroys the write buffer.
-void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer);
-
-// Returns 1 if the given write buffer object contains a buffer, 0 otherwise.
-int dvrWriteBufferIsValid(DvrWriteBuffer* write_buffer);
-
-// Returns the global BufferHub id of this buffer.
-int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer);
-
-// Returns an AHardwareBuffer for the underlying buffer.
-// Caller must call AHardwareBuffer_release on hardware_buffer.
-int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
-                                     AHardwareBuffer** hardware_buffer);
-
-// Destroys the read buffer.
-void dvrReadBufferDestroy(DvrReadBuffer* read_buffer);
-
-// Returns 1 if the given write buffer object contains a buffer, 0 otherwise.
-int dvrReadBufferIsValid(DvrReadBuffer* read_buffer);
-
-// Returns the global BufferHub id of this buffer.
-int dvrReadBufferGetId(DvrReadBuffer* read_buffer);
-
-// Returns an AHardwareBuffer for the underlying buffer.
-// Caller must call AHardwareBuffer_release on hardware_buffer.
-int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
-                                    AHardwareBuffer** hardware_buffer);
-
-// Destroys the buffer.
-void dvrBufferDestroy(DvrBuffer* buffer);
-
-// Gets an AHardwareBuffer from the buffer.
-// Caller must call AHardwareBuffer_release on hardware_buffer.
-int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
-                                AHardwareBuffer** hardware_buffer);
-
-// Retrieve the shared buffer layout version defined in dvr_shared_buffers.h.
-int dvrBufferGlobalLayoutVersionGet();
-
-__END_DECLS
-
-#endif  // ANDROID_DVR_BUFFER_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
deleted file mode 100644
index ac789da..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
+++ /dev/null
@@ -1,263 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_QUEUE_H_
-#define ANDROID_DVR_BUFFER_QUEUE_H_
-
-#include <sys/cdefs.h>
-
-#include <dvr/dvr_buffer.h>
-
-__BEGIN_DECLS
-
-typedef struct ANativeWindow ANativeWindow;
-
-typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-
-// Creates a write buffer queue to be used locally.
-//
-// Note that this API is mostly for testing purpose. For now there is no
-// mechanism to send a DvrWriteBufferQueue cross process. Use
-// dvrSurfaceCreateWriteBufferQueue if cross-process buffer transport is
-// intended.
-//
-// @param width The width of the buffers that this queue will produce.
-// @param height The height of buffers that this queue will produce.
-// @param format The format of the buffers that this queue will produce. This
-//     must be one of the AHARDWAREBUFFER_FORMAT_XXX enums.
-// @param layer_count The number of layers of the buffers that this queue will
-//     produce.
-// @param usage The usage of the buffers that this queue will produce. This
-//     must a combination of the AHARDWAREBUFFER_USAGE_XXX flags.
-// @param capacity The number of buffer that this queue will allocate. Note that
-//     all buffers will be allocated on create. Currently, the number of buffers
-//     is the queue cannot be changed after creation though DVR API. However,
-//     ANativeWindow can choose to reallocate, attach, or detach buffers from
-//     a DvrWriteBufferQueue through Android platform logic.
-// @param metadata_size The size of metadata in bytes.
-// @param out_write_queue The pointer of a DvrWriteBufferQueue will be filled
-//      here if the method call succeeds. The metadata size must match
-//      the metadata size in dvrWriteBufferPost/dvrReadBufferAcquire.
-// @return Zero on success, or negative error code.
-int dvrWriteBufferQueueCreate(uint32_t width, uint32_t height, uint32_t format,
-                              uint32_t layer_count, uint64_t usage,
-                              size_t capacity, size_t metadata_size,
-                              DvrWriteBufferQueue** out_write_queue);
-
-// Destroy a write buffer queue.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue);
-
-// Get the total number of buffers in a write buffer queue.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-// @return The capacity on success; or negative error code.
-ssize_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue);
-
-// Get the system unique queue id of a write buffer queue.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-// @return Queue id on success; or negative error code.
-int dvrWriteBufferQueueGetId(DvrWriteBufferQueue* write_queue);
-
-// Gets an ANativeWindow backed by the DvrWriteBufferQueue
-//
-// Can be casted to a Java Surface using ANativeWindow_toSurface NDK API. Note
-// that the native window is lazily created at the first time |GetNativeWindow|
-// is called, and the created ANativeWindow will be cached so that multiple
-// calls to this method will return the same object. Also note that this method
-// does not acquire an additional reference to the ANativeWindow returned, don't
-// call ANativeWindow_release on it.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-// @param out_window The pointer of an ANativeWindow will be filled here if
-//     the method call succeeds.
-// @return Zero on success; or -EINVAL if this DvrWriteBufferQueue does not
-//     support being used as an android Surface.
-int dvrWriteBufferQueueGetANativeWindow(DvrWriteBufferQueue* write_queue,
-                                        ANativeWindow** out_window);
-
-// Create a read buffer queue from an existing write buffer queue.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-// @param out_read_queue The pointer of a DvrReadBufferQueue will be filled here
-//     if the method call succeeds.
-// @return Zero on success, or negative error code.
-int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
-                                       DvrReadBufferQueue** out_read_queue);
-
-// Gains a buffer to write into.
-//
-// @param write_queue The DvrWriteBufferQueue to gain buffer from.
-// @param timeout Specifies the number of milliseconds that the method will
-//     block. Specifying a timeout of -1 causes it to block indefinitely,
-//     while specifying a timeout equal to zero cause it to return immediately,
-//     even if no buffers are available.
-// @param out_buffer A targeting DvrWriteBuffer object to hold the output of the
-//     dequeue operation.
-// @param out_meta A DvrNativeBufferMetadata object populated by the
-//     corresponding dvrReadBufferQueueReleaseBuffer API.
-// @param out_fence_fd A sync fence fd defined in NDK's sync.h API, which
-//     signals the release of underlying buffer. The producer should wait until
-//     this fence clears before writing data into it.
-// @return Zero on success, or negative error code.
-int dvrWriteBufferQueueGainBuffer(DvrWriteBufferQueue* write_queue, int timeout,
-                                  DvrWriteBuffer** out_write_buffer,
-                                  DvrNativeBufferMetadata* out_meta,
-                                  int* out_fence_fd);
-
-// Posts a buffer and signals its readiness to be read from.
-//
-// @param write_queue The DvrWriteBufferQueue to post buffer into.
-// @param write_buffer The buffer to be posted.
-// @param meta The buffer metadata describing the buffer.
-// @param ready_fence_fd  A sync fence fd defined in NDK's sync.h API, which
-//     signals the readdiness of underlying buffer. When a valid fence gets
-//     passed in, the consumer will wait the fence to be ready before it starts
-//     to ready from the buffer.
-// @return Zero on success, or negative error code.
-int dvrWriteBufferQueuePostBuffer(DvrWriteBufferQueue* write_queue,
-                                  DvrWriteBuffer* write_buffer,
-                                  const DvrNativeBufferMetadata* meta,
-                                  int ready_fence_fd);
-
-// Overrides buffer dimension with new width and height.
-//
-// After the call successfully returns, each |dvrWriteBufferQueueDequeue| call
-// will return buffer with newly assigned |width| and |height|. When necessary,
-// old buffer will be removed from the buffer queue and replaced with new buffer
-// matching the new buffer size.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-// @param width Desired width, cannot be Zero.
-// @param height Desired height, cannot be Zero.
-// @return Zero on success, or negative error code.
-int dvrWriteBufferQueueResizeBuffer(DvrWriteBufferQueue* write_queue,
-                                    uint32_t width, uint32_t height);
-
-// Destroy a read buffer queue.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue);
-
-// Get the total number of buffers in a read buffer queue.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @return The capacity on success; or negative error code.
-ssize_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue);
-
-// Get the system unique queue id of a read buffer queue.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @return Queue id on success; or negative error code.
-int dvrReadBufferQueueGetId(DvrReadBufferQueue* read_queue);
-
-// Get the event fd that signals when queue updates occur.
-//
-// Use ReadBufferQueueHandleEvents to trigger registered event callbacks.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @return Fd on success; or negative error code.
-int dvrReadBufferQueueGetEventFd(DvrReadBufferQueue* read_queue);
-
-// Create a read buffer queue from an existing read buffer queue.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @param out_read_queue The pointer of a DvrReadBufferQueue will be filled here
-//     if the method call succeeds.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
-                                      DvrReadBufferQueue** out_read_queue);
-
-// Dequeues a buffer to read from.
-//
-// @param read_queue The DvrReadBufferQueue to acquire buffer from.
-// @param timeout Specifies the number of milliseconds that the method will
-//     block. Specifying a timeout of -1 causes it to block indefinitely,
-//     while specifying a timeout equal to zero cause it to return immediately,
-//     even if no buffers are available.
-// @param out_buffer A targeting DvrReadBuffer object to hold the output of the
-//     dequeue operation. Must be created by |dvrReadBufferCreateEmpty|.
-// @param out_meta A DvrNativeBufferMetadata object populated by the
-//     corresponding dvrWriteBufferQueuePostBuffer API.
-// @param out_fence_fd A sync fence fd defined in NDK's sync.h API, which
-//     signals the release of underlying buffer. The consumer should wait until
-//     this fence clears before reading data from it.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueAcquireBuffer(DvrReadBufferQueue* read_queue, int timeout,
-                                    DvrReadBuffer** out_read_buffer,
-                                    DvrNativeBufferMetadata* out_meta,
-                                    int* out_fence_fd);
-
-// Releases a buffer and signals its readiness to be written into.
-//
-// @param read_queue The DvrReadBufferQueue to release buffer into.
-// @param read_buffer The buffer to be released.
-// @param meta The buffer metadata describing the buffer.
-// @param release_fence_fd A sync fence fd defined in NDK's sync.h API, which
-//     signals the readdiness of underlying buffer. When a valid fence gets
-//     passed in, the producer will wait the fence to be ready before it starts
-//     to write into the buffer again.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueReleaseBuffer(DvrReadBufferQueue* read_queue,
-                                    DvrReadBuffer* read_buffer,
-                                    const DvrNativeBufferMetadata* meta,
-                                    int release_fence_fd);
-
-// Callback function which will be called when a buffer is avaiable.
-//
-// Note that there is no guarantee of thread safety and on which thread the
-// callback will be fired.
-//
-// @param context User provided opaque pointer.
-typedef void (*DvrReadBufferQueueBufferAvailableCallback)(void* context);
-
-// Set buffer avaiable callback.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @param callback The callback function. Set this to NULL if caller no longer
-//     needs to listen to new buffer available events.
-// @param context User provided opaque pointer, will be passed back during
-//     callback. The caller is responsible for ensuring the validity of the
-//     context through the life cycle of the DvrReadBufferQueue.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueSetBufferAvailableCallback(
-    DvrReadBufferQueue* read_queue,
-    DvrReadBufferQueueBufferAvailableCallback callback, void* context);
-
-// Callback function which will be called when a buffer is about to be removed.
-//
-// Note that there is no guarantee of thread safety and on which thread the
-// callback will be fired.
-//
-// @param buffer The buffer being removed. Once the callbacks returns, this
-//     buffer will be dereferenced from the buffer queue. If user has ever
-//     cached other DvrReadBuffer/AHardwareBuffer/EglImageKHR objects derived
-//     from this buffer, it's the user's responsibility to clean them up.
-//     Note that the ownership of the read buffer is not passed to this
-//     callback, so it should call dvrReadBufferDestroy on the buffer.
-// @param context User provided opaque pointer.
-typedef void (*DvrReadBufferQueueBufferRemovedCallback)(DvrReadBuffer* buffer,
-                                                        void* context);
-
-// Set buffer removed callback.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @param callback The callback function. Set this to NULL if caller no longer
-//     needs to listen to buffer removed events.
-// @param context User provided opaque pointer, will be passed back during
-//     callback. The caller is responsible for ensuring the validity of the
-//     context through the life cycle of the DvrReadBufferQueue.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueSetBufferRemovedCallback(
-    DvrReadBufferQueue* read_queue,
-    DvrReadBufferQueueBufferRemovedCallback callback, void* context);
-
-// Handle all pending events on the read queue.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueHandleEvents(DvrReadBufferQueue* read_queue);
-
-__END_DECLS
-
-#endif  // ANDROID_DVR_BUFFER_QUEUE_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_config.h b/libs/vr/libdvr/include/dvr/dvr_config.h
deleted file mode 100644
index 3d2c066..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_config.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef ANDROID_DVR_CONFIG_H
-#define ANDROID_DVR_CONFIG_H
-
-// This header is shared by VrCore and Android and must be kept in sync.
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-// This is a shared memory buffer for passing config data from VrCore to
-// libvrflinger in SurfaceFlinger.
-struct __attribute__((packed, aligned(16))) DvrConfig {
-  // Offset before vsync to submit frames to hardware composer.
-  int32_t frame_post_offset_ns{4000000};
-
-  // If the number of pending fences goes over this count at the point when we
-  // are about to submit a new frame to HWC, we will drop the frame. This
-  // should be a signal that the display driver has begun queuing frames. Note
-  // that with smart displays (with RAM), the fence is signaled earlier than
-  // the next vsync, at the point when the DMA to the display completes.
-  // Currently we use a smart display and the EDS timing coincides with zero
-  // pending fences, so this is 0.
-  int32_t allowed_pending_fence_count{0};
-
-  // New fields should always be added to the end for backwards compat.
-
-  // Reserved padding to 16 bytes.
-  uint8_t pad[8];
-};
-
-__END_DECLS
-
-#endif  // ANDROID_DVR_CONFIG_H
diff --git a/libs/vr/libdvr/include/dvr/dvr_configuration_data.h b/libs/vr/libdvr/include/dvr/dvr_configuration_data.h
deleted file mode 100644
index 22a509f..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_configuration_data.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef DVR_CONFIGURATION_DATA_H_
-#define DVR_CONFIGURATION_DATA_H_
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#include <dvr/dvr_display_types.h>
-#include <dvr/dvr_surface.h>
-
-__BEGIN_DECLS
-
-// Loads device configuration data of DVR_CONFIGURATION_DATA_*.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrConfigurationDataGet(int config_type,
-                            uint8_t** data, size_t* data_size);
-
-// Destroy the configuration data returned from dvrGetConfigurationData.
-void dvrConfigurationDataDestroy(uint8_t* data);
-
-__END_DECLS
-
-#endif  // DVR_CONFIGURATION_DATA_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_deleter.h b/libs/vr/libdvr/include/dvr/dvr_deleter.h
deleted file mode 100644
index fe59d1f..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_deleter.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef ANDROID_DVR_DELETER_H_
-#define ANDROID_DVR_DELETER_H_
-
-#include <sys/cdefs.h>
-
-#include <memory>
-
-// Header-only C++ helper to delete opaque DVR objects.
-
-__BEGIN_DECLS
-
-// Use forward declarations to avoid dependency on other headers.
-typedef struct DvrBuffer DvrBuffer;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
-typedef struct DvrDisplayManager DvrDisplayManager;
-typedef struct DvrSurfaceState DvrSurfaceState;
-typedef struct DvrSurface DvrSurface;
-typedef struct DvrHwcClient DvrHwcClient;
-typedef struct DvrHwcFrame DvrHwcFrame;
-
-void dvrBufferDestroy(DvrBuffer* buffer);
-void dvrReadBufferDestroy(DvrReadBuffer* read_buffer);
-void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer);
-void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue);
-void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue);
-void dvrDisplayManagerDestroy(DvrDisplayManager* client);
-void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state);
-void dvrSurfaceDestroy(DvrSurface* surface);
-void dvrHwcClientDestroy(DvrHwcClient* client);
-void dvrHwcFrameDestroy(DvrHwcFrame* frame);
-
-__END_DECLS
-
-// Avoid errors if this header is included in C code.
-#if defined(__cplusplus)
-
-namespace android {
-namespace dvr {
-
-// Universal DVR object deleter. May be passed to smart pointer types to handle
-// deletion of DVR API objects.
-struct DvrObjectDeleter {
-  void operator()(DvrBuffer* p) { dvrBufferDestroy(p); }
-  void operator()(DvrReadBuffer* p) { dvrReadBufferDestroy(p); }
-  void operator()(DvrWriteBuffer* p) { dvrWriteBufferDestroy(p); }
-  void operator()(DvrReadBufferQueue* p) { dvrReadBufferQueueDestroy(p); }
-  void operator()(DvrWriteBufferQueue* p) { dvrWriteBufferQueueDestroy(p); }
-  void operator()(DvrDisplayManager* p) { dvrDisplayManagerDestroy(p); }
-  void operator()(DvrSurfaceState* p) { dvrSurfaceStateDestroy(p); }
-  void operator()(DvrSurface* p) { dvrSurfaceDestroy(p); }
-  void operator()(DvrHwcClient* p) { dvrHwcClientDestroy(p); }
-  void operator()(DvrHwcFrame* p) { dvrHwcFrameDestroy(p); }
-};
-
-// Helper to define unique pointers for DVR object types.
-template <typename T>
-using MakeUniqueDvrPointer = std::unique_ptr<T, DvrObjectDeleter>;
-
-// Unique pointer types for DVR objects.
-using UniqueDvrBuffer = MakeUniqueDvrPointer<DvrBuffer>;
-using UniqueDvrReadBuffer = MakeUniqueDvrPointer<DvrReadBuffer>;
-using UniqueDvrWriteBuffer = MakeUniqueDvrPointer<DvrWriteBuffer>;
-using UniqueDvrReadBufferQueue = MakeUniqueDvrPointer<DvrReadBufferQueue>;
-using UniqueDvrWriteBufferQueue = MakeUniqueDvrPointer<DvrWriteBufferQueue>;
-using UniqueDvrDisplayManager = MakeUniqueDvrPointer<DvrDisplayManager>;
-using UniqueDvrSurfaceState = MakeUniqueDvrPointer<DvrSurfaceState>;
-using UniqueDvrSurface = MakeUniqueDvrPointer<DvrSurface>;
-using UniqueDvrHwcClient = MakeUniqueDvrPointer<DvrHwcClient>;
-using UniqueDvrHwcFrame = MakeUniqueDvrPointer<DvrHwcFrame>;
-
-// TODO(eieio): Add an adapter for std::shared_ptr that injects the deleter into
-// the relevant constructors.
-
-}  // namespace dvr
-}  // namespace android
-
-#endif // defined(__cplusplus)
-
-#endif  // ANDROID_DVR_DELETER_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_display_manager.h b/libs/vr/libdvr/include/dvr/dvr_display_manager.h
deleted file mode 100644
index f910d61..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_display_manager.h
+++ /dev/null
@@ -1,133 +0,0 @@
-#ifndef ANDROID_DVR_DISPLAY_MANAGER_H_
-#define ANDROID_DVR_DISPLAY_MANAGER_H_
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#include <dvr/dvr_display_types.h>
-#include <dvr/dvr_surface.h>
-
-__BEGIN_DECLS
-
-typedef struct DvrBuffer DvrBuffer;
-typedef struct DvrDisplayManager DvrDisplayManager;
-typedef struct DvrSurfaceState DvrSurfaceState;
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-
-typedef uint64_t DvrSurfaceUpdateFlags;
-
-// Attempts to connect to the display manager service.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrDisplayManagerCreate(DvrDisplayManager** client_out);
-
-// Destroys the display manager client object.
-void dvrDisplayManagerDestroy(DvrDisplayManager* client);
-
-// Returns an fd used to signal when surface updates occur. Note that depending
-// on the underlying transport, only a subset of the real event bits may be
-// supported. Use dvrDisplayManagerClientTranslateEpollEventMask to get the real
-// event flags.
-// @return the fd on success. Otherwise returns a negative error value.
-int dvrDisplayManagerGetEventFd(DvrDisplayManager* client);
-
-// @param in_events pass in the epoll revents that were initially returned by
-// poll/epoll.
-// @param on success, this value will be overwritten with the true poll/epoll
-// values.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrDisplayManagerTranslateEpollEventMask(DvrDisplayManager* client,
-                                             int in_events, int* out_events);
-
-// Queries the display manager service for the current state of the display
-// surfaces and stores the results in the given surface state object.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrDisplayManagerGetSurfaceState(DvrDisplayManager* client,
-                                     DvrSurfaceState* surface_state);
-
-// Gets a read buffer queue from the surface |surface_id| named |queue_id|. Each
-// call returns a different read buffer queue connected to the same write buffer
-// queue. Callers should cache these instead of requesting new ones when
-// possible.
-int dvrDisplayManagerGetReadBufferQueue(DvrDisplayManager* client,
-                                        int surface_id, int queue_id,
-                                        DvrReadBufferQueue** queue_out);
-
-// Creates a new surface state object. This object may be used to receive the
-// results of a surface state query. More than one state object may be created
-// to keep multiple snapshots, if desired.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateCreate(DvrSurfaceState** surface_state);
-
-// Destorys the surface state object.
-void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state);
-
-// Writes the number of surfaces described in the state object into |count_out|.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetSurfaceCount(DvrSurfaceState* surface_state,
-                                   size_t* count_out);
-
-// Returns the update flags for the surface at |surface_index| in the state
-// object. The flags may be used to determine what changes, if any, occurred to
-// the surface since the last state update.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetUpdateFlags(DvrSurfaceState* surface_state,
-                                  size_t surface_index,
-                                  DvrSurfaceUpdateFlags* flags_out);
-
-// Returns the unique identifier of surface at |surface_index| in the state
-// object. The identifier may be used to distinguish between surfaces.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetSurfaceId(DvrSurfaceState* surface_state,
-                                size_t surface_index, int* surface_id_out);
-
-// Returns the process id of surface at |surface_index| in the state object.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetProcessId(DvrSurfaceState* surface_state,
-                                size_t surface_index, int* process_id_out);
-
-// Writes the number of queues in the surface at |surface_index| in the state
-// object into |count_out|.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetQueueCount(DvrSurfaceState* surface_state,
-                                 size_t surface_index, size_t* count_out);
-
-// Returns up to |max_count| queue ids for the queues belonging to the surface
-// at |surface_index| in the state object.
-// @return The number of queue ids written on success. Otherwise returns a
-// negative error value.
-ssize_t dvrSurfaceStateGetQueueIds(DvrSurfaceState* surface_state,
-                                   size_t surface_index, int* queue_ids,
-                                   size_t max_count);
-
-// Writes the z-order of the surface at |surface_index| in surface state object
-// into |z_order_out|.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetZOrder(DvrSurfaceState* surface_state,
-                             size_t surface_index, int* z_order_out);
-
-// Writes the visible state of the surface at |surface_index| in the surface
-// state object into |visible_out|.
-// @return 0 on success. Otherwise it returns a negative error value.
-int dvrSurfaceStateGetVisible(DvrSurfaceState* surface_state,
-                              size_t surface_index, bool* visible_out);
-
-// Writes the number of attributes on the surface at |surface_index| in the
-// state object into |count_out|.
-// @return 0 on success. Otherwise it returns a negative error value.
-int dvrSurfaceStateGetAttributeCount(DvrSurfaceState* surface_state,
-                                     size_t surface_index, size_t* count_out);
-
-// Writes the list of attribute key/value pairs for the surface at
-// |surface_index| in the surface state object into |attributes|.
-// @return The number of attributes written on success. Otherwise returns a
-// negative error value.
-ssize_t dvrSurfaceStateGetAttributes(DvrSurfaceState* surface_state,
-                                     size_t surface_index,
-                                     DvrSurfaceAttribute* attributes,
-                                     size_t max_count);
-
-__END_DECLS
-
-#endif  // ANDROID_DVR_DISPLAY_MANAGER_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_display_types.h b/libs/vr/libdvr/include/dvr/dvr_display_types.h
deleted file mode 100644
index fd69843..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_display_types.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef ANDROID_DVR_DISPLAY_TYPES_H_
-#define ANDROID_DVR_DISPLAY_TYPES_H_
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-// Define types used in pose buffer fields. These types have atomicity
-// guarantees that are useful in lock-free shared memory ring buffers.
-#ifdef __ARM_NEON
-#include <arm_neon.h>
-#else
-#ifndef __FLOAT32X4T_86
-#define __FLOAT32X4T_86
-typedef float float32x4_t __attribute__((__vector_size__(16)));
-typedef struct float32x4x4_t { float32x4_t val[4]; } float32x4x4_t;
-#endif
-#endif
-
-// VrFlinger display manager surface state snapshots per surface flags
-// indicating what changed since the last snapshot.
-enum {
-  // No changes.
-  DVR_SURFACE_UPDATE_FLAGS_NONE = 0,
-  // This surface is new.
-  DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE = (1 << 0),
-  // Buffer queues added/removed.
-  DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED = (1 << 1),
-  // Visibility/z-order changed.
-  DVR_SURFACE_UPDATE_FLAGS_VISIBILITY_CHANGED = (1 << 2),
-  // Generic attributes changed.
-  DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED = (1 << 3),
-};
-
-// Surface attribute keys. VrFlinger defines keys in the negative integer space.
-// The compositor is free to use keys in the positive integer space for
-// implementation-defined purposes.
-enum {
-  // DIRECT: bool
-  // Determines whether a direct surface is created (compositor output) or an
-  // application surface. Defaults to false (application surface). May only be
-  // set to true by a process with either UID=root or UID validated with
-  // IsTrustedUid() (VrCore).
-  DVR_SURFACE_ATTRIBUTE_DIRECT = -3,
-  // Z_ORDER: int32_t
-  // Interpreted by VrFlinger only on direct surfaces to order the corresponding
-  // hardware layers. More positive values render on top of more negative
-  // values.
-  DVR_SURFACE_ATTRIBUTE_Z_ORDER = -2,
-  // VISIBLE: bool
-  // Interpreted by VrFlinger only on direct surfaces to determine whether a
-  // surface is assigned to a hardware layer or ignored.
-  DVR_SURFACE_ATTRIBUTE_VISIBLE = -1,
-  // INVALID
-  // Invalid key. No attributes should have this key.
-  DVR_SURFACE_ATTRIBUTE_INVALID = 0,
-  // FIRST_USER_KEY
-  // VrFlinger ingores any keys with this value or greater, passing them to the
-  // compositor through surface state query results.
-  DVR_SURFACE_ATTRIBUTE_FIRST_USER_KEY = 1,
-};
-
-__END_DECLS
-
-#endif  // ANDROID_DVR_DISPLAY_TYPES_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h
deleted file mode 100644
index 0ba76e2..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h
+++ /dev/null
@@ -1,199 +0,0 @@
-#ifndef ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
-#define ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
-
-#include <dvr/dvr_hardware_composer_types.h>
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct AHardwareBuffer AHardwareBuffer;
-typedef struct DvrHwcClient DvrHwcClient;
-typedef struct DvrHwcFrame DvrHwcFrame;
-
-// Called when a new frame has arrived.
-//
-// @param client_state Pointer to client state passed in |dvrHwcCreateClient()|.
-// @param frame New frame. Owned by the client.
-// @return fence FD for the release of the last frame.
-typedef int(*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
-
-// @param callback Called when a new frame is available.
-// @param client_state Pointer to client state passed back in the callback.
-DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback,
-                                 void* client_state);
-
-// Called to free the DvrHwcClient pointer.
-void dvrHwcClientDestroy(DvrHwcClient* client);
-
-// Called to free the frame information.
-// @param frame Pointer for the valid frame used for the query.
-void dvrHwcFrameDestroy(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return Identifier for the display associated by the frame.
-DvrHwcDisplay dvrHwcFrameGetDisplayId(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return width of the physical display associated with |frame|. This does not
-// take into account any orientation changes.
-int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return height of the physical display associated with |frame|. This does not
-// take into account any orientation changes.
-int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return True if the display has been removed. In this case the current frame
-// does not contain any valid layers to display. It is a signal to clean up any
-// display related state.
-bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return Number of layers in the frame.
-size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return The ID of the currently active display configuration.
-uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return The ID of the current color mode. See HAL_COLOR_MODE_* for valid
-// values.
-uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param out_matrix Output parameter for a float[16] array which will be filled
-// with the color transform matrix.
-// @param out_hint Output parameter which will contain the color transform hint.
-// See HAL_COLOR_TRANSFORM_* for valid values.
-void dvrHwcFrameGetColorTransform(DvrHwcFrame* frame, float* out_matrix,
-                                  int32_t* out_hint);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return The current power mode for the display. See HWC2_POWER_MODE_* for
-// valid values.
-uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return The current state of vsync. See HWC2_VSYNC_* for valid values.
-uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return A unique ID for the layer.
-DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index);
-
-// Return the graphic buffer associated with the layer at |layer_index| in
-// |frame|.
-//
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return Graphic buffer. Caller owns the buffer and is responsible for freeing
-// it. (see AHardwareBuffer_release())
-AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame,
-                                           size_t layer_index);
-
-// Returns the fence FD for the layer at index |layer_index| in |frame|.
-//
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return Fence FD. Caller owns the FD and is responsible for closing it.
-int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return describing the portion of the display covered by the layer. Will
-// not exceed the display dimensions.
-DvrHwcRecti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame,
-                                            size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return describing the portion of the layer that will fill the display
-// frame. Will not exceed the layer dimensions.
-DvrHwcRectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The blend mode of the layer.
-DvrHwcBlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame,
-                                             size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The alpha value to be applied to the whole layer. Will be in the
-// [0.0, 1.0] range.
-float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The type of the layer assigned by the window manager.
-uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The application id the layer belongs to.
-uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
-                                          size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The z-order for the layer.
-uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @param out_x Output parameter for the x coordinate of the cursor location.
-// @param out_y Output parameter for the y coordinate of the cursor location.
-void dvrHwcFrameGetLayerCursor(DvrHwcFrame* frame, size_t layer_index,
-                               int32_t* out_x, int32_t* out_y);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The transformation that needs to be applied to the layer before
-// presenting it. See DVR_HWC_TRANSFORM_* for valid values.
-uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The dataspace which represents how the pixel values should be
-// interpreted. See HAL_DATASPACE_* for valid values.
-uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The color of the layer if layer composition is SOLID_COLOR.
-uint32_t dvrHwcFrameGetLayerColor(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The number of visible regions.
-uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame,
-                                              size_t layer_index);
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @param index The index of the visible region for the layer.
-// @return The rectangle describing the visible region.
-DvrHwcRecti dvrHwcFrameGetLayerVisibleRegion(DvrHwcFrame* frame,
-                                             size_t layer_index, size_t index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The number of damanged regions.
-uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame,
-                                              size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @param index The index of the damanged region for the layer.
-// @return The rectangle describing the damaged region.
-DvrHwcRecti dvrHwcFrameGetLayerDamagedRegion(DvrHwcFrame* frame,
-                                             size_t layer_index, size_t index);
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  // ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
diff --git a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_types.h b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_types.h
deleted file mode 100644
index 1d5eda6..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_types.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef ANDROID_VR_HARDWARE_COMPOSER_DEFS_H
-#define ANDROID_VR_HARDWARE_COMPOSER_DEFS_H
-
-#include <inttypes.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// NOTE: These definitions must match the ones in
-// //hardware/libhardware/include/hardware/hwcomposer2.h. They are used by the
-// client side which does not have access to hwc2 headers.
-enum DvrHwcBlendMode {
-  DVR_HWC_BLEND_MODE_INVALID = 0,
-  DVR_HWC_BLEND_MODE_NONE = 1,
-  DVR_HWC_BLEND_MODE_PREMULTIPLIED = 2,
-  DVR_HWC_BLEND_MODE_COVERAGE = 3,
-};
-
-enum DvrHwcComposition {
-  DVR_HWC_COMPOSITION_INVALID = 0,
-  DVR_HWC_COMPOSITION_CLIENT = 1,
-  DVR_HWC_COMPOSITION_DEVICE = 2,
-  DVR_HWC_COMPOSITION_SOLID_COLOR = 3,
-  DVR_HWC_COMPOSITION_CURSOR = 4,
-  DVR_HWC_COMPOSITION_SIDEBAND = 5,
-};
-
-enum DvrHwcTransform {
-  DVR_HWC_TRANSFORM_NONE = 0,
-  DVR_HWC_TRANSFORM_FLIP_H = 1,
-  DVR_HWC_TRANSFORM_FLIP_V = 2,
-  DVR_HWC_TRANSFORM_ROT_90 = 4,
-  DVR_HWC_TRANSFORM_ROT_180 = 3,
-  DVR_HWC_TRANSFORM_ROT_270 = 7,
-};
-
-typedef uint64_t DvrHwcDisplay;
-typedef uint64_t DvrHwcLayer;
-
-struct DvrHwcRecti {
-  int32_t left;
-  int32_t top;
-  int32_t right;
-  int32_t bottom;
-};
-
-struct DvrHwcRectf {
-  float left;
-  float top;
-  float right;
-  float bottom;
-};
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  // ANDROID_DVR_HARDWARE_COMPOSER_DEFS_H
diff --git a/libs/vr/libdvr/include/dvr/dvr_performance.h b/libs/vr/libdvr/include/dvr/dvr_performance.h
deleted file mode 100644
index 5df35ad..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_performance.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCE_H_
-#define ANDROID_DVR_PERFORMANCE_H_
-
-#include <stddef.h>
-#include <unistd.h>
-
-__BEGIN_DECLS
-
-/// Sets the scheduler policy for a task.
-///
-/// Sets the scheduler policy for a task to the class described by a semantic
-/// string.
-///
-/// Supported policies are device-specific.
-///
-/// @param task_id The task id of task to set the policy for. When task_id is 0
-/// the current task id is substituted.
-/// @param scheduler_policy NULL-terminated ASCII string containing the desired
-/// scheduler policy.
-/// @returns Returns 0 on success or a negative errno error code on error.
-int dvrPerformanceSetSchedulerPolicy(pid_t task_id, const char* scheduler_policy);
-
-__END_DECLS
-
-#endif  // ANDROID_DVR_PERFORMANCE_H_
-
diff --git a/libs/vr/libdvr/include/dvr/dvr_pose.h b/libs/vr/libdvr/include/dvr/dvr_pose.h
deleted file mode 100644
index 8752751..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_pose.h
+++ /dev/null
@@ -1,154 +0,0 @@
-#ifndef ANDROID_DVR_PUBLIC_POSE_H_
-#define ANDROID_DVR_PUBLIC_POSE_H_
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-#ifdef __ARM_NEON
-#include <arm_neon.h>
-#else
-#ifndef __FLOAT32X4T_86
-#define __FLOAT32X4T_86
-typedef float float32x4_t __attribute__((__vector_size__(16)));
-#endif
-#endif
-
-typedef struct DvrPoseClient DvrPoseClient;
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-
-// Represents an estimated pose, accessed asynchronously through a shared ring
-// buffer. No assumptions should be made about the data in padding space.
-// The size of this struct is 128 bytes.
-typedef struct __attribute__((packed, aligned(16))) DvrPoseAsync {
-  // Left eye head-from-start orientation quaternion x,y,z,w.
-  float32x4_t orientation;
-  // Left eye head-from-start position x,y,z,pad in meters.
-  float32x4_t position;
-  // Right eye head-from-start orientation quaternion x,y,z,w.
-  float32x4_t right_orientation;
-  // Right eye head-from-start position x,y,z,pad in meters.
-  float32x4_t right_position;
-  // Start-space angular velocity x,y,z,pad in radians per second.
-  float32x4_t angular_velocity;
-  // Start-space positional velocity x,y,z,pad in meters per second.
-  float32x4_t velocity;
-  // Timestamp of when this pose is predicted for, typically halfway through
-  // scanout.
-  int64_t timestamp_ns;
-  // Bitmask of DVR_POSE_FLAG_* constants that apply to this pose.
-  //
-  // If DVR_POSE_FLAG_INVALID is set, the pose is indeterminate.
-  uint64_t flags;
-  // Reserved padding to 128 bytes.
-  uint8_t pad[16];
-} DvrPoseAsync;
-
-enum {
-  DVR_POSE_FLAG_INVALID = (1ULL << 0),       // This pose is invalid.
-  DVR_POSE_FLAG_INITIALIZING = (1ULL << 1),  // The pose delivered during
-                                             // initialization and it may not be
-                                             // correct.
-  DVR_POSE_FLAG_3DOF =
-      (1ULL << 2),  // This pose is derived from 3Dof sensors. If
-                    // this is not set, pose is derived using
-                    // 3Dof and 6Dof sensors.
-  DVR_POSE_FLAG_FLOOR_HEIGHT_INVALID =
-      (1ULL << 3),  // If set the floor height is invalid.
-
-  // Bits that indicate the tracking system state.
-  DVR_POSE_FLAG_SERVICE_EXCEPTION = (1ULL << 32),
-  DVR_POSE_FLAG_FISHEYE_OVER_EXPOSED = (1ULL << 33),
-  DVR_POSE_FLAG_FISHEYE_UNDER_EXPOSED = (1ULL << 34),
-  DVR_POSE_FLAG_COLOR_OVER_EXPOSED = (1ULL << 35),
-  DVR_POSE_FLAG_COLOR_UNDER_EXPOSED = (1ULL << 36),
-  DVR_POSE_FLAG_TOO_FEW_FEATURES_TRACKED = (1ULL << 37)
-};
-
-// Represents a sensor pose sample.
-typedef struct __attribute__((packed, aligned(16))) DvrPose {
-  // Head-from-start orientation quaternion x,y,z,w.
-  float32x4_t orientation;
-
-  // The angular velocity where the x,y,z is the rotation axis and the
-  // magnitude is the radians / second in the same coordinate frame as
-  // orientation.
-  float32x4_t angular_velocity;
-
-  // Head-from-start position x,y,z,pad in meters.
-  float32x4_t position;
-
-  // In meters / second in the same coordinate frame as position.
-  float32x4_t velocity;
-
-  // In meters / second ^ 2 in the same coordinate frame as position.
-  float32x4_t acceleration;
-
-  // Timestamp for the measurement in nanoseconds.
-  int64_t timestamp_ns;
-
-  // The combination of flags above.
-  uint64_t flags;
-
-  // The current floor height. May be updated at a lower cadence than pose.
-  float floor_height;
-
-  // Padding to 112 bytes so the size is a multiple of 16.
-  uint8_t padding[12];
-} DvrPose;
-
-// Represents a data type that can be streamed from pose service.
-enum {
-  DVR_POSE_RAW_DATA_STEREO_IMAGE = (1ULL << 0),
-  DVR_POSE_RAW_DATA_POINT_CLOUD = (1ULL << 1),
-  DVR_POSE_RAW_DATA_FEATURES = (1ULL << 2),
-
-  // Always last.
-  DVR_POSE_RAW_DATA_COUNT = (1ULL << 3),
-};
-
-// A request to retrieve data from the pose service. Expects that a buffer
-// queue has been initialized through dvrPoseClientGetDataReader().
-typedef struct DvrPoseDataCaptureRequest {
-  // The type of data to capture. Refer to enum DVR_POSE_RAW_DATA_* for types.
-  uint64_t data_type;
-  // The sample interval. This can be used to skip samples. For example, a
-  // value of 5 will capture every fifth frame and discard the 4 frames in
-  // between. Set to 1 to capture all frames.
-  uint32_t sample_interval;
-  // The length of time to capture samples in milliseconds. Set to 0 to capture
-  // indefinitely.
-  uint32_t capture_time_ms;
-  // Reserved fields.
-  uint32_t reserved0;
-  uint32_t reserved1;
-  uint32_t reserved2;
-  uint32_t reserved3;
-  uint32_t reserved4;
-} DvrPoseDataCaptureRequest;
-
-// Gets a read buffer queue for the data type |data_type|. Each call returns a
-// different read buffer queue connected to the same write buffer queue. A
-// separate write buffer queue exists for each |data_type|.
-//
-// PoseService supports a single consumer per write buffer queue. The consumer
-// is expected to hold a single DvrReadBufferQueue at a time. Callers should
-// cache these instead of requesting new ones when possible. If the consumer
-// disconnects from the queue, it can regain a read buffer queue for the same
-// producer by calling this function.
-//
-// For data_type DVR_POSE_RAW_DATA_STEREO_IMAGE, each buffer consists of two
-// images formatted as a AHARDWAREBUFFER_FORMAT_BLOB, where height is 1 and
-// width is the total size of both images. The size of an individual image can
-// be found in the metadata struct DvrNativeBufferMetadata, where width is
-// |crop_right| and height is |crop_bottom|/2. Each image is contiguous in
-// memory with stride equal to width.
-int dvrPoseClientGetDataReader(DvrPoseClient* client, uint64_t data_type,
-                               DvrReadBufferQueue** queue_out);
-
-// TODO(b/65067592): Move pose api's from pose_client.h to here.
-
-__END_DECLS
-
-#endif  // ANDROID_DVR_PUBLIC_POSE_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h b/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h
deleted file mode 100644
index 63c7385..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef ANDROID_DVR_SHARED_BUFFERS_H_
-#define ANDROID_DVR_SHARED_BUFFERS_H_
-
-#include <dvr/dvr_config.h>
-#include <dvr/dvr_pose.h>
-#include <dvr/dvr_vsync.h>
-#include <libbroadcastring/broadcast_ring.h>
-
-// This header is shared by VrCore and Android and must be kept in sync.
-namespace android {
-namespace dvr {
-
-// Increment when the layout for the buffers change.
-enum : uint32_t { kSharedBufferLayoutVersion = 2 };
-
-// Note: These buffers will be mapped from various system processes as well
-// as VrCore and the application processes in a r/w manner.
-//
-// Therefore it is possible for the application to mess with the contents of
-// these buffers.
-//
-// While using them, assume garbage memory: Your logic must not crash or lead
-// to execution of unsafe code as a function of the contents of these buffers.
-
-// Sanity check for basic type sizes.
-static_assert(sizeof(DvrPoseAsync) == 128, "Unexpected size for DvrPoseAsync");
-static_assert(sizeof(DvrPose) == 112, "Unexpected size for DvrPose");
-static_assert(sizeof(DvrVsync) == 32, "Unexpected size for DvrVsync");
-static_assert(sizeof(DvrConfig) == 16, "Unexpected size for DvrConfig");
-
-// A helper class that provides compile time sized traits for the BroadcastRing.
-template <class DvrType, size_t StaticCount>
-class DvrRingBufferTraits {
- public:
-  using Record = DvrType;
-  static constexpr bool kUseStaticRecordSize = false;
-  static constexpr uint32_t kStaticRecordCount = StaticCount;
-  static constexpr int kMaxReservedRecords = 1;
-  static constexpr int kMinAvailableRecords = 1;
-};
-
-// Traits classes.
-using DvrPoseTraits = DvrRingBufferTraits<DvrPose, 0>;
-using DvrVsyncTraits = DvrRingBufferTraits<DvrVsync, 2>;
-using DvrConfigTraits = DvrRingBufferTraits<DvrConfig, 2>;
-
-// The broadcast ring classes that will expose the data.
-using DvrPoseRing = BroadcastRing<DvrPose, DvrPoseTraits>;
-using DvrVsyncRing = BroadcastRing<DvrVsync, DvrVsyncTraits>;
-using DvrConfigRing = BroadcastRing<DvrConfig, DvrConfigTraits>;
-
-// This is a shared memory buffer for passing pose data estimated at vsyncs.
-//
-// This will be primarily used for late latching and EDS where we bind this
-// buffer in a shader and extract the right vsync-predicted pose.
-struct __attribute__((packed, aligned(16))) DvrVsyncPoseBuffer {
-  enum : int {
-    // The number vsync predicted poses to keep in the ring buffer.
-    // Must be a power of 2.
-    kSize = 8,
-    kIndexMask = kSize - 1,
-
-    // The number of vsyncs (from the current vsync) we predict in vsync buffer.
-    // The other poses are left alone.
-    kMinFutureCount = 4
-  };
-
-  // The vsync predicted poses.
-  // The pose for the vsync n is:
-  // vsync_poses[n % kSize]
-  //
-  // This buffer is unsynchronized: It is possible to get torn reads as the
-  // sensor service updates the predictions as new sensor measurements come
-  // in. In particular, it is possible to get the position and an updated
-  // orientation while reading.
-  DvrPoseAsync vsync_poses[kSize];
-
-  // The latest sensor pose for GPU usage.
-  DvrPose current_pose;
-
-  // Current vsync_count (where sensord is writing poses from).
-  uint32_t vsync_count;
-
-  // For 16 byte alignment.
-  uint8_t padding[12];
-};
-
-static_assert(sizeof(DvrVsyncPoseBuffer) == 1152,
-              "Unexpected size for DvrVsyncPoseBuffer");
-
-// The keys for the dvr global buffers.
-enum DvrGlobalBuffers : int32_t {
-  kVsyncPoseBuffer = 1,
-  kVsyncBuffer = 2,
-  kSensorPoseBuffer = 3,
-  kVrFlingerConfigBufferKey = 4
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_SHARED_BUFFERS_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_surface.h b/libs/vr/libdvr/include/dvr/dvr_surface.h
deleted file mode 100644
index 74a68a1..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_surface.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef ANDROID_DVR_SURFACE_H_
-#define ANDROID_DVR_SURFACE_H_
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#include <dvr/dvr_api.h>
-#include <dvr/dvr_buffer.h>
-#include <dvr/dvr_buffer_queue.h>
-#include <dvr/dvr_display_types.h>
-
-__BEGIN_DECLS
-
-// Attribute types. The values are one-hot encoded to support singluar types or
-// masks of supported types.
-enum {
-  DVR_SURFACE_ATTRIBUTE_TYPE_NONE = 0,
-  DVR_SURFACE_ATTRIBUTE_TYPE_INT32 = (1 << 0),
-  DVR_SURFACE_ATTRIBUTE_TYPE_INT64 = (1 << 1),
-  DVR_SURFACE_ATTRIBUTE_TYPE_BOOL = (1 << 2),
-  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT = (1 << 3),
-  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2 = (1 << 4),
-  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3 = (1 << 5),
-  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4 = (1 << 6),
-  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8 = (1 << 7),
-  DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16 = (1 << 8),
-};
-
-typedef uint64_t DvrSurfaceAttributeType;
-typedef int32_t DvrSurfaceAttributeKey;
-
-typedef struct DvrSurfaceAttributeValue {
-  DvrSurfaceAttributeType type;
-  union {
-    int32_t int32_value;
-    int64_t int64_value;
-    bool bool_value;
-    float float_value;
-    float float2_value[2];
-    float float3_value[3];
-    float float4_value[4];
-    float float8_value[8];
-    float float16_value[16];
-  };
-} DvrSurfaceAttributeValue;
-
-typedef struct DvrSurfaceAttribute {
-  DvrSurfaceAttributeKey key;
-  DvrSurfaceAttributeValue value;
-} DvrSurfaceAttribute;
-
-// Creates a new display surface with the given attributes.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
-                     size_t attribute_count, DvrSurface** surface_out);
-
-// Destroys the display surface.
-void dvrSurfaceDestroy(DvrSurface* surface);
-
-// Gets the DisplayService global id for this surface.
-int dvrSurfaceGetId(DvrSurface* surface);
-
-// Sets attributes on the given display surface.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceSetAttributes(DvrSurface* surface,
-                            const DvrSurfaceAttribute* attributes,
-                            size_t attribute_count);
-
-// Creates a new write-side buffer queue on the given surface. Direct surfaces
-// may only have one queue, the latest call replacing any prior queue. Replaced
-// queues are still referenced and should be destryoed using the queue destroy
-// API.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
-                                     uint32_t height, uint32_t format,
-                                     uint32_t layer_count, uint64_t usage,
-                                     size_t capacity, size_t metadata_size,
-                                     DvrWriteBufferQueue** queue_out);
-
-// Sets up a named buffer for shared memory data transfer between display
-// clients and the system. Protected API that may only be called with sufficient
-// privilege.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSetupGlobalBuffer(DvrGlobalBufferKey key, size_t size, uint64_t usage,
-                         DvrBuffer** buffer_out);
-
-// Deletes a named buffer. WARNING: This is dangerous because any existing
-// clients of this buffer will not be notified and will remain attached to
-// the old buffer. This is useful for tests, but probably not for production
-// code.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrDeleteGlobalBuffer(DvrGlobalBufferKey key);
-
-// Get a global buffer from the display service.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrGetGlobalBuffer(DvrGlobalBufferKey key, DvrBuffer** out_buffer);
-
-// Read the native device display metrics as reported by the hardware composer.
-// This is useful as otherwise the device metrics are only reported as
-// relative to the current device orientation.
-// @param sizeof_metrics the size of the passed in metrics struct. This is used
-//   to ensure we don't break each other during active development.
-// @param metrics on success holds the retrieved device metrics.
-// @return 0 on success. Otherwise returns a negative error value (typically
-//   this means the display service is not available).
-int dvrGetNativeDisplayMetrics(size_t metrics_struct_size,
-                               DvrNativeDisplayMetrics* metrics);
-
-__END_DECLS
-
-#endif  // ANDROID_DVR_SURFACE_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_tracking.h b/libs/vr/libdvr/include/dvr/dvr_tracking.h
deleted file mode 100644
index 5e388f3..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_tracking.h
+++ /dev/null
@@ -1,185 +0,0 @@
-#ifndef ANDROID_DVR_TRACKING_H_
-#define ANDROID_DVR_TRACKING_H_
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#include <dvr/dvr_tracking_types.h>
-
-__BEGIN_DECLS
-
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrTrackingCamera DvrTrackingCamera;
-typedef struct DvrTrackingFeatureExtractor DvrTrackingFeatureExtractor;
-typedef struct DvrTrackingSensors DvrTrackingSensors;
-typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
-
-// The callback for DvrTrackingFeatureExtractor that will deliver the feature
-// events. This callback is passed to dvrTrackingFeatureExtractorStart.
-typedef void (*DvrTrackingFeatureCallback)(void* context,
-                                           const DvrTrackingFeatures* event);
-
-// The callback for DvrTrackingSensors session that will deliver the events.
-// This callback is passed to dvrTrackingSensorsStart.
-typedef void (*DvrTrackingSensorEventCallback)(void* context,
-                                               DvrTrackingSensorEvent* event);
-
-// Creates a DvrTrackingCamera session.
-//
-// On creation, the session is not in operating mode. Client code must call
-// dvrTrackingCameraStart to bootstrap the underlying camera stack.
-//
-// There is no plan to expose camera configuration through this API. All camera
-// parameters are determined by the system optimized for better tracking
-// results. See b/78662281 for detailed deprecation plan of this API and the
-// Stage 2 of VR tracking data source refactoring.
-//
-// @param out_camera The pointer of a DvrTrackingCamera will be filled here if
-//     the method call succeeds.
-// @return Zero on success, or negative error code.
-int dvrTrackingCameraCreate(DvrTrackingCamera** out_camera);
-
-// Destroys a DvrTrackingCamera handle.
-//
-// @param camera The DvrTrackingCamera of interest.
-void dvrTrackingCameraDestroy(DvrTrackingCamera* camera);
-
-// Starts the DvrTrackingCamera.
-//
-// On successful return, all DvrReadBufferQueue's associated with the given
-// write_queue will start to receive buffers from the camera stack. Note that
-// clients of this API should not assume the buffer dimension, format, and/or
-// usage of the outcoming buffers, as they are governed by the underlying camera
-// logic. Also note that it's the client's responsibility to consume buffers
-// from DvrReadBufferQueue on time and return them back to the producer;
-// otherwise the camera stack might be blocked.
-//
-// @param camera The DvrTrackingCamera of interest.
-// @param write_queue A DvrWriteBufferQueue that the camera stack can use to
-//     populate the buffer into. The queue must be empty and the camera stack
-//     will request buffer allocation with proper buffer dimension, format, and
-//     usage. Note that the write queue must be created with user_metadata_size
-//     set to sizeof(DvrTrackingBufferMetadata). On success, the write_queue
-//     handle will become invalid and the ownership of the queue handle will be
-//     transferred into the camera; otherwise, the write_queue handle will keep
-//     untouched and the caller still has the ownership.
-// @return Zero on success, or negative error code.
-int dvrTrackingCameraStart(DvrTrackingCamera* camera,
-                           DvrWriteBufferQueue* write_queue);
-
-// Stops the DvrTrackingCamera.
-//
-// On successful return, the DvrWriteBufferQueue set during
-// dvrTrackingCameraStart will stop getting new buffers from the camera stack.
-//
-// @param camera The DvrTrackingCamera of interest.
-// @return Zero on success, or negative error code.
-int dvrTrackingCameraStop(DvrTrackingCamera* camera);
-
-// Creates a DvrTrackingSensors session.
-//
-// This will initialize but not start device sensors (gyro / accel). Upon
-// successfull creation, the clients can call dvrTrackingSensorsStart to start
-// receiving sensor events.
-//
-// @param out_sensors The pointer of a DvrTrackingSensors will be filled here if
-//     the method call succeeds.
-// @param mode The sensor mode.
-//        mode="ndk": Use the Android NDK.
-//        mode="direct": Use direct mode sensors (lower latency).
-// @return Zero on success, or negative error code.
-int dvrTrackingSensorsCreate(DvrTrackingSensors** out_sensors,
-                             const char* mode);
-
-// Destroys a DvrTrackingSensors session.
-//
-// @param sensors The DvrTrackingSensors struct to destroy.
-void dvrTrackingSensorsDestroy(DvrTrackingSensors* sensors);
-
-// Starts the tracking sensor session.
-//
-// This will start the device sensors and start pumping the feature and sensor
-// events as they arrive.
-//
-// @param client A tracking client created by dvrTrackingSensorsCreate.
-// @param context A client supplied pointer that will be passed to the callback.
-// @param callback A callback that will receive the sensor events on an
-// arbitrary thread.
-// @return Zero on success, or negative error code.
-int dvrTrackingSensorsStart(DvrTrackingSensors* sensors,
-                            DvrTrackingSensorEventCallback callback,
-                            void* context);
-
-// Stops a DvrTrackingSensors session.
-//
-// This will stop the device sensors. dvrTrackingSensorsStart can be called to
-// restart them again.
-//
-// @param client A tracking client created by dvrTrackingClientCreate.
-// @return Zero on success, or negative error code.
-int dvrTrackingSensorsStop(DvrTrackingSensors* sensors);
-
-// Creates a tracking feature extractor.
-//
-// This will initialize but not start the feature extraction session. Upon
-// successful creation, the client can call dvrTrackingFeatureExtractorStart to
-// start receiving features.
-//
-// @param out_extractor The pointer of a DvrTrackingFeatureExtractor will be
-//     filled here if the method call succeeds.
-int dvrTrackingFeatureExtractorCreate(
-    DvrTrackingFeatureExtractor** out_extractor);
-
-// Destroys a tracking feature extractor.
-//
-// @param extractor The DvrTrackingFeatureExtractor to destroy.
-void dvrTrackingFeatureExtractorDestroy(DvrTrackingFeatureExtractor* extractor);
-
-// Starts the tracking feature extractor.
-//
-// This will start the extractor and start pumping the output feature events to
-// the registered callback. Note that this method will create one or more
-// threads to handle feature processing.
-//
-// @param extractor The DvrTrackingFeatureExtractor to destroy.
-int dvrTrackingFeatureExtractorStart(DvrTrackingFeatureExtractor* extractor,
-                                     DvrTrackingFeatureCallback callback,
-                                     void* context);
-
-// Stops the tracking feature extractor.
-//
-// This will stop the extractor session and clean up all internal resourcse
-// related to this extractor. On succssful return, all internal therad started
-// by dvrTrackingFeatureExtractorStart should be stopped.
-//
-// @param extractor The DvrTrackingFeatureExtractor to destroy.
-int dvrTrackingFeatureExtractorStop(DvrTrackingFeatureExtractor* extractor);
-
-// Processes one buffer to extract features from.
-//
-// The buffer will be sent over to DSP for feature extraction. Once the process
-// is done, the processing thread will invoke DvrTrackingFeatureCallback with
-// newly extracted features. Note that not all buffers will be processed, as the
-// underlying DSP can only process buffers at a certain framerate. If a buffer
-// needs to be skipped, out_skipped filed will be set to true. Also note that
-// for successfully processed stereo buffer, two callbacks (one for each eye)
-// will be fired.
-//
-// @param extractor The DvrTrackingFeatureExtractor to destroy.
-// @param buffer The buffer to extract features from. Note that the buffer must
-//     be in acquired state for the buffer to be processed. Also note that the
-//     buffer will be released back to its producer on successful return of the
-//     method.
-// @param metadata The metadata associated with the buffer. Should be populated
-//     by DvrTrackingCamera session as user defined metadata.
-// @param out_skipped On successful return, the field will be set to true iff
-//     the buffer was skipped; and false iff the buffer was processed. This
-//     field is optional and nullptr can be passed here to ignore the field.
-// @return Zero on success, or negative error code.
-int dvrTrackingFeatureExtractorProcessBuffer(
-    DvrTrackingFeatureExtractor* extractor, DvrReadBuffer* buffer,
-    const DvrTrackingBufferMetadata* metadata, bool* out_skipped);
-
-__END_DECLS
-
-#endif  // ANDROID_DVR_TRACKING_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_tracking_types.h b/libs/vr/libdvr/include/dvr/dvr_tracking_types.h
deleted file mode 100644
index 81310d2..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_tracking_types.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef ANDROID_DVR_TRACKING_TYPES_H_
-#define ANDROID_DVR_TRACKING_TYPES_H_
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-typedef struct DvrTrackingBufferMetadata {
-  // Specifies the source of this image.
-  uint32_t camera_mask;
-  // Specifies the memory format of this image.
-  uint32_t format;
-  /// The width of the image data.
-  uint32_t width;
-  /// The height of the image data.
-  uint32_t height;
-  /// The number of bytes per scanline of image data.
-  uint32_t stride;
-  /// The frame number of this image.
-  int32_t frame_number;
-  /// The timestamp of this image in nanoseconds. Taken in the middle of the
-  /// exposure interval.
-  int64_t timestamp_ns;
-  // This is the timestamp for recording when the system using the HAL
-  // received the callback.  It will not be populated by the HAL.
-  int64_t callback_timestamp_ns;
-  /// The exposure duration of this image in nanoseconds.
-  int64_t exposure_duration_ns;
-} DvrTrackingBufferMetadata;
-
-// Represents a set of features extracted from a camera frame. Note that this
-// should be in sync with TangoHalCallbacks defined in tango-hal.h.
-typedef struct DvrTrackingFeatures {
-  // Specifies the source of the features.
-  uint32_t camera_mask;
-
-  // This is unused.
-  uint32_t unused;
-
-  // The timestamp in nanoseconds from the image that generated the features.
-  // Taken in the middle of the exposure interval.
-  int64_t timestamp_ns;
-
-  // This is the timestamp for recording when the system using the HAL
-  // received the callback.  It will not be populated by the HAL.
-  int64_t callback_timestamp_ns;
-
-  // The frame number from the image that generated the features.
-  int64_t frame_number;
-
-  // The number of features.
-  int count;
-
-  // An array of 2D image points for each feature in the current image.
-  // This is sub-pixel refined extremum location at the fine resolution.
-  float (*positions)[2];
-
-  // The id of these measurements.
-  int32_t* ids;
-
-  // The feature descriptors.
-  uint64_t (*descriptors)[8];
-
-  // Laplacian scores for each feature.
-  float* scores;
-
-  // Is this feature a minimum or maximum in the Laplacian image.
-  // 0 if the feature is a maximum, 1 if it is a minimum.
-  int32_t* is_minimum;
-
-  // This corresponds to the sub-pixel index of the laplacian image
-  // that the extremum was found.
-  float* scales;
-
-  // Computed orientation of keypoint as part of FREAK extraction, except
-  // it's represented in radians and measured anti-clockwise.
-  float* angles;
-
-  // Edge scores for each feature.
-  float* edge_scores;
-} DvrTrackingFeatures;
-
-// Represents a sensor event.
-typedef struct DvrTrackingSensorEvent {
-  // The sensor type.
-  int32_t sensor;
-
-  // Event type.
-  int32_t type;
-
-  // This is the timestamp recorded from the device. Taken in the middle
-  // of the integration interval and adjusted for any low pass filtering.
-  int64_t timestamp_ns;
-
-  // The event data.
-  float x;
-  float y;
-  float z;
-} DvrTrackingSensorEvent;
-
-__END_DECLS
-
-#endif  // ANDROID_DVR_TRACKING_TYPES_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_vsync.h b/libs/vr/libdvr/include/dvr/dvr_vsync.h
deleted file mode 100644
index 498bb5c..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_vsync.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef ANDROID_DVR_VSYNC_H_
-#define ANDROID_DVR_VSYNC_H_
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-// Represents a vsync sample. The size of this struct is 32 bytes.
-typedef struct __attribute__((packed, aligned(16))) DvrVsync {
-  // The timestamp for the last vsync in nanoseconds.
-  uint64_t vsync_timestamp_ns;
-
-  // The index of the last vsync.
-  uint32_t vsync_count;
-
-  // Scan out for the left eye = vsync_timestamp_ns + vsync_left_eye_offset_ns.
-  int32_t vsync_left_eye_offset_ns;
-
-  // Scan out for the right eye = vsync_timestamp_ns + vsync_right_eye_offset_ns
-  int32_t vsync_right_eye_offset_ns;
-
-  // The period of a vsync in nanoseconds.
-  uint32_t vsync_period_ns;
-
-  // Padding to 32 bytes so the size is a multiple of 16.
-  uint8_t padding[8];
-} DvrVsync;
-
-__END_DECLS
-
-#endif  // ANDROID_DVR_VSYNC_H_
diff --git a/libs/vr/libdvrcommon/Android.bp b/libs/vr/libdvrcommon/Android.bp
deleted file mode 100644
index fe4dfc7..0000000
--- a/libs/vr/libdvrcommon/Android.bp
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (C) 2016 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"],
-}
-
-localIncludeFiles = [
-    "include",
-]
-
-sharedLibraries = [
-    "libbase",
-    "libcutils",
-    "liblog",
-    "libutils",
-    "libEGL",
-    "libGLESv2",
-    "libui",
-    "libgui",
-    "libhardware",
-    "libpdx_default_transport",
-]
-
-staticLibraries = ["libbroadcastring"]
-
-headerLibraries = [
-    "libeigen",
-]
-
-cc_library {
-    local_include_dirs: localIncludeFiles,
-
-    cflags: [
-        "-DLOG_TAG=\"libdvrcommon\"",
-        "-DTRACE=0",
-        "-Wall",
-        "-Werror",
-    ],
-    export_include_dirs: localIncludeFiles,
-
-    header_libs: headerLibraries,
-    export_header_lib_headers: headerLibraries,
-
-    name: "libdvrcommon",
-}
-
-testFiles = [
-    "tests/numeric_test.cpp",
-    "tests/pose_test.cpp",
-]
-
-cc_test {
-    name: "libdvrcommon_test",
-
-    srcs: testFiles,
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-unused-parameter",
-    ],
-
-    shared_libs: sharedLibraries,
-
-    static_libs: [
-        "libgmock_main",
-        "libgmock",
-        "libgtest",
-	"libdvrcommon",
-    ] + staticLibraries,
-}
diff --git a/libs/vr/libdvrcommon/include/private/dvr/benchmark.h b/libs/vr/libdvrcommon/include/private/dvr/benchmark.h
deleted file mode 100644
index 7eeab16..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/benchmark.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef ANDROID_DVR_BENCHMARK_H_
-#define ANDROID_DVR_BENCHMARK_H_
-
-#include <stdio.h>
-#include <time.h>
-
-#include <cutils/trace.h>
-
-#include <private/dvr/clock_ns.h>
-
-// Set benchmark traces, using Android systrace.
-//
-// The simplest one-parameter version of btrace automatically sets the
-// timestamp with the system clock. The other versions can optionally set the
-// timestamp manually, or pass additional data to be written to the log line.
-//
-// Example:
-// Btrace("Start execution");
-// ... code to benchmark ...
-// Btrace("End execution");
-//
-// Use compute_benchmarks.py
-// with the trace path "Start execution,End execution",
-// to report the elapsed time between the two calls.
-//
-// Btrace will either output to standard atrace, or to a file if specified.
-// The versions BtraceData also allow an int64_t to be included in the trace.
-
-// Btrace without data payload.
-static inline void Btrace(const char* name, int64_t nanoseconds_monotonic);
-static inline void Btrace(const char* name);
-static inline void Btrace(FILE* file, const char* name,
-                          int64_t nanoseconds_monotonic);
-static inline void Btrace(FILE* file, const char* name);
-
-// Btrace with data payload.
-static inline void BtraceData(const char* name, int64_t nanoseconds_monotonic,
-                              int64_t data);
-static inline void BtraceData(const char* name, int64_t data);
-static inline void BtraceData(FILE* file, const char* name,
-                              int64_t nanoseconds_monotonic, int64_t data);
-static inline void BtraceData(FILE* file, const char* name, int64_t data);
-
-static inline void Btrace(const char* name, int64_t nanoseconds_monotonic) {
-  const int kLogMessageLength = 256;
-  char log_message[kLogMessageLength];
-  snprintf(log_message, kLogMessageLength, "#btrace#%s", name);
-  atrace_int64(ATRACE_TAG_WEBVIEW, log_message, nanoseconds_monotonic);
-}
-
-static inline void Btrace(const char* name) {
-  Btrace(name, android::dvr::GetSystemClockNs());
-}
-
-static inline void Btrace(FILE* file, const char* name,
-                          int64_t nanoseconds_monotonic) {
-  fprintf(file, "#btrace#%s|%" PRId64 "\n", name, nanoseconds_monotonic);
-}
-
-static inline void Btrace(FILE* file, const char* name) {
-  Btrace(file, name, android::dvr::GetSystemClockNs());
-}
-
-static inline void BtraceData(const char* name, int64_t nanoseconds_monotonic,
-                              int64_t data) {
-  const int kLogMessageLength = 256;
-  char log_message[kLogMessageLength];
-  snprintf(log_message, kLogMessageLength, "#btrace#%s|%" PRId64, name, data);
-  atrace_int64(ATRACE_TAG_WEBVIEW, log_message, nanoseconds_monotonic);
-}
-
-static inline void BtraceData(const char* name, int64_t data) {
-  BtraceData(name, android::dvr::GetSystemClockNs(), data);
-}
-
-static inline void BtraceData(FILE* file, const char* name,
-                              int64_t nanoseconds_monotonic, int64_t data) {
-  fprintf(file, "#btrace#%s|%" PRId64 "|%" PRId64 "\n", name, data,
-          nanoseconds_monotonic);
-}
-
-static inline void BtraceData(FILE* file, const char* name, int64_t data) {
-  BtraceData(file, name, android::dvr::GetSystemClockNs(), data);
-}
-
-#endif  // ANDROID_DVR_BENCHMARK_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/clock_ns.h b/libs/vr/libdvrcommon/include/private/dvr/clock_ns.h
deleted file mode 100644
index 8e777ed..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/clock_ns.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef ANDROID_DVR_CLOCK_NS_H_
-#define ANDROID_DVR_CLOCK_NS_H_
-
-#include <stdint.h>
-#include <time.h>
-
-namespace android {
-namespace dvr {
-
-constexpr int64_t kNanosPerSecond = 1000000000ll;
-
-// Returns the standard Dream OS monotonic system time that corresponds with all
-// timestamps found in Dream OS APIs.
-static inline timespec GetSystemClock() {
-  timespec t;
-  clock_gettime(CLOCK_MONOTONIC, &t);
-  return t;
-}
-
-static inline timespec GetSystemClockRaw() {
-  timespec t;
-  clock_gettime(CLOCK_MONOTONIC_RAW, &t);
-  return t;
-}
-
-static inline int64_t GetSystemClockNs() {
-  timespec t = GetSystemClock();
-  int64_t ns = kNanosPerSecond * (int64_t)t.tv_sec + (int64_t)t.tv_nsec;
-  return ns;
-}
-
-static inline int64_t GetSystemClockRawNs() {
-  timespec t = GetSystemClockRaw();
-  int64_t ns = kNanosPerSecond * (int64_t)t.tv_sec + (int64_t)t.tv_nsec;
-  return ns;
-}
-
-static inline double NsToSec(int64_t nanoseconds) {
-  return nanoseconds / static_cast<double>(kNanosPerSecond);
-}
-
-static inline double GetSystemClockSec() { return NsToSec(GetSystemClockNs()); }
-
-static inline double GetSystemClockMs() { return GetSystemClockSec() * 1000.0; }
-
-// Converts a nanosecond timestamp to a timespec. Based on the kernel function
-// of the same name.
-static inline timespec NsToTimespec(int64_t ns) {
-  timespec t;
-  int32_t remainder;
-
-  t.tv_sec = ns / kNanosPerSecond;
-  remainder = ns % kNanosPerSecond;
-  if (remainder < 0) {
-    t.tv_nsec--;
-    remainder += kNanosPerSecond;
-  }
-  t.tv_nsec = remainder;
-
-  return t;
-}
-
-// Timestamp comparison functions that handle wrapping values correctly.
-static inline bool TimestampLT(int64_t a, int64_t b) {
-  return static_cast<int64_t>(static_cast<uint64_t>(a) -
-                              static_cast<uint64_t>(b)) < 0;
-}
-static inline bool TimestampLE(int64_t a, int64_t b) {
-  return static_cast<int64_t>(static_cast<uint64_t>(a) -
-                              static_cast<uint64_t>(b)) <= 0;
-}
-static inline bool TimestampGT(int64_t a, int64_t b) {
-  return static_cast<int64_t>(static_cast<uint64_t>(a) -
-                              static_cast<uint64_t>(b)) > 0;
-}
-static inline bool TimestampGE(int64_t a, int64_t b) {
-  return static_cast<int64_t>(static_cast<uint64_t>(a) -
-                              static_cast<uint64_t>(b)) >= 0;
-}
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_CLOCK_NS_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/debug.h b/libs/vr/libdvrcommon/include/private/dvr/debug.h
deleted file mode 100644
index c31a385..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/debug.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef ANDROID_DVR_DEBUG_H_
-#define ANDROID_DVR_DEBUG_H_
-
-#include <GLES3/gl3.h>
-#include <math.h>
-
-#include <log/log.h>
-
-#ifndef NDEBUG
-#define CHECK_GL()                   \
-  do {                               \
-    const GLenum err = glGetError(); \
-    if (err != GL_NO_ERROR) {        \
-      ALOGE("OpenGL error %d", err); \
-    }                                \
-  } while (0)
-
-#define CHECK_GL_FBO()                                        \
-  do {                                                        \
-    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); \
-    switch (status) {                                         \
-      case GL_FRAMEBUFFER_COMPLETE:                           \
-        break;                                                \
-      case GL_FRAMEBUFFER_UNSUPPORTED:                        \
-        ALOGE("GL_FRAMEBUFFER_UNSUPPORTED");                  \
-        break;                                                \
-      default:                                                \
-        ALOGE("FBO user error: %d", status);                  \
-        break;                                                \
-    }                                                         \
-  } while (0)
-#else
-#define CHECK_GL()
-#define CHECK_GL_FBO()
-#endif
-
-#endif  // ANDROID_DVR_DEBUG_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/eigen.h b/libs/vr/libdvrcommon/include/private/dvr/eigen.h
deleted file mode 100644
index defaf58..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/eigen.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef ANDROID_DVR_EIGEN_H_
-#define ANDROID_DVR_EIGEN_H_
-
-#include <Eigen/Core>
-#include <Eigen/Geometry>
-
-namespace Eigen {
-
-// Eigen doesn't take advantage of C++ template typedefs, but we can
-template <class T, int N>
-using Vector = Matrix<T, N, 1>;
-
-template <class T>
-using Vector2 = Vector<T, 2>;
-
-template <class T>
-using Vector3 = Vector<T, 3>;
-
-template <class T>
-using Vector4 = Vector<T, 4>;
-
-template <class T, int N>
-using RowVector = Matrix<T, 1, N>;
-
-template <class T>
-using RowVector2 = RowVector<T, 2>;
-
-template <class T>
-using RowVector3 = RowVector<T, 3>;
-
-template <class T>
-using RowVector4 = RowVector<T, 4>;
-
-// In Eigen, the type you should be using for transformation matrices is the
-// `Transform` class, instead of a raw `Matrix`.
-// The `Projective` option means this will not make any assumptions about the
-// last row of the object, making this suitable for use as general OpenGL
-// projection matrices (which is the most common use-case). The one caveat
-// is that in order to apply this transformation to non-homogeneous vectors
-// (e.g., vec3), you must use the `.linear()` method to get the affine part of
-// the matrix.
-//
-// Example:
-//   mat4 transform;
-//   vec3 position;
-//   vec3 transformed = transform.linear() * position;
-//
-// Note, the use of N-1 is because the parameter passed to Eigen is the ambient
-// dimension of the transformation, not the size of the matrix iself.
-// However graphics programmers sometimes get upset when they see a 3 next
-// to a matrix when they expect a 4, so I'm hoping this will avoid that.
-template <class T, int N>
-using AffineMatrix = Transform<T, N-1, Projective>;
-
-}  // namespace Eigen
-
-#endif  // ANDROID_DVR_EIGEN_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/field_of_view.h b/libs/vr/libdvrcommon/include/private/dvr/field_of_view.h
deleted file mode 100644
index d0ee69c..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/field_of_view.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef ANDROID_DVR_FIELD_OF_VIEW_H_
-#define ANDROID_DVR_FIELD_OF_VIEW_H_
-
-#include <cmath>
-
-#include <private/dvr/eigen.h>
-
-namespace android {
-namespace dvr {
-
-// Encapsulates a generalized, asymmetric field of view with four half angles.
-// Each half angle denotes the angle between the corresponding frustum plane.
-// Together with a near and far plane, a FieldOfView forms the frustum of an
-// off-axis perspective projection.
-class FieldOfView {
- public:
-  // The default constructor sets an angle of 0 (in any unit) for all four
-  // half-angles.
-  FieldOfView() : left_(0.0f), right_(0.0f), bottom_(0.0f), top_(0.0f) {}
-
-  // Constructs a FieldOfView from four angles.
-  FieldOfView(float left, float right, float bottom, float top)
-      : left_(left), right_(right), bottom_(bottom), top_(top) {}
-
-  explicit FieldOfView(const float* fov)
-      : FieldOfView(fov[0], fov[1], fov[2], fov[3]) {}
-
-  // Accessors for all four half-angles.
-  float GetLeft() const { return left_; }
-  float GetRight() const { return right_; }
-  float GetBottom() const { return bottom_; }
-  float GetTop() const { return top_; }
-
-  // Setters for all four half-angles.
-  void SetLeft(float left) { left_ = left; }
-  void SetRight(float right) { right_ = right; }
-  void SetBottom(float bottom) { bottom_ = bottom; }
-  void SetTop(float top) { top_ = top; }
-
-  Eigen::AffineMatrix<float, 4> GetProjectionMatrix(float z_near,
-                                                    float z_far) const {
-    float x_left = -std::tan(left_) * z_near;
-    float x_right = std::tan(right_) * z_near;
-    float y_bottom = -std::tan(bottom_) * z_near;
-    float y_top = std::tan(top_) * z_near;
-
-    float zero = 0.0f;
-    if (x_left == x_right || y_bottom == y_top || z_near == z_far ||
-        z_near <= zero || z_far <= zero) {
-      return Eigen::AffineMatrix<float, 4>::Identity();
-    }
-
-    float x = (2 * z_near) / (x_right - x_left);
-    float y = (2 * z_near) / (y_top - y_bottom);
-    float a = (x_right + x_left) / (x_right - x_left);
-    float b = (y_top + y_bottom) / (y_top - y_bottom);
-    float c = (z_near + z_far) / (z_near - z_far);
-    float d = (2 * z_near * z_far) / (z_near - z_far);
-
-    // Note: Eigen matrix initialization syntax is always 'column-major'
-    // even if the storage is row-major. Or in other words, just write the
-    // matrix like you'd see in a math textbook.
-    Eigen::AffineMatrix<float, 4> result;
-    result.matrix() << x,  0,  a,  0,
-                       0,  y,  b,  0,
-                       0,  0,  c,  d,
-                       0,  0, -1,  0;
-    return result;
-  }
-
-  static FieldOfView FromProjectionMatrix(
-      const Eigen::AffineMatrix<float, 4>& m) {
-    // Compute tangents.
-    float tan_vert_fov = 1.0f / m(1, 1);
-    float tan_horz_fov = 1.0f / m(0, 0);
-    float t = (m(1, 2) + 1.0f) * tan_vert_fov;
-    float b = (m(1, 2) - 1.0f) * tan_vert_fov;
-    float l = (m(0, 2) - 1.0f) * tan_horz_fov;
-    float r = (m(0, 2) + 1.0f) * tan_horz_fov;
-
-    return FieldOfView(std::atan(-l), std::atan(r), std::atan(-b),
-                       std::atan(t));
-  }
-
- private:
-  float left_;
-  float right_;
-  float bottom_;
-  float top_;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_FIELD_OF_VIEW_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/log_helpers.h b/libs/vr/libdvrcommon/include/private/dvr/log_helpers.h
deleted file mode 100644
index 12ef622..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/log_helpers.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef ANDROID_DVR_LOG_HELPERS_H_
-#define ANDROID_DVR_LOG_HELPERS_H_
-
-#include <iomanip>
-#include <ostream>
-
-#include <private/dvr/eigen.h>
-#include <private/dvr/field_of_view.h>
-
-namespace android {
-namespace dvr {
-
-template <typename T>
-inline std::ostream& operator<<(std::ostream& out,
-                                const Eigen::Vector<T, 2>& vec) {
-  return out << "vec2(" << vec.x() << ',' << vec.y() << ')';
-}
-
-template <typename T>
-inline std::ostream& operator<<(std::ostream& out,
-                                const Eigen::Vector<T, 3>& vec) {
-  return out << "vec3(" << vec.x() << ',' << vec.y() << ',' << vec.z() << ')';
-}
-
-template <typename T>
-inline std::ostream& operator<<(std::ostream& out,
-                                const Eigen::Vector<T, 4>& vec) {
-  return out << "vec4(" << vec.x() << ',' << vec.y() << ',' << vec.z() << ','
-             << vec.w() << ')';
-}
-
-template <typename T>
-inline std::ostream& operator<<(std::ostream& out,
-                                const Eigen::AffineMatrix<T, 4>& mat) {
-  out << std::setfill(' ') << std::setprecision(4) << std::fixed
-      << std::showpos;
-  out << "\nmat4[";
-  out << std::setw(10) << mat(0, 0) << " " << std::setw(10) << mat(0, 1) << " "
-      << std::setw(10) << mat(0, 2) << " " << std::setw(10) << mat(0, 3);
-  out << "]\n    [";
-  out << std::setw(10) << mat(1, 0) << " " << std::setw(10) << mat(1, 1) << " "
-      << std::setw(10) << mat(1, 2) << " " << std::setw(10) << mat(1, 3);
-  out << "]\n    [";
-  out << std::setw(10) << mat(2, 0) << " " << std::setw(10) << mat(2, 1) << " "
-      << std::setw(10) << mat(2, 2) << " " << std::setw(10) << mat(2, 3);
-  out << "]\n    [";
-  out << std::setw(10) << mat(3, 0) << " " << std::setw(10) << mat(3, 1) << " "
-      << std::setw(10) << mat(3, 2) << " " << std::setw(10) << mat(3, 3);
-  out << "]\n";
-
-  return out;
-}
-
-inline std::ostream& operator<<(std::ostream& out, const FieldOfView& fov) {
-  return out << "fov(" << (fov.GetLeft() * 180.0f / M_PI) << ','
-             << (fov.GetRight() * 180.0f / M_PI) << ','
-             << (fov.GetBottom() * 180.0f / M_PI) << ','
-             << (fov.GetTop() * 180.0f / M_PI) << ')';
-}
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_LOG_HELPERS_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/matrix_helpers.h b/libs/vr/libdvrcommon/include/private/dvr/matrix_helpers.h
deleted file mode 100644
index aef7146..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/matrix_helpers.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef ANDROID_DVR_MATRIX_HELPERS_H_
-#define ANDROID_DVR_MATRIX_HELPERS_H_
-
-#include <private/dvr/eigen.h>
-#include <private/dvr/types.h>
-
-namespace android {
-namespace dvr {
-
-// A helper function for creating a mat4 directly.
-inline mat4 MakeMat4(float m00, float m01, float m02, float m03, float m10,
-                     float m11, float m12, float m13, float m20, float m21,
-                     float m22, float m23, float m30, float m31, float m32,
-                     float m33) {
-  Eigen::Matrix4f matrix;
-
-  matrix << m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30,
-      m31, m32, m33;
-
-  return mat4(matrix);
-}
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_LOG_HELPERS_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/numeric.h b/libs/vr/libdvrcommon/include/private/dvr/numeric.h
deleted file mode 100644
index 4545893..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/numeric.h
+++ /dev/null
@@ -1,175 +0,0 @@
-#ifndef ANDROID_DVR_NUMERIC_H_
-#define ANDROID_DVR_NUMERIC_H_
-
-#include <cmath>
-#include <limits>
-#include <random>
-#include <type_traits>
-
-#include <private/dvr/eigen.h>
-#include <private/dvr/types.h>
-
-namespace android {
-namespace dvr {
-
-template <typename FT>
-static inline FT ToDeg(FT f) {
-  return f * static_cast<FT>(180.0 / M_PI);
-}
-
-template <typename FT>
-static inline FT ToRad(FT f) {
-  return f * static_cast<FT>(M_PI / 180.0);
-}
-
-// Adjusts `x` to the periodic range `[lo, hi]` (to normalize angle values
-// for example).
-template <typename T>
-T NormalizePeriodicRange(T x, T lo, T hi) {
-  T range_size = hi - lo;
-
-  while (x < lo) {
-    x += range_size;
-  }
-
-  while (x > hi) {
-    x -= range_size;
-  }
-
-  return x;
-}
-
-// Normalizes a measurement in radians.
-// @param x the angle to be normalized
-// @param centre the point around which to normalize the range
-// @return the value of x, normalized to the range [centre - 180, centre + 180]
-template <typename T>
-T NormalizeDegrees(T x, T centre = static_cast<T>(180.0)) {
-  return NormalizePeriodicRange(x, centre - static_cast<T>(180.0),
-                                centre + static_cast<T>(180.0));
-}
-
-// Normalizes a measurement in radians.
-// @param x the angle to be normalized
-// @param centre the point around which to normalize the range
-// @return the value of x, normalized to the range
-//         [centre - M_PI, centre + M_PI]
-// @remark the centre parameter is to make it possible to specify a different
-//         periodic range. This is useful if you are planning on comparing two
-//         angles close to 0 or M_PI, so that one might not accidentally end
-//         up on the other side of the range
-template <typename T>
-T NormalizeRadians(T x, T centre = static_cast<T>(M_PI)) {
-  return NormalizePeriodicRange(x, centre - static_cast<T>(M_PI),
-                                centre + static_cast<T>(M_PI));
-}
-
-static inline vec2i Round(const vec2& v) {
-  return vec2i(roundf(v.x()), roundf(v.y()));
-}
-
-static inline vec2i Scale(const vec2i& v, float scale) {
-  return vec2i(roundf(static_cast<float>(v.x()) * scale),
-               roundf(static_cast<float>(v.y()) * scale));
-}
-
-// Re-maps `x` from `[lba,uba]` to `[lbb,ubb]`.
-template <typename T>
-T ConvertRange(T x, T lba, T uba, T lbb, T ubb) {
-  return (((x - lba) * (ubb - lbb)) / (uba - lba)) + lbb;
-}
-
-template <typename R1, typename R2>
-static inline vec2 MapPoint(const vec2& pt, const R1& from, const R2& to) {
-  vec2 normalized((pt - vec2(from.p1)).array() / vec2(from.GetSize()).array());
-  return (normalized * vec2(to.GetSize())) + vec2(to.p1);
-}
-
-template <typename T>
-inline bool IsZero(const T& v,
-                   const T& tol = std::numeric_limits<T>::epsilon()) {
-  return std::abs(v) <= tol;
-}
-
-template <typename T>
-inline bool IsEqual(const T& a, const T& b,
-                    const T& tol = std::numeric_limits<T>::epsilon()) {
-  return std::abs(b - a) <= tol;
-}
-
-template <typename T>
-T Square(const T& x) {
-  return x * x;
-}
-
-template <typename T>
-T RandomInRange(T lo, T hi,
-                typename
-                std::enable_if<std::is_floating_point<T>::value>::type* = 0) {
-  std::random_device rd;
-  std::mt19937 gen(rd());
-  std::uniform_real_distribution<T> distro(lo, hi);
-  return distro(gen);
-}
-
-template <typename T>
-T RandomInRange(T lo, T hi,
-                typename
-                std::enable_if<std::is_integral<T>::value>::type* = 0) {
-  std::random_device rd;
-  std::mt19937 gen(rd());
-  std::uniform_int_distribution<T> distro(lo, hi);
-  return distro(gen);
-}
-
-template <typename Derived1, typename Derived2>
-Derived1 RandomInRange(
-    const Eigen::MatrixBase<Derived1>& lo,
-    const Eigen::MatrixBase<Derived2>& hi) {
-  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived1, Derived2);
-
-  Derived1 result = Eigen::MatrixBase<Derived1>::Zero();
-
-  for (int row = 0; row < result.rows(); ++row) {
-    for (int col = 0; col < result.cols(); ++col) {
-      result(row, col) = RandomInRange(lo(row, col), hi(row, col));
-    }
-  }
-
-  return result;
-}
-
-template <typename T>
-T RandomRange(T x) {
-  return RandomInRange(-x, x);
-}
-
-template <typename T>
-T Clamp(T x, T lo, T hi) {
-  return std::min(std::max(x, lo), hi);
-}
-
-inline mat3 ScaleMatrix(const vec2& scale_xy) {
-  return mat3(Eigen::Scaling(scale_xy[0], scale_xy[1], 1.0f));
-}
-
-inline mat3 TranslationMatrix(const vec2& translation) {
-  return mat3(Eigen::Translation2f(translation));
-}
-
-inline mat4 TranslationMatrix(const vec3& translation) {
-  return mat4(Eigen::Translation3f(translation));
-}
-
-inline vec2 TransformPoint(const mat3& m, const vec2& p) {
-  return m.linear() * p + m.translation();
-}
-
-inline vec2 TransformVector(const mat3& m, const vec2& p) {
-  return m.linear() * p;
-}
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_NUMERIC_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/ortho.h b/libs/vr/libdvrcommon/include/private/dvr/ortho.h
deleted file mode 100644
index fc0bce3..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/ortho.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef ANDROID_DVR_ORTHO_H_
-#define ANDROID_DVR_ORTHO_H_
-
-#include <private/dvr/types.h>
-
-namespace android {
-namespace dvr {
-
-template <class T>
-Eigen::AffineMatrix<T, 4> OrthoMatrix(T left, T right, T bottom, T top,
-                                      T znear, T zfar) {
-  Eigen::AffineMatrix<T, 4> result;
-  const T t2 = static_cast<T>(2);
-  const T a = t2 / (right - left);
-  const T b = t2 / (top - bottom);
-  const T c = t2 / (zfar - znear);
-  const T xoff = -(right + left) / (right - left);
-  const T yoff = -(top + bottom) / (top - bottom);
-  const T zoff = -(zfar + znear) / (zfar - znear);
-  const T t1 = static_cast<T>(1);
-  result.matrix() << a, 0, 0, xoff,
-            0, b, 0, yoff,
-            0, 0, c, zoff,
-            0, 0, 0, t1;
-  return result;
-}
-
-}  // namespace android
-}  // namespace dvr
-
-#endif  // ANDROID_DVR_ORTHO_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/pose.h b/libs/vr/libdvrcommon/include/private/dvr/pose.h
deleted file mode 100644
index 97944e8..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/pose.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#ifndef ANDROID_DVR_POSE_H_
-#define ANDROID_DVR_POSE_H_
-
-#include <private/dvr/eigen.h>
-
-namespace android {
-namespace dvr {
-
-// Encapsulates a 3D pose (rotation and position).
-//
-// @tparam T Data type for storing the position coordinate and rotation
-//     quaternion.
-template <typename T>
-class Pose {
- public:
-  // Creates identity pose.
-  Pose()
-      : rotation_(Eigen::Quaternion<T>::Identity()),
-        position_(Eigen::Vector3<T>::Zero()) {}
-
-  // Initializes a pose with given rotation and position.
-  //
-  // rotation Initial rotation.
-  // position Initial position.
-  Pose(Eigen::Quaternion<T> rotation, Eigen::Vector3<T> position)
-      : rotation_(rotation), position_(position) {}
-
-  void Invert() {
-    rotation_ = rotation_.inverse();
-    position_ = rotation_ * -position_;
-  }
-
-  Pose Inverse() const {
-    Pose result(*this);
-    result.Invert();
-    return result;
-  }
-
-  // Compute the composition of this pose with another, storing the result
-  // in the current object
-  void ComposeInPlace(const Pose& other) {
-    position_ = position_ + rotation_ * other.position_;
-    rotation_ = rotation_ * other.rotation_;
-  }
-
-  // Computes the composition of this pose with another, and returns the result
-  Pose Compose(const Pose& other) const {
-    Pose result(*this);
-    result.ComposeInPlace(other);
-    return result;
-  }
-
-  Eigen::Vector3<T> TransformPoint(const Eigen::Vector3<T>& v) const {
-    return rotation_ * v + position_;
-  }
-
-  Eigen::Vector3<T> Transform(const Eigen::Vector3<T>& v) const {
-    return rotation_ * v;
-  }
-
-  Pose& operator*=(const Pose& other) {
-    ComposeInPlace(other);
-    return *this;
-  }
-
-  Pose operator*(const Pose& other) const { return Compose(other); }
-
-  // Gets the rotation of the 3D pose.
-  Eigen::Quaternion<T> GetRotation() const { return rotation_; }
-
-  // Gets the position of the 3D pose.
-  Eigen::Vector3<T> GetPosition() const { return position_; }
-
-  // Sets the rotation of the 3D pose.
-  void SetRotation(Eigen::Quaternion<T> rotation) { rotation_ = rotation; }
-
-  // Sets the position of the 3D pose.
-  void SetPosition(Eigen::Vector3<T> position) { position_ = position; }
-
-  // Gets a 4x4 matrix representing a transform from the reference space (that
-  // the rotation and position of the pose are relative to) to the object space.
-  Eigen::AffineMatrix<T, 4> GetObjectFromReferenceMatrix() const;
-
-  // Gets a 4x4 matrix representing a transform from the object space to the
-  // reference space (that the rotation and position of the pose are relative
-  // to).
-  Eigen::AffineMatrix<T, 4> GetReferenceFromObjectMatrix() const;
-
- private:
-  Eigen::Quaternion<T> rotation_;
-  Eigen::Vector3<T> position_;
-};
-
-template <typename T>
-Eigen::AffineMatrix<T, 4> Pose<T>::GetObjectFromReferenceMatrix() const {
-  // The transfrom from the reference is the inverse of the pose.
-  Eigen::AffineMatrix<T, 4> matrix(rotation_.inverse().toRotationMatrix());
-  return matrix.translate(-position_);
-}
-
-template <typename T>
-Eigen::AffineMatrix<T, 4> Pose<T>::GetReferenceFromObjectMatrix() const {
-  // The transfrom to the reference.
-  Eigen::AffineMatrix<T, 4> matrix(rotation_.toRotationMatrix());
-  return matrix.pretranslate(position_);
-}
-
-//------------------------------------------------------------------------------
-// Type-specific typedefs.
-//------------------------------------------------------------------------------
-
-using Posef = Pose<float>;
-using Posed = Pose<double>;
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_POSE_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/range.h b/libs/vr/libdvrcommon/include/private/dvr/range.h
deleted file mode 100644
index 1d06c96..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/range.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef ANDROID_DVR_RANGE_H_
-#define ANDROID_DVR_RANGE_H_
-
-#include <private/dvr/eigen.h>
-
-namespace android {
-namespace dvr {
-
-// TODO(skiazyk): Replace all instances of this with Eigen::AlignedBox
-
-// Container of two points that define a 2D range.
-template <class T, int d>
-struct Range {
-  // Construct an uninitialized Range.
-  Range() {}
-  Range(Eigen::Vector<T, d> p1, Eigen::Vector<T, d> p2) : p1(p1), p2(p2) {}
-
-  static Range<T, d> FromSize(Eigen::Vector<T, d> p1,
-                              Eigen::Vector<T, d> size) {
-    return Range<T, d>(p1, p1 + size);
-  }
-
-  bool operator==(const Range<T, d>& rhs) const {
-    return p1 == rhs.p1 && p2 == rhs.p2;
-  }
-
-  Eigen::Vector<T, d> GetMinPoint() const { return p1; }
-
-  Eigen::Vector<T, d> GetMaxPoint() const { return p2; }
-
-  Eigen::Vector<T, d> GetSize() const { return p2 - p1; }
-
-  Eigen::Vector<T, d> p1;
-  Eigen::Vector<T, d> p2;
-};
-
-typedef Range<int, 2> Range2i;
-typedef Range<float, 2> Range2f;
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_RANGE_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/ring_buffer.h b/libs/vr/libdvrcommon/include/private/dvr/ring_buffer.h
deleted file mode 100644
index 1824241..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/ring_buffer.h
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef ANDROID_DVR_RING_BUFFER_H_
-#define ANDROID_DVR_RING_BUFFER_H_
-
-#include <utility>
-#include <vector>
-
-namespace android {
-namespace dvr {
-
-// A simple ring buffer implementation.
-//
-// A vector works but you either have to keep track of start_ and size_ yourself
-// or erase() from the front which is inefficient.
-//
-// A deque works but the common usage pattern of Append() PopFront() Append()
-// PopFront() looks like it allocates each time size goes from 0 --> 1, which we
-// don't want. This class allocates only once.
-template <typename T>
-class RingBuffer {
- public:
-  RingBuffer() { Reset(0); }
-
-  explicit RingBuffer(size_t capacity) { Reset(capacity); }
-
-  RingBuffer(const RingBuffer& other) = default;
-  RingBuffer(RingBuffer&& other) noexcept = default;
-  RingBuffer& operator=(const RingBuffer& other) = default;
-  RingBuffer& operator=(RingBuffer&& other) noexcept = default;
-
-  void Append(const T& val) {
-    if (IsFull())
-      PopFront();
-    Get(size_) = val;
-    size_++;
-  }
-
-  void Append(T&& val) {
-    if (IsFull())
-      PopFront();
-    Get(size_) = std::move(val);
-    size_++;
-  }
-
-  bool IsEmpty() const { return size_ == 0; }
-
-  bool IsFull() const { return size_ == buffer_.size(); }
-
-  size_t GetSize() const { return size_; }
-
-  size_t GetCapacity() const { return buffer_.size(); }
-
-  T& Get(size_t i) { return buffer_[(start_ + i) % buffer_.size()]; }
-
-  const T& Get(size_t i) const {
-    return buffer_[(start_ + i) % buffer_.size()];
-  }
-
-  const T& Back() const { return Get(size_ - 1); }
-
-  T& Back() { return Get(size_ - 1); }
-
-  const T& Front() const { return Get(0); }
-
-  T& Front() { return Get(0); }
-
-  void PopBack() {
-    if (size_ != 0) {
-      Get(size_ - 1) = T();
-      size_--;
-    }
-  }
-
-  void PopFront() {
-    if (size_ != 0) {
-      Get(0) = T();
-      start_ = (start_ + 1) % buffer_.size();
-      size_--;
-    }
-  }
-
-  void Clear() { Reset(GetCapacity()); }
-
-  void Reset(size_t capacity) {
-    start_ = size_ = 0;
-    buffer_.clear();
-    buffer_.resize(capacity);
-  }
-
- private:
-  // Ideally we'd allocate our own memory and use placement new to instantiate
-  // instances of T instead of using a vector, but the vector is simpler.
-  std::vector<T> buffer_;
-  size_t start_, size_;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_RING_BUFFER_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/test/test_macros.h b/libs/vr/libdvrcommon/include/private/dvr/test/test_macros.h
deleted file mode 100644
index 6048652..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/test/test_macros.h
+++ /dev/null
@@ -1,124 +0,0 @@
-#ifndef LIBS_VR_LIBDVRCOMMON_INCLUDE_PRIVATE_DVR_TEST_TEST_MACROS_H_
-#define LIBS_VR_LIBDVRCOMMON_INCLUDE_PRIVATE_DVR_TEST_TEST_MACROS_H_
-
-#include <gtest/gtest.h>
-
-#include <cmath>
-
-#include <private/dvr/numeric.h>
-
-namespace android {
-namespace dvr {
-
-template <int N, typename A, typename B, typename T>
-::testing::AssertionResult CmpArrayLikeFloatEq(
-    const char* expectedStr, const char* actualStr, const char* toleranceStr,
-    const A& expected, const B& actual, const T& tolerance) {
-  for (int i = 0; i < N; ++i) {
-    if (!IsEqual(expected[i], actual[i], tolerance)) {
-      return ::testing::AssertionFailure()
-             << "\"" << expectedStr << "\" and \"" << actualStr
-             << "\" differ at element " << i << " by at least " << tolerance
-             << " : "
-             << " Expected \"" << expected[i] << "\", was \"" << actual[i]
-             << "\".";
-    }
-  }
-
-  return ::testing::AssertionSuccess();
-}
-
-template <int N, typename A, typename B, typename T>
-::testing::AssertionResult CmpMatrixLikeFloatEq(
-    const char* expectedStr, const char* actualStr, const char* toleranceStr,
-    const A& expected, const B& actual, const T& tolerance) {
-  for (int r = 0; r < N; ++r) {
-    for (int c = 0; c < N; ++c) {
-      if (!IsEqual(expected(r, c), actual(r, c), tolerance)) {
-        return ::testing::AssertionFailure()
-               << "\"" << expectedStr << "\" and \"" << actualStr
-               << "\" differ at (" << r << "," << c << ")"
-               << " by at least " << tolerance << " : "
-               << " Expected \"" << expected(r, c) << "\", was \""
-               << actual(r, c) << "\".";
-      }
-    }
-  }
-
-  return ::testing::AssertionSuccess();
-}
-
-template <int N, typename A, typename B, typename T>
-::testing::AssertionResult CmpArrayLikeFloatNe(
-    const char* expectedStr, const char* actualStr, const char* toleranceStr,
-    const A& expected, const B& actual, const T& tolerance) {
-  for (int i = 0; i < N; ++i) {
-    if (!IsEqual(expected[i], actual[i], tolerance)) {
-      return ::testing::AssertionSuccess();
-    }
-  }
-
-  ::testing::Message message;
-  message << "Expected \"" << expectedStr
-          << "\" to differ from provided value \"" << actualStr
-          << "\" by at least " << tolerance << ".";
-
-  return ::testing::AssertionFailure(message);
-}
-
-template <int N, typename A, typename B, typename T>
-::testing::AssertionResult CmpMatrixLikeFloatNe(
-    const char* expectedStr, const char* actualStr, const char* toleranceStr,
-    const A& expected, const B& actual, const T& tolerance) {
-  for (int r = 0; r < N; ++r) {
-    for (int c = 0; c < N; ++c) {
-      if (!IsEqual(expected(r, c), actual(r, c), tolerance)) {
-        return ::testing::AssertionSuccess();
-      }
-    }
-  }
-
-  ::testing::Message message;
-  message << "Expected \"" << expectedStr
-          << "\" to differ from provided value \"" << actualStr
-          << "\" by at least " << tolerance << ".";
-
-  return ::testing::AssertionFailure(message);
-}
-
-}  // namespace dvr
-}  // namespace android
-
-#define EXPECT_VEC3_NEAR(expected, actual, tol)                               \
-  EXPECT_PRED_FORMAT3(android::dvr::CmpArrayLikeFloatEq<3>, expected, actual, \
-                      tol)
-
-#define EXPECT_VEC3_NOT_NEAR(expected, actual, tol)                           \
-  EXPECT_PRED_FORMAT3(android::dvr::CmpArrayLikeFloatNe<3>, expected, actual, \
-                      tol)
-
-#define EXPECT_QUAT_NEAR(expected, actual, tol)                                \
-  EXPECT_PRED_FORMAT3(android::dvr::CmpArrayLikeFloatEq<3>, expected.coeffs(), \
-                      actual.coeffs(), tol)
-
-#define EXPECT_QUAT_NOT_NEAR(expected, actual, tol)                            \
-  EXPECT_PRED_FORMAT3(android::dvr::CmpArrayLikeFloatNe<3>, expected.coeffs(), \
-                      actual.coeffs(), tol)
-
-#define EXPECT_MAT4_NEAR(expected, actual, tol)                                \
-  EXPECT_PRED_FORMAT3(android::dvr::CmpMatrixLikeFloatEq<4>, expected, actual, \
-                      tol)
-
-#define EXPECT_MAT4_NOT_NEAR(expected, actual, tol)                            \
-  EXPECT_PRED_FORMAT3(android::dvr::CmpMatrixLikeFloatNe<4>, expected, actual, \
-                      tol)
-
-#define EXPECT_MAT3_NEAR(expected, actual, tol) \
-  EXPECT_PRED_FORMAT3(android::dvr              \
-                      : CmpMatrixLikeFloatEq<3>, expected, actual, tol)
-
-#define EXPECT_MAT3_NOT_NEAR(expected, actual, tol)                            \
-  EXPECT_PRED_FORMAT3(android::dvr::CmpMatrixLikeFloatNe<3>, expected, actual, \
-                      tol)
-
-#endif  // LIBS_VR_LIBDVRCOMMON_INCLUDE_PRIVATE_DVR_TEST_TEST_MACROS_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/types.h b/libs/vr/libdvrcommon/include/private/dvr/types.h
deleted file mode 100644
index 1fa54af..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/types.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef ANDROID_DVR_TYPES_H_
-#define ANDROID_DVR_TYPES_H_
-
-// All basic types used by VR code.
-
-#include <private/dvr/eigen.h>
-#include <private/dvr/field_of_view.h>
-#include <private/dvr/pose.h>
-#include <private/dvr/range.h>
-
-namespace android {
-namespace dvr {
-
-enum RgbColorChannel { kRed, kGreen, kBlue };
-
-// EyeType: 0 for left, 1 for right.
-enum EyeType { kLeftEye = 0, kRightEye = 1 };
-
-// In the context of VR, vector types are used as much as base types.
-
-using vec2f = Eigen::Vector2f;
-using vec2d = Eigen::Vector2d;
-using vec2i = Eigen::Vector2i;
-using vec2 = vec2f;
-
-using vec3f = Eigen::Vector3f;
-using vec3d = Eigen::Vector3d;
-using vec3i = Eigen::Vector3i;
-using vec3 = vec3f;
-
-using vec4f = Eigen::Vector4f;
-using vec4d = Eigen::Vector4d;
-using vec4i = Eigen::Vector4i;
-using vec4 = vec4f;
-
-using mat3f = Eigen::AffineMatrix<float, 3>;
-using mat3d = Eigen::AffineMatrix<double, 3>;
-using mat3 = mat3f;
-
-using mat4f = Eigen::AffineMatrix<float, 4>;
-using mat4d = Eigen::AffineMatrix<double, 4>;
-using mat4 = mat4f;
-
-using quatf = Eigen::Quaternionf;
-using quatd = Eigen::Quaterniond;
-using quat = quatf;
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_TYPES_H_
diff --git a/libs/vr/libdvrcommon/tests/numeric_test.cpp b/libs/vr/libdvrcommon/tests/numeric_test.cpp
deleted file mode 100644
index 1ee1447..0000000
--- a/libs/vr/libdvrcommon/tests/numeric_test.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <private/dvr/numeric.h>
-
-using TestTypes = ::testing::Types<float, double, int>;
-
-using android::dvr::RandomInRange;
-
-template <typename T>
-class NumericTest : public ::testing::TestWithParam<T> {
- public:
-  using FT = T;
-};
-
-TYPED_TEST_CASE(NumericTest, TestTypes);
-
-TYPED_TEST(NumericTest, RandomInRange) {
-  using FT = typename TestFixture::FT;
-
-  const int kNumTrials = 50;
-  const FT kLowRange = static_cast<FT>(-100);
-  const FT kHighRange = static_cast<FT>(100);
-
-  for (int i = 0; i < kNumTrials; ++i) {
-    FT value = RandomInRange(kLowRange, kHighRange);
-
-    EXPECT_LE(kLowRange, value);
-    EXPECT_GE(kHighRange, value);
-  }
-}
-
-TEST(RandomInRange, TestIntVersion) {
-  // This checks specifically that the function does not always give the lo
-  // value (this was previously a bug)
-
-  const int kNumTrials = 50;
-  const int kLowRange = -100;
-  const int kHighRange = 100;
-
-  for (int i = 0; i < kNumTrials; ++i) {
-    int value = RandomInRange(kLowRange, kHighRange);
-
-    if (value != kLowRange) {
-      SUCCEED();
-      return;
-    }
-  }
-
-  FAIL() << "Did not produce a value other than the range minimum for "
-         << "integers.";
-}
-
-TEST(RandomInRange, TestVectorVersion) {
-  Eigen::Vector3d lo(-3.0, -4.0, -5.0);
-  Eigen::Vector3d hi(5.0, 4.0, 3.0);
-
-  const int kNumTrials = 50;
-
-  for (int i = 0; i < kNumTrials; ++i) {
-    Eigen::Vector3d result = RandomInRange(lo, hi);
-
-    for (int j = 0; j < 3; ++j) {
-      EXPECT_LE(lo[j], result[j]);
-      EXPECT_GE(hi[j], result[j]);
-    }
-  }
-}
diff --git a/libs/vr/libdvrcommon/tests/pose_test.cpp b/libs/vr/libdvrcommon/tests/pose_test.cpp
deleted file mode 100644
index aa1896d..0000000
--- a/libs/vr/libdvrcommon/tests/pose_test.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <private/dvr/eigen.h>
-#include <private/dvr/pose.h>
-#include <private/dvr/test/test_macros.h>
-
-using PoseTypes = ::testing::Types<float, double>;
-
-template <class T>
-class PoseTest : public ::testing::TestWithParam<T> {
- public:
-  using FT = T;
-  using Pose_t = android::dvr::Pose<FT>;
-  using quat_t = Eigen::Quaternion<FT>;
-  using vec3_t = Eigen::Vector3<FT>;
-  using mat4_t = Eigen::AffineMatrix<FT, 4>;
-};
-
-TYPED_TEST_CASE(PoseTest, PoseTypes);
-
-// Check that the two matrix methods are inverses of each other
-TYPED_TEST(PoseTest, SelfInverse) {
-  using quat_t = typename TestFixture::quat_t;
-  using vec3_t = typename TestFixture::vec3_t;
-  using Pose_t = typename TestFixture::Pose_t;
-  using mat4_t = typename TestFixture::mat4_t;
-  using FT = typename TestFixture::FT;
-
-  const auto tolerance = FT(0.0001);
-
-  const quat_t initial_rotation(Eigen::AngleAxis<FT>(
-      FT(M_PI / 3.0), vec3_t(FT(3.0), FT(4.0), FT(5.0)).normalized()));
-  const vec3_t initial_position = vec3_t(FT(2.0), FT(10.0), FT(-4.0));
-  const Pose_t initial_pose(initial_rotation, initial_position);
-
-  auto result_pose = initial_pose.GetReferenceFromObjectMatrix() *
-                     initial_pose.GetObjectFromReferenceMatrix();
-
-  EXPECT_MAT4_NEAR(result_pose, mat4_t::Identity(), tolerance);
-}
-
-TYPED_TEST(PoseTest, TransformPoint) {
-  using quat_t = typename TestFixture::quat_t;
-  using vec3_t = typename TestFixture::vec3_t;
-  using Pose_t = typename TestFixture::Pose_t;
-  using FT = typename TestFixture::FT;
-
-  const auto tolerance = FT(0.0001);
-
-  const quat_t pose_rotation(
-      Eigen::AngleAxis<FT>(FT(M_PI / 2.0), vec3_t(FT(0.0), FT(0.0), FT(1.0))));
-  const auto pose_position = vec3_t(FT(1.0), FT(1.0), FT(2.0));
-
-  const Pose_t test_pose(pose_rotation, pose_position);
-
-  for (int axis = 0; axis < 3; ++axis) {
-    vec3_t start_position = vec3_t::Zero();
-    start_position[axis] = FT(1.0);
-    const vec3_t expected_transformed =
-        (pose_rotation * start_position) + pose_position;
-    const vec3_t actual_transformed = test_pose.TransformPoint(start_position);
-    EXPECT_VEC3_NEAR(expected_transformed, actual_transformed, tolerance);
-  }
-}
-
-TYPED_TEST(PoseTest, TransformVector) {
-  using quat_t = typename TestFixture::quat_t;
-  using vec3_t = typename TestFixture::vec3_t;
-  using Pose_t = typename TestFixture::Pose_t;
-  using FT = typename TestFixture::FT;
-
-  const auto tolerance = FT(0.0001);
-
-  const quat_t pose_rotation(Eigen::AngleAxis<FT>(
-      FT(M_PI / 6.0), vec3_t(FT(3.0), FT(4.0), FT(5.0)).normalized()));
-
-  const auto pose_position = vec3_t(FT(500.0), FT(-500.0), FT(300.0));
-
-  const Pose_t test_pose(pose_rotation, pose_position);
-
-  for (int axis = 0; axis < 3; ++axis) {
-    vec3_t start_position = vec3_t::Zero();
-    start_position[axis] = FT(1.0);
-    const vec3_t expected_rotated = pose_rotation * start_position;
-    const vec3_t actual_rotated = test_pose.Transform(start_position);
-    EXPECT_VEC3_NEAR(expected_rotated, actual_rotated, tolerance);
-  }
-}
-
-TYPED_TEST(PoseTest, Composition) {
-  using quat_t = typename TestFixture::quat_t;
-  using Pose_t = typename TestFixture::Pose_t;
-  using vec3_t = typename TestFixture::vec3_t;
-  using FT = typename TestFixture::FT;
-
-  const auto tolerance = FT(0.0001);
-
-  const quat_t first_rotation(
-      Eigen::AngleAxis<FT>(FT(M_PI / 2.0), vec3_t(FT(0.0), FT(0.0), FT(1.0))));
-  const auto first_offset = vec3_t(FT(-3.0), FT(2.0), FT(-1.0));
-  const quat_t second_rotation(Eigen::AngleAxis<FT>(
-      FT(M_PI / 3.0), vec3_t(FT(1.0), FT(-1.0), FT(0.0)).normalized()));
-  const auto second_offset = vec3_t(FT(6.0), FT(-7.0), FT(-8.0));
-
-  const Pose_t first_pose(first_rotation, first_offset);
-  const Pose_t second_pose(second_rotation, second_offset);
-
-  const auto combined_pose(second_pose.Compose(first_pose));
-
-  for (int axis = 0; axis < 3; ++axis) {
-    vec3_t start_position = vec3_t::Zero();
-    start_position[axis] = FT(1.0);
-    const vec3_t expected_transformed =
-        second_pose.TransformPoint(first_pose.TransformPoint(start_position));
-    const vec3_t actual_transformed =
-        combined_pose.TransformPoint(start_position);
-    EXPECT_VEC3_NEAR(expected_transformed, actual_transformed, tolerance);
-  }
-}
-
-TYPED_TEST(PoseTest, Inverse) {
-  using quat_t = typename TestFixture::quat_t;
-  using vec3_t = typename TestFixture::vec3_t;
-  using Pose_t = typename TestFixture::Pose_t;
-  using FT = typename TestFixture::FT;
-
-  const auto tolerance = FT(0.0001);
-
-  const quat_t pose_rotation(Eigen::AngleAxis<FT>(
-      FT(M_PI / 2.0), vec3_t(FT(4.0), FT(-2.0), FT(-1.0)).normalized()));
-  const auto pose_position = vec3_t(FT(-1.0), FT(2.0), FT(-4.0));
-
-  Pose_t pose(pose_rotation, pose_position);
-  const Pose_t pose_inverse = pose.Inverse();
-
-  for (int axis = 0; axis < 3; ++axis) {
-    vec3_t start_position = vec3_t::Zero();
-    start_position[axis] = FT(1.0);
-    const vec3_t transformed = pose.Transform(start_position);
-    const vec3_t inverted = pose_inverse.Transform(transformed);
-    EXPECT_VEC3_NEAR(start_position, inverted, tolerance);
-  }
-
-  Pose_t nullified_pose[2] = {
-      pose.Compose(pose_inverse), pose_inverse.Compose(pose),
-  };
-
-  for (int i = 0; i < 2; ++i) {
-    EXPECT_QUAT_NEAR(quat_t::Identity(), nullified_pose[i].GetRotation(),
-                     tolerance);
-    EXPECT_VEC3_NEAR(vec3_t::Zero(), nullified_pose[i].GetPosition(),
-                     tolerance);
-  }
-}
diff --git a/libs/vr/libpdx/Android.bp b/libs/vr/libpdx/Android.bp
deleted file mode 100644
index c95603b..0000000
--- a/libs/vr/libpdx/Android.bp
+++ /dev/null
@@ -1,85 +0,0 @@
-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_library_headers {
-    name: "libpdx_headers",
-    export_include_dirs: ["private"],
-    vendor_available: true,
-    min_sdk_version: "29",
-}
-
-cc_library_static {
-    name: "libpdx",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-DLOG_TAG=\"libpdx\"",
-        "-DTRACE=0",
-    ],
-    header_libs: ["libpdx_headers"],
-    export_header_lib_headers: ["libpdx_headers"],
-    srcs: [
-        "client.cpp",
-        "service.cpp",
-        "service_dispatcher.cpp",
-        "status.cpp",
-    ],
-    shared_libs: [
-        "libbinder",
-        "libcutils",
-        "libutils",
-        "liblog",
-    ],
-}
-
-cc_test {
-    name: "pdx_tests",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-    srcs: [
-        "client_tests.cpp",
-        "mock_tests.cpp",
-        "serialization_tests.cpp",
-        "service_tests.cpp",
-        "status_tests.cpp",
-        "thread_local_buffer_tests.cpp",
-        "variant_tests.cpp",
-    ],
-    static_libs: [
-        "libcutils",
-        "libgmock",
-        "libpdx",
-        "liblog",
-        "libutils",
-    ],
-    shared_libs: [
-        "libvndksupport",
-    ],
-}
-
-// Code analysis target.
-cc_test {
-    name: "pdx_encoder_performance_test",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-O2",
-    ],
-    srcs: [
-        "encoder_performance_test.cpp",
-    ],
-    static_libs: [
-        "libpdx",
-    ],
-}
diff --git a/libs/vr/libpdx/client.cpp b/libs/vr/libpdx/client.cpp
deleted file mode 100644
index 3c66a40..0000000
--- a/libs/vr/libpdx/client.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-#include "pdx/client.h"
-
-#include <log/log.h>
-
-#include <pdx/trace.h>
-
-namespace android {
-namespace pdx {
-
-void Client::EnableAutoReconnect(int64_t reconnect_timeout_ms) {
-  if (channel_factory_) {
-    reconnect_timeout_ms_ = reconnect_timeout_ms;
-    auto_reconnect_enabled_ = true;
-  }
-}
-
-void Client::DisableAutoReconnect() { auto_reconnect_enabled_ = false; }
-
-bool Client::IsConnected() const { return channel_.get() != nullptr; }
-
-Status<void> Client::CheckReconnect() {
-  Status<void> ret;
-  bool was_disconnected = !IsConnected();
-  if (auto_reconnect_enabled_ && was_disconnected && channel_factory_) {
-    auto status = channel_factory_->Connect(reconnect_timeout_ms_);
-    if (!status) {
-      error_ = -status.error();
-      ret.SetError(status.error());
-      return ret;
-    }
-    channel_ = status.take();
-  }
-
-  if (!IsConnected()) {
-    ret.SetError(ESHUTDOWN);
-  } else {
-    // Call the subclass OnConnect handler. The subclass may choose to close the
-    // connection in the handler, in which case error_ will be non-zero.
-    if (was_disconnected)
-      OnConnect();
-    if (!IsConnected())
-      ret.SetError(-error_);
-    else
-      ret.SetValue();
-  }
-
-  return ret;
-}
-
-bool Client::NeedToDisconnectChannel(int error) const {
-  return error == ESHUTDOWN && auto_reconnect_enabled_;
-}
-
-void Client::CheckDisconnect(int error) {
-  if (NeedToDisconnectChannel(error))
-    Close(error);
-}
-
-Client::Client(std::unique_ptr<ClientChannel> channel)
-    : channel_{std::move(channel)} {}
-
-Client::Client(std::unique_ptr<ClientChannelFactory> channel_factory,
-               int64_t timeout_ms)
-    : channel_factory_{std::move(channel_factory)} {
-  auto status = channel_factory_->Connect(timeout_ms);
-  if (!status) {
-    ALOGE("Client::Client: Failed to connect to service because: %s",
-          status.GetErrorMessage().c_str());
-    error_ = -status.error();
-  } else {
-    channel_ = status.take();
-  }
-}
-
-bool Client::IsInitialized() const {
-  return IsConnected() || (channel_factory_ && auto_reconnect_enabled_);
-}
-
-void Client::OnConnect() {}
-
-int Client::error() const { return error_; }
-
-Status<void> Client::SendImpulse(int opcode) {
-  PDX_TRACE_NAME("Client::SendImpulse");
-
-  auto status = CheckReconnect();
-  if (!status)
-    return status;
-
-  status = channel_->SendImpulse(opcode, nullptr, 0);
-  CheckDisconnect(status);
-  return status;
-}
-
-Status<void> Client::SendImpulse(int opcode, const void* buffer,
-                                 size_t length) {
-  PDX_TRACE_NAME("Client::SendImpulse");
-
-  auto status = CheckReconnect();
-  if (!status)
-    return status;
-
-  status = channel_->SendImpulse(opcode, buffer, length);
-  CheckDisconnect(status);
-  return status;
-}
-
-void Client::Close(int error) {
-  channel_.reset();
-  // Normalize error codes to negative integer space.
-  error_ = error <= 0 ? error : -error;
-}
-
-int Client::event_fd() const {
-  return IsConnected() ? channel_->event_fd() : -1;
-}
-
-LocalChannelHandle& Client::GetChannelHandle() {
-  return channel_->GetChannelHandle();
-}
-
-const LocalChannelHandle& Client::GetChannelHandle() const {
-  return channel_->GetChannelHandle();
-}
-
-///////////////////////////// Transaction implementation //////////////////////
-
-Transaction::Transaction(Client& client) : client_{client} {}
-
-Transaction::~Transaction() {
-  if (state_allocated_ && client_.GetChannel())
-    client_.GetChannel()->FreeTransactionState(state_);
-}
-
-bool Transaction::EnsureStateAllocated() {
-  if (!state_allocated_ && client_.GetChannel()) {
-    state_ = client_.GetChannel()->AllocateTransactionState();
-    state_allocated_ = true;
-  }
-  return state_allocated_;
-}
-
-void Transaction::SendTransaction(int opcode, Status<void>* ret,
-                                  const iovec* send_vector, size_t send_count,
-                                  const iovec* receive_vector,
-                                  size_t receive_count) {
-  *ret = client_.CheckReconnect();
-  if (!*ret)
-    return;
-
-  if (!EnsureStateAllocated()) {
-    ret->SetError(ESHUTDOWN);
-    return;
-  }
-
-  auto status = client_.GetChannel()->SendWithInt(
-      state_, opcode, send_vector, send_count, receive_vector, receive_count);
-
-  if (status) {
-    ret->SetValue();
-  } else {
-    ret->SetError(status.error());
-  }
-  CheckDisconnect(status);
-}
-
-void Transaction::SendTransaction(int opcode, Status<int>* ret,
-                                  const iovec* send_vector, size_t send_count,
-                                  const iovec* receive_vector,
-                                  size_t receive_count) {
-  auto status = client_.CheckReconnect();
-  if (!status) {
-    ret->SetError(status.error());
-    return;
-  }
-
-  if (!EnsureStateAllocated()) {
-    ret->SetError(ESHUTDOWN);
-    return;
-  }
-
-  *ret = client_.GetChannel()->SendWithInt(
-      state_, opcode, send_vector, send_count, receive_vector, receive_count);
-
-  CheckDisconnect(*ret);
-}
-
-void Transaction::SendTransaction(int opcode, Status<LocalHandle>* ret,
-                                  const iovec* send_vector, size_t send_count,
-                                  const iovec* receive_vector,
-                                  size_t receive_count) {
-  auto status = client_.CheckReconnect();
-  if (!status) {
-    ret->SetError(status.error());
-    return;
-  }
-
-  if (!EnsureStateAllocated()) {
-    ret->SetError(ESHUTDOWN);
-    return;
-  }
-
-  *ret = client_.GetChannel()->SendWithFileHandle(
-      state_, opcode, send_vector, send_count, receive_vector, receive_count);
-
-  CheckDisconnect(*ret);
-}
-
-void Transaction::SendTransaction(int opcode, Status<LocalChannelHandle>* ret,
-                                  const iovec* send_vector, size_t send_count,
-                                  const iovec* receive_vector,
-                                  size_t receive_count) {
-  auto status = client_.CheckReconnect();
-  if (!status) {
-    ret->SetError(status.error());
-    return;
-  }
-
-  if (!EnsureStateAllocated()) {
-    ret->SetError(ESHUTDOWN);
-    return;
-  }
-
-  *ret = client_.GetChannel()->SendWithChannelHandle(
-      state_, opcode, send_vector, send_count, receive_vector, receive_count);
-
-  CheckDisconnect(*ret);
-}
-
-Status<FileReference> Transaction::PushFileHandle(const LocalHandle& handle) {
-  if (client_.CheckReconnect() && EnsureStateAllocated())
-    return client_.GetChannel()->PushFileHandle(state_, handle);
-  return ErrorStatus{ESHUTDOWN};
-}
-
-Status<FileReference> Transaction::PushFileHandle(
-    const BorrowedHandle& handle) {
-  if (client_.CheckReconnect() && EnsureStateAllocated())
-    return client_.GetChannel()->PushFileHandle(state_, handle);
-  return ErrorStatus{ESHUTDOWN};
-}
-
-Status<FileReference> Transaction::PushFileHandle(const RemoteHandle& handle) {
-  return handle.Get();
-}
-
-Status<ChannelReference> Transaction::PushChannelHandle(
-    const LocalChannelHandle& handle) {
-  if (client_.CheckReconnect() && EnsureStateAllocated())
-    return client_.GetChannel()->PushChannelHandle(state_, handle);
-  return ErrorStatus{ESHUTDOWN};
-}
-
-Status<ChannelReference> Transaction::PushChannelHandle(
-    const BorrowedChannelHandle& handle) {
-  if (client_.CheckReconnect() && EnsureStateAllocated())
-    return client_.GetChannel()->PushChannelHandle(state_, handle);
-  return ErrorStatus{ESHUTDOWN};
-}
-
-Status<ChannelReference> Transaction::PushChannelHandle(
-    const RemoteChannelHandle& handle) {
-  return handle.value();
-}
-
-bool Transaction::GetFileHandle(FileReference ref, LocalHandle* handle) {
-  return client_.CheckReconnect() && EnsureStateAllocated() &&
-         client_.GetChannel()->GetFileHandle(state_, ref, handle);
-}
-
-bool Transaction::GetChannelHandle(ChannelReference ref,
-                                   LocalChannelHandle* handle) {
-  return client_.CheckReconnect() && EnsureStateAllocated() &&
-         client_.GetChannel()->GetChannelHandle(state_, ref, handle);
-}
-
-void Transaction::CheckDisconnect(int error) {
-  if (client_.NeedToDisconnectChannel(error)) {
-    if (state_allocated_) {
-      if (client_.GetChannel())
-        client_.GetChannel()->FreeTransactionState(state_);
-      state_ = nullptr;
-      state_allocated_ = false;
-    }
-    client_.Close(error);
-  }
-}
-
-}  // namespace pdx
-}  // namespace android
diff --git a/libs/vr/libpdx/client_tests.cpp b/libs/vr/libpdx/client_tests.cpp
deleted file mode 100644
index 99ccc69..0000000
--- a/libs/vr/libpdx/client_tests.cpp
+++ /dev/null
@@ -1,567 +0,0 @@
-#include <pdx/client.h>
-
-#include <gmock/gmock.h>
-#include <sys/eventfd.h>
-
-#include <pdx/mock_client_channel.h>
-#include <pdx/mock_client_channel_factory.h>
-#include <pdx/rpc/remote_method.h>
-
-using android::pdx::BorrowedChannelHandle;
-using android::pdx::BorrowedHandle;
-using android::pdx::ClientBase;
-using android::pdx::ClientChannel;
-using android::pdx::ClientChannelFactory;
-using android::pdx::ErrorStatus;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::MockClientChannel;
-using android::pdx::MockClientChannelFactory;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::RemoteHandle;
-using android::pdx::Status;
-using android::pdx::Transaction;
-using android::pdx::rpc::Void;
-
-using testing::A;
-using testing::AnyNumber;
-using testing::ByMove;
-using testing::Invoke;
-using testing::Ne;
-using testing::Return;
-using testing::_;
-
-namespace {
-
-inline void* IntToPtr(intptr_t addr) { return reinterpret_cast<void*>(addr); }
-inline const void* IntToConstPtr(intptr_t addr) {
-  return reinterpret_cast<const void*>(addr);
-}
-
-struct TestInterface final {
-  // Op codes.
-  enum {
-    kOpAdd = 0,
-    kOpSendFile,
-    kOpGetFile,
-    kOpPushChannel,
-  };
-
-  // Methods.
-  PDX_REMOTE_METHOD(Add, kOpAdd, int(int, int));
-  PDX_REMOTE_METHOD(SendFile, kOpSendFile, void(const LocalHandle& fd));
-  PDX_REMOTE_METHOD(GetFile, kOpGetFile, LocalHandle(const std::string&, int));
-  PDX_REMOTE_METHOD(PushChannel, kOpPushChannel, LocalChannelHandle(Void));
-
-  PDX_REMOTE_API(API, Add, SendFile, GetFile, PushChannel);
-};
-
-class SimpleClient : public ClientBase<SimpleClient> {
- public:
-  explicit SimpleClient(std::unique_ptr<ClientChannel> channel)
-      : BASE{std::move(channel)} {}
-  SimpleClient(std::unique_ptr<ClientChannelFactory> channel_factory,
-               int64_t timeout_ms)
-      : BASE{std::move(channel_factory), timeout_ms} {
-    EnableAutoReconnect(timeout_ms);
-  }
-
-  using BASE::SendImpulse;
-  using BASE::InvokeRemoteMethod;
-  using BASE::InvokeRemoteMethodInPlace;
-  using BASE::Close;
-  using BASE::IsConnected;
-  using BASE::EnableAutoReconnect;
-  using BASE::DisableAutoReconnect;
-  using BASE::event_fd;
-  using BASE::GetChannel;
-
-  MOCK_METHOD0(OnConnect, void());
-};
-
-class FailingClient : public ClientBase<FailingClient> {
- public:
-  explicit FailingClient(std::unique_ptr<ClientChannel> channel, int error_code)
-      : BASE{std::move(channel)} {
-    Close(error_code);
-  }
-};
-
-class ClientChannelTest : public testing::Test {
- public:
-  ClientChannelTest()
-      : client_{SimpleClient::Create(
-            std::make_unique<testing::StrictMock<MockClientChannel>>())} {}
-
-  MockClientChannel* mock_channel() {
-    return static_cast<MockClientChannel*>(client_->GetChannel());
-  }
-
-  std::unique_ptr<SimpleClient> client_;
-};
-
-class ClientChannelFactoryTest : public testing::Test {
- public:
-  ClientChannelFactoryTest() {
-    auto factory =
-        std::make_unique<testing::NiceMock<MockClientChannelFactory>>();
-    ON_CALL(*factory, Connect(kTimeout))
-        .WillByDefault(Invoke(this, &ClientChannelFactoryTest::OnConnect));
-    client_ = SimpleClient::Create(std::move(factory), kTimeout);
-  }
-
-  MockClientChannel* mock_channel() {
-    return static_cast<MockClientChannel*>(client_->GetChannel());
-  }
-
-  Status<std::unique_ptr<ClientChannel>> OnConnect(int64_t /*timeout_ms*/) {
-    if (on_connect_error_)
-      return ErrorStatus(on_connect_error_);
-    std::unique_ptr<MockClientChannel> channel =
-        std::make_unique<testing::StrictMock<MockClientChannel>>();
-    if (on_connect_callback_)
-      on_connect_callback_(channel.get());
-    return Status<std::unique_ptr<ClientChannel>>{std::move(channel)};
-  }
-
-  void OnConnectCallback(std::function<void(MockClientChannel*)> callback) {
-    on_connect_callback_ = callback;
-  }
-  void SetOnConnectError(int error) { on_connect_error_ = error; }
-  void ResetOnConnectError() { on_connect_error_ = 0; }
-
-  constexpr static int64_t kTimeout = 123;
-  std::unique_ptr<SimpleClient> client_;
-  std::function<void(MockClientChannel*)> on_connect_callback_;
-  int on_connect_error_{0};
-};
-
-constexpr int64_t ClientChannelFactoryTest::kTimeout;
-
-class ClientTransactionTest : public ClientChannelTest {
- public:
-  ClientTransactionTest() : transaction_{*client_} {}
-
-  Transaction transaction_;
-};
-
-}  // anonymous namespace
-
-TEST_F(ClientChannelTest, IsInitialized) {
-  ASSERT_NE(client_.get(), nullptr);
-  EXPECT_TRUE(client_->IsInitialized());
-  EXPECT_TRUE(client_->IsConnected());
-}
-
-TEST_F(ClientChannelTest, CloseOnConstruction) {
-  FailingClient failed_client1{std::make_unique<MockClientChannel>(), EACCES};
-  ASSERT_FALSE(failed_client1.IsInitialized());
-  EXPECT_EQ(-EACCES, failed_client1.error());
-
-  FailingClient failed_client2{std::make_unique<MockClientChannel>(), -EACCES};
-  ASSERT_FALSE(failed_client2.IsInitialized());
-  EXPECT_EQ(-EACCES, failed_client2.error());
-
-  auto failed_client3 =
-      FailingClient::Create(std::make_unique<MockClientChannel>(), EIO);
-  ASSERT_EQ(failed_client3.get(), nullptr);
-}
-
-TEST_F(ClientChannelTest, IsConnected) {
-  EXPECT_TRUE(client_->IsConnected());
-  EXPECT_EQ(0, client_->error());
-  client_->Close(-EINVAL);
-  EXPECT_FALSE(client_->IsConnected());
-  EXPECT_EQ(-EINVAL, client_->error());
-}
-
-TEST_F(ClientChannelTest, event_fd) {
-  EXPECT_CALL(*mock_channel(), event_fd()).WillOnce(Return(12));
-  EXPECT_EQ(12, client_->event_fd());
-}
-
-TEST_F(ClientChannelTest, SendImpulse) {
-  EXPECT_CALL(*mock_channel(), SendImpulse(123, nullptr, 0))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(client_->SendImpulse(123));
-
-  EXPECT_CALL(*mock_channel(), SendImpulse(17, nullptr, 0))
-      .WillOnce(Return(ErrorStatus{EIO}));
-  auto status = client_->SendImpulse(17);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EIO, status.error());
-
-  const void* const kTestPtr = IntToConstPtr(1234);
-  EXPECT_CALL(*mock_channel(), SendImpulse(1, kTestPtr, 17))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(client_->SendImpulse(1, kTestPtr, 17));
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodNullTransactionState) {
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(nullptr));
-  EXPECT_CALL(*mock_channel(),
-              SendWithInt(nullptr, TestInterface::kOpAdd, _, _, nullptr, 0))
-      .WillOnce(Return(9));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
-  EXPECT_TRUE(client_->InvokeRemoteMethod<TestInterface::Add>(4, 5));
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodAddSuccess) {
-  void* const kTransactionState = IntToPtr(123);
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(kTransactionState));
-  EXPECT_CALL(
-      *mock_channel(),
-      SendWithInt(kTransactionState, TestInterface::kOpAdd, _, _, nullptr, 0))
-      .WillOnce(Return(3));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-  Status<int> status = client_->InvokeRemoteMethod<TestInterface::Add>(1, 2);
-  ASSERT_TRUE(status);
-  EXPECT_EQ(3, status.get());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodAddFailure) {
-  void* const kTransactionState = IntToPtr(123);
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(kTransactionState));
-  EXPECT_CALL(
-      *mock_channel(),
-      SendWithInt(kTransactionState, TestInterface::kOpAdd, _, _, nullptr, 0))
-      .WillOnce(Return(ErrorStatus{EIO}));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-  Status<int> status = client_->InvokeRemoteMethod<TestInterface::Add>(1, 2);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EIO, status.error());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodGetFileSuccess) {
-  void* const kTransactionState = IntToPtr(123);
-  int fd = eventfd(0, 0);
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(kTransactionState));
-  EXPECT_CALL(*mock_channel(),
-              SendWithFileHandle(kTransactionState, TestInterface::kOpGetFile,
-                                 _, _, nullptr, 0))
-      .WillOnce(Return(ByMove(LocalHandle{fd})));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-  Status<LocalHandle> status =
-      client_->InvokeRemoteMethod<TestInterface::GetFile>();
-  ASSERT_TRUE(status);
-  EXPECT_EQ(fd, status.get().Get());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodGetFileFailure) {
-  void* const kTransactionState = IntToPtr(123);
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(kTransactionState));
-  EXPECT_CALL(*mock_channel(),
-              SendWithFileHandle(kTransactionState, TestInterface::kOpGetFile,
-                                 _, _, nullptr, 0))
-      .WillOnce(Return(ByMove(ErrorStatus{EACCES})));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-  Status<LocalHandle> status =
-      client_->InvokeRemoteMethod<TestInterface::GetFile>("file", 0);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EACCES, status.error());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodPushChannelSuccess) {
-  void* const kTransactionState = IntToPtr(123);
-  const int32_t kHandleValue = 17;
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(kTransactionState));
-  EXPECT_CALL(
-      *mock_channel(),
-      SendWithChannelHandle(kTransactionState, TestInterface::kOpPushChannel, _,
-                            _, nullptr, 0))
-      .WillOnce(Return(ByMove(LocalChannelHandle{nullptr, kHandleValue})));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-  Status<LocalChannelHandle> status =
-      client_->InvokeRemoteMethod<TestInterface::PushChannel>();
-  ASSERT_TRUE(status);
-  EXPECT_EQ(kHandleValue, status.get().value());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodPushChannelFailure) {
-  void* const kTransactionState = IntToPtr(123);
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(kTransactionState));
-  EXPECT_CALL(
-      *mock_channel(),
-      SendWithChannelHandle(kTransactionState, TestInterface::kOpPushChannel, _,
-                            _, nullptr, 0))
-      .WillOnce(Return(ByMove(ErrorStatus{EACCES})));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-  Status<LocalChannelHandle> status =
-      client_->InvokeRemoteMethod<TestInterface::PushChannel>();
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EACCES, status.error());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodSendFileSuccess) {
-  void* const kTransactionState = IntToPtr(123);
-  LocalHandle fd{eventfd(0, 0)};
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(kTransactionState));
-  EXPECT_CALL(*mock_channel(),
-              PushFileHandle(kTransactionState, A<const LocalHandle&>()))
-      .WillOnce(Return(1));
-  EXPECT_CALL(*mock_channel(),
-              SendWithInt(kTransactionState, TestInterface::kOpSendFile, _, _,
-                          nullptr, 0))
-      .WillOnce(Return(0));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-  EXPECT_TRUE(client_->InvokeRemoteMethod<TestInterface::SendFile>(fd));
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodSendFileFailure) {
-  void* const kTransactionState = IntToPtr(123);
-  LocalHandle fd{eventfd(0, 0)};
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(kTransactionState));
-  EXPECT_CALL(*mock_channel(),
-              PushFileHandle(kTransactionState, A<const LocalHandle&>()))
-      .WillOnce(Return(1));
-  EXPECT_CALL(*mock_channel(),
-              SendWithInt(kTransactionState, TestInterface::kOpSendFile, _, _,
-                          nullptr, 0))
-      .WillOnce(Return(ErrorStatus{EACCES}));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-  EXPECT_FALSE(client_->InvokeRemoteMethod<TestInterface::SendFile>(fd));
-}
-
-TEST_F(ClientChannelFactoryTest, IsInitialized) {
-  ASSERT_NE(client_.get(), nullptr);
-  EXPECT_TRUE(client_->IsInitialized());
-  EXPECT_TRUE(client_->IsConnected());
-}
-
-TEST_F(ClientChannelFactoryTest, NotConnectedButInitialized) {
-  auto factory =
-      std::make_unique<testing::NiceMock<MockClientChannelFactory>>();
-  EXPECT_CALL(*factory, Connect(kTimeout))
-      .WillOnce(Return(ByMove(ErrorStatus(ESHUTDOWN))))
-      .WillOnce(Invoke(this, &ClientChannelFactoryTest::OnConnect));
-  client_ = SimpleClient::Create(std::move(factory), kTimeout);
-  ASSERT_NE(client_.get(), nullptr);
-  EXPECT_TRUE(client_->IsInitialized());
-  EXPECT_FALSE(client_->IsConnected());
-  client_->DisableAutoReconnect();
-  ASSERT_FALSE(client_->SendImpulse(17));
-  EXPECT_FALSE(client_->IsConnected());
-  client_->EnableAutoReconnect(kTimeout);
-  EXPECT_CALL(*client_, OnConnect());
-  OnConnectCallback([](auto* mock) {
-    EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
-        .WillOnce(Return(Status<void>{}));
-  });
-  ASSERT_TRUE(client_->SendImpulse(17));
-  EXPECT_TRUE(client_->IsConnected());
-}
-
-TEST_F(ClientChannelFactoryTest, CheckDisconnect) {
-  EXPECT_CALL(*mock_channel(), SendImpulse(17, nullptr, 0))
-      .WillOnce(Return(ErrorStatus{ESHUTDOWN}));
-  ASSERT_FALSE(client_->SendImpulse(17));
-  EXPECT_FALSE(client_->IsConnected());
-  EXPECT_EQ(-ESHUTDOWN, client_->error());
-}
-
-TEST_F(ClientChannelFactoryTest, CheckReconnect) {
-  client_->Close(ESHUTDOWN);
-  ASSERT_FALSE(client_->IsConnected());
-
-  EXPECT_CALL(*client_, OnConnect());
-  OnConnectCallback([](auto* mock) {
-    EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
-        .WillOnce(Return(Status<void>{}));
-  });
-  ASSERT_TRUE(client_->SendImpulse(17));
-  EXPECT_TRUE(client_->IsConnected());
-}
-
-TEST_F(ClientChannelFactoryTest, CloseOnConnect) {
-  client_->Close(ESHUTDOWN);
-
-  EXPECT_CALL(*client_, OnConnect()).WillOnce(Invoke([this] {
-    client_->Close(EIO);
-  }));
-  auto status = client_->SendImpulse(17);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EIO, status.error());
-  EXPECT_FALSE(client_->IsConnected());
-  EXPECT_EQ(-EIO, client_->error());
-}
-
-TEST_F(ClientChannelFactoryTest, DisableAutoReconnect) {
-  client_->Close(EIO);
-  ASSERT_FALSE(client_->IsConnected());
-  client_->DisableAutoReconnect();
-  auto status = client_->SendImpulse(17);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(ESHUTDOWN, status.error());
-  EXPECT_FALSE(client_->IsConnected());
-  client_->EnableAutoReconnect(kTimeout);
-  EXPECT_CALL(*client_, OnConnect());
-  OnConnectCallback([](auto* mock) {
-    EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
-        .WillOnce(Return(Status<void>{}));
-  });
-  ASSERT_TRUE(client_->SendImpulse(17));
-  EXPECT_TRUE(client_->IsConnected());
-}
-
-TEST_F(ClientTransactionTest, SendNoData) {
-  void* const kTransactionState = IntToPtr(123);
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(kTransactionState));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-  EXPECT_CALL(*mock_channel(),
-              SendWithInt(kTransactionState, 1, nullptr, 0, nullptr, 0))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(transaction_.Send<void>(1));
-  EXPECT_CALL(*mock_channel(),
-              SendWithFileHandle(kTransactionState, 2, nullptr, 0, nullptr, 0))
-      .WillOnce(Return(ByMove(LocalHandle{-1})));
-  EXPECT_TRUE(transaction_.Send<LocalHandle>(2));
-  EXPECT_CALL(*mock_channel(), SendWithChannelHandle(kTransactionState, 3,
-                                                     nullptr, 0, nullptr, 0))
-      .WillOnce(Return(ByMove(LocalChannelHandle{nullptr, 1})));
-  EXPECT_TRUE(transaction_.Send<LocalChannelHandle>(3));
-}
-
-TEST_F(ClientTransactionTest, SendNoState) {
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(nullptr));
-  EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
-      .WillOnce(Return(0));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
-  EXPECT_TRUE(transaction_.Send<void>(1));
-}
-
-TEST_F(ClientTransactionTest, SendBuffers) {
-  const void* const kSendBuffer = IntToConstPtr(123);
-  const size_t kSendSize = 12;
-  void* const kReceiveBuffer = IntToPtr(456);
-  const size_t kReceiveSize = 34;
-
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(nullptr));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
-
-  EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(transaction_.Send<void>(1, nullptr, 0, nullptr, 0));
-
-  EXPECT_CALL(*mock_channel(),
-              SendWithInt(nullptr, 2, Ne(nullptr), 1, nullptr, 0))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(transaction_.Send<void>(2, kSendBuffer, kSendSize, nullptr, 0));
-
-  EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 3, nullptr, 0, nullptr, 0))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(transaction_.Send<void>(3, kSendBuffer, 0, nullptr, 0));
-
-  EXPECT_CALL(*mock_channel(),
-              SendWithInt(nullptr, 4, nullptr, 0, Ne(nullptr), 1))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(
-      transaction_.Send<void>(4, nullptr, 0, kReceiveBuffer, kReceiveSize));
-
-  EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 5, nullptr, 0, nullptr, 0))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(transaction_.Send<void>(5, nullptr, 0, kReceiveBuffer, 0));
-
-  EXPECT_CALL(*mock_channel(),
-              SendWithInt(nullptr, 5, Ne(nullptr), 1, Ne(nullptr), 1))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(transaction_.Send<void>(5, kSendBuffer, kSendSize, kReceiveBuffer,
-                                      kReceiveSize));
-}
-
-TEST_F(ClientTransactionTest, SendVector) {
-  iovec send[3] = {};
-  iovec recv[4] = {};
-
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(nullptr));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
-
-  EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(transaction_.SendVector<void>(1, nullptr, 0, nullptr, 0));
-
-  EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 2, send, 3, recv, 4))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(transaction_.SendVector<void>(2, send, 3, recv, 4));
-
-  EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 3, send, 3, nullptr, 0))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(transaction_.SendVector<void>(3, send, nullptr));
-
-  EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 4, nullptr, 0, recv, 4))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(transaction_.SendVector<void>(4, nullptr, recv));
-
-  EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 5, send, 3, recv, 4))
-      .WillOnce(Return(0));
-  EXPECT_TRUE(transaction_.SendVector<void>(5, send, recv));
-}
-
-TEST_F(ClientTransactionTest, PushHandle) {
-  void* const kTransactionState = IntToPtr(123);
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(kTransactionState));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-
-  EXPECT_CALL(*mock_channel(),
-              PushFileHandle(kTransactionState, A<const LocalHandle&>()))
-      .WillOnce(Return(1));
-  EXPECT_EQ(1, transaction_.PushFileHandle(LocalHandle{-1}).get());
-
-  EXPECT_CALL(*mock_channel(),
-              PushFileHandle(kTransactionState, A<const BorrowedHandle&>()))
-      .WillOnce(Return(2));
-  EXPECT_EQ(2, transaction_.PushFileHandle(BorrowedHandle{-1}).get());
-
-  EXPECT_EQ(3, transaction_.PushFileHandle(RemoteHandle{3}).get());
-
-  EXPECT_CALL(
-      *mock_channel(),
-      PushChannelHandle(kTransactionState, A<const LocalChannelHandle&>()))
-      .WillOnce(Return(11));
-  EXPECT_EQ(
-      11, transaction_.PushChannelHandle(LocalChannelHandle{nullptr, 1}).get());
-
-  EXPECT_CALL(
-      *mock_channel(),
-      PushChannelHandle(kTransactionState, A<const BorrowedChannelHandle&>()))
-      .WillOnce(Return(12));
-  EXPECT_EQ(12, transaction_.PushChannelHandle(BorrowedChannelHandle{2}).get());
-
-  EXPECT_EQ(13, transaction_.PushChannelHandle(RemoteChannelHandle{13}).get());
-}
-
-TEST_F(ClientTransactionTest, GetHandle) {
-  void* const kTransactionState = IntToPtr(123);
-  EXPECT_CALL(*mock_channel(), AllocateTransactionState())
-      .WillOnce(Return(kTransactionState));
-  EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-
-  EXPECT_CALL(*mock_channel(), GetFileHandle(kTransactionState, 1, _))
-      .WillOnce(Return(false))
-      .WillOnce(Return(true));
-
-  LocalHandle file_handle;
-  EXPECT_FALSE(transaction_.GetFileHandle(1, &file_handle));
-  EXPECT_TRUE(transaction_.GetFileHandle(1, &file_handle));
-
-  EXPECT_CALL(*mock_channel(), GetChannelHandle(kTransactionState, 2, _))
-      .WillOnce(Return(false))
-      .WillOnce(Return(true));
-
-  LocalChannelHandle channel_handle;
-  EXPECT_FALSE(transaction_.GetChannelHandle(2, &channel_handle));
-  EXPECT_TRUE(transaction_.GetChannelHandle(2, &channel_handle));
-}
diff --git a/libs/vr/libpdx/encoder_performance_test.cpp b/libs/vr/libpdx/encoder_performance_test.cpp
deleted file mode 100644
index 7b477c4..0000000
--- a/libs/vr/libpdx/encoder_performance_test.cpp
+++ /dev/null
@@ -1,515 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <chrono>
-#include <iomanip>
-#include <iostream>
-#include <vector>
-
-#include <pdx/rpc/argument_encoder.h>
-#include <pdx/rpc/message_buffer.h>
-#include <pdx/rpc/payload.h>
-#include <pdx/utility.h>
-
-using namespace android::pdx::rpc;
-using namespace android::pdx;
-using std::placeholders::_1;
-using std::placeholders::_2;
-using std::placeholders::_3;
-using std::placeholders::_4;
-using std::placeholders::_5;
-using std::placeholders::_6;
-
-namespace {
-
-constexpr size_t kMaxStaticBufferSize = 20480;
-
-// Provide numpunct facet that formats numbers with ',' as thousands separators.
-class CommaNumPunct : public std::numpunct<char> {
- protected:
-  char do_thousands_sep() const override { return ','; }
-  std::string do_grouping() const override { return "\03"; }
-};
-
-class TestPayload : public MessagePayload<SendBuffer>,
-                    public MessageWriter,
-                    public MessageReader,
-                    public NoOpResourceMapper {
- public:
-  // MessageWriter
-  void* GetNextWriteBufferSection(size_t size) override {
-    const size_t section_offset = Size();
-    Extend(size);
-    return Data() + section_offset;
-  }
-
-  OutputResourceMapper* GetOutputResourceMapper() override { return this; }
-
-  // MessageReader
-  BufferSection GetNextReadBufferSection() override {
-    return {&*ConstCursor(), &*ConstEnd()};
-  }
-
-  void ConsumeReadBufferSectionData(const void* new_start) override {
-    std::advance(ConstCursor(), PointerDistance(new_start, &*ConstCursor()));
-  }
-
-  InputResourceMapper* GetInputResourceMapper() override { return this; }
-};
-
-class StaticBuffer : public MessageWriter,
-                     public MessageReader,
-                     public NoOpResourceMapper {
- public:
-  void Clear() {
-    read_ptr_ = buffer_;
-    write_ptr_ = 0;
-  }
-  void Rewind() { read_ptr_ = buffer_; }
-
-  // MessageWriter
-  void* GetNextWriteBufferSection(size_t size) override {
-    void* ptr = buffer_ + write_ptr_;
-    write_ptr_ += size;
-    return ptr;
-  }
-
-  OutputResourceMapper* GetOutputResourceMapper() override { return this; }
-
-  // MessageReader
-  BufferSection GetNextReadBufferSection() override {
-    return {read_ptr_, std::end(buffer_)};
-  }
-
-  void ConsumeReadBufferSectionData(const void* new_start) override {
-    read_ptr_ = static_cast<const uint8_t*>(new_start);
-  }
-
-  InputResourceMapper* GetInputResourceMapper() override { return this; }
-
- private:
-  uint8_t buffer_[kMaxStaticBufferSize];
-  const uint8_t* read_ptr_{buffer_};
-  size_t write_ptr_{0};
-};
-
-// Simple callback function to clear/reset the input/output buffers for
-// serialization. Using raw function pointer here instead of std::function to
-// minimize the overhead of invocation in the tight test loop over millions of
-// iterations.
-using ResetFunc = void(void*);
-
-// Serialization test function signature, used by the TestRunner.
-using SerializeTestSignature = std::chrono::nanoseconds(MessageWriter* writer,
-                                                        size_t iterations,
-                                                        ResetFunc* write_reset,
-                                                        void* reset_data);
-
-// Deserialization test function signature, used by the TestRunner.
-using DeserializeTestSignature = std::chrono::nanoseconds(
-    MessageReader* reader, MessageWriter* writer, size_t iterations,
-    ResetFunc* read_reset, ResetFunc* write_reset, void* reset_data);
-
-// Generic serialization test runner method. Takes the |value| of type T and
-// serializes it into the output buffer represented by |writer|.
-template <typename T>
-std::chrono::nanoseconds SerializeTestRunner(MessageWriter* writer,
-                                             size_t iterations,
-                                             ResetFunc* write_reset,
-                                             void* reset_data, const T& value) {
-  auto start = std::chrono::high_resolution_clock::now();
-  for (size_t i = 0; i < iterations; i++) {
-    write_reset(reset_data);
-    Serialize(value, writer);
-  }
-  auto stop = std::chrono::high_resolution_clock::now();
-  return stop - start;
-}
-
-// Generic deserialization test runner method. Takes the |value| of type T and
-// temporarily serializes it into the output buffer, then repeatedly
-// deserializes the data back from that buffer.
-template <typename T>
-std::chrono::nanoseconds DeserializeTestRunner(
-    MessageReader* reader, MessageWriter* writer, size_t iterations,
-    ResetFunc* read_reset, ResetFunc* write_reset, void* reset_data,
-    const T& value) {
-  write_reset(reset_data);
-  Serialize(value, writer);
-  T output_data;
-  auto start = std::chrono::high_resolution_clock::now();
-  for (size_t i = 0; i < iterations; i++) {
-    read_reset(reset_data);
-    Deserialize(&output_data, reader);
-  }
-  auto stop = std::chrono::high_resolution_clock::now();
-  if (output_data != value)
-    return start - stop;  // Return negative value to indicate error.
-  return stop - start;
-}
-
-// Special version of SerializeTestRunner that doesn't perform any serialization
-// but does all the same setup steps and moves data of size |data_size| into
-// the output buffer. Useful to determine the baseline to calculate time used
-// just for serialization layer.
-std::chrono::nanoseconds SerializeBaseTest(MessageWriter* writer,
-                                           size_t iterations,
-                                           ResetFunc* write_reset,
-                                           void* reset_data, size_t data_size) {
-  std::vector<uint8_t> fake_data(data_size);
-  auto start = std::chrono::high_resolution_clock::now();
-  for (size_t i = 0; i < iterations; i++) {
-    write_reset(reset_data);
-    memcpy(writer->GetNextWriteBufferSection(fake_data.size()),
-           fake_data.data(), fake_data.size());
-  }
-  auto stop = std::chrono::high_resolution_clock::now();
-  return stop - start;
-}
-
-// Special version of DeserializeTestRunner that doesn't perform any
-// deserialization but invokes Rewind on the input buffer repeatedly.
-// Useful to determine the baseline to calculate time used just for
-// deserialization layer.
-std::chrono::nanoseconds DeserializeBaseTest(
-    MessageReader* reader, MessageWriter* writer, size_t iterations,
-    ResetFunc* read_reset, ResetFunc* write_reset, void* reset_data,
-    size_t data_size) {
-  std::vector<uint8_t> fake_data(data_size);
-  write_reset(reset_data);
-  memcpy(writer->GetNextWriteBufferSection(fake_data.size()), fake_data.data(),
-         fake_data.size());
-  auto start = std::chrono::high_resolution_clock::now();
-  for (size_t i = 0; i < iterations; i++) {
-    read_reset(reset_data);
-    auto section = reader->GetNextReadBufferSection();
-    memcpy(fake_data.data(), section.first, fake_data.size());
-    reader->ConsumeReadBufferSectionData(
-        AdvancePointer(section.first, fake_data.size()));
-  }
-  auto stop = std::chrono::high_resolution_clock::now();
-  return stop - start;
-}
-
-// The main class that accumulates individual tests to be executed.
-class TestRunner {
- public:
-  struct BufferInfo {
-    BufferInfo(const std::string& buffer_name, MessageReader* reader,
-               MessageWriter* writer, ResetFunc* read_reset_func,
-               ResetFunc* write_reset_func, void* reset_data)
-        : name{buffer_name},
-          reader{reader},
-          writer{writer},
-          read_reset_func{read_reset_func},
-          write_reset_func{write_reset_func},
-          reset_data{reset_data} {}
-    std::string name;
-    MessageReader* reader;
-    MessageWriter* writer;
-    ResetFunc* read_reset_func;
-    ResetFunc* write_reset_func;
-    void* reset_data;
-  };
-
-  void AddTestFunc(const std::string& name,
-                   std::function<SerializeTestSignature> serialize_test,
-                   std::function<DeserializeTestSignature> deserialize_test,
-                   size_t data_size) {
-    tests_.emplace_back(name, std::move(serialize_test),
-                        std::move(deserialize_test), data_size);
-  }
-
-  template <typename T>
-  void AddSerializationTest(const std::string& name, T&& value) {
-    const size_t data_size = GetSerializedSize(value);
-    auto serialize_test =
-        std::bind(static_cast<std::chrono::nanoseconds (*)(
-                      MessageWriter*, size_t, ResetFunc*, void*, const T&)>(
-                      &SerializeTestRunner),
-                  _1, _2, _3, _4, std::forward<T>(value));
-    tests_.emplace_back(name, std::move(serialize_test),
-                        std::function<DeserializeTestSignature>{}, data_size);
-  }
-
-  template <typename T>
-  void AddDeserializationTest(const std::string& name, T&& value) {
-    const size_t data_size = GetSerializedSize(value);
-    auto deserialize_test =
-        std::bind(static_cast<std::chrono::nanoseconds (*)(
-                      MessageReader*, MessageWriter*, size_t, ResetFunc*,
-                      ResetFunc*, void*, const T&)>(&DeserializeTestRunner),
-                  _1, _2, _3, _4, _5, _6, std::forward<T>(value));
-    tests_.emplace_back(name, std::function<SerializeTestSignature>{},
-                        std::move(deserialize_test), data_size);
-  }
-
-  template <typename T>
-  void AddTest(const std::string& name, T&& value) {
-    const size_t data_size = GetSerializedSize(value);
-    if (data_size > kMaxStaticBufferSize) {
-      std::cerr << "Test '" << name << "' requires " << data_size
-                << " bytes in the serialization buffer but only "
-                << kMaxStaticBufferSize << " are available." << std::endl;
-      exit(1);
-    }
-    auto serialize_test =
-        std::bind(static_cast<std::chrono::nanoseconds (*)(
-                      MessageWriter*, size_t, ResetFunc*, void*, const T&)>(
-                      &SerializeTestRunner),
-                  _1, _2, _3, _4, value);
-    auto deserialize_test =
-        std::bind(static_cast<std::chrono::nanoseconds (*)(
-                      MessageReader*, MessageWriter*, size_t, ResetFunc*,
-                      ResetFunc*, void*, const T&)>(&DeserializeTestRunner),
-                  _1, _2, _3, _4, _5, _6, std::forward<T>(value));
-    tests_.emplace_back(name, std::move(serialize_test),
-                        std::move(deserialize_test), data_size);
-  }
-
-  std::string CenterString(std::string text, size_t column_width) {
-    if (text.size() < column_width) {
-      text = std::string((column_width - text.size()) / 2, ' ') + text;
-    }
-    return text;
-  }
-
-  void RunTests(size_t iteration_count,
-                const std::vector<BufferInfo>& buffers) {
-    using float_seconds = std::chrono::duration<double>;
-    const std::string name_column_separator = " : ";
-    const std::string buffer_column_separator = " || ";
-    const std::string buffer_timing_column_separator = " | ";
-    const size_t data_size_column_width = 6;
-    const size_t time_column_width = 9;
-    const size_t qps_column_width = 18;
-    const size_t buffer_column_width = time_column_width +
-                                       buffer_timing_column_separator.size() +
-                                       qps_column_width;
-
-    auto compare_name_length = [](const TestEntry& t1, const TestEntry& t2) {
-      return t1.name.size() < t2.name.size();
-    };
-    auto test_with_longest_name =
-        std::max_element(tests_.begin(), tests_.end(), compare_name_length);
-    size_t name_column_width = test_with_longest_name->name.size();
-
-    size_t total_width =
-        name_column_width + name_column_separator.size() +
-        data_size_column_width + buffer_column_separator.size() +
-        buffers.size() * (buffer_column_width + buffer_column_separator.size());
-
-    const std::string dbl_separator(total_width, '=');
-    const std::string separator(total_width, '-');
-
-    auto print_header = [&](const std::string& header) {
-      std::cout << dbl_separator << std::endl;
-      std::stringstream ss;
-      ss.imbue(std::locale(ss.getloc(), new CommaNumPunct));
-      ss << header << " (" << iteration_count << " iterations)";
-      std::cout << CenterString(ss.str(), total_width) << std::endl;
-      std::cout << dbl_separator << std::endl;
-      std::cout << std::setw(name_column_width) << "Test Name" << std::left
-                << name_column_separator << std::setw(data_size_column_width)
-                << CenterString("Size", data_size_column_width)
-                << buffer_column_separator;
-      for (const auto& buffer_info : buffers) {
-        std::cout << std::setw(buffer_column_width)
-                  << CenterString(buffer_info.name, buffer_column_width)
-                  << buffer_column_separator;
-      }
-      std::cout << std::endl;
-      std::cout << std::setw(name_column_width) << "" << name_column_separator
-                << std::setw(data_size_column_width)
-                << CenterString("bytes", data_size_column_width)
-                << buffer_column_separator << std::left;
-      for (size_t i = 0; i < buffers.size(); i++) {
-        std::cout << std::setw(time_column_width)
-                  << CenterString("Time, s", time_column_width)
-                  << buffer_timing_column_separator
-                  << std::setw(qps_column_width)
-                  << CenterString("QPS", qps_column_width)
-                  << buffer_column_separator;
-      }
-      std::cout << std::right << std::endl;
-      std::cout << separator << std::endl;
-    };
-
-    print_header("Serialization benchmarks");
-    for (const auto& test : tests_) {
-      if (test.serialize_test) {
-        std::cout << std::setw(name_column_width) << test.name << " : "
-                  << std::setw(data_size_column_width) << test.data_size
-                  << buffer_column_separator;
-        for (const auto& buffer_info : buffers) {
-          auto seconds =
-              std::chrono::duration_cast<float_seconds>(test.serialize_test(
-                  buffer_info.writer, iteration_count,
-                  buffer_info.write_reset_func, buffer_info.reset_data));
-          double qps = iteration_count / seconds.count();
-          std::cout << std::fixed << std::setprecision(3)
-                    << std::setw(time_column_width) << seconds.count()
-                    << buffer_timing_column_separator
-                    << std::setw(qps_column_width) << qps
-                    << buffer_column_separator;
-        }
-        std::cout << std::endl;
-      }
-    }
-
-    print_header("Deserialization benchmarks");
-    for (const auto& test : tests_) {
-      if (test.deserialize_test) {
-        std::cout << std::setw(name_column_width) << test.name << " : "
-                  << std::setw(data_size_column_width) << test.data_size
-                  << buffer_column_separator;
-        for (const auto& buffer_info : buffers) {
-          auto seconds =
-              std::chrono::duration_cast<float_seconds>(test.deserialize_test(
-                  buffer_info.reader, buffer_info.writer, iteration_count,
-                  buffer_info.read_reset_func, buffer_info.write_reset_func,
-                  buffer_info.reset_data));
-          double qps = iteration_count / seconds.count();
-          std::cout << std::fixed << std::setprecision(3)
-                    << std::setw(time_column_width) << seconds.count()
-                    << buffer_timing_column_separator
-                    << std::setw(qps_column_width) << qps
-                    << buffer_column_separator;
-        }
-        std::cout << std::endl;
-      }
-    }
-    std::cout << dbl_separator << std::endl;
-  }
-
- private:
-  struct TestEntry {
-    TestEntry(const std::string& test_name,
-              std::function<SerializeTestSignature> serialize_test,
-              std::function<DeserializeTestSignature> deserialize_test,
-              size_t data_size)
-        : name{test_name},
-          serialize_test{std::move(serialize_test)},
-          deserialize_test{std::move(deserialize_test)},
-          data_size{data_size} {}
-    std::string name;
-    std::function<SerializeTestSignature> serialize_test;
-    std::function<DeserializeTestSignature> deserialize_test;
-    size_t data_size;
-  };
-
-  std::vector<TestEntry> tests_;
-};
-
-std::string GenerateContainerName(const std::string& type, size_t count) {
-  std::stringstream ss;
-  ss << type << "(" << count << ")";
-  return ss.str();
-}
-
-}  // anonymous namespace
-
-int main(int /*argc*/, char** /*argv*/) {
-  const size_t iteration_count = 10000000;  // 10M iterations.
-  TestRunner test_runner;
-  std::cout.imbue(std::locale(std::cout.getloc(), new CommaNumPunct));
-
-  // Baseline tests to figure out the overhead of buffer resizing and data
-  // transfers.
-  for (size_t len : {0, 1, 9, 66, 259}) {
-    auto serialize_base_test =
-        std::bind(&SerializeBaseTest, _1, _2, _3, _4, len);
-    auto deserialize_base_test =
-        std::bind(&DeserializeBaseTest, _1, _2, _3, _4, _5, _6, len);
-    test_runner.AddTestFunc("--Baseline--", std::move(serialize_base_test),
-                            std::move(deserialize_base_test), len);
-  }
-
-  // Individual serialization/deserialization tests.
-  test_runner.AddTest("bool", true);
-  test_runner.AddTest("int32_t", 12);
-
-  for (size_t len : {0, 1, 8, 64, 256}) {
-    test_runner.AddTest(GenerateContainerName("string", len),
-                        std::string(len, '*'));
-  }
-  // Serialization is too slow to handle such large strings, add this test for
-  // deserialization only.
-  test_runner.AddDeserializationTest(GenerateContainerName("string", 10240),
-                                     std::string(10240, '*'));
-
-  for (size_t len : {0, 1, 8, 64, 256}) {
-    std::vector<int32_t> int_vector(len);
-    std::iota(int_vector.begin(), int_vector.end(), 0);
-    test_runner.AddTest(GenerateContainerName("vector<int32_t>", len),
-                        std::move(int_vector));
-  }
-
-  std::vector<std::string> vector_of_strings = {
-      "012345678901234567890123456789", "012345678901234567890123456789",
-      "012345678901234567890123456789", "012345678901234567890123456789",
-      "012345678901234567890123456789",
-  };
-  test_runner.AddTest(
-      GenerateContainerName("vector<string>", vector_of_strings.size()),
-      std::move(vector_of_strings));
-
-  test_runner.AddTest("tuple<int, bool, string, double>",
-                      std::make_tuple(123, true, std::string{"foobar"}, 1.1));
-
-  for (size_t len : {0, 1, 8, 64}) {
-    std::map<int, std::string> test_map;
-    for (size_t i = 0; i < len; i++)
-      test_map.emplace(i, std::to_string(i));
-    test_runner.AddTest(GenerateContainerName("map<int, string>", len),
-                        std::move(test_map));
-  }
-
-  for (size_t len : {0, 1, 8, 64}) {
-    std::unordered_map<int, std::string> test_map;
-    for (size_t i = 0; i < len; i++)
-      test_map.emplace(i, std::to_string(i));
-    test_runner.AddTest(
-        GenerateContainerName("unordered_map<int, string>", len),
-        std::move(test_map));
-  }
-
-  // BufferWrapper can't be used with deserialization tests right now because
-  // it requires external buffer to be filled in, which is not available.
-  std::vector<std::vector<uint8_t>> data_buffers;
-  for (size_t len : {0, 1, 8, 64, 256}) {
-    data_buffers.emplace_back(len);
-    test_runner.AddSerializationTest(
-        GenerateContainerName("BufferWrapper<uint8_t*>", len),
-        BufferWrapper<uint8_t*>(data_buffers.back().data(),
-                                data_buffers.back().size()));
-  }
-
-  // Various backing buffers to run the tests on.
-  std::vector<TestRunner::BufferInfo> buffers;
-
-  Payload buffer;
-  buffers.emplace_back("Non-TLS Buffer", &buffer, &buffer,
-                       [](void* ptr) { static_cast<Payload*>(ptr)->Rewind(); },
-                       [](void* ptr) { static_cast<Payload*>(ptr)->Clear(); },
-                       &buffer);
-
-  TestPayload tls_buffer;
-  buffers.emplace_back(
-      "TLS Buffer", &tls_buffer, &tls_buffer,
-      [](void* ptr) { static_cast<TestPayload*>(ptr)->Rewind(); },
-      [](void* ptr) { static_cast<TestPayload*>(ptr)->Clear(); }, &tls_buffer);
-
-  StaticBuffer static_buffer;
-  buffers.emplace_back(
-      "Static Buffer", &static_buffer, &static_buffer,
-      [](void* ptr) { static_cast<StaticBuffer*>(ptr)->Rewind(); },
-      [](void* ptr) { static_cast<StaticBuffer*>(ptr)->Clear(); },
-      &static_buffer);
-
-  // Finally, run all the tests.
-  test_runner.RunTests(iteration_count, buffers);
-  return 0;
-}
diff --git a/libs/vr/libpdx/fuzz/Android.bp b/libs/vr/libpdx/fuzz/Android.bp
deleted file mode 100644
index ac831ce..0000000
--- a/libs/vr/libpdx/fuzz/Android.bp
+++ /dev/null
@@ -1,68 +0,0 @@
-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: "libpdx_service_dispatcher_fuzzer",
-    srcs: [
-        "service_dispatcher_fuzzer.cpp",
-    ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-    static_libs: [
-        "libpdx",
-    ],
-    shared_libs: [
-        "libutils",
-        "liblog",
-        "libcutils",
-    ],
-}
-
-cc_fuzz {
-    name: "libpdx_message_fuzzer",
-    srcs: [
-        "message_fuzzer.cpp",
-    ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-    static_libs: [
-        "libpdx",
-    ],
-    shared_libs: [
-        "libutils",
-        "liblog",
-        "libcutils",
-    ],
-}
-
-cc_fuzz {
-    name: "libpdx_serialization_fuzzer",
-    srcs: [
-        "serialization_fuzzer.cpp",
-    ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-    static_libs: [
-        "libpdx",
-    ],
-    shared_libs: [
-        "libutils",
-        "liblog",
-        "libcutils",
-    ],
-}
diff --git a/libs/vr/libpdx/fuzz/helpers.h b/libs/vr/libpdx/fuzz/helpers.h
deleted file mode 100644
index 83ec409..0000000
--- a/libs/vr/libpdx/fuzz/helpers.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright 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.
- */
-// Authors: corbin.souffrant@leviathansecurity.com
-//          brian.balling@leviathansecurity.com
-
-#ifndef LEV_FUZZERS_LIBPDX_HELPERS_H_
-#define LEV_FUZZERS_LIBPDX_HELPERS_H_
-
-#define UNUSED(expr) \
-  do {               \
-    (void)(expr);    \
-  } while (0)
-
-#include <fuzzer/FuzzedDataProvider.h>
-#include <pdx/client.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-#include <pdx/service_endpoint.h>
-#include <sys/eventfd.h>
-#include <memory>
-#include <vector>
-
-using namespace android::pdx;
-
-// Vector of operations we can call in the dispatcher.
-static const std::vector<std::function<void(
-    const std::unique_ptr<ServiceDispatcher>&, FuzzedDataProvider*)>>
-    dispatcher_operations = {
-        [](const std::unique_ptr<ServiceDispatcher>& dispatcher,
-           FuzzedDataProvider*) -> void { dispatcher->EnterDispatchLoop(); },
-        [](const std::unique_ptr<ServiceDispatcher>& dispatcher,
-           FuzzedDataProvider*) -> void { dispatcher->ReceiveAndDispatch(); },
-        [](const std::unique_ptr<ServiceDispatcher>& dispatcher,
-           FuzzedDataProvider* fdp) -> void {
-          dispatcher->ReceiveAndDispatch(fdp->ConsumeIntegral<int>());
-        }};
-
-// Most of the fuzzing occurs within the endpoint, which is derived from an
-// abstract class. So we are returning garbage data for most functions besides
-// the ones we added or need to actually use.
-class FuzzEndpoint : public Endpoint {
- public:
-  explicit FuzzEndpoint(FuzzedDataProvider* fdp) {
-    _fdp = fdp;
-    _epoll_fd = eventfd(0, 0);
-  }
-
-  ~FuzzEndpoint() { close(_epoll_fd); }
-
-  // Returns an fd that can be used with epoll() to wait for incoming messages
-  // from this endpoint.
-  int epoll_fd() const { return _epoll_fd; }
-
-  // Associates a Service instance with an endpoint by setting the service
-  // context pointer to the address of the Service. Only one Service may be
-  // associated with a given endpoint.
-  Status<void> SetService(Service* service) {
-    _service = service;
-    return Status<void>(0);
-  }
-
-  // Set the channel context for the given channel.
-  Status<void> SetChannel(int channel_id, Channel* channel) {
-    UNUSED(channel_id);
-    _channel = std::shared_ptr<Channel>(channel);
-    return Status<void>(0);
-  }
-
-  // Receives a message on the given endpoint file descriptor.
-  // This is called by the dispatcher to determine what operations
-  // to make, so we are fuzzing the response.
-  Status<void> MessageReceive(Message* message) {
-    // Create a randomized MessageInfo struct.
-    MessageInfo info;
-    eventfd_t wakeup_val = 0;
-    info.pid = _fdp->ConsumeIntegral<int>();
-    info.tid = _fdp->ConsumeIntegral<int>();
-    info.cid = _fdp->ConsumeIntegral<int>();
-    info.mid = _fdp->ConsumeIntegral<int>();
-    info.euid = _fdp->ConsumeIntegral<int>();
-    info.egid = _fdp->ConsumeIntegral<int>();
-    info.op = _fdp->ConsumeIntegral<int32_t>();
-    info.flags = _fdp->ConsumeIntegral<uint32_t>();
-    info.service = _service;
-    info.channel = _channel.get();
-    info.send_len = _fdp->ConsumeIntegral<size_t>();
-    info.recv_len = _fdp->ConsumeIntegral<size_t>();
-    info.fd_count = _fdp->ConsumeIntegral<size_t>();
-    if (_fdp->remaining_bytes() >= 32) {
-      std::vector<uint8_t> impulse_vec = _fdp->ConsumeBytes<uint8_t>(32);
-      memcpy(info.impulse, impulse_vec.data(), 32);
-    }
-
-    *message = Message(info);
-    eventfd_read(_epoll_fd, &wakeup_val);
-
-    return Status<void>();
-  }
-
-  // Returns a tag that uniquely identifies a specific underlying IPC
-  // transport.
-  uint32_t GetIpcTag() const { return 0; }
-
-  // Close a channel, signaling the client file object and freeing the channel
-  // id. Once closed, the client side of the channel always returns the error
-  // ESHUTDOWN and signals the poll/epoll events POLLHUP and POLLFREE.
-  Status<void> CloseChannel(int channel_id) {
-    UNUSED(channel_id);
-    return Status<void>();
-  }
-
-  // Update the event bits for the given channel (given by id), using the
-  // given clear and set masks.
-  Status<void> ModifyChannelEvents(int channel_id, int clear_mask,
-                                   int set_mask) {
-    UNUSED(channel_id);
-    UNUSED(clear_mask);
-    UNUSED(set_mask);
-    return Status<void>();
-  }
-
-  // Create a new channel and push it as a file descriptor to the process
-  // sending the |message|. |flags| may be set to O_NONBLOCK and/or
-  // O_CLOEXEC to control the initial behavior of the new file descriptor (the
-  // sending process may change these later using fcntl()). The internal
-  // Channel instance associated with this channel is set to |channel|,
-  // which may be nullptr. The new channel id allocated for this channel is
-  // returned in |channel_id|, which may also be nullptr if not needed.
-  Status<RemoteChannelHandle> PushChannel(Message* message, int flags,
-                                          Channel* channel, int* channel_id) {
-    UNUSED(message);
-    UNUSED(flags);
-    UNUSED(channel);
-    UNUSED(channel_id);
-    return Status<RemoteChannelHandle>();
-  }
-
-  // Check whether the |ref| is a reference to a channel to the service
-  // represented by the |endpoint|. If the channel reference in question is
-  // valid, the Channel object is returned in |channel| when non-nullptr and
-  // the channel ID is returned through the Status object.
-  Status<int> CheckChannel(const Message* message, ChannelReference ref,
-                           Channel** channel) {
-    UNUSED(message);
-    UNUSED(ref);
-    UNUSED(channel);
-    return Status<int>();
-  }
-
-  // Replies to the message with a return code.
-  Status<void> MessageReply(Message* message, int return_code) {
-    UNUSED(message);
-    UNUSED(return_code);
-    return Status<void>();
-  }
-
-  // Replies to the message with a file descriptor.
-  Status<void> MessageReplyFd(Message* message, unsigned int push_fd) {
-    UNUSED(message);
-    UNUSED(push_fd);
-    return Status<void>();
-  }
-
-  // Replies to the message with a local channel handle.
-  Status<void> MessageReplyChannelHandle(Message* message,
-                                         const LocalChannelHandle& handle) {
-    UNUSED(message);
-    UNUSED(handle);
-    return Status<void>();
-  }
-
-  // Replies to the message with a borrowed local channel handle.
-  Status<void> MessageReplyChannelHandle(Message* message,
-                                         const BorrowedChannelHandle& handle) {
-    UNUSED(message);
-    UNUSED(handle);
-    return Status<void>();
-  }
-
-  // Replies to the message with a remote channel handle.
-  Status<void> MessageReplyChannelHandle(Message* message,
-                                         const RemoteChannelHandle& handle) {
-    UNUSED(message);
-    UNUSED(handle);
-    return Status<void>();
-  }
-
-  // Reads message data into an array of memory buffers.
-  Status<size_t> ReadMessageData(Message* message, const iovec* vector,
-                                 size_t vector_length) {
-    UNUSED(message);
-    UNUSED(vector);
-    UNUSED(vector_length);
-    return Status<size_t>();
-  }
-
-  // Sends reply data for message.
-  Status<size_t> WriteMessageData(Message* message, const iovec* vector,
-                                  size_t vector_length) {
-    UNUSED(message);
-    UNUSED(vector);
-    UNUSED(vector_length);
-    return Status<size_t>();
-  }
-
-  // Records a file descriptor into the message buffer and returns the
-  // remapped reference to be sent to the remote process.
-  Status<FileReference> PushFileHandle(Message* message,
-                                       const LocalHandle& handle) {
-    UNUSED(message);
-    UNUSED(handle);
-    return Status<FileReference>();
-  }
-
-  Status<FileReference> PushFileHandle(Message* message,
-                                       const BorrowedHandle& handle) {
-    UNUSED(message);
-    UNUSED(handle);
-    return Status<FileReference>();
-  }
-
-  Status<FileReference> PushFileHandle(Message* message,
-                                       const RemoteHandle& handle) {
-    UNUSED(message);
-    UNUSED(handle);
-    return Status<FileReference>();
-  }
-
-  Status<ChannelReference> PushChannelHandle(Message* message,
-                                             const LocalChannelHandle& handle) {
-    UNUSED(message);
-    UNUSED(handle);
-    return Status<ChannelReference>();
-  }
-
-  Status<ChannelReference> PushChannelHandle(
-      Message* message, const BorrowedChannelHandle& handle) {
-    UNUSED(message);
-    UNUSED(handle);
-    return Status<ChannelReference>();
-  }
-
-  Status<ChannelReference> PushChannelHandle(
-      Message* message, const RemoteChannelHandle& handle) {
-    UNUSED(message);
-    UNUSED(handle);
-    return Status<ChannelReference>();
-  }
-
-  // Obtains a file descriptor/channel handle from a message for the given
-  // reference.
-  LocalHandle GetFileHandle(Message* message, FileReference ref) const {
-    UNUSED(message);
-    UNUSED(ref);
-    return LocalHandle();
-  }
-
-  LocalChannelHandle GetChannelHandle(Message* message,
-                                      ChannelReference ref) const {
-    UNUSED(message);
-    UNUSED(ref);
-    return LocalChannelHandle();
-  }
-
-  // Transport-specific message state management.
-  void* AllocateMessageState() { return nullptr; }
-
-  void FreeMessageState(void* state) { UNUSED(state); }
-
-  // Cancels the endpoint, unblocking any receiver threads waiting for a
-  // message.
-  Status<void> Cancel() { return Status<void>(); }
-
- private:
-  FuzzedDataProvider* _fdp;
-  std::shared_ptr<Channel> _channel;
-  Service* _service;
-  int _epoll_fd;
-};
-
-#endif  // LEV_FUZZERS_LIBPDX_HELPERS_H_
diff --git a/libs/vr/libpdx/fuzz/message_fuzzer.cpp b/libs/vr/libpdx/fuzz/message_fuzzer.cpp
deleted file mode 100644
index b627045..0000000
--- a/libs/vr/libpdx/fuzz/message_fuzzer.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright 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.
- */
-// Authors: corbin.souffrant@leviathansecurity.com
-//          brian.balling@leviathansecurity.com
-
-#include <fuzzer/FuzzedDataProvider.h>
-#include <helpers.h>
-#include <pdx/client_channel.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/eventfd.h>
-#include <thread>
-
-using namespace android::pdx;
-
-// Fuzzer for Message object functions.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-
-  FuzzEndpoint* endpoint = new FuzzEndpoint(&fdp);
-  std::shared_ptr<Service> service(
-      new Service("FuzzService", std::unique_ptr<Endpoint>(endpoint)));
-  std::shared_ptr<Channel> channel(nullptr);
-
-  // Generate a random Message object to call functions in.
-  MessageInfo info;
-  info.pid = fdp.ConsumeIntegral<int>();
-  info.tid = fdp.ConsumeIntegral<int>();
-  info.cid = fdp.ConsumeIntegral<int>();
-  info.mid = fdp.ConsumeIntegral<int>();
-  info.euid = fdp.ConsumeIntegral<int>();
-  info.egid = fdp.ConsumeIntegral<int>();
-  info.op = fdp.ConsumeIntegral<int32_t>();
-  info.flags = fdp.ConsumeIntegral<uint32_t>();
-  info.service = service.get();
-  info.channel = channel.get();
-  info.send_len = fdp.ConsumeIntegral<size_t>();
-  info.recv_len = fdp.ConsumeIntegral<size_t>();
-  info.fd_count = fdp.ConsumeIntegral<size_t>();
-  if (fdp.remaining_bytes() >= 32) {
-    std::vector<uint8_t> impulse_vec = fdp.ConsumeBytes<uint8_t>(32);
-    memcpy(info.impulse, impulse_vec.data(), 32);
-  }
-
-  Message message = Message(info);
-
-  // A bunch of getters that probably won't do much, but might as well
-  // get coverage, while we are here.
-  message.GetProcessId();
-  message.GetThreadId();
-  message.GetEffectiveUserId();
-  message.GetEffectiveGroupId();
-  message.GetChannelId();
-  message.GetMessageId();
-  message.GetOp();
-  message.GetFlags();
-  message.GetSendLength();
-  message.GetReceiveLength();
-  message.GetFileDescriptorCount();
-  message.ImpulseEnd();
-  message.replied();
-  message.IsChannelExpired();
-  message.IsServiceExpired();
-  message.GetState();
-  message.GetState();
-
-  // Some misc. functions.
-  unsigned int fd = fdp.ConsumeIntegral<unsigned int>();
-  int clear_mask = fdp.ConsumeIntegral<int>();
-  int set_mask = fdp.ConsumeIntegral<int>();
-  Status<void> status = {};
-  message.ModifyChannelEvents(clear_mask, set_mask);
-
-  // Fuzz the handle functions.
-  LocalHandle l_handle = {};
-  BorrowedHandle b_handle = {};
-  RemoteHandle r_handle = {};
-  LocalChannelHandle lc_handle = {};
-  BorrowedChannelHandle bc_handle = {};
-  RemoteChannelHandle rc_handle = {};
-  FileReference f_ref = fdp.ConsumeIntegral<int32_t>();
-  ChannelReference c_ref = fdp.ConsumeIntegral<int32_t>();
-
-  // These don't actually modify any state in the Message or params.
-  // They can be called in any order.
-  message.PushFileHandle(b_handle);
-  message.PushFileHandle(r_handle);
-  message.PushChannelHandle(lc_handle);
-  message.PushChannelHandle(bc_handle);
-  message.PushChannelHandle(rc_handle);
-  message.GetFileHandle(f_ref, &l_handle);
-  message.GetChannelHandle(c_ref, &lc_handle);
-
-  // Can only reply once, pick at random.
-  switch (fdp.ConsumeIntegral<uint8_t>()) {
-    case 0:
-      message.ReplyFileDescriptor(fd);
-      break;
-    case 1:
-      message.Reply(status);
-      break;
-    case 2:
-      message.Reply(l_handle);
-      break;
-    case 3:
-      message.Reply(b_handle);
-      break;
-    case 4:
-      message.Reply(r_handle);
-      break;
-    case 5:
-      message.Reply(lc_handle);
-      break;
-    case 6:
-      message.Reply(bc_handle);
-      break;
-    case 7:
-      message.Reply(rc_handle);
-  }
-
-  // Fuzz the channel functions.
-  int flags = fdp.ConsumeIntegral<int>();
-  int channel_id = 0;
-  message.PushChannel(flags, channel, &channel_id);
-  message.CheckChannel(service.get(), c_ref, &channel);
-  message.CheckChannel(c_ref, &channel);
-  message.PushChannel(service.get(), flags, channel, &channel_id);
-  size_t iovec_size = sizeof(iovec);
-  struct iovec* iovecs = nullptr;
-
-  // Fuzz the read/write functions. Needs at least one iovec, plus one byte.
-  if (fdp.remaining_bytes() >= iovec_size + 1) {
-    std::vector<uint8_t> tmp_vec = fdp.ConsumeBytes<uint8_t>(iovec_size);
-    struct iovec* vector = reinterpret_cast<struct iovec*>(tmp_vec.data());
-    std::vector<uint8_t> tmp_buf =
-        fdp.ConsumeBytes<uint8_t>(fdp.remaining_bytes());
-    void* buf = reinterpret_cast<void*>(tmp_buf.data());
-    size_t buf_size = fdp.ConsumeIntegral<size_t>();
-
-    // Capping num_vecs to 1024 so it doesn't allocate too much memory.
-    size_t num_vecs = fdp.ConsumeIntegralInRange<size_t>(0, 1024);
-
-    if (num_vecs > 0)
-      iovecs = new struct iovec[num_vecs];
-    for (size_t i = 0; i < num_vecs; i++) {
-      iovecs[i] = *vector;
-    }
-
-    message.ReadAll(vector, buf_size);
-    message.WriteAll(buf, buf_size);
-    message.ReadVectorAll(vector, num_vecs);
-    message.WriteVectorAll(vector, num_vecs);
-    message.ReadVector(vector, buf_size);
-    message.WriteVector(vector, buf_size);
-  }
-
-  if (iovecs != nullptr)
-    delete[] iovecs;
-  return 0;
-}
diff --git a/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp b/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp
deleted file mode 100644
index f5c5a5a..0000000
--- a/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright 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.
- */
-// Authors: corbin.souffrant@leviathansecurity.com
-//          brian.balling@leviathansecurity.com
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <memory>
-#include <string>
-#include <thread>
-#include <utility>
-
-#include <fuzzer/FuzzedDataProvider.h>
-#include <pdx/rpc/argument_encoder.h>
-#include <pdx/rpc/array_wrapper.h>
-#include <pdx/rpc/default_initialization_allocator.h>
-#include <pdx/rpc/payload.h>
-#include <pdx/rpc/serializable.h>
-#include <pdx/rpc/serialization.h>
-#include <pdx/rpc/string_wrapper.h>
-#include <pdx/utility.h>
-
-using namespace android::pdx;
-using namespace android::pdx::rpc;
-
-struct FuzzType {
-  int a;
-  float b;
-  std::string c;
-
-  FuzzType() {}
-  FuzzType(int a, float b, const std::string& c) : a(a), b(b), c(c) {}
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(FuzzType, a, b, c);
-};
-
-// Fuzzer for Serialization operations, this is mostly just lifted from the
-// existing test cases to use fuzzed values as inputs.
-void FuzzSerializeDeserialize(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload result;
-
-  // Currently, only fuzzing subset of types. In the future, may want
-  // to add more difficult to generate types like array, map, enum, etc...
-  bool b_val = fdp.ConsumeBool();
-  uint8_t u8_val = fdp.ConsumeIntegral<uint8_t>();
-  uint16_t u16_val = fdp.ConsumeIntegral<uint16_t>();
-  uint32_t u32_val = fdp.ConsumeIntegral<uint32_t>();
-  uint64_t u64_val = fdp.ConsumeIntegral<uint64_t>();
-  int8_t i8_val = fdp.ConsumeIntegral<int8_t>();
-  int16_t i16_val = fdp.ConsumeIntegral<uint16_t>();
-  int32_t i32_val = fdp.ConsumeIntegral<uint32_t>();
-  int64_t i64_val = fdp.ConsumeIntegral<uint64_t>();
-  float f_val = fdp.ConsumeFloatingPoint<float>();
-  double d_val = fdp.ConsumeFloatingPoint<double>();
-  std::string s_val = fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
-  std::vector<uint8_t> vec_val =
-      fdp.ConsumeBytes<uint8_t>(fdp.remaining_bytes());
-  FuzzType t1_val{reinterpret_cast<int>(i32_val), f_val, s_val};
-
-  // Types need to be individually fuzzed because code path changes depending
-  // on which type is being serialized/deserialized.
-  Serialize(b_val, &result);
-  Deserialize(&b_val, &result);
-  Serialize(u8_val, &result);
-  Deserialize(&u8_val, &result);
-  Serialize(u16_val, &result);
-  Deserialize(&u16_val, &result);
-  Serialize(u32_val, &result);
-  Deserialize(&u32_val, &result);
-  Serialize(u64_val, &result);
-  Deserialize(&u64_val, &result);
-  Serialize(i8_val, &result);
-  Deserialize(&i8_val, &result);
-  Serialize(i16_val, &result);
-  Deserialize(&i16_val, &result);
-  Serialize(i32_val, &result);
-  Deserialize(&i32_val, &result);
-  Serialize(i64_val, &result);
-  Deserialize(&i64_val, &result);
-  Serialize(f_val, &result);
-  Deserialize(&f_val, &result);
-  Serialize(d_val, &result);
-  Deserialize(&d_val, &result);
-  Serialize(s_val, &result);
-  Deserialize(&s_val, &result);
-  Serialize(WrapString(s_val), &result);
-  Deserialize(&s_val, &result);
-  Serialize(vec_val, &result);
-  Deserialize(&vec_val, &result);
-  Serialize(t1_val, &result);
-  Deserialize(&t1_val, &result);
-}
-
-void FuzzDeserializeUint8(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {ENCODING_TYPE_UINT8, fdp.ConsumeIntegral<uint8_t>()};
-  std::uint8_t result;
-  Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeUint16(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {ENCODING_TYPE_UINT16, fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>()};
-  std::uint16_t result;
-  Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeUint32(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {ENCODING_TYPE_UINT32, fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>()};
-  std::uint32_t result;
-  Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeUint64(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {
-      ENCODING_TYPE_UINT64,           fdp.ConsumeIntegral<uint8_t>(),
-      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
-      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
-      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
-      fdp.ConsumeIntegral<uint8_t>()};
-  std::uint64_t result;
-  Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeInt8(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {ENCODING_TYPE_INT8, fdp.ConsumeIntegral<uint8_t>()};
-  std::int8_t result;
-  Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeInt16(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {ENCODING_TYPE_INT16, fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>()};
-  std::int16_t result;
-  Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeInt32(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {ENCODING_TYPE_INT32, fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>()};
-  std::int32_t result;
-  Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeInt64(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {ENCODING_TYPE_INT64,
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>()};
-  std::int64_t result;
-  Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeFloat32(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {ENCODING_TYPE_FLOAT32, fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>()};
-  float floatResult;
-  Deserialize(&floatResult, &buffer);
-
-  buffer.Rewind();
-  double doubleResult;
-  Deserialize(&doubleResult, &buffer);
-}
-
-void FuzzDeserializeFloat64(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {
-      ENCODING_TYPE_FLOAT64,          fdp.ConsumeIntegral<uint8_t>(),
-      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
-      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
-      fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
-      fdp.ConsumeIntegral<uint8_t>()};
-  double result;
-  Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeFixstr(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  std::string s_val = fdp.ConsumeRemainingBytesAsString();
-  Payload buffer = {ENCODING_TYPE_FIXSTR_MAX};
-  for (std::string::iterator iter = s_val.begin(); iter != s_val.end();
-       iter++) {
-    buffer.Append(1, *iter);
-  }
-  std::string result;
-  Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeFixmap(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {ENCODING_TYPE_FIXMAP_MAX};
-  // Fill the map with the fuzzed data, not attempting to
-  // make a valid map
-  while (fdp.remaining_bytes() > 0) {
-    buffer.Append(1, fdp.ConsumeIntegral<uint8_t>());
-  }
-
-  std::map<std::uint32_t, std::uint32_t> result;
-  Deserialize(&result, &buffer);
-
-  buffer.Rewind();
-  std::unordered_map<std::uint32_t, std::uint32_t> unorderedResult;
-  Deserialize(&unorderedResult, &buffer);
-}
-
-void FuzzDeserializeVariant(const uint8_t* data, size_t size) {
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-  Payload buffer = {ENCODING_TYPE_INT16,
-                    ENCODING_TYPE_FLOAT32,
-                    ENCODING_TYPE_FIXSTR_MAX,
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>(),
-                    fdp.ConsumeIntegral<uint8_t>()};
-  // Add the rest of the data as a string
-  std::string s_val = fdp.ConsumeRemainingBytesAsString();
-  for (std::string::iterator iter = s_val.begin(); iter != s_val.end();
-       iter++) {
-    buffer.Append(1, *iter);
-  }
-  Variant<int, float, std::string> result;
-  Deserialize(&result, &buffer);
-}
-
-// Attempts to deserialize fuzzed data as various types
-void FuzzDeserialize(const uint8_t* data, size_t size) {
-  FuzzDeserializeUint8(data, size);
-  FuzzDeserializeUint16(data, size);
-  FuzzDeserializeUint32(data, size);
-  FuzzDeserializeUint64(data, size);
-  FuzzDeserializeInt8(data, size);
-  FuzzDeserializeInt16(data, size);
-  FuzzDeserializeInt32(data, size);
-  FuzzDeserializeInt64(data, size);
-  FuzzDeserializeFloat32(data, size);
-  FuzzDeserializeFloat64(data, size);
-  FuzzDeserializeFixstr(data, size);
-  FuzzDeserializeFixmap(data, size);
-  FuzzDeserializeVariant(data, size);
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  FuzzSerializeDeserialize(data, size);
-  FuzzDeserialize(data, size);
-
-  return 0;
-}
diff --git a/libs/vr/libpdx/fuzz/service_dispatcher_fuzzer.cpp b/libs/vr/libpdx/fuzz/service_dispatcher_fuzzer.cpp
deleted file mode 100644
index 3a3bfd9..0000000
--- a/libs/vr/libpdx/fuzz/service_dispatcher_fuzzer.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 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.
- */
-// Authors: corbin.souffrant@leviathansecurity.com
-//          brian.balling@leviathansecurity.com
-
-#include <fuzzer/FuzzedDataProvider.h>
-#include <helpers.h>
-#include <pdx/client_channel.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/eventfd.h>
-#include <thread>
-
-using namespace android::pdx;
-
-// Dispatch fuzzer entry point. This fuzzer creates a ServiceDispatcher
-// and creates an endpoint that returns fuzzed messages that are passed
-// to the ReceiveAndDispatch and DispatchLoop functions.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  eventfd_t wakeup_val = 1;
-  FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-
-  // Endpoint is only used to be immediately wrapped as a unique_ptr,
-  // so it is ok to be using a raw ptr and new here without freeing.
-  FuzzEndpoint* endpoint = new FuzzEndpoint(&fdp);
-  std::unique_ptr<ServiceDispatcher> dispatcher = ServiceDispatcher::Create();
-  std::shared_ptr<Channel> channel(nullptr);
-  std::shared_ptr<Client> client(nullptr);
-  std::shared_ptr<Service> service(
-      new Service("FuzzService", std::unique_ptr<Endpoint>(endpoint)));
-
-  service->SetChannel(0, std::shared_ptr<Channel>(channel));
-  dispatcher->AddService(service);
-
-  // Dispatcher blocks, so needs to run in its own thread.
-  std::thread run_dispatcher([&]() {
-    uint8_t opt = 0;
-
-    // Right now the only operations block, so the while loop is pointless
-    // but leaving it in, just in case that ever changes.
-    while (fdp.remaining_bytes() > sizeof(MessageInfo)) {
-      opt = fdp.ConsumeIntegral<uint8_t>() % dispatcher_operations.size();
-      dispatcher_operations[opt](dispatcher, &fdp);
-    }
-  });
-
-  // Continuously wake up the epoll so the dispatcher can run.
-  while (fdp.remaining_bytes() > sizeof(MessageInfo)) {
-    eventfd_write(endpoint->epoll_fd(), wakeup_val);
-  }
-
-  // Cleanup the dispatcher and thread.
-  dispatcher->SetCanceled(true);
-  if (run_dispatcher.joinable())
-    run_dispatcher.join();
-  dispatcher->RemoveService(service);
-
-  return 0;
-}
diff --git a/libs/vr/libpdx/mock_tests.cpp b/libs/vr/libpdx/mock_tests.cpp
deleted file mode 100644
index 4143837..0000000
--- a/libs/vr/libpdx/mock_tests.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <gtest/gtest.h>
-#include <pdx/mock_client_channel.h>
-#include <pdx/mock_client_channel_factory.h>
-#include <pdx/mock_message_reader.h>
-#include <pdx/mock_message_writer.h>
-#include <pdx/mock_service_endpoint.h>
-
-TEST(MockTypes, Instantiation) {
-  // Make sure all our interfaces are mocked out properly and mock instances
-  // can be created.
-  android::pdx::MockClientChannel client_channel;
-  android::pdx::MockClientChannelFactory client_channel_factory;
-  android::pdx::MockInputResourceMapper input_resource_mapper;
-  android::pdx::MockMessageReader message_reader;
-  android::pdx::MockOutputResourceMapper output_resource_mapper;
-  android::pdx::MockMessageWriter message_writer;
-  android::pdx::MockEndpoint endpoint;
-}
diff --git a/libs/vr/libpdx/private/pdx/channel_handle.h b/libs/vr/libpdx/private/pdx/channel_handle.h
deleted file mode 100644
index bd04305..0000000
--- a/libs/vr/libpdx/private/pdx/channel_handle.h
+++ /dev/null
@@ -1,123 +0,0 @@
-#ifndef ANDROID_PDX_CHANNEL_HANDLE_H_
-#define ANDROID_PDX_CHANNEL_HANDLE_H_
-
-#include <cstdint>
-#include <type_traits>
-
-namespace android {
-namespace pdx {
-
-enum class ChannelHandleMode {
-  Local,
-  Borrowed,
-  Remote,
-};
-
-class ChannelManagerInterface {
- public:
-  virtual void CloseHandle(std::int32_t handle) = 0;
-
- protected:
-  // Nobody should be allowed to delete the instance of channel manager
-  // through this interface.
-  virtual ~ChannelManagerInterface() = default;
-};
-
-class ChannelHandleBase {
- public:
-  ChannelHandleBase() = default;
-  explicit ChannelHandleBase(const int32_t& value) : value_{value} {}
-
-  ChannelHandleBase(const ChannelHandleBase&) = delete;
-  ChannelHandleBase& operator=(const ChannelHandleBase&) = delete;
-
-  std::int32_t value() const { return value_; }
-  bool valid() const { return value_ >= 0; }
-  explicit operator bool() const { return valid(); }
-
-  void Close() { value_ = kEmptyHandle; }
-
- protected:
-  // Must not be used by itself. Must be derived from.
-  ~ChannelHandleBase() = default;
-  enum : std::int32_t { kEmptyHandle = -1 };
-
-  std::int32_t value_{kEmptyHandle};
-};
-
-template <ChannelHandleMode Mode>
-class ChannelHandle : public ChannelHandleBase {
- public:
-  ChannelHandle() = default;
-  using ChannelHandleBase::ChannelHandleBase;
-  ChannelHandle(ChannelHandle&& other) noexcept : ChannelHandleBase{other.value_} {
-    other.value_ = kEmptyHandle;
-  }
-  ~ChannelHandle() = default;
-
-  ChannelHandle Duplicate() const { return ChannelHandle{value_}; }
-
-  ChannelHandle& operator=(ChannelHandle&& other) noexcept {
-    value_ = other.value_;
-    other.value_ = kEmptyHandle;
-    return *this;
-  }
-};
-
-template <>
-class ChannelHandle<ChannelHandleMode::Local> : public ChannelHandleBase {
- public:
-  ChannelHandle() = default;
-  ChannelHandle(ChannelManagerInterface* manager, int32_t value)
-      : ChannelHandleBase{value}, manager_{manager} {}
-
-  ChannelHandle(const ChannelHandle&) = delete;
-  ChannelHandle& operator=(const ChannelHandle&) = delete;
-
-  ChannelHandle(ChannelHandle&& other) noexcept
-      : ChannelHandleBase{other.value_}, manager_{other.manager_} {
-    other.manager_ = nullptr;
-    other.value_ = kEmptyHandle;
-  }
-
-  ChannelHandle& operator=(ChannelHandle&& other) noexcept {
-    value_ = other.value_;
-    manager_ = other.manager_;
-    other.value_ = kEmptyHandle;
-    other.manager_ = nullptr;
-    return *this;
-  }
-
-  ~ChannelHandle() {
-    if (manager_)
-      manager_->CloseHandle(value_);
-  }
-
-  ChannelHandle<ChannelHandleMode::Borrowed> Borrow() const {
-    return ChannelHandle<ChannelHandleMode::Borrowed>{value_};
-  }
-
-  void Close() {
-    if (manager_)
-      manager_->CloseHandle(value_);
-    manager_ = nullptr;
-    value_ = kEmptyHandle;
-  }
-
- private:
-  ChannelManagerInterface* manager_{nullptr};
-};
-
-using LocalChannelHandle = ChannelHandle<ChannelHandleMode::Local>;
-using BorrowedChannelHandle = ChannelHandle<ChannelHandleMode::Borrowed>;
-using RemoteChannelHandle = ChannelHandle<ChannelHandleMode::Remote>;
-
-// ChannelReference is a 32 bit integer used in IPC serialization to be
-// transferred across processes. You can convert this value to a local channel
-// handle by calling Transaction.GetChannelHandle().
-using ChannelReference = int32_t;
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_CHANNEL_HANDLE_H_
diff --git a/libs/vr/libpdx/private/pdx/channel_parcelable.h b/libs/vr/libpdx/private/pdx/channel_parcelable.h
deleted file mode 100644
index 59ef9d3..0000000
--- a/libs/vr/libpdx/private/pdx/channel_parcelable.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef ANDROID_PDX_CHANNEL_PARCELABLE_H_
-#define ANDROID_PDX_CHANNEL_PARCELABLE_H_
-
-#include <binder/Parcelable.h>
-#include <pdx/channel_handle.h>
-
-namespace android {
-namespace pdx {
-
-/**
- * A parcelable object holds all necessary objects to recreate a ClientChannel.
- * In addition to the android::Parcelable interface, this interface exposees
- * more PDX-related interface.
- */
-class ChannelParcelable : public Parcelable {
- public:
-  virtual ~ChannelParcelable() = default;
-
-  // Returns whether the parcelable object holds a valid client channel.
-  virtual bool IsValid() const = 0;
-
-  // Returns a channel handle constructed from this parcelable object and takes
-  // the ownership of all resources from the parcelable object. In another word,
-  // the parcelable object will become invalid after TakeChannelHandle returns.
-  virtual LocalChannelHandle TakeChannelHandle() = 0;
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_CHANNEL_PARCELABLE_H_
diff --git a/libs/vr/libpdx/private/pdx/client.h b/libs/vr/libpdx/private/pdx/client.h
deleted file mode 100644
index 7e2d55c..0000000
--- a/libs/vr/libpdx/private/pdx/client.h
+++ /dev/null
@@ -1,302 +0,0 @@
-#ifndef ANDROID_PDX_CLIENT_H_
-#define ANDROID_PDX_CLIENT_H_
-
-#include <errno.h>
-#include <sys/types.h>
-
-#include <memory>
-#include <string>
-#include <type_traits>
-
-#include <pdx/channel_handle.h>
-#include <pdx/client_channel.h>
-#include <pdx/client_channel_factory.h>
-#include <pdx/file_handle.h>
-#include <pdx/message_reader.h>
-#include <pdx/message_writer.h>
-#include <pdx/rpc/remote_method_type.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-
-class Transaction;
-
-/*
- * Base class of client-side service API classes.
- */
-class Client {
- public:
-  static const int64_t kInfiniteTimeout = -1;
-
-  virtual ~Client() = default;
-
-  /*
-   * Returns true if the Client instance successfully initialized, false
-   * otherwise. Subclasses that can fail to initialize must override this and
-   * AND their initialization result with this base class method's result.
-   *
-   * This method is not intended to perform initialization, only to report
-   * the status of the initialization.
-   */
-  virtual bool IsInitialized() const;
-
-  /*
-   * Returns the error code describing the Client initialization failure, or 0
-   * if there was no failure.
-   */
-  int error() const;
-
-  // Returns a reference to IPC channel handle.
-  LocalChannelHandle& GetChannelHandle();
-  const LocalChannelHandle& GetChannelHandle() const;
-
- protected:
-  friend Transaction;
-  explicit Client(std::unique_ptr<ClientChannel> channel);
-  explicit Client(std::unique_ptr<ClientChannelFactory> channel_factory,
-                  int64_t timeout_ms = kInfiniteTimeout);
-
-  /*
-   * Called by Client::Connect() after successfully connecting to the service
-   * endpoint. Subclasses may override this method to perform additional setup,
-   * including sending messages to complete the connection process.
-   *
-   * Subclasses may call Client::Close() within this method to terminate the
-   * connection; Client::Connect() returns the negated error passed to
-   * Client::Close() when this happens.
-   */
-  virtual void OnConnect();
-
-  enum : size_t { MAX_IMPULSE_LENGTH = sizeof(uint64_t) * 4 };
-
-  Status<void> SendImpulse(int opcode);
-  Status<void> SendImpulse(int opcode, const void* buffer, size_t length);
-
-  /*
-   * Remote method call API using pdx::rpc serialization.
-   * Include pdx/rpc/remote_method.h to use these methods.
-   */
-  template <typename RemoteMethodType, typename... Args>
-  Status<typename RemoteMethodType::Return> InvokeRemoteMethod(Args&&... args);
-
-  template <typename RemoteMethodType, typename ReturnType, typename... Args>
-  Status<void> InvokeRemoteMethodInPlace(ReturnType* return_value,
-                                         Args&&... args);
-
-  /*
-   * Close the endpoint file descriptor and optionally indicate an error, which
-   * may be retrieved through error(). Subclasses may use this in their
-   * constructor to signal failure during initialization or at other times
-   * during operation.
-   */
-  void Close(int error);
-
-  /*
-   * Returns true if the client is connected to the service, false otherwise.
-   */
-  bool IsConnected() const;
-
-  /*
-   * Enables auto-reconnect with the given timeout. Use kInfiniteTimeout (-1)
-   * for no timeout. Auto-reconnect can only be enabled if the Client class
-   * was constructed with a ClientChannelFactory.
-   */
-  void EnableAutoReconnect(int64_t reconnect_timeout_ms);
-
-  /*
-   * Disables auto-reconnect.
-   */
-  void DisableAutoReconnect();
-
-  /*
-   * Returns an fd that the client may use to check/wait for asynchronous
-   * notifications to the channel. It is implementation dependent how the
-   * transport backend handles this feature, however all implementations must
-   * support at least POLLIN/EPOLLIN/readable.
-   *
-   * For uses that require more than one type of event, use
-   * ClientChannel::GetEventMask() to distinguish between events.
-   */
-  int event_fd() const;
-
-  /*
-   * Returns the underlying ClientChannel object.
-   */
-  ClientChannel* GetChannel() const { return channel_.get(); }
-  std::unique_ptr<ClientChannel>&& TakeChannel() { return std::move(channel_); }
-
- private:
-  Client(const Client&) = delete;
-  void operator=(const Client&) = delete;
-
-  Status<void> CheckReconnect();
-  bool NeedToDisconnectChannel(int error) const;
-  void CheckDisconnect(int error);
-
-  template <typename T>
-  inline void CheckDisconnect(const Status<T>& status) {
-    if (!status)
-      CheckDisconnect(status.error());
-  }
-
-  std::unique_ptr<ClientChannel> channel_;
-  int error_{0};
-
-  // Reconnection state.
-  std::unique_ptr<ClientChannelFactory> channel_factory_;
-  int64_t reconnect_timeout_ms_{0};
-  bool auto_reconnect_enabled_{false};
-};
-
-/*
- * Utility template base class for client-side service API classes. Handles
- * initialization checks during allocation and automatically cleans up on
- * failure.
- *
- * @tparam T Type of the class extending this one.
- * @tparam C Client class to wrap. Defaults to the Client class.
- */
-template <typename T, typename ParentClient = Client>
-class ClientBase : public ParentClient {
- public:
-  // Type of the client this class wraps.
-  using ClientType = ParentClient;
-
-  static_assert(std::is_base_of<Client, ParentClient>::value,
-                "The provided parent client is not a Client subclass.");
-
-  /*
-   * Allocates a new instance of the superclass and checks for successful
-   * initialization.
-   *
-   * The variadic arguments must expand to match one of type T's constructors
-   * and are passed through unchanged. If a timeout is desired, subclasses are
-   * responsible for passing this through to the appropriate ClientBase
-   * constructor.
-   *
-   * Returns a unique_ptr to the new instance on success, or an empty unique_ptr
-   * otherwise.
-   */
-  template <typename... Args>
-  static inline std::unique_ptr<T> Create(Args&&... args) {
-    std::unique_ptr<T> client(new T(std::forward<Args>(args)...));
-    if (client->IsInitialized())
-      return client;
-    else
-      return nullptr;
-  }
-
- protected:
-  /*
-   * Type of the base class. Useful for referencing the base class type and
-   * constructor in subclasses. Subclasses with non-public constructors
-   * must declare BASE a friend.
-   */
-  using BASE = ClientBase<T, ParentClient>;
-
-  /*
-   * Type of the unique_ptr deleter. Useful for friend declarations.
-   */
-  using deleter_type = typename std::unique_ptr<T>::deleter_type;
-
-  using ParentClient::ParentClient;
-};
-
-class Transaction final : public OutputResourceMapper,
-                          public InputResourceMapper {
- public:
-  explicit Transaction(Client& client);
-  ~Transaction();
-
-  template <typename T>
-  Status<T> Send(int opcode) {
-    return SendVector<T>(opcode, nullptr, 0, nullptr, 0);
-  }
-
-  template <typename T>
-  Status<T> Send(int opcode, const void* send_buffer, size_t send_length,
-                 void* receive_buffer, size_t receive_length) {
-    const bool send = (send_buffer && send_length);
-    const bool receive = (receive_buffer && receive_length);
-    const iovec send_vector = {const_cast<void*>(send_buffer), send_length};
-    const iovec receive_vector = {receive_buffer, receive_length};
-    return SendVector<T>(opcode, send ? &send_vector : nullptr, send ? 1 : 0,
-                         receive ? &receive_vector : nullptr, receive ? 1 : 0);
-  }
-
-  template <typename T>
-  Status<T> SendVector(int opcode, const iovec* send_vector, size_t send_count,
-                       const iovec* receive_vector, size_t receive_count) {
-    Status<T> ret;
-    SendTransaction(opcode, &ret, send_vector, send_count, receive_vector,
-                    receive_count);
-    return ret;
-  }
-
-  template <typename T, size_t send_count, size_t receive_count>
-  Status<T> SendVector(int opcode, const iovec (&send_vector)[send_count],
-                       const iovec (&receive_vector)[receive_count]) {
-    return SendVector<T>(opcode, send_vector, send_count, receive_vector,
-                         receive_count);
-  }
-
-  template <typename T, size_t send_count>
-  Status<T> SendVector(int opcode, const iovec (&send_vector)[send_count],
-                       std::nullptr_t) {
-    return SendVector<T>(opcode, send_vector, send_count, nullptr, 0);
-  }
-
-  template <typename T, size_t receive_count>
-  Status<T> SendVector(int opcode, std::nullptr_t,
-                       const iovec (&receive_vector)[receive_count]) {
-    return SendVector<T>(opcode, nullptr, 0, receive_vector, receive_count);
-  }
-
-  // OutputResourceMapper
-  Status<FileReference> PushFileHandle(const LocalHandle& handle) override;
-  Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override;
-  Status<FileReference> PushFileHandle(const RemoteHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      const LocalChannelHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      const BorrowedChannelHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      const RemoteChannelHandle& handle) override;
-
-  // InputResourceMapper
-  bool GetFileHandle(FileReference ref, LocalHandle* handle) override;
-  bool GetChannelHandle(ChannelReference ref,
-                        LocalChannelHandle* handle) override;
-
- private:
-  bool EnsureStateAllocated();
-  void SendTransaction(int opcode, Status<void>* ret, const iovec* send_vector,
-                       size_t send_count, const iovec* receive_vector,
-                       size_t receive_count);
-  void SendTransaction(int opcode, Status<int>* ret, const iovec* send_vector,
-                       size_t send_count, const iovec* receive_vector,
-                       size_t receive_count);
-  void SendTransaction(int opcode, Status<LocalHandle>* ret,
-                       const iovec* send_vector, size_t send_count,
-                       const iovec* receive_vector, size_t receive_count);
-  void SendTransaction(int opcode, Status<LocalChannelHandle>* ret,
-                       const iovec* send_vector, size_t send_count,
-                       const iovec* receive_vector, size_t receive_count);
-  void CheckDisconnect(int error);
-
-  template <typename T>
-  inline void CheckDisconnect(const Status<T>& status) {
-    if (!status)
-      CheckDisconnect(status.error());
-  }
-
-  Client& client_;
-  void* state_{nullptr};
-  bool state_allocated_{false};
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_CLIENT_H_
diff --git a/libs/vr/libpdx/private/pdx/client_channel.h b/libs/vr/libpdx/private/pdx/client_channel.h
deleted file mode 100644
index f33a60e..0000000
--- a/libs/vr/libpdx/private/pdx/client_channel.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef ANDROID_PDX_CLIENT_CHANNEL_H_
-#define ANDROID_PDX_CLIENT_CHANNEL_H_
-
-#include <vector>
-
-#include <pdx/channel_handle.h>
-#include <pdx/channel_parcelable.h>
-#include <pdx/file_handle.h>
-#include <pdx/status.h>
-
-struct iovec;
-
-namespace android {
-namespace pdx {
-
-class ClientChannel {
- public:
-  virtual ~ClientChannel() = default;
-
-  // Returns a tag that uniquely identifies a specific underlying IPC transport.
-  virtual uint32_t GetIpcTag() const = 0;
-
-  virtual int event_fd() const = 0;
-  virtual Status<int> GetEventMask(int events) = 0;
-
-  struct EventSource {
-    int event_fd;
-    int event_mask;
-  };
-
-  // Returns a set of event-generating fds with and event mask for each. These
-  // fds are owned by the ClientChannel and must never be closed by the caller.
-  virtual std::vector<EventSource> GetEventSources() const = 0;
-
-  virtual LocalChannelHandle& GetChannelHandle() = 0;
-  virtual const LocalChannelHandle& GetChannelHandle() const = 0;
-  virtual void* AllocateTransactionState() = 0;
-  virtual void FreeTransactionState(void* state) = 0;
-
-  virtual Status<void> SendImpulse(int opcode, const void* buffer,
-                                   size_t length) = 0;
-
-  virtual Status<int> SendWithInt(void* transaction_state, int opcode,
-                                  const iovec* send_vector, size_t send_count,
-                                  const iovec* receive_vector,
-                                  size_t receive_count) = 0;
-  virtual Status<LocalHandle> SendWithFileHandle(
-      void* transaction_state, int opcode, const iovec* send_vector,
-      size_t send_count, const iovec* receive_vector, size_t receive_count) = 0;
-  virtual Status<LocalChannelHandle> SendWithChannelHandle(
-      void* transaction_state, int opcode, const iovec* send_vector,
-      size_t send_count, const iovec* receive_vector, size_t receive_count) = 0;
-
-  virtual FileReference PushFileHandle(void* transaction_state,
-                                       const LocalHandle& handle) = 0;
-  virtual FileReference PushFileHandle(void* transaction_state,
-                                       const BorrowedHandle& handle) = 0;
-  virtual ChannelReference PushChannelHandle(
-      void* transaction_state, const LocalChannelHandle& handle) = 0;
-  virtual ChannelReference PushChannelHandle(
-      void* transaction_state, const BorrowedChannelHandle& handle) = 0;
-  virtual bool GetFileHandle(void* transaction_state, FileReference ref,
-                             LocalHandle* handle) const = 0;
-  virtual bool GetChannelHandle(void* transaction_state, ChannelReference ref,
-                                LocalChannelHandle* handle) const = 0;
-
-  // Returns the internal state of the channel as a parcelable object. The
-  // ClientChannel is invalidated however, the channel is kept alive by the
-  // parcelable object and may be transferred to another process.
-  virtual std::unique_ptr<ChannelParcelable> TakeChannelParcelable() = 0;
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_CLIENT_CHANNEL_H_
diff --git a/libs/vr/libpdx/private/pdx/client_channel_factory.h b/libs/vr/libpdx/private/pdx/client_channel_factory.h
deleted file mode 100644
index a82ab70..0000000
--- a/libs/vr/libpdx/private/pdx/client_channel_factory.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef ANDROID_PDX_CLIENT_CHANNEL_FACTORY_H_
-#define ANDROID_PDX_CLIENT_CHANNEL_FACTORY_H_
-
-#include <pdx/client_channel.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-
-class ClientChannelFactory {
- public:
-  virtual ~ClientChannelFactory() = default;
-
-  virtual Status<std::unique_ptr<ClientChannel>> Connect(
-      int64_t timeout_ms) const = 0;
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_CLIENT_CHANNEL_FACTORY_H_
diff --git a/libs/vr/libpdx/private/pdx/file_handle.h b/libs/vr/libpdx/private/pdx/file_handle.h
deleted file mode 100644
index fed1529..0000000
--- a/libs/vr/libpdx/private/pdx/file_handle.h
+++ /dev/null
@@ -1,141 +0,0 @@
-#ifndef ANDROID_PDX_FILE_HANDLE_H_
-#define ANDROID_PDX_FILE_HANDLE_H_
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <string>
-
-namespace android {
-namespace pdx {
-
-enum class FileHandleMode {
-  Local,
-  Remote,
-  Borrowed,
-};
-
-// Manages ownership, sharing, and lifetime of file descriptors.
-template <FileHandleMode Mode>
-class FileHandle {
- public:
-  static constexpr int kEmptyFileHandle = -1;
-
-  // Constructs an empty FileHandle object.
-  FileHandle() : fd_(kEmptyFileHandle) {}
-
-  // Constructs a FileHandle from an integer file descriptor and takes
-  // ownership.
-  explicit FileHandle(int fd) : fd_(fd) {}
-
-  // Constructs a FileHandle by opening |path|. The arguments follow the
-  // semantics of open().
-  FileHandle(const std::string& path, int flags, mode_t mode = 0) {
-    fd_ = open(path.c_str(), flags, mode);
-  }
-
-  // Constructs a FileHandle by opening |path| relative to |dir_fd|, following
-  // the semantics of openat().
-  FileHandle(const int directory_fd, const std::string& path, int flags,
-             mode_t mode = 0) {
-    fd_ = openat(directory_fd, path.c_str(), flags, mode);
-  }
-
-  // Move constructor that assumes ownership of the file descriptor, leaving the
-  // other FileHandle object empty.
-  FileHandle(FileHandle&& other) noexcept {
-    fd_ = other.fd_;
-    other.fd_ = kEmptyFileHandle;
-  }
-
-  // Returns a FileHandle as a duplicate handle of |fd|. Borrowed handles and
-  // handles in remote handle space are not duplicated.
-  static FileHandle AsDuplicate(const int fd) {
-    if (Mode == FileHandleMode::Local)
-      return FileHandle(dup(fd));
-    else
-      return FileHandle(fd);
-  }
-
-  // Destructor closes the file descriptor when non-empty.
-  ~FileHandle() { Close(); }
-
-  // Move assignment operator that assumes ownership of the underlying file
-  // descriptor, leaving the other FileHandle object empty.
-  FileHandle& operator=(FileHandle&& other) noexcept {
-    if (this != &other) {
-      Reset(other.fd_);
-      other.fd_ = kEmptyFileHandle;
-    }
-    return *this;
-  }
-
-  // Resets the underlying file handle to |fd|.
-  void Reset(int fd) {
-    Close();
-    fd_ = fd;
-  }
-
-  // Closes the underlying file descriptor when non-empty.
-  void Close() {
-    if (IsValid() && Mode == FileHandleMode::Local)
-      close(fd_);
-    fd_ = kEmptyFileHandle;
-  }
-
-  // Return the internal fd, passing ownership to the caller.
-  int Release() {
-    int release_fd = fd_;
-    fd_ = kEmptyFileHandle;
-    return release_fd;
-  }
-
-  // Duplicates the underlying file descriptor and returns a FileHandle that
-  // owns the new file descriptor. File descriptors are not duplicated when Mode
-  // is Remote or Borrowed.
-  FileHandle Duplicate() const {
-    return FileHandle(Mode == FileHandleMode::Local ? dup(fd_) : fd_);
-  }
-
-  FileHandle<FileHandleMode::Borrowed> Borrow() const {
-    return FileHandle<FileHandleMode::Borrowed>(Get());
-  }
-
-  // Gets the underlying file descriptor value.
-  int Get() const { return fd_; }
-  bool IsValid() const { return fd_ >= 0; }
-  explicit operator bool() const { return IsValid(); }
-
- private:
-  int fd_;
-
-  FileHandle(const FileHandle&) = delete;
-  void operator=(const FileHandle&) = delete;
-};
-
-// Alias for a file handle in the local process' handle space.
-using LocalHandle = FileHandle<FileHandleMode::Local>;
-
-// Alias for a file handle in another process' handle space. Handles returned
-// from pushing a file object or channel must be stored in this type of handle
-// class, which doesn't close the underlying file descriptor. The underlying
-// file descriptor in this wrapper should not be passed to close() because doing
-// so would close an unrelated file descriptor in the local handle space.
-using RemoteHandle = FileHandle<FileHandleMode::Remote>;
-
-// Alias for borrowed handles in the local process' handle space. A borrowed
-// file handle is not close() because this wrapper does not own the underlying
-// file descriptor. Care must be take to ensure that a borrowed file handle
-// remains valid during use.
-using BorrowedHandle = FileHandle<FileHandleMode::Borrowed>;
-
-// FileReference is a 16 bit integer used in IPC serialization to be
-// transferred across processes. You can convert this value to a local file
-// handle by calling Transaction.GetFileHandle() on client side and
-// Message.GetFileHandle() on service side.
-using FileReference = int16_t;
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_FILE_HANDLE_H_
diff --git a/libs/vr/libpdx/private/pdx/message_reader.h b/libs/vr/libpdx/private/pdx/message_reader.h
deleted file mode 100644
index bc280cf..0000000
--- a/libs/vr/libpdx/private/pdx/message_reader.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef ANDROID_PDX_MESSAGE_READER_H_
-#define ANDROID_PDX_MESSAGE_READER_H_
-
-#include <memory>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-
-namespace android {
-namespace pdx {
-
-class InputResourceMapper {
- public:
-  virtual bool GetFileHandle(FileReference ref, LocalHandle* handle) = 0;
-  virtual bool GetChannelHandle(ChannelReference ref,
-                                LocalChannelHandle* handle) = 0;
-
- protected:
-  virtual ~InputResourceMapper() = default;
-};
-
-class MessageReader {
- public:
-  // Pointers to start/end of the region in the read buffer.
-  using BufferSection = std::pair<const void*, const void*>;
-
-  virtual BufferSection GetNextReadBufferSection() = 0;
-  virtual void ConsumeReadBufferSectionData(const void* new_start) = 0;
-  virtual InputResourceMapper* GetInputResourceMapper() = 0;
-
- protected:
-  virtual ~MessageReader() = default;
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_MESSAGE_READER_H_
diff --git a/libs/vr/libpdx/private/pdx/message_writer.h b/libs/vr/libpdx/private/pdx/message_writer.h
deleted file mode 100644
index 4a101d6..0000000
--- a/libs/vr/libpdx/private/pdx/message_writer.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef ANDROID_PDX_MESSAGE_WRITER_H_
-#define ANDROID_PDX_MESSAGE_WRITER_H_
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-
-class OutputResourceMapper {
- public:
-  virtual Status<FileReference> PushFileHandle(const LocalHandle& handle) = 0;
-  virtual Status<FileReference> PushFileHandle(
-      const BorrowedHandle& handle) = 0;
-  virtual Status<FileReference> PushFileHandle(const RemoteHandle& handle) = 0;
-  virtual Status<ChannelReference> PushChannelHandle(
-      const LocalChannelHandle& handle) = 0;
-  virtual Status<ChannelReference> PushChannelHandle(
-      const BorrowedChannelHandle& handle) = 0;
-  virtual Status<ChannelReference> PushChannelHandle(
-      const RemoteChannelHandle& handle) = 0;
-
- protected:
-  virtual ~OutputResourceMapper() = default;
-};
-
-class MessageWriter {
- public:
-  virtual void* GetNextWriteBufferSection(size_t size) = 0;
-  virtual OutputResourceMapper* GetOutputResourceMapper() = 0;
-
- protected:
-  virtual ~MessageWriter() = default;
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_MESSAGE_WRITER_H_
diff --git a/libs/vr/libpdx/private/pdx/mock_client_channel.h b/libs/vr/libpdx/private/pdx/mock_client_channel.h
deleted file mode 100644
index b1a1299..0000000
--- a/libs/vr/libpdx/private/pdx/mock_client_channel.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef ANDROID_PDX_MOCK_CLIENT_CHANNEL_H_
-#define ANDROID_PDX_MOCK_CLIENT_CHANNEL_H_
-
-#include <gmock/gmock.h>
-#include <pdx/client_channel.h>
-
-namespace android {
-namespace pdx {
-
-class MockClientChannel : public ClientChannel {
- public:
-  MOCK_CONST_METHOD0(GetIpcTag, uint32_t());
-  MOCK_CONST_METHOD0(event_fd, int());
-  MOCK_CONST_METHOD0(GetEventSources, std::vector<EventSource>());
-  MOCK_METHOD1(GetEventMask, Status<int>(int));
-  MOCK_METHOD0(GetChannelHandle, LocalChannelHandle&());
-  MOCK_CONST_METHOD0(GetChannelHandle, const LocalChannelHandle&());
-  MOCK_METHOD0(AllocateTransactionState, void*());
-  MOCK_METHOD1(FreeTransactionState, void(void* state));
-  MOCK_METHOD3(SendImpulse,
-               Status<void>(int opcode, const void* buffer, size_t length));
-  MOCK_METHOD6(SendWithInt,
-               Status<int>(void* transaction_state, int opcode,
-                           const iovec* send_vector, size_t send_count,
-                           const iovec* receive_vector, size_t receive_count));
-  MOCK_METHOD6(SendWithFileHandle,
-               Status<LocalHandle>(void* transaction_state, int opcode,
-                                   const iovec* send_vector, size_t send_count,
-                                   const iovec* receive_vector,
-                                   size_t receive_count));
-  MOCK_METHOD6(SendWithChannelHandle,
-               Status<LocalChannelHandle>(void* transaction_state, int opcode,
-                                          const iovec* send_vector,
-                                          size_t send_count,
-                                          const iovec* receive_vector,
-                                          size_t receive_count));
-  MOCK_METHOD2(PushFileHandle, FileReference(void* transaction_state,
-                                             const LocalHandle& handle));
-  MOCK_METHOD2(PushFileHandle, FileReference(void* transaction_state,
-                                             const BorrowedHandle& handle));
-  MOCK_METHOD2(PushChannelHandle,
-               ChannelReference(void* transaction_state,
-                                const LocalChannelHandle& handle));
-  MOCK_METHOD2(PushChannelHandle,
-               ChannelReference(void* transaction_state,
-                                const BorrowedChannelHandle& handle));
-  MOCK_CONST_METHOD3(GetFileHandle,
-                     bool(void* transaction_state, FileReference ref,
-                          LocalHandle* handle));
-  MOCK_CONST_METHOD3(GetChannelHandle,
-                     bool(void* transaction_state, ChannelReference ref,
-                          LocalChannelHandle* handle));
-  MOCK_METHOD0(TakeChannelParcelable, std::unique_ptr<ChannelParcelable>());
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_MOCK_CLIENT_CHANNEL_H_
diff --git a/libs/vr/libpdx/private/pdx/mock_client_channel_factory.h b/libs/vr/libpdx/private/pdx/mock_client_channel_factory.h
deleted file mode 100644
index 0190f5e..0000000
--- a/libs/vr/libpdx/private/pdx/mock_client_channel_factory.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef ANDROID_PDX_MOCK_CLIENT_CHANNEL_FACTORY_H_
-#define ANDROID_PDX_MOCK_CLIENT_CHANNEL_FACTORY_H_
-
-#include <gmock/gmock.h>
-#include <pdx/client_channel_factory.h>
-
-namespace android {
-namespace pdx {
-
-class MockClientChannelFactory : public ClientChannelFactory {
- public:
-  MOCK_CONST_METHOD1(
-      Connect, Status<std::unique_ptr<ClientChannel>>(int64_t timeout_ms));
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_MOCK_CLIENT_CHANNEL_FACTORY_H_
diff --git a/libs/vr/libpdx/private/pdx/mock_message_reader.h b/libs/vr/libpdx/private/pdx/mock_message_reader.h
deleted file mode 100644
index 85e96ef..0000000
--- a/libs/vr/libpdx/private/pdx/mock_message_reader.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef ANDROID_PDX_MOCK_MESSAGE_READER_H_
-#define ANDROID_PDX_MOCK_MESSAGE_READER_H_
-
-#include <gmock/gmock.h>
-#include <pdx/message_reader.h>
-
-namespace android {
-namespace pdx {
-
-class MockInputResourceMapper : public InputResourceMapper {
- public:
-  MOCK_METHOD2(GetFileHandle, bool(FileReference ref, LocalHandle* handle));
-  MOCK_METHOD2(GetChannelHandle,
-               bool(ChannelReference ref, LocalChannelHandle* handle));
-};
-
-class MockMessageReader : public MessageReader {
- public:
-  MOCK_METHOD0(GetNextReadBufferSection, BufferSection());
-  MOCK_METHOD1(ConsumeReadBufferSectionData, void(const void* new_start));
-  MOCK_METHOD0(GetInputResourceMapper, InputResourceMapper*());
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_MOCK_MESSAGE_READER_H_
diff --git a/libs/vr/libpdx/private/pdx/mock_message_writer.h b/libs/vr/libpdx/private/pdx/mock_message_writer.h
deleted file mode 100644
index e06e5bb..0000000
--- a/libs/vr/libpdx/private/pdx/mock_message_writer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef ANDROID_PDX_MOCK_MESSAGE_WRITER_H_
-#define ANDROID_PDX_MOCK_MESSAGE_WRITER_H_
-
-#include <gmock/gmock.h>
-#include <pdx/message_writer.h>
-
-namespace android {
-namespace pdx {
-
-class MockOutputResourceMapper : public OutputResourceMapper {
- public:
-  MOCK_METHOD1(PushFileHandle,
-               Status<FileReference>(const LocalHandle& handle));
-  MOCK_METHOD1(PushFileHandle,
-               Status<FileReference>(const BorrowedHandle& handle));
-  MOCK_METHOD1(PushFileHandle,
-               Status<FileReference>(const RemoteHandle& handle));
-  MOCK_METHOD1(PushChannelHandle,
-               Status<ChannelReference>(const LocalChannelHandle& handle));
-  MOCK_METHOD1(PushChannelHandle,
-               Status<ChannelReference>(const BorrowedChannelHandle& handle));
-  MOCK_METHOD1(PushChannelHandle,
-               Status<ChannelReference>(const RemoteChannelHandle& handle));
-};
-
-class MockMessageWriter : public MessageWriter {
- public:
-  MOCK_METHOD1(GetNextWriteBufferSection, void*(size_t size));
-  MOCK_METHOD0(GetOutputResourceMapper, OutputResourceMapper*());
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_MOCK_MESSAGE_WRITER_H_
diff --git a/libs/vr/libpdx/private/pdx/mock_service_endpoint.h b/libs/vr/libpdx/private/pdx/mock_service_endpoint.h
deleted file mode 100644
index 7f829e7..0000000
--- a/libs/vr/libpdx/private/pdx/mock_service_endpoint.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef ANDROID_PDX_MOCK_ENDPOINT_H_
-#define ANDROID_PDX_MOCK_ENDPOINT_H_
-
-#include <gmock/gmock.h>
-#include <pdx/service_endpoint.h>
-
-namespace android {
-namespace pdx {
-
-class MockEndpoint : public Endpoint {
- public:
-  MOCK_CONST_METHOD0(GetIpcTag, uint32_t());
-  MOCK_METHOD1(SetService, Status<void>(Service* service));
-  MOCK_METHOD2(SetChannel, Status<void>(int channel_id, Channel* channel));
-  MOCK_METHOD1(CloseChannel, Status<void>(int channel_id));
-  MOCK_METHOD3(ModifyChannelEvents,
-               Status<void>(int channel_id, int clear_mask, int set_mask));
-  MOCK_METHOD4(PushChannel,
-               Status<RemoteChannelHandle>(Message* message, int flags,
-                                           Channel* channel, int* channel_id));
-  MOCK_METHOD3(CheckChannel,
-               Status<int>(const Message* message, ChannelReference ref,
-                           Channel** channel));
-  MOCK_METHOD1(MessageReceive, Status<void>(Message* message));
-  MOCK_METHOD2(MessageReply, Status<void>(Message* message, int return_code));
-  MOCK_METHOD2(MessageReplyFd,
-               Status<void>(Message* message, unsigned int push_fd));
-  MOCK_METHOD2(MessageReplyChannelHandle,
-               Status<void>(Message* message,
-                            const LocalChannelHandle& handle));
-  MOCK_METHOD2(MessageReplyChannelHandle,
-               Status<void>(Message* message,
-                            const BorrowedChannelHandle& handle));
-  MOCK_METHOD2(MessageReplyChannelHandle,
-               Status<void>(Message* message,
-                            const RemoteChannelHandle& handle));
-  MOCK_METHOD3(ReadMessageData,
-               Status<size_t>(Message* message, const iovec* vector,
-                              size_t vector_length));
-  MOCK_METHOD3(WriteMessageData,
-               Status<size_t>(Message* message, const iovec* vector,
-                              size_t vector_length));
-  MOCK_METHOD2(PushFileHandle,
-               Status<FileReference>(Message* message,
-                                     const LocalHandle& handle));
-  MOCK_METHOD2(PushFileHandle,
-               Status<FileReference>(Message* message,
-                                     const BorrowedHandle& handle));
-  MOCK_METHOD2(PushFileHandle,
-               Status<FileReference>(Message* message,
-                                     const RemoteHandle& handle));
-  MOCK_METHOD2(PushChannelHandle,
-               Status<ChannelReference>(Message* message,
-                                        const LocalChannelHandle& handle));
-  MOCK_METHOD2(PushChannelHandle,
-               Status<ChannelReference>(Message* message,
-                                        const BorrowedChannelHandle& handle));
-  MOCK_METHOD2(PushChannelHandle,
-               Status<ChannelReference>(Message* message,
-                                        const RemoteChannelHandle& handle));
-  MOCK_CONST_METHOD2(GetFileHandle,
-                     LocalHandle(Message* message, FileReference ref));
-  MOCK_CONST_METHOD2(GetChannelHandle,
-                     LocalChannelHandle(Message* message,
-                                        ChannelReference ref));
-  MOCK_METHOD0(AllocateMessageState, void*());
-  MOCK_METHOD1(FreeMessageState, void(void* state));
-  MOCK_METHOD0(Cancel, Status<void>());
-  MOCK_CONST_METHOD0(epoll_fd, int());
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_MOCK_ENDPOINT_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/argument_encoder.h b/libs/vr/libpdx/private/pdx/rpc/argument_encoder.h
deleted file mode 100644
index e006284..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/argument_encoder.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef ANDROID_PDX_RPC_ARGUMENT_ENCODER_H_
-#define ANDROID_PDX_RPC_ARGUMENT_ENCODER_H_
-
-#include <cstdint>
-#include <tuple>
-#include <type_traits>
-
-#include <pdx/rpc/serialization.h>
-#include <pdx/service.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Provides automatic serialization of argument lists and return
-// values by analyzing the supplied function signature types.
-// Examples:
-//     ArgumentEncoder<int(int, float)> encoder(writer);
-//     encoder.EncodeArguments(1, 1.0);
-
-template <typename T>
-class ArgumentEncoder;
-
-// Specialization of ArgumentEncoder for void return types.
-template <typename... Args>
-class ArgumentEncoder<void(Args...)> {
- public:
-  explicit ArgumentEncoder(MessageWriter* writer) : writer_{writer} {}
-
-  // Serializes the arguments as a tuple.
-  void EncodeArguments(Args... args) {
-    Serialize(std::forward_as_tuple(args...), writer_);
-  }
-
- private:
-  MessageWriter* writer_;
-};
-
-// Specialization of ArgumentEncoder for non-void return types.
-template <typename Return, typename... Args>
-class ArgumentEncoder<Return(Args...)> {
- public:
-  // Simplified types with reference and cv removed.
-  using ReturnType = typename std::decay<Return>::type;
-
-  explicit ArgumentEncoder(MessageWriter* writer) : writer_{writer} {}
-
-  // Serializes the arguments as a tuple.
-  void EncodeArguments(Args... args) {
-    Serialize(std::forward_as_tuple(args...), writer_);
-  }
-
-  // Serializes the return value for rvalue references.
-  void EncodeReturn(const ReturnType& return_value) {
-    Serialize(return_value, writer_);
-  }
-
- private:
-  MessageWriter* writer_;
-};
-
-// Utility to build an ArgumentEncoder from a function pointer and a message
-// writer.
-template <typename Return, typename... Args>
-inline ArgumentEncoder<Return(Args...)> MakeArgumentEncoder(
-    Return (*)(Args...), MessageWriter* writer) {
-  return ArgumentEncoder<Return(Args...)>(writer);
-}
-
-// Utility to build an ArgumentEncoder from a method pointer and a message
-// writer.
-template <typename Class, typename Return, typename... Args>
-inline ArgumentEncoder<Return(Args...)> MakeArgumentEncoder(
-    Return (Class::*)(Args...), MessageWriter* writer) {
-  return ArgumentEncoder<Return(Args...)>(writer);
-}
-
-// Utility to build an ArgumentEncoder from a const method pointer and a
-// message writer.
-template <typename Class, typename Return, typename... Args>
-inline ArgumentEncoder<Return(Args...)> MakeArgumentEncoder(
-    Return (Class::*)(Args...) const, MessageWriter* writer) {
-  return ArgumentEncoder<Return(Args...)>(writer);
-}
-
-// Utility to build an ArgumentEncoder from a function type and a message
-// writer.
-template <typename Signature>
-inline ArgumentEncoder<Signature> MakeArgumentEncoder(MessageWriter* writer) {
-  return ArgumentEncoder<Signature>(writer);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Provides automatic deserialization of argument lists and return
-// values by analyzing the supplied function signature types.
-// Examples:
-//     auto decoder = MakeArgumentDecoder<std::string(void)>(reader);
-//     ErrorType error = decoder.DecodeReturn(&return_value);
-
-template <typename T>
-class ArgumentDecoder;
-
-// Specialization of ArgumentDecoder for void return types.
-template <typename... Args>
-class ArgumentDecoder<void(Args...)> {
- public:
-  // Simplified types with reference and cv removed.
-  using ArgsTupleType = std::tuple<typename std::decay<Args>::type...>;
-
-  explicit ArgumentDecoder(MessageReader* reader) : reader_{reader} {}
-
-  // Deserializes arguments into a tuple.
-  ArgsTupleType DecodeArguments(ErrorType* error) {
-    ArgsTupleType value;
-    *error = Deserialize(&value, reader_);
-    return value;
-  }
-
- private:
-  MessageReader* reader_;
-};
-
-// Specialization of ArgumentDecoder for non-void return types.
-template <typename Return, typename... Args>
-class ArgumentDecoder<Return(Args...)> {
- public:
-  // Simplified types with reference and cv removed.
-  using ArgsTupleType = std::tuple<typename std::decay<Args>::type...>;
-  using ReturnType = typename std::decay<Return>::type;
-
-  explicit ArgumentDecoder(MessageReader* reader) : reader_{reader} {}
-
-  // Deserializes arguments into a tuple.
-  ArgsTupleType DecodeArguments(ErrorType* error) {
-    ArgsTupleType value;
-    *error = Deserialize(&value, reader_);
-    return value;
-  }
-
-  // Deserializes the return value.
-  ErrorType DecodeReturn(ReturnType* value) {
-    return Deserialize(value, reader_);
-  }
-
- private:
-  MessageReader* reader_;
-};
-
-// Utility to build an ArgumentDecoder from a function pointer and a message
-// reader.
-template <typename Return, typename... Args>
-inline ArgumentDecoder<Return(Args...)> MakeArgumentDecoder(
-    Return (*)(Args...), MessageReader* reader) {
-  return ArgumentDecoder<Return(Args...)>(reader);
-}
-
-// Utility to build an ArgumentDecoder from a method pointer and a message
-// reader.
-template <typename Class, typename Return, typename... Args>
-inline ArgumentDecoder<Return(Args...)> MakeArgumentDecoder(
-    Return (Class::*)(Args...), MessageReader* reader) {
-  return ArgumentDecoder<Return(Args...)>(reader);
-}
-
-// Utility to build an ArgumentDecoder from a const method pointer and a
-// message reader.
-template <typename Class, typename Return, typename... Args>
-inline ArgumentDecoder<Return(Args...)> MakeArgumentDecoder(
-    Return (Class::*)(Args...) const, MessageReader* reader) {
-  return ArgumentDecoder<Return(Args...)>(reader);
-}
-
-// Utility to build an ArgumentDecoder from a function type and a message
-// reader.
-template <typename Signature>
-inline ArgumentDecoder<Signature> MakeArgumentDecoder(MessageReader* reader) {
-  return ArgumentDecoder<Signature>(reader);
-}
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_ARGUMENT_ENCODER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/array_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/array_wrapper.h
deleted file mode 100644
index d835c57..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/array_wrapper.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef ANDROID_PDX_RPC_ARRAY_WRAPPER_H_
-#define ANDROID_PDX_RPC_ARRAY_WRAPPER_H_
-
-#include <cstddef>
-#include <memory>
-#include <type_traits>
-#include <vector>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Wrapper class for C array buffers, providing an interface suitable for
-// SerializeObject and DeserializeObject. This class serializes to the same
-// format as std::vector, and may be substituted for std::vector during
-// serialization and deserialization. This substitution makes handling of C
-// arrays more efficient by avoiding unnecessary copies when remote method
-// signatures specify std::vector arguments or return values.
-template <typename T>
-class ArrayWrapper {
- public:
-  // Define types in the style of STL containers to support STL operators.
-  typedef T value_type;
-  typedef std::size_t size_type;
-  typedef T& reference;
-  typedef const T& const_reference;
-  typedef T* pointer;
-  typedef const T* const_pointer;
-
-  ArrayWrapper() : buffer_(nullptr), capacity_(0), end_(0) {}
-
-  ArrayWrapper(pointer buffer, size_type capacity, size_type size)
-      : buffer_(&buffer[0]),
-        capacity_(capacity),
-        end_(capacity < size ? capacity : size) {}
-
-  ArrayWrapper(pointer buffer, size_type size)
-      : ArrayWrapper(buffer, size, size) {}
-
-  ArrayWrapper(const ArrayWrapper& other) { *this = other; }
-
-  ArrayWrapper(ArrayWrapper&& other) noexcept { *this = std::move(other); }
-
-  ArrayWrapper& operator=(const ArrayWrapper& other) {
-    if (&other == this) {
-      return *this;
-    } else {
-      buffer_ = other.buffer_;
-      capacity_ = other.capacity_;
-      end_ = other.end_;
-    }
-
-    return *this;
-  }
-
-  ArrayWrapper& operator=(ArrayWrapper&& other) noexcept {
-    if (&other == this) {
-      return *this;
-    } else {
-      buffer_ = other.buffer_;
-      capacity_ = other.capacity_;
-      end_ = other.end_;
-      other.buffer_ = nullptr;
-      other.capacity_ = 0;
-      other.end_ = 0;
-    }
-
-    return *this;
-  }
-
-  pointer data() { return buffer_; }
-  const_pointer data() const { return buffer_; }
-
-  pointer begin() { return &buffer_[0]; }
-  pointer end() { return &buffer_[end_]; }
-  const_pointer begin() const { return &buffer_[0]; }
-  const_pointer end() const { return &buffer_[end_]; }
-
-  size_type size() const { return end_; }
-  size_type max_size() const { return capacity_; }
-  size_type capacity() const { return capacity_; }
-
-  // Moves the end marker to |size|, clamping the end marker to the max capacity
-  // of the underlying array. This method does not change the size of the
-  // underlying array.
-  void resize(size_type size) {
-    if (size <= capacity_)
-      end_ = size;
-    else
-      end_ = capacity_;
-  }
-
-  reference operator[](size_type pos) { return buffer_[pos]; }
-  const_reference operator[](size_type pos) const { return buffer_[pos]; }
-
- private:
-  pointer buffer_;
-  size_type capacity_;
-  size_type end_;
-};
-
-template <typename T, typename SizeType = std::size_t>
-ArrayWrapper<T> WrapArray(T* buffer, SizeType size) {
-  return ArrayWrapper<T>(buffer, size);
-}
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_ARRAY_WRAPPER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h
deleted file mode 100644
index 43184dd..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h
+++ /dev/null
@@ -1,177 +0,0 @@
-#ifndef ANDROID_PDX_RPC_BUFFER_WRAPPER_H_
-#define ANDROID_PDX_RPC_BUFFER_WRAPPER_H_
-
-#include <cstddef>
-#include <memory>
-#include <type_traits>
-#include <vector>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Wrapper class for buffers, providing an interface suitable for
-// SerializeObject and DeserializeObject. This class supports serialization of
-// buffers as raw bytes.
-template <typename T>
-class BufferWrapper;
-
-template <typename T>
-class BufferWrapper<T*> {
- public:
-  // Define types in the style of STL containers to support STL operators.
-  typedef T value_type;
-  typedef std::size_t size_type;
-  typedef T& reference;
-  typedef const T& const_reference;
-  typedef T* pointer;
-  typedef const T* const_pointer;
-
-  BufferWrapper() : buffer_(nullptr), capacity_(0), end_(0) {}
-
-  BufferWrapper(pointer buffer, size_type capacity, size_type size)
-      : buffer_(&buffer[0]),
-        capacity_(capacity),
-        end_(capacity < size ? capacity : size) {}
-
-  BufferWrapper(pointer buffer, size_type size)
-      : BufferWrapper(buffer, size, size) {}
-
-  BufferWrapper(const BufferWrapper& other) { *this = other; }
-
-  BufferWrapper(BufferWrapper&& other) noexcept { *this = std::move(other); }
-
-  BufferWrapper& operator=(const BufferWrapper& other) {
-    if (&other == this) {
-      return *this;
-    } else {
-      buffer_ = other.buffer_;
-      capacity_ = other.capacity_;
-      end_ = other.end_;
-    }
-
-    return *this;
-  }
-
-  BufferWrapper& operator=(BufferWrapper&& other) noexcept {
-    if (&other == this) {
-      return *this;
-    } else {
-      buffer_ = other.buffer_;
-      capacity_ = other.capacity_;
-      end_ = other.end_;
-      other.buffer_ = nullptr;
-      other.capacity_ = 0;
-      other.end_ = 0;
-    }
-
-    return *this;
-  }
-
-  pointer data() { return buffer_; }
-  const_pointer data() const { return buffer_; }
-
-  pointer begin() { return &buffer_[0]; }
-  pointer end() { return &buffer_[end_]; }
-  const_pointer begin() const { return &buffer_[0]; }
-  const_pointer end() const { return &buffer_[end_]; }
-
-  size_type size() const { return end_; }
-  size_type max_size() const { return capacity_; }
-  size_type capacity() const { return capacity_; }
-
-  void resize(size_type size) {
-    if (size <= capacity_)
-      end_ = size;
-    else
-      end_ = capacity_;
-  }
-
-  reference operator[](size_type pos) { return buffer_[pos]; }
-  const_reference operator[](size_type pos) const { return buffer_[pos]; }
-
- private:
-  pointer buffer_;
-  size_type capacity_;
-  size_type end_;
-};
-
-template <typename T, typename Allocator>
-class BufferWrapper<std::vector<T, Allocator>> {
- public:
-  using BufferType = typename std::vector<T, Allocator>;
-  using value_type = typename BufferType::value_type;
-  using size_type = typename BufferType::size_type;
-  using reference = typename BufferType::reference;
-  using const_reference = typename BufferType::const_reference;
-  using pointer = typename BufferType::pointer;
-  using const_pointer = typename BufferType::const_pointer;
-  using iterator = typename BufferType::iterator;
-  using const_iterator = typename BufferType::const_iterator;
-
-  BufferWrapper() {}
-  explicit BufferWrapper(const BufferType& buffer) : buffer_(buffer) {}
-  BufferWrapper(const BufferType& buffer, const Allocator& allocator)
-      : buffer_(buffer, allocator) {}
-  explicit BufferWrapper(BufferType&& buffer) : buffer_(std::move(buffer)) {}
-  BufferWrapper(BufferType&& buffer, const Allocator& allocator)
-      : buffer_(std::move(buffer), allocator) {}
-  BufferWrapper(const BufferWrapper&) = default;
-  BufferWrapper(BufferWrapper&&) noexcept = default;
-  BufferWrapper& operator=(const BufferWrapper&) = default;
-  BufferWrapper& operator=(BufferWrapper&&) noexcept = default;
-
-  pointer data() { return buffer_.data(); }
-  const_pointer data() const { return buffer_.data(); }
-
-  iterator begin() { return buffer_.begin(); }
-  iterator end() { return buffer_.end(); }
-  const_iterator begin() const { return buffer_.begin(); }
-  const_iterator end() const { return buffer_.end(); }
-
-  size_type size() const { return buffer_.size(); }
-  size_type max_size() const { return buffer_.capacity(); }
-  size_type capacity() const { return buffer_.capacity(); }
-
-  void resize(size_type size) { buffer_.resize(size); }
-  void reserve(size_type size) { buffer_.reserve(size); }
-
-  reference operator[](size_type pos) { return buffer_[pos]; }
-  const_reference operator[](size_type pos) const { return buffer_[pos]; }
-
-  BufferType& buffer() { return buffer_; }
-  const BufferType& buffer() const { return buffer_; }
-
- private:
-  BufferType buffer_;
-};
-
-template <typename T, typename SizeType = std::size_t>
-BufferWrapper<T*> WrapBuffer(T* buffer, SizeType size) {
-  return BufferWrapper<T*>(buffer, size);
-}
-
-template <typename SizeType = std::size_t>
-BufferWrapper<std::uint8_t*> WrapBuffer(void* buffer, SizeType size) {
-  return BufferWrapper<std::uint8_t*>(static_cast<std::uint8_t*>(buffer), size);
-}
-
-template <typename SizeType = std::size_t>
-BufferWrapper<const std::uint8_t*> WrapBuffer(const void* buffer,
-                                              SizeType size) {
-  return BufferWrapper<const std::uint8_t*>(
-      static_cast<const std::uint8_t*>(buffer), size);
-}
-
-template <typename T, typename Allocator = std::allocator<T>>
-BufferWrapper<std::vector<T, Allocator>> WrapBuffer(
-    std::vector<T, Allocator>&& buffer) {
-  return BufferWrapper<std::vector<T, Allocator>>(
-      std::forward<std::vector<T, Allocator>>(buffer));
-}
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_BUFFER_WRAPPER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/copy_cv_reference.h b/libs/vr/libpdx/private/pdx/rpc/copy_cv_reference.h
deleted file mode 100644
index 5ce34f8..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/copy_cv_reference.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef ANDROID_PDX_RPC_COPY_CV_REFERENCE_H_
-#define ANDROID_PDX_RPC_COPY_CV_REFERENCE_H_
-
-#include <type_traits>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Copies const, void, and reference qualifiers from type T to type U, such that
-// the new type U' carries the same cv-reference qualifiers as T, with the same
-// underlying type as U.
-template <typename T, typename U>
-class CopyCVReference {
- private:
-  using R = typename std::remove_reference<T>::type;
-  using U1 =
-      typename std::conditional<std::is_const<R>::value,
-                                typename std::add_const<U>::type, U>::type;
-  using U2 =
-      typename std::conditional<std::is_volatile<R>::value,
-                                typename std::add_volatile<U1>::type, U1>::type;
-  using U3 =
-      typename std::conditional<std::is_lvalue_reference<T>::value,
-                                typename std::add_lvalue_reference<U2>::type,
-                                U2>::type;
-  using U4 =
-      typename std::conditional<std::is_rvalue_reference<T>::value,
-                                typename std::add_rvalue_reference<U3>::type,
-                                U3>::type;
-
- public:
-  using Type = U4;
-};
-
-template <typename T, typename U>
-using CopyCVReferenceType = typename CopyCVReference<T, U>::Type;
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  //  ANDROID_PDX_RPC_COPY_CV_REFERENCE_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/default_initialization_allocator.h b/libs/vr/libpdx/private/pdx/rpc/default_initialization_allocator.h
deleted file mode 100644
index b6e2980..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/default_initialization_allocator.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef ANDROID_PDX_RPC_DEFAULT_INITIALIZATION_ALLOCATOR_H_
-#define ANDROID_PDX_RPC_DEFAULT_INITIALIZATION_ALLOCATOR_H_
-
-#include <memory>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Allocator adaptor that interposes construct() calls to convert value
-// initialization into default initialization. All standard containers
-// value-initialize their elements when constructed with a single size_type
-// argument or when grown by a call to resize. This allocator avoids potentially
-// costly value-initialization in these situations for value types that are
-// default constructible. As a consequence, elements of non-class types are left
-// uninitialized; this is desirable when using std::vector as a resizable
-// buffer, for example.
-template <typename T, typename Allocator = std::allocator<T>>
-class DefaultInitializationAllocator : public Allocator {
-  typedef std::allocator_traits<Allocator> AllocatorTraits;
-
- public:
-  template <typename U>
-  struct rebind {
-    using other = DefaultInitializationAllocator<
-        U, typename AllocatorTraits::template rebind_alloc<U>>;
-  };
-
-  using Allocator::Allocator;
-
-  template <typename U>
-  void construct(U* pointer) noexcept(
-      std::is_nothrow_default_constructible<U>::value) {
-    ::new (static_cast<void*>(pointer)) U;
-  }
-  template <typename U, typename... Args>
-  void construct(U* pointer, Args&&... args) {
-    AllocatorTraits::construct(static_cast<Allocator&>(*this), pointer,
-                               std::forward<Args>(args)...);
-  }
-};
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  //  ANDROID_PDX_RPC_DEFAULT_INITIALIZATION_ALLOCATOR_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/encoding.h b/libs/vr/libpdx/private/pdx/rpc/encoding.h
deleted file mode 100644
index f51d807..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/encoding.h
+++ /dev/null
@@ -1,616 +0,0 @@
-#ifndef ANDROID_PDX_RPC_ENCODING_H_
-#define ANDROID_PDX_RPC_ENCODING_H_
-
-#include <array>
-#include <cstdint>
-#include <cstring>
-#include <map>
-#include <numeric>
-#include <string>
-#include <tuple>
-#include <unordered_map>
-#include <vector>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-
-#include "array_wrapper.h"
-#include "buffer_wrapper.h"
-#include "string_wrapper.h"
-#include "variant.h"
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// This library uses a subset, or profile, of MessagePack (http://msgpack.org)
-// to encode supported data types during serialization and to verify the
-// expected data types during deserialization. One notable deviation from the
-// MessagePack specification is that little-endian byte order is used for
-// multi-byte numeric types to avoid unnecessary conversion on nearly all
-// relevant architectures.
-//
-// Some data types, integers for example, support multiple encoding strategies.
-// This library attempts to optimize for space based on the value of such types.
-// However, during decode all valid encodings for a given type are accepted.
-
-// Prefix byte for type encodings. This is the complete list of prefix bytes
-// from the MessagePack specification, even though not all types are used by
-// this library.
-enum EncodingPrefix {
-  ENCODING_TYPE_POSITIVE_FIXINT = 0x00,
-  ENCODING_TYPE_POSITIVE_FIXINT_MIN = 0x00,
-  ENCODING_TYPE_POSITIVE_FIXINT_MAX = 0x7f,
-  ENCODING_TYPE_POSITIVE_FIXINT_MASK = 0x7f,
-  ENCODING_TYPE_FIXMAP = 0x80,
-  ENCODING_TYPE_FIXMAP_MIN = 0x80,
-  ENCODING_TYPE_FIXMAP_MAX = 0x8f,
-  ENCODING_TYPE_FIXMAP_MASK = 0x0f,
-  ENCODING_TYPE_FIXARRAY = 0x90,
-  ENCODING_TYPE_FIXARRAY_MIN = 0x90,
-  ENCODING_TYPE_FIXARRAY_MAX = 0x9f,
-  ENCODING_TYPE_FIXARRAY_MASK = 0x0f,
-  ENCODING_TYPE_FIXSTR = 0xa0,
-  ENCODING_TYPE_FIXSTR_MIN = 0xa0,
-  ENCODING_TYPE_FIXSTR_MAX = 0xbf,
-  ENCODING_TYPE_FIXSTR_MASK = 0x1f,
-  ENCODING_TYPE_NIL = 0xc0,
-  ENCODING_TYPE_RESERVED = 0xc1,
-  ENCODING_TYPE_FALSE = 0xc2,
-  ENCODING_TYPE_TRUE = 0xc3,
-  ENCODING_TYPE_BIN8 = 0xc4,
-  ENCODING_TYPE_BIN16 = 0xc5,
-  ENCODING_TYPE_BIN32 = 0xc6,
-  ENCODING_TYPE_EXT8 = 0xc7,
-  ENCODING_TYPE_EXT16 = 0xc8,
-  ENCODING_TYPE_EXT32 = 0xc9,
-  ENCODING_TYPE_FLOAT32 = 0xca,
-  ENCODING_TYPE_FLOAT64 = 0xcb,
-  ENCODING_TYPE_UINT8 = 0xcc,
-  ENCODING_TYPE_UINT16 = 0xcd,
-  ENCODING_TYPE_UINT32 = 0xce,
-  ENCODING_TYPE_UINT64 = 0xcf,
-  ENCODING_TYPE_INT8 = 0xd0,
-  ENCODING_TYPE_INT16 = 0xd1,
-  ENCODING_TYPE_INT32 = 0xd2,
-  ENCODING_TYPE_INT64 = 0xd3,
-  ENCODING_TYPE_FIXEXT1 = 0xd4,
-  ENCODING_TYPE_FIXEXT2 = 0xd5,
-  ENCODING_TYPE_FIXEXT4 = 0xd6,
-  ENCODING_TYPE_FIXEXT8 = 0xd7,
-  ENCODING_TYPE_FIXEXT16 = 0xd8,
-  ENCODING_TYPE_STR8 = 0xd9,
-  ENCODING_TYPE_STR16 = 0xda,
-  ENCODING_TYPE_STR32 = 0xdb,
-  ENCODING_TYPE_ARRAY16 = 0xdc,
-  ENCODING_TYPE_ARRAY32 = 0xdd,
-  ENCODING_TYPE_MAP16 = 0xde,
-  ENCODING_TYPE_MAP32 = 0xdf,
-  ENCODING_TYPE_NEGATIVE_FIXINT = 0xe0,
-  ENCODING_TYPE_NEGATIVE_FIXINT_MIN = 0xe0,
-  ENCODING_TYPE_NEGATIVE_FIXINT_MAX = 0xff,
-};
-
-// Base encoding classes grouping multi-strategy encodings.
-enum EncodingClass {
-  ENCODING_CLASS_BOOL,
-  ENCODING_CLASS_NIL,
-  ENCODING_CLASS_INT,
-  ENCODING_CLASS_UINT,
-  ENCODING_CLASS_FLOAT,
-  ENCODING_CLASS_ARRAY,
-  ENCODING_CLASS_MAP,
-  ENCODING_CLASS_STRING,
-  ENCODING_CLASS_BINARY,
-  ENCODING_CLASS_EXTENSION,
-};
-
-// Encoding prefixes are unsigned bytes.
-typedef std::uint8_t EncodingType;
-
-// Extension encoding types defined by this library.
-enum EncodingExtType : int8_t {
-  ENCODING_EXT_TYPE_FILE_DESCRIPTOR,
-  ENCODING_EXT_TYPE_CHANNEL_HANDLE,
-};
-
-// Encoding predicates. Determines whether the given encoding is of a specific
-// type.
-inline constexpr bool IsFixintEncoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
-    case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsUnsignedFixintEncoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsInt8Encoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
-    case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
-    case ENCODING_TYPE_INT8:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsUInt8Encoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
-    case ENCODING_TYPE_UINT8:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsInt16Encoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
-    case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
-    case ENCODING_TYPE_INT8:
-    case ENCODING_TYPE_INT16:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsUInt16Encoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
-    case ENCODING_TYPE_UINT8:
-    case ENCODING_TYPE_UINT16:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsInt32Encoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
-    case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
-    case ENCODING_TYPE_INT8:
-    case ENCODING_TYPE_INT16:
-    case ENCODING_TYPE_INT32:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsUInt32Encoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
-    case ENCODING_TYPE_UINT8:
-    case ENCODING_TYPE_UINT16:
-    case ENCODING_TYPE_UINT32:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsInt64Encoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
-    case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
-    case ENCODING_TYPE_INT8:
-    case ENCODING_TYPE_INT16:
-    case ENCODING_TYPE_INT32:
-    case ENCODING_TYPE_INT64:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsUInt64Encoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
-    case ENCODING_TYPE_UINT8:
-    case ENCODING_TYPE_UINT16:
-    case ENCODING_TYPE_UINT32:
-    case ENCODING_TYPE_UINT64:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsFixmapEncoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_FIXMAP_MIN ... ENCODING_TYPE_FIXMAP_MAX:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsFixarrayEncoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_FIXARRAY_MIN ... ENCODING_TYPE_FIXARRAY_MAX:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsFixstrEncoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_FIXSTR_MIN ... ENCODING_TYPE_FIXSTR_MAX:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsFixextEncoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_FIXEXT1:
-    case ENCODING_TYPE_FIXEXT2:
-    case ENCODING_TYPE_FIXEXT4:
-    case ENCODING_TYPE_FIXEXT8:
-    case ENCODING_TYPE_FIXEXT16:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsFloat32Encoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_FLOAT32:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsFloat64Encoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_FLOAT32:
-    case ENCODING_TYPE_FLOAT64:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr bool IsBoolEncoding(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_FALSE:
-    case ENCODING_TYPE_TRUE:
-      return true;
-    default:
-      return false;
-  }
-}
-
-inline constexpr std::size_t GetFixstrSize(EncodingType encoding) {
-  return encoding & ENCODING_TYPE_FIXSTR_MASK;
-}
-
-inline constexpr std::size_t GetFixarraySize(EncodingType encoding) {
-  return encoding & ENCODING_TYPE_FIXARRAY_MASK;
-}
-
-inline constexpr std::size_t GetFixmapSize(EncodingType encoding) {
-  return encoding & ENCODING_TYPE_FIXMAP_MASK;
-}
-
-inline constexpr std::size_t GetFixextSize(EncodingType encoding) {
-  switch (encoding) {
-    case ENCODING_TYPE_FIXEXT1:
-      return 1;
-    case ENCODING_TYPE_FIXEXT2:
-      return 2;
-    case ENCODING_TYPE_FIXEXT4:
-      return 4;
-    case ENCODING_TYPE_FIXEXT8:
-      return 8;
-    case ENCODING_TYPE_FIXEXT16:
-      return 16;
-    default:
-      return 0;  // Invalid fixext size.
-  }
-}
-
-// Gets the size of the encoding in bytes, not including external payload data.
-inline constexpr std::size_t GetEncodingSize(EncodingType encoding) {
-  switch (encoding) {
-    // Encoding is fully contained within the type value.
-    case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
-    case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
-    case ENCODING_TYPE_FIXMAP_MIN ... ENCODING_TYPE_FIXMAP_MAX:
-    case ENCODING_TYPE_FIXARRAY_MIN ... ENCODING_TYPE_FIXARRAY_MAX:
-    case ENCODING_TYPE_FIXSTR_MIN ... ENCODING_TYPE_FIXSTR_MAX:
-    case ENCODING_TYPE_NIL:
-    case ENCODING_TYPE_RESERVED:
-    case ENCODING_TYPE_FALSE:
-    case ENCODING_TYPE_TRUE:
-      return 1;
-
-    // Encoding type followed by one-byte size or immediate value.
-    case ENCODING_TYPE_BIN8:
-    case ENCODING_TYPE_EXT8:
-    case ENCODING_TYPE_UINT8:
-    case ENCODING_TYPE_INT8:
-    case ENCODING_TYPE_STR8:
-    // Encoding type followed by one-byte extension type.
-    case ENCODING_TYPE_FIXEXT1:
-    case ENCODING_TYPE_FIXEXT2:
-    case ENCODING_TYPE_FIXEXT4:
-    case ENCODING_TYPE_FIXEXT8:
-    case ENCODING_TYPE_FIXEXT16:
-      return 2;
-
-    // Encoding type followed by two-byte size or immediate value.
-    case ENCODING_TYPE_BIN16:
-    case ENCODING_TYPE_EXT16:
-    case ENCODING_TYPE_UINT16:
-    case ENCODING_TYPE_INT16:
-    case ENCODING_TYPE_STR16:
-    case ENCODING_TYPE_ARRAY16:
-    case ENCODING_TYPE_MAP16:
-      return 3;
-
-    // Encoding type followed by four-byte size or immediate value.
-    case ENCODING_TYPE_BIN32:
-    case ENCODING_TYPE_EXT32:
-    case ENCODING_TYPE_FLOAT32:
-    case ENCODING_TYPE_UINT32:
-    case ENCODING_TYPE_INT32:
-    case ENCODING_TYPE_STR32:
-    case ENCODING_TYPE_ARRAY32:
-    case ENCODING_TYPE_MAP32:
-      return 5;
-
-    // Encoding type followed by eight-byte immediate value.
-    case ENCODING_TYPE_FLOAT64:
-    case ENCODING_TYPE_UINT64:
-    case ENCODING_TYPE_INT64:
-      return 9;
-
-    default:
-      return 0;
-  }
-}
-
-// Encoding for standard types. Each supported data type has an associated
-// encoding or set of encodings. These functions determine the MessagePack
-// encoding based on the data type, value, and size of their arguments.
-
-inline constexpr EncodingType EncodeArrayType(std::size_t size) {
-  if (size < (1U << 4))
-    return ENCODING_TYPE_FIXARRAY | (size & ENCODING_TYPE_FIXARRAY_MASK);
-  else if (size < (1U << 16))
-    return ENCODING_TYPE_ARRAY16;
-  else
-    return ENCODING_TYPE_ARRAY32;
-}
-
-inline constexpr EncodingType EncodeMapType(std::size_t size) {
-  if (size < (1U << 4))
-    return ENCODING_TYPE_FIXMAP | (size & ENCODING_TYPE_FIXMAP_MASK);
-  else if (size < (1U << 16))
-    return ENCODING_TYPE_MAP16;
-  else
-    return ENCODING_TYPE_MAP32;
-}
-
-inline constexpr EncodingType EncodeStringType(std::size_t size) {
-  if (size < (1U << 5))
-    return ENCODING_TYPE_FIXSTR | (size & ENCODING_TYPE_FIXSTR_MASK);
-  else if (size < (1U << 8))
-    return ENCODING_TYPE_STR8;
-  else if (size < (1U << 16))
-    return ENCODING_TYPE_STR16;
-  else
-    return ENCODING_TYPE_STR32;
-}
-
-inline constexpr EncodingType EncodeBinType(std::size_t size) {
-  if (size < (1U << 8))
-    return ENCODING_TYPE_BIN8;
-  else if (size < (1U << 16))
-    return ENCODING_TYPE_BIN16;
-  else
-    return ENCODING_TYPE_BIN32;
-}
-
-inline EncodingType EncodeType(const EmptyVariant& /*empty*/) {
-  return ENCODING_TYPE_NIL;
-}
-
-// Variant is encoded as a single-element map, with the type index as the key.
-template <typename... Types>
-inline EncodingType EncodeType(const Variant<Types...>& /*variant*/) {
-  return EncodeMapType(1);
-}
-
-template <typename T>
-inline constexpr EncodingType EncodeType(const StringWrapper<T>& value) {
-  return EncodeStringType(value.length());
-}
-
-inline constexpr EncodingType EncodeType(const std::string& value) {
-  return EncodeStringType(value.length());
-}
-
-template <typename T, std::size_t Size>
-inline constexpr EncodingType EncodeType(const std::array<T, Size>& /*value*/) {
-  return EncodeArrayType(Size);
-}
-
-template <typename T>
-inline constexpr EncodingType EncodeType(const ArrayWrapper<T>& value) {
-  return EncodeArrayType(value.size());
-}
-
-template <typename T, typename Allocator>
-inline constexpr EncodingType EncodeType(
-    const std::vector<T, Allocator>& value) {
-  return EncodeArrayType(value.size());
-}
-
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline constexpr EncodingType EncodeType(
-    const std::map<Key, T, Compare, Allocator>& value) {
-  return EncodeMapType(value.size());
-}
-
-template <typename Key, typename T, typename Hash, typename KeyEqual,
-          typename Allocator>
-inline constexpr EncodingType EncodeType(
-    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& value) {
-  return EncodeMapType(value.size());
-}
-
-template <typename T>
-inline constexpr EncodingType EncodeType(const BufferWrapper<T>& value) {
-  // BIN size is in bytes.
-  return EncodeBinType(value.size() *
-                       sizeof(typename BufferWrapper<T>::value_type));
-}
-
-template <typename T, typename U>
-inline constexpr EncodingType EncodeType(const std::pair<T, U>& /*value*/) {
-  return EncodeArrayType(2);
-}
-
-template <typename... T>
-inline constexpr EncodingType EncodeType(const std::tuple<T...>& /*value*/) {
-  return EncodeArrayType(sizeof...(T));
-}
-
-// FileHandle is encoded as a FIXEXT2 with a type code for "FileDescriptor"
-// and a signed 16-bit index into the pushed fd array. Empty file descriptor
-// have an array index of -1.
-template <FileHandleMode Mode>
-inline constexpr EncodingType EncodeType(const FileHandle<Mode>& /*fd*/) {
-  return ENCODING_TYPE_FIXEXT2;
-}
-
-// ChannelHandle is encoded as a FIXEXT4 with a type of
-// ENCODING_EXT_TYPE_CHANNEL_HANDLE and a signed 32-bit value representing
-// a client channel in a remote process. Empty handle has a value of -1.
-template <ChannelHandleMode Mode>
-inline constexpr EncodingType EncodeType(
-    const ChannelHandle<Mode>& /*handle*/) {
-  return ENCODING_TYPE_FIXEXT4;
-}
-
-inline constexpr EncodingType EncodeType(const bool& value) {
-  return value ? ENCODING_TYPE_TRUE : ENCODING_TYPE_FALSE;
-}
-
-// Type 'char' is a little bit special in that it is distinct from 'signed char'
-// and 'unsigned char'. Treating it as an unsigned 8-bit value is safe for
-// encoding purposes and nicely handles 7-bit ASCII encodings as FIXINT.
-inline constexpr EncodingType EncodeType(const char& value) {
-  if (value < static_cast<char>(1 << 7))
-    return value;
-  else
-    return ENCODING_TYPE_UINT8;
-}
-
-inline constexpr EncodingType EncodeType(const uint8_t& value) {
-  if (value < (1U << 7))
-    return value;
-  else
-    return ENCODING_TYPE_UINT8;
-}
-inline constexpr EncodingType EncodeType(const int8_t& value) {
-  if (value >= -32)
-    return value;
-  else
-    return ENCODING_TYPE_INT8;
-}
-inline constexpr EncodingType EncodeType(const uint16_t& value) {
-  if (value < (1U << 7))
-    return static_cast<EncodingType>(value);
-  else if (value < (1U << 8))
-    return ENCODING_TYPE_UINT8;
-  else
-    return ENCODING_TYPE_UINT16;
-}
-inline constexpr EncodingType EncodeType(const int16_t& value) {
-  if (value >= -32 && value <= 127)
-    return static_cast<EncodingType>(value);
-  else if (value >= -128 && value <= 127)
-    return ENCODING_TYPE_INT8;
-  else
-    return ENCODING_TYPE_INT16;
-}
-inline constexpr EncodingType EncodeType(const uint32_t& value) {
-  if (value < (1U << 7))
-    return static_cast<EncodingType>(value);
-  else if (value < (1U << 8))
-    return ENCODING_TYPE_UINT8;
-  else if (value < (1U << 16))
-    return ENCODING_TYPE_UINT16;
-  else
-    return ENCODING_TYPE_UINT32;
-}
-inline constexpr EncodingType EncodeType(const int32_t& value) {
-  if (value >= -32 && value <= 127)
-    return static_cast<EncodingType>(value);
-  else if (value >= -128 && value <= 127)
-    return ENCODING_TYPE_INT8;
-  else if (value >= -32768 && value <= 32767)
-    return ENCODING_TYPE_INT16;
-  else
-    return ENCODING_TYPE_INT32;
-}
-inline constexpr EncodingType EncodeType(const uint64_t& value) {
-  if (value < (1ULL << 7))
-    return static_cast<EncodingType>(value);
-  else if (value < (1ULL << 8))
-    return ENCODING_TYPE_UINT8;
-  else if (value < (1ULL << 16))
-    return ENCODING_TYPE_UINT16;
-  else if (value < (1ULL << 32))
-    return ENCODING_TYPE_UINT32;
-  else
-    return ENCODING_TYPE_UINT64;
-}
-inline constexpr EncodingType EncodeType(const int64_t& value) {
-  if (value >= -32 && value <= 127)
-    return static_cast<EncodingType>(value);
-  else if (value >= -128 && value <= 127)  // Effectively [-128, -32).
-    return ENCODING_TYPE_INT8;
-  else if (value >= -32768 && value <= 32767)
-    return ENCODING_TYPE_INT16;
-  else if (value >= -2147483648 && value <= 2147483647)
-    return ENCODING_TYPE_INT32;
-  else
-    return ENCODING_TYPE_INT64;
-}
-
-inline constexpr EncodingType EncodeType(const float& /*value*/) {
-  return ENCODING_TYPE_FLOAT32;
-}
-
-inline constexpr EncodingType EncodeType(const double& /*value*/) {
-  return ENCODING_TYPE_FLOAT64;
-}
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_ENCODING_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/enumeration.h b/libs/vr/libpdx/private/pdx/rpc/enumeration.h
deleted file mode 100644
index 7a35d31..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/enumeration.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef ANDROID_PDX_RPC_ENUMERATION_H_
-#define ANDROID_PDX_RPC_ENUMERATION_H_
-
-#include <pdx/rpc/sequence.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility for manipulating lists of types. Provides operations to lookup an
-// element by type or index.
-
-namespace detail {
-
-// Helper type that captures type and index for each element of a type
-// enumeration.
-template <std::size_t I, typename T>
-struct IndexedElement {
-  using Type = T;
-  static constexpr std::size_t Index = I;
-};
-
-// Helper type that captures an IndexSequence and corresponding list of types.
-template <typename Is, typename... Ts>
-struct ElementIndexer;
-
-// Partial specialization that generates an instantiation of IndexElement<I, T>
-// for each element of a type enumeration using inheritance. Once a type
-// enumeration is instantiated this way the compiler is able to deduce either I
-// or T from the other using the method below.
-template <std::size_t... Is, typename... Ts>
-struct ElementIndexer<IndexSequence<Is...>, Ts...> : IndexedElement<Is, Ts>... {
-};
-
-// Helper function that causes the compiler to deduce an IndexedElement<I, T>
-// given T.
-template <typename T, std::size_t I>
-static IndexedElement<I, T> SelectElementByType(IndexedElement<I, T>);
-
-// Helper function that causes the compiler to deduce an IndexedElement<I, T>
-// given I.
-template <std::size_t I, typename T>
-static IndexedElement<I, T> SelectElementByIndex(IndexedElement<I, T>);
-
-}  // namespace detail
-
-// Deduces the IndexedElement<I, T> given T and a type sequence Ts. This may be
-// used to determine the index of T within Ts at compile time.
-template <typename T, typename... Ts>
-using ElementForType = decltype(detail::SelectElementByType<T>(
-    detail::ElementIndexer<typename IndexSequenceFor<Ts...>::type, Ts...>{}));
-
-// Deduces the IndexedElement<I, T> given I and a type sequence Ts. This may be
-// used to determine the type of the element at index I within Ts at compile
-// time. Tuple operations may also be used to accomplish the same task, however
-// this implementation is provided here for symmetry.
-template <std::size_t I, typename... Ts>
-using ElementForIndex = decltype(detail::SelectElementByIndex<I>(
-    detail::ElementIndexer<typename IndexSequenceFor<Ts...>::type, Ts...>{}));
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_ENUMERATION_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/find_replace.h b/libs/vr/libpdx/private/pdx/rpc/find_replace.h
deleted file mode 100644
index b4b086b..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/find_replace.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef ANDROID_PDX_RPC_FIND_REPLACE_H_
-#define ANDROID_PDX_RPC_FIND_REPLACE_H_
-
-#include <type_traits>
-
-#include <pdx/rpc/copy_cv_reference.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility class to capture types to find and replace.
-template <typename Find, typename Replace>
-struct FindReplace;
-
-template <typename T, typename U>
-using IsSameBaseType = typename std::is_same<typename std::decay<T>::type,
-                                             typename std::decay<U>::type>;
-
-// Replaces the type Subject with type Replace if type Subject is the same type
-// as type Find, excluding cv-reference qualifiers in the match.
-template <typename Find, typename Replace, typename Subject>
-using ReplaceType =
-    typename std::conditional<IsSameBaseType<Find, Subject>::value,
-                              CopyCVReferenceType<Subject, Replace>,
-                              Subject>::type;
-
-// Determines whether the type Find (excluding cv-reference qualifiers) is in
-// the given parameter pack.
-template <typename Find, typename... Types>
-struct ContainsType : std::true_type {};
-
-template <typename Find, typename First, typename... Rest>
-struct ContainsType<Find, First, Rest...>
-    : std::conditional<IsSameBaseType<Find, First>::value, std::true_type,
-                       ContainsType<Find, Rest...>>::type {};
-
-template <typename Find>
-struct ContainsType<Find> : std::false_type {};
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  //  ANDROID_PDX_RPC_FIND_REPLACE_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/function_traits.h b/libs/vr/libpdx/private/pdx/rpc/function_traits.h
deleted file mode 100644
index 7641b0a..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/function_traits.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef ANDROID_PDX_RPC_FUNCTION_TRAITS_H_
-#define ANDROID_PDX_RPC_FUNCTION_TRAITS_H_
-
-#include <type_traits>
-
-#include <pdx/rpc/type_operators.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility type to capture return and argument types of a function signature.
-// Examples:
-//     typedef SignatureType<int(int)> SignatureType;
-//     using SignatureType = SignatureType<int(int)>;
-template <typename T>
-using SignatureType = T;
-
-// Utility class to extract return and argument types from function types.
-// Provides nested types for return value, arguments, and full signature. Also
-// provides accessor types for individual arguments, argument-arity, and type
-// substitution.
-template <typename T>
-struct FunctionTraits;
-
-template <typename Return_, typename... Args_>
-struct FunctionTraits<Return_(Args_...)> {
-  using Return = Return_;
-  using Args = std::tuple<Args_...>;
-  using Signature = SignatureType<Return_(Args_...)>;
-
-  enum : std::size_t { Arity = sizeof...(Args_) };
-
-  template <std::size_t Index>
-  using Arg = typename std::tuple_element<Index, Args>::type;
-
-  template <typename... Params>
-  using RewriteArgs =
-      SignatureType<Return_(ConditionalRewrite<Args_, Params>...)>;
-
-  template <typename ReturnType, typename... Params>
-  using RewriteSignature =
-      SignatureType<ConditionalRewrite<Return_, ReturnType>(
-          ConditionalRewrite<Args_, Params>...)>;
-
-  template <template <typename> class Wrapper, typename ReturnType,
-            typename... Params>
-  using RewriteSignatureWrapReturn =
-      SignatureType<Wrapper<ConditionalRewrite<Return_, ReturnType>>(
-          ConditionalRewrite<Args_, Params>...)>;
-
-  template <typename ReturnType>
-  using RewriteReturn =
-      SignatureType<ConditionalRewrite<Return_, ReturnType>(Args_...)>;
-};
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  //  ANDROID_PDX_RPC_FUNCTION_TRAITS_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/macros.h b/libs/vr/libpdx/private/pdx/rpc/macros.h
deleted file mode 100644
index 99325b5..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/macros.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef ANDROID_PDX_RPC_MACROS_H_
-#define ANDROID_PDX_RPC_MACROS_H_
-
-// Macros to apply other macros over all elements in a list.
-//
-// For example, for a macro A(x) and B(x, y):
-// - FOR_EACH(A, 1, 2, 3) -> A(1) A(2) A(3).
-// - FOR_EACH_BINARY(B, z, 1, 2, 3) -> B(z, 1) B(z, 2) B(z, 3)
-// - FOR_EACH_LIST(A, 1, 2, 3) -> A(1), B(2), C(3)
-// - FOR_EACH_BINARY_LIST(B, z, 1, 2, 3) -> B(z, 1), B(z, 2), B(z, 3)
-//
-// Empty lists are supported and will produce no output.
-
-// Recursive expansion macros.
-#define _PDX_EXPAND0(...) __VA_ARGS__
-#define _PDX_EXPAND1(...) _PDX_EXPAND0(_PDX_EXPAND0(_PDX_EXPAND0(__VA_ARGS__)))
-#define _PDX_EXPAND2(...) _PDX_EXPAND1(_PDX_EXPAND1(_PDX_EXPAND1(__VA_ARGS__)))
-#define _PDX_EXPAND3(...) _PDX_EXPAND2(_PDX_EXPAND2(_PDX_EXPAND2(__VA_ARGS__)))
-#define _PDX_EXPAND4(...) _PDX_EXPAND3(_PDX_EXPAND3(_PDX_EXPAND3(__VA_ARGS__)))
-#define _PDX_EXPAND(...) _PDX_EXPAND4(_PDX_EXPAND4(_PDX_EXPAND4(__VA_ARGS__)))
-
-// Required to workaround a bug in the VC++ preprocessor.
-#define _PDX_INDIRECT_EXPAND(macro, args) macro args
-
-// Defines a step separation for macro expansion.
-#define _PDX_SEPARATOR
-
-// Clears any remaining contents wrapped in parentheses.
-#define _PDX_CLEAR(...)
-
-// Introduces a first stub argument and _PDX_CLEAR as second argument.
-#define _PDX_CLEAR_IF_LAST() _, _PDX_CLEAR
-
-// Returns the first argument of a list.
-#define _PDX_FIRST_ARG(first, ...) first
-
-// Returns the second argument of a list.
-#define _PDX_SECOND_ARG(_, second, ...) second
-
-// Expands the arguments and introduces a separator.
-#define _PDX_EXPAND_NEXT_FUNC(_, next_func, ...)        \
-  _PDX_INDIRECT_EXPAND(_PDX_SECOND_ARG, (_, next_func)) \
-  _PDX_SEPARATOR
-
-// Returns next_func if the next element is not (), or _PDX_CLEAR
-// otherwise.
-//
-// _PDX_CLEAR_IF_LAST inserts an extra first stub argument if peek is ().
-#define _PDX_NEXT_FUNC(next_element, next_func) \
-  _PDX_EXPAND_NEXT_FUNC(_PDX_CLEAR_IF_LAST next_element, next_func)
-
-// Macros for the unary version of PDX_FOR_EACH.
-
-// Applies the unary macro. Duplicated for macro recursive expansion.
-#define _PDX_APPLY_1(macro, head, next, ...) \
-  macro(head) _PDX_NEXT_FUNC(next, _PDX_APPLY_2)(macro, next, __VA_ARGS__)
-
-// Applies the unary macro. Duplicated for macro recursive expansion.
-#define _PDX_APPLY_2(macro, head, next, ...) \
-  macro(head) _PDX_NEXT_FUNC(next, _PDX_APPLY_1)(macro, next, __VA_ARGS__)
-
-// Stops expansion if __VA_ARGS__ is empty, calling _PDX_APPLY_1
-// otherwise.
-#define _PDX_HANDLE_EMPTY_ARGS(macro, ...)                    \
-  _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_1) \
-  (macro, __VA_ARGS__, ())
-
-// Applies a unary macro over all the elements in a list.
-#define PDX_FOR_EACH(macro, ...) \
-  _PDX_EXPAND(_PDX_HANDLE_EMPTY_ARGS(macro, __VA_ARGS__))
-
-// Applies the unary macro at the end of a list. Duplicated for macro recursive
-// expansion.
-#define _PDX_APPLY_LIST_1(macro, head, next, ...) \
-  , macro(head)                                   \
-        _PDX_NEXT_FUNC(next, _PDX_APPLY_LIST_2)(macro, next, __VA_ARGS__)
-
-// Applies the unary macro at the end of a list. Duplicated for macro recursive
-// expansion.
-#define _PDX_APPLY_LIST_2(macro, head, next, ...) \
-  , macro(head)                                   \
-        _PDX_NEXT_FUNC(next, _PDX_APPLY_LIST_1)(macro, next, __VA_ARGS__)
-
-// Applies the unary macro at the start of a list.
-#define _PDX_APPLY_LIST_0(macro, head, next, ...) \
-  macro(head) _PDX_NEXT_FUNC(next, _PDX_APPLY_LIST_1)(macro, next, __VA_ARGS__)
-
-// Stops expansion if __VA_ARGS__ is empty, calling _PDX_APPLY_LIST_0
-// otherwise.
-#define _PDX_HANDLE_EMPTY_LIST(macro, ...)                         \
-  _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_LIST_0) \
-  (macro, __VA_ARGS__, ())
-
-// Applies a unary macro over all the elements in a list.
-#define PDX_FOR_EACH_LIST(macro, ...) \
-  _PDX_EXPAND(_PDX_HANDLE_EMPTY_LIST(macro, __VA_ARGS__))
-
-// Macros for the binary version of PDX_FOR_EACH.
-
-// Applies the binary macro. Duplicated for macro recursive expansion.
-#define _PDX_APPLY_BINARY_1(macro, arg, head, next, ...) \
-  macro(arg, head)                                       \
-      _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_2)(macro, arg, next, __VA_ARGS__)
-
-// Applies the binary macro. Duplicated for macro recursive expansion.
-#define _PDX_APPLY_BINARY_2(macro, arg, head, next, ...) \
-  macro(arg, head)                                       \
-      _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_1)(macro, arg, next, __VA_ARGS__)
-
-// Version of _PDX_HANDLE_EMPTY_ARGS that takes 1 fixed argument for a
-// binary macro.
-#define _PDX_HANDLE_EMPTY_ARGS_BINARY(macro, arg, ...)               \
-  _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_BINARY_1) \
-  (macro, arg, __VA_ARGS__, ())
-
-// Applies a binary macro over all the elements in a list and a given argument.
-#define PDX_FOR_EACH_BINARY(macro, arg, ...) \
-  _PDX_EXPAND(_PDX_HANDLE_EMPTY_ARGS_BINARY(macro, arg, __VA_ARGS__))
-
-// Applies the binary macro at the end of a list. Duplicated for macro recursive
-// expansion.
-#define _PDX_APPLY_BINARY_LIST_1(macro, arg, head, next, ...)        \
-  , macro(arg, head) _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_LIST_2)( \
-        macro, arg, next, __VA_ARGS__)
-
-// Applies the binary macro at the end of a list. Duplicated for macro recursive
-// expansion.
-#define _PDX_APPLY_BINARY_LIST_2(macro, arg, head, next, ...)        \
-  , macro(arg, head) _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_LIST_1)( \
-        macro, arg, next, __VA_ARGS__)
-
-// Applies the binary macro at the start of a list. Duplicated for macro
-// recursive expansion.
-#define _PDX_APPLY_BINARY_LIST_0(macro, arg, head, next, ...)      \
-  macro(arg, head) _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_LIST_1)( \
-      macro, arg, next, __VA_ARGS__)
-
-// Version of _PDX_HANDLE_EMPTY_LIST that takes 1 fixed argument for a
-// binary macro.
-#define _PDX_HANDLE_EMPTY_LIST_BINARY(macro, arg, ...)                    \
-  _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_BINARY_LIST_0) \
-  (macro, arg, __VA_ARGS__, ())
-
-// Applies a binary macro over all the elements in a list and a given argument.
-#define PDX_FOR_EACH_BINARY_LIST(macro, arg, ...) \
-  _PDX_EXPAND(_PDX_HANDLE_EMPTY_LIST_BINARY(macro, arg, __VA_ARGS__))
-
-#endif  // ANDROID_PDX_RPC_MACROS_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/message_buffer.h b/libs/vr/libpdx/private/pdx/rpc/message_buffer.h
deleted file mode 100644
index ba4e86e..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/message_buffer.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef ANDROID_PDX_RPC_MESSAGE_BUFFER_H_
-#define ANDROID_PDX_RPC_MESSAGE_BUFFER_H_
-
-#include <pdx/rpc/thread_local_buffer.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility type for thread-local buffers, providing suitable defaults for most
-// situations. Independent thread-local buffers may be created by using
-// different types for Slot -- ThreadLocalSlot, ThreadLocalTypedSlot and
-// ThreadLocalIndexedSlot provide utilities for building these types.
-template <typename Slot, std::size_t Capacity = 4096, typename T = std::uint8_t,
-          typename Allocator = DefaultInitializationAllocator<T>>
-using MessageBuffer = ThreadLocalBuffer<T, Allocator, Capacity, Slot>;
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_MESSAGE_BUFFER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/payload.h b/libs/vr/libpdx/private/pdx/rpc/payload.h
deleted file mode 100644
index d2df14f..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/payload.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef ANDROID_PDX_RPC_PAYLOAD_H_
-#define ANDROID_PDX_RPC_PAYLOAD_H_
-
-#include <iterator>
-
-#include <pdx/client.h>
-#include <pdx/rpc/message_buffer.h>
-#include <pdx/service.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Implements the payload interface, required by Serialize/Deserialize, on top
-// of a thread-local MessageBuffer.
-template <typename Slot>
-class MessagePayload {
- public:
-  using BufferType = typename MessageBuffer<Slot>::BufferType;
-  using ValueType = typename MessageBuffer<Slot>::ValueType;
-
-  // Constructs a MessagePayload with an empty TLS buffer.
-  MessagePayload()
-      : buffer_(MessageBuffer<Slot>::GetEmptyBuffer()),
-        cursor_(buffer_.begin()),
-        const_cursor_(buffer_.cbegin()) {}
-
-  // Returns a reference to the cursor iterator to be used during serialization
-  // into the underlying MessageBuffer.
-  typename BufferType::iterator& Cursor() { return cursor_; }
-
-  // Returns a reference to the const cursor iterator at the beginning of the
-  // underlying MessageBuffer.
-  typename BufferType::const_iterator& ConstCursor() { return const_cursor_; }
-
-  // Returns a const iterator marking the end of the underlying MessageBuffer.
-  typename BufferType::const_iterator ConstEnd() { return buffer_.cend(); }
-
-  // Resizes the underlying MessageBuffer and sets the cursor to the beginning.
-  void Resize(std::size_t size) {
-    buffer_.resize(size);
-    cursor_ = buffer_.begin();
-    const_cursor_ = buffer_.cbegin();
-  }
-
-  // Resets the read cursor so that data can be read from the buffer again.
-  void Rewind() { const_cursor_ = buffer_.cbegin(); }
-
-  // Adds |size| bytes to the size of the underlying MessageBuffer and positions
-  // the cursor at the beginning of the extended region.
-  void Extend(std::size_t size) {
-    const std::size_t offset = buffer_.size();
-    buffer_.resize(offset + size);
-    cursor_ = buffer_.begin() + offset;
-    const_cursor_ = buffer_.cbegin() + offset;
-  }
-
-  // Clears the underlying MessageBuffer and sets the cursor to the beginning.
-  void Clear() {
-    buffer_.clear();
-    cursor_ = buffer_.begin();
-    const_cursor_ = buffer_.cbegin();
-  }
-
-  ValueType* Data() { return buffer_.data(); }
-  const ValueType* Data() const { return buffer_.data(); }
-  std::size_t Size() const { return buffer_.size(); }
-  std::size_t Capacity() const { return buffer_.capacity(); }
-
- private:
-  BufferType& buffer_;
-  typename BufferType::iterator cursor_;
-  typename BufferType::const_iterator const_cursor_;
-
-  MessagePayload(const MessagePayload<Slot>&) = delete;
-  void operator=(const MessagePayload<Slot>&) = delete;
-};
-
-// Implements the payload interface for service-side RPCs. Handles translating
-// between remote and local handle spaces automatically.
-template <typename Slot>
-class ServicePayload : public MessagePayload<Slot>,
-                       public MessageWriter,
-                       public MessageReader {
- public:
-  explicit ServicePayload(Message& message) : message_(message) {}
-
-  // MessageWriter
-  void* GetNextWriteBufferSection(size_t size) override {
-    this->Extend(size);
-    return &*this->Cursor();
-  }
-
-  OutputResourceMapper* GetOutputResourceMapper() override { return &message_; }
-
-  // MessageReader
-  BufferSection GetNextReadBufferSection() override {
-    return {&*this->ConstCursor(), &*this->ConstEnd()};
-  }
-
-  void ConsumeReadBufferSectionData(const void* new_start) override {
-    std::advance(this->ConstCursor(),
-                 PointerDistance(new_start, &*this->ConstCursor()));
-  }
-
-  InputResourceMapper* GetInputResourceMapper() override { return &message_; }
-
- private:
-  Message& message_;
-};
-
-// Implements the payload interface for client-side RPCs. Handles gathering file
-// handles to be sent over IPC automatically.
-template <typename Slot>
-class ClientPayload : public MessagePayload<Slot>,
-                      public MessageWriter,
-                      public MessageReader {
- public:
-  using ContainerType =
-      MessageBuffer<ThreadLocalTypeSlot<ClientPayload<Slot>>, 1024u, int>;
-  using BufferType = typename ContainerType::BufferType;
-
-  explicit ClientPayload(Transaction& transaction)
-      : transaction_{transaction} {}
-
-  // MessageWriter
-  void* GetNextWriteBufferSection(size_t size) override {
-    this->Extend(size);
-    return &*this->Cursor();
-  }
-
-  OutputResourceMapper* GetOutputResourceMapper() override {
-    return &transaction_;
-  }
-
-  // MessageReader
-  BufferSection GetNextReadBufferSection() override {
-    return {&*this->ConstCursor(), &*this->ConstEnd()};
-  }
-
-  void ConsumeReadBufferSectionData(const void* new_start) override {
-    std::advance(this->ConstCursor(),
-                 PointerDistance(new_start, &*this->ConstCursor()));
-  }
-
-  InputResourceMapper* GetInputResourceMapper() override {
-    return &transaction_;
-  }
-
- private:
-  Transaction& transaction_;
-};
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_PAYLOAD_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h
deleted file mode 100644
index 88868fe..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef ANDROID_PDX_RPC_POINTER_WRAPPER_H_
-#define ANDROID_PDX_RPC_POINTER_WRAPPER_H_
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Wrapper class for pointers to any serializable type. This class is used by
-// serialization/deserialization to handle pointers to objects that are to be
-// serialized or deserialized.
-template <typename T>
-class PointerWrapper {
- public:
-  using BaseType = T;
-
-  explicit PointerWrapper(T* pointer) : pointer_(pointer) {}
-  PointerWrapper(const PointerWrapper&) = default;
-  PointerWrapper(PointerWrapper&&) noexcept = default;
-  PointerWrapper& operator=(const PointerWrapper&) = default;
-  PointerWrapper& operator=(PointerWrapper&&) noexcept = default;
-
-  T& Dereference() { return *pointer_; }
-  const T& Dereference() const { return *pointer_; }
-
- private:
-  T* pointer_;
-};
-
-template <typename T>
-PointerWrapper<T> WrapPointer(T* pointer) {
-  return PointerWrapper<T>(pointer);
-}
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_POINTER_WRAPPER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/remote_method.h b/libs/vr/libpdx/private/pdx/rpc/remote_method.h
deleted file mode 100644
index 505c63b..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/remote_method.h
+++ /dev/null
@@ -1,473 +0,0 @@
-#ifndef ANDROID_PDX_RPC_REMOTE_METHOD_H_
-#define ANDROID_PDX_RPC_REMOTE_METHOD_H_
-
-#include <tuple>
-#include <type_traits>
-
-#include <pdx/client.h>
-#include <pdx/rpc/argument_encoder.h>
-#include <pdx/rpc/message_buffer.h>
-#include <pdx/rpc/payload.h>
-#include <pdx/rpc/remote_method_type.h>
-#include <pdx/service.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-#ifdef __clang__
-// Stand-in type to avoid Clang compiler bug. Clang currently has a bug where
-// performing parameter pack expansion for arguments with empty packs causes a
-// compiler crash. Provide a substitute void type and specializations/overloads
-// of CheckArgumentTypes and DispatchRemoteMethod to work around this problem.
-struct Void {};
-
-// Evaluates to true if the method type is <any>(Void), false otherwise.
-template <typename RemoteMethodType>
-using IsVoidMethod = typename std::integral_constant<
-    bool, RemoteMethodType::Traits::Arity == 1 &&
-              std::is_same<typename RemoteMethodType::Traits::template Arg<0>,
-                           Void>::value>;
-
-// Utility to determine if a method is of type <any>(Void).
-template <typename RemoteMethodType>
-using EnableIfVoidMethod =
-    typename std::enable_if<IsVoidMethod<RemoteMethodType>::value>::type;
-
-// Utility to determine if a method is not of type <any>(Void).
-template <typename RemoteMethodType>
-using EnableIfNotVoidMethod =
-    typename std::enable_if<!IsVoidMethod<RemoteMethodType>::value>::type;
-
-#else
-// GCC works fine with void argument types, always enable the regular
-// implementation of DispatchRemoteMethod.
-using Void = void;
-template <typename RemoteMethodType>
-using EnableIfVoidMethod = void;
-template <typename RemoteMethodType>
-using EnableIfNotVoidMethod = void;
-#endif
-
-// Helper type trait to specialize InvokeRemoteMethods for return types that
-// can be obtained directly from Transaction::Send<T>() without deserializing
-// reply payload.
-template <typename T>
-struct IsDirectReturn : std::false_type {};
-
-template <>
-struct IsDirectReturn<void> : std::true_type {};
-
-template <>
-struct IsDirectReturn<int> : std::true_type {};
-
-template <>
-struct IsDirectReturn<LocalHandle> : std::true_type {};
-
-template <>
-struct IsDirectReturn<LocalChannelHandle> : std::true_type {};
-
-template <typename Return, typename Type = void>
-using EnableIfDirectReturn =
-    typename std::enable_if<IsDirectReturn<Return>::value, Type>::type;
-
-template <typename Return, typename Type = void>
-using EnableIfNotDirectReturn =
-    typename std::enable_if<!IsDirectReturn<Return>::value, Type>::type;
-
-// Utility class to invoke a method with arguments packed in a tuple.
-template <typename Class, typename T>
-class UnpackArguments;
-
-// Utility class to invoke a method with arguments packed in a tuple.
-template <typename Class, typename Return, typename... Args>
-class UnpackArguments<Class, Return(Args...)> {
- public:
-  using ArgsTupleType = std::tuple<typename std::decay<Args>::type...>;
-  using MethodType = Return (Class::*)(Message&, Args...);
-
-  UnpackArguments(Class& instance, MethodType method, Message& message,
-                  ArgsTupleType& parameters)
-      : instance_(instance),
-        method_(method),
-        message_(message),
-        parameters_(parameters) {}
-
-  // Invokes method_ on intance_ with the packed arguments from parameters_.
-  Return Invoke() {
-    constexpr auto Arity = sizeof...(Args);
-    return static_cast<Return>(InvokeHelper(MakeIndexSequence<Arity>{}));
-  }
-
- private:
-  Class& instance_;
-  MethodType method_;
-  Message& message_;
-  ArgsTupleType& parameters_;
-
-  template <std::size_t... Index>
-  Return InvokeHelper(IndexSequence<Index...>) {
-    return static_cast<Return>((instance_.*method_)(
-        message_,
-        std::get<Index>(std::forward<ArgsTupleType>(parameters_))...));
-  }
-
-  UnpackArguments(const UnpackArguments&) = delete;
-  void operator=(const UnpackArguments&) = delete;
-};
-
-// Returns an error code from a remote method to the client. May be called
-// either during dispatch of the remote method handler or at a later time if the
-// message is moved for delayed response.
-inline void RemoteMethodError(Message& message, int error_code) {
-  const auto status = message.ReplyError(error_code);
-  ALOGE_IF(!status, "RemoteMethodError: Failed to reply to message: %s",
-           status.GetErrorMessage().c_str());
-}
-
-// Returns a value from a remote method to the client. The usual method to
-// return a value during dispatch of a remote method is to simply use a return
-// statement in the handler. If the message is moved however, these methods may
-// be used to return a value at a later time, outside of initial dispatch.
-
-// Overload for direct return types.
-template <typename RemoteMethodType, typename Return>
-EnableIfDirectReturn<typename RemoteMethodType::Return> RemoteMethodReturn(
-    Message& message, const Return& return_value) {
-  const auto status = message.Reply(return_value);
-  ALOGE_IF(!status, "RemoteMethodReturn: Failed to reply to message: %s",
-           status.GetErrorMessage().c_str());
-}
-
-// Overload for non-direct return types.
-template <typename RemoteMethodType, typename Return>
-EnableIfNotDirectReturn<typename RemoteMethodType::Return> RemoteMethodReturn(
-    Message& message, const Return& return_value) {
-  using Signature = typename RemoteMethodType::template RewriteReturn<Return>;
-  rpc::ServicePayload<ReplyBuffer> payload(message);
-  MakeArgumentEncoder<Signature>(&payload).EncodeReturn(return_value);
-
-  auto ret = message.WriteAll(payload.Data(), payload.Size());
-  auto status = message.Reply(ret);
-  ALOGE_IF(!status, "RemoteMethodReturn: Failed to reply to message: %s",
-           status.GetErrorMessage().c_str());
-}
-
-// Overload for Status<void> return types.
-template <typename RemoteMethodType>
-void RemoteMethodReturn(Message& message, const Status<void>& return_value) {
-  if (return_value)
-    RemoteMethodReturn<RemoteMethodType>(message, 0);
-  else
-    RemoteMethodError(message, return_value.error());
-}
-
-// Overload for Status<T> return types. This overload forwards the underlying
-// value or error within the Status<T>.
-template <typename RemoteMethodType, typename Return>
-void RemoteMethodReturn(Message& message, const Status<Return>& return_value) {
-  if (return_value)
-    RemoteMethodReturn<RemoteMethodType, Return>(message, return_value.get());
-  else
-    RemoteMethodError(message, return_value.error());
-}
-
-// Dispatches a method by deserializing arguments from the given Message, with
-// compile-time interface check. Overload for void return types.
-template <typename RemoteMethodType, typename Class, typename... Args,
-          typename = EnableIfNotVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance,
-                          void (Class::*method)(Message&, Args...),
-                          Message& message,
-                          std::size_t max_capacity = InitialBufferCapacity) {
-  using Signature = typename RemoteMethodType::template RewriteArgs<Args...>;
-  rpc::ServicePayload<ReceiveBuffer> payload(message);
-  payload.Resize(max_capacity);
-
-  Status<size_t> read_status = message.Read(payload.Data(), payload.Size());
-  if (!read_status) {
-    RemoteMethodError(message, read_status.error());
-    return;
-  }
-
-  payload.Resize(read_status.get());
-
-  ErrorType error;
-  auto decoder = MakeArgumentDecoder<Signature>(&payload);
-  auto arguments = decoder.DecodeArguments(&error);
-  if (error) {
-    RemoteMethodError(message, EIO);
-    return;
-  }
-
-  UnpackArguments<Class, Signature>(instance, method, message, arguments)
-      .Invoke();
-  // Return to the caller unless the message was moved.
-  if (message)
-    RemoteMethodReturn<RemoteMethodType>(message, 0);
-}
-
-// Dispatches a method by deserializing arguments from the given Message, with
-// compile-time interface signature check. Overload for generic return types.
-template <typename RemoteMethodType, typename Class, typename Return,
-          typename... Args, typename = EnableIfNotVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance,
-                          Return (Class::*method)(Message&, Args...),
-                          Message& message,
-                          std::size_t max_capacity = InitialBufferCapacity) {
-  using Signature =
-      typename RemoteMethodType::template RewriteSignature<Return, Args...>;
-  rpc::ServicePayload<ReceiveBuffer> payload(message);
-  payload.Resize(max_capacity);
-
-  Status<size_t> read_status = message.Read(payload.Data(), payload.Size());
-  if (!read_status) {
-    RemoteMethodError(message, read_status.error());
-    return;
-  }
-
-  payload.Resize(read_status.get());
-
-  ErrorType error;
-  auto decoder = MakeArgumentDecoder<Signature>(&payload);
-  auto arguments = decoder.DecodeArguments(&error);
-  if (error) {
-    RemoteMethodError(message, EIO);
-    return;
-  }
-
-  auto return_value =
-      UnpackArguments<Class, Signature>(instance, method, message, arguments)
-          .Invoke();
-  // Return the value to the caller unless the message was moved.
-  if (message)
-    RemoteMethodReturn<RemoteMethodType>(message, return_value);
-}
-
-// Dispatches a method by deserializing arguments from the given Message, with
-// compile-time interface signature check. Overload for Status<T> return types.
-template <typename RemoteMethodType, typename Class, typename Return,
-          typename... Args, typename = EnableIfNotVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance,
-                          Status<Return> (Class::*method)(Message&, Args...),
-                          Message& message,
-                          std::size_t max_capacity = InitialBufferCapacity) {
-  using Signature =
-      typename RemoteMethodType::template RewriteSignature<Return, Args...>;
-  using InvokeSignature =
-      typename RemoteMethodType::template RewriteSignatureWrapReturn<
-          Status, Return, Args...>;
-  rpc::ServicePayload<ReceiveBuffer> payload(message);
-  payload.Resize(max_capacity);
-
-  Status<size_t> read_status = message.Read(payload.Data(), payload.Size());
-  if (!read_status) {
-    RemoteMethodError(message, read_status.error());
-    return;
-  }
-
-  payload.Resize(read_status.get());
-
-  ErrorType error;
-  auto decoder = MakeArgumentDecoder<Signature>(&payload);
-  auto arguments = decoder.DecodeArguments(&error);
-  if (error) {
-    RemoteMethodError(message, EIO);
-    return;
-  }
-
-  auto return_value = UnpackArguments<Class, InvokeSignature>(
-                          instance, method, message, arguments)
-                          .Invoke();
-  // Return the value to the caller unless the message was moved.
-  if (message)
-    RemoteMethodReturn<RemoteMethodType>(message, return_value);
-}
-
-#ifdef __clang__
-// Overloads to handle Void argument type without exploding clang.
-
-// Overload for void return type.
-template <typename RemoteMethodType, typename Class,
-          typename = EnableIfVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance, void (Class::*method)(Message&),
-                          Message& message) {
-  (instance.*method)(message);
-  // Return to the caller unless the message was moved.
-  if (message)
-    RemoteMethodReturn<RemoteMethodType>(message, 0);
-}
-
-// Overload for generic return type.
-template <typename RemoteMethodType, typename Class, typename Return,
-          typename = EnableIfVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance, Return (Class::*method)(Message&),
-                          Message& message) {
-  auto return_value = (instance.*method)(message);
-  // Return the value to the caller unless the message was moved.
-  if (message)
-    RemoteMethodReturn<RemoteMethodType>(message, return_value);
-}
-
-// Overload for Status<T> return type.
-template <typename RemoteMethodType, typename Class, typename Return,
-          typename = EnableIfVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance,
-                          Status<Return> (Class::*method)(Message&),
-                          Message& message) {
-  auto return_value = (instance.*method)(message);
-  // Return the value to the caller unless the message was moved.
-  if (message)
-    RemoteMethodReturn<RemoteMethodType>(message, return_value);
-}
-#endif
-
-}  // namespace rpc
-
-// Definitions for template methods declared in pdx/client.h.
-
-template <int Opcode, typename T>
-struct CheckArgumentTypes;
-
-template <int Opcode, typename Return, typename... Args>
-struct CheckArgumentTypes<Opcode, Return(Args...)> {
-  template <typename R>
-  static typename rpc::EnableIfDirectReturn<R, Status<R>> Invoke(Client& client,
-                                                                 Args... args) {
-    Transaction trans{client};
-    rpc::ClientPayload<rpc::SendBuffer> payload{trans};
-    rpc::MakeArgumentEncoder<Return(Args...)>(&payload).EncodeArguments(
-        std::forward<Args>(args)...);
-    return trans.Send<R>(Opcode, payload.Data(), payload.Size(), nullptr, 0);
-  }
-
-  template <typename R>
-  static typename rpc::EnableIfNotDirectReturn<R, Status<R>> Invoke(
-      Client& client, Args... args) {
-    Transaction trans{client};
-
-    rpc::ClientPayload<rpc::SendBuffer> send_payload{trans};
-    rpc::MakeArgumentEncoder<Return(Args...)>(&send_payload)
-        .EncodeArguments(std::forward<Args>(args)...);
-
-    rpc::ClientPayload<rpc::ReplyBuffer> reply_payload{trans};
-    reply_payload.Resize(reply_payload.Capacity());
-
-    Status<R> result;
-    auto status =
-        trans.Send<void>(Opcode, send_payload.Data(), send_payload.Size(),
-                         reply_payload.Data(), reply_payload.Size());
-    if (!status) {
-      result.SetError(status.error());
-    } else {
-      R return_value;
-      rpc::ErrorType error =
-          rpc::MakeArgumentDecoder<Return(Args...)>(&reply_payload)
-              .DecodeReturn(&return_value);
-
-      switch (error.error_code()) {
-        case rpc::ErrorCode::NO_ERROR:
-          result.SetValue(std::move(return_value));
-          break;
-
-        // This error is returned when ArrayWrapper/StringWrapper is too
-        // small to receive the payload.
-        case rpc::ErrorCode::INSUFFICIENT_DESTINATION_SIZE:
-          result.SetError(ENOBUFS);
-          break;
-
-        default:
-          result.SetError(EIO);
-          break;
-      }
-    }
-    return result;
-  }
-
-  template <typename R>
-  static typename rpc::EnableIfDirectReturn<R, Status<void>> InvokeInPlace(
-      Client& client, R* return_value, Args... args) {
-    Transaction trans{client};
-
-    rpc::ClientPayload<rpc::SendBuffer> send_payload{trans};
-    rpc::MakeArgumentEncoder<Return(Args...)>(&send_payload)
-        .EncodeArguments(std::forward<Args>(args)...);
-
-    Status<void> result;
-    auto status = trans.Send<R>(Opcode, send_payload.Data(),
-                                send_payload.Size(), nullptr, 0);
-    if (status) {
-      *return_value = status.take();
-      result.SetValue();
-    } else {
-      result.SetError(status.error());
-    }
-    return result;
-  }
-
-  template <typename R>
-  static typename rpc::EnableIfNotDirectReturn<R, Status<void>> InvokeInPlace(
-      Client& client, R* return_value, Args... args) {
-    Transaction trans{client};
-
-    rpc::ClientPayload<rpc::SendBuffer> send_payload{trans};
-    rpc::MakeArgumentEncoder<Return(Args...)>(&send_payload)
-        .EncodeArguments(std::forward<Args>(args)...);
-
-    rpc::ClientPayload<rpc::ReplyBuffer> reply_payload{trans};
-    reply_payload.Resize(reply_payload.Capacity());
-
-    auto result =
-        trans.Send<void>(Opcode, send_payload.Data(), send_payload.Size(),
-                         reply_payload.Data(), reply_payload.Size());
-    if (result) {
-      rpc::ErrorType error =
-          rpc::MakeArgumentDecoder<Return(Args...)>(&reply_payload)
-              .DecodeReturn(return_value);
-
-      switch (error.error_code()) {
-        case rpc::ErrorCode::NO_ERROR:
-          result.SetValue();
-          break;
-
-        // This error is returned when ArrayWrapper/StringWrapper is too
-        // small to receive the payload.
-        case rpc::ErrorCode::INSUFFICIENT_DESTINATION_SIZE:
-          result.SetError(ENOBUFS);
-          break;
-
-        default:
-          result.SetError(EIO);
-          break;
-      }
-    }
-    return result;
-  }
-};
-
-// Invokes the remote method with opcode and signature described by
-// |RemoteMethodType|.
-template <typename RemoteMethodType, typename... Args>
-Status<typename RemoteMethodType::Return> Client::InvokeRemoteMethod(
-    Args&&... args) {
-  return CheckArgumentTypes<
-      RemoteMethodType::Opcode,
-      typename RemoteMethodType::template RewriteArgs<Args...>>::
-      template Invoke<typename RemoteMethodType::Return>(
-          *this, std::forward<Args>(args)...);
-}
-
-template <typename RemoteMethodType, typename Return, typename... Args>
-Status<void> Client::InvokeRemoteMethodInPlace(Return* return_value,
-                                               Args&&... args) {
-  return CheckArgumentTypes<
-      RemoteMethodType::Opcode,
-      typename RemoteMethodType::template RewriteSignature<Return, Args...>>::
-      template InvokeInPlace(*this, return_value, std::forward<Args>(args)...);
-}
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_REMOTE_METHOD_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/remote_method_type.h b/libs/vr/libpdx/private/pdx/rpc/remote_method_type.h
deleted file mode 100644
index cf9a189..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/remote_method_type.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef ANDROID_PDX_RPC_REMOTE_METHOD_TYPE_H_
-#define ANDROID_PDX_RPC_REMOTE_METHOD_TYPE_H_
-
-#include <cstddef>
-#include <tuple>
-#include <type_traits>
-
-#include <pdx/rpc/enumeration.h>
-#include <pdx/rpc/function_traits.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility class binding a remote method opcode to its function signature.
-// Describes the interface between RPC clients and services for a single method.
-template <int Opcode_, typename Signature_>
-struct RemoteMethodType {
-  typedef FunctionTraits<Signature_> Traits;
-
-  enum : int { Opcode = Opcode_ };
-
-  typedef typename Traits::Signature Signature;
-  typedef typename Traits::Return Return;
-  typedef typename Traits::Args Args;
-
-  template <typename... Params>
-  using RewriteArgs = typename Traits::template RewriteArgs<Params...>;
-
-  template <typename ReturnType, typename... Params>
-  using RewriteSignature =
-      typename Traits::template RewriteSignature<ReturnType, Params...>;
-
-  template <template <typename> class Wrapper, typename ReturnType,
-            typename... Params>
-  using RewriteSignatureWrapReturn =
-      typename Traits::template RewriteSignatureWrapReturn<Wrapper, ReturnType,
-                                                           Params...>;
-
-  template <typename ReturnType>
-  using RewriteReturn = typename Traits::template RewriteReturn<ReturnType>;
-};
-
-// Utility class representing a set of related RemoteMethodTypes. Describes the
-// interface between RPC clients and services as a set of methods.
-template <typename... MethodTypes>
-struct RemoteAPI {
-  typedef std::tuple<MethodTypes...> Methods;
-  enum : std::size_t { Length = sizeof...(MethodTypes) };
-
-  template <std::size_t Index>
-  using Method = typename std::tuple_element<Index, Methods>::type;
-
-  template <typename MethodType>
-  static constexpr std::size_t MethodIndex() {
-    return ElementForType<MethodType, MethodTypes...>::Index;
-  }
-};
-
-// Macro to simplify defining remote method signatures. Remote method signatures
-// are specified by defining a RemoteMethodType for each remote method.
-#define PDX_REMOTE_METHOD(name, opcode, ... /*signature*/) \
-  using name = ::android::pdx::rpc::RemoteMethodType<opcode, __VA_ARGS__>
-
-// Macro to simplify defining a set of remote method signatures.
-#define PDX_REMOTE_API(name, ... /*methods*/) \
-  using name = ::android::pdx::rpc::RemoteAPI<__VA_ARGS__>
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_REMOTE_METHOD_TYPE_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/sequence.h b/libs/vr/libpdx/private/pdx/rpc/sequence.h
deleted file mode 100644
index 5fd898a..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/sequence.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef ANDROID_PDX_RPC_SEQUENCE_H_
-#define ANDROID_PDX_RPC_SEQUENCE_H_
-
-#include <cstdint>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Provides a C++11 implementation of C++14 index_sequence and
-// make_index_sequence for compatibility with common compilers. This
-// implementation may be conditionally replaced with compiler-provided versions
-// when C++14 support is available.
-
-// Utility to capture a sequence of unsigned indices.
-template <std::size_t... I>
-struct IndexSequence {
-  using type = IndexSequence;
-  using value_type = std::size_t;
-  static constexpr std::size_t size() { return sizeof...(I); }
-};
-
-namespace detail {
-
-// Helper class to merge and renumber sequence parts in log N instantiations.
-template <typename S1, typename S2>
-struct MergeSequencesAndRenumber;
-
-template <std::size_t... I1, std::size_t... I2>
-struct MergeSequencesAndRenumber<IndexSequence<I1...>, IndexSequence<I2...>>
-    : IndexSequence<I1..., (sizeof...(I1) + I2)...> {};
-
-}  // namespace detail
-
-// Utility to build an IndexSequence with N indices.
-template <std::size_t N>
-struct MakeIndexSequence : detail::MergeSequencesAndRenumber<
-                               typename MakeIndexSequence<N / 2>::type,
-                               typename MakeIndexSequence<N - N / 2>::type> {};
-
-// Identity sequences.
-template <>
-struct MakeIndexSequence<0> : IndexSequence<> {};
-template <>
-struct MakeIndexSequence<1> : IndexSequence<0> {};
-
-// Utility to build an IndexSequence with indices for each element of a
-// parameter pack.
-template <typename... T>
-using IndexSequenceFor = MakeIndexSequence<sizeof...(T)>;
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_SEQUENCE_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/serializable.h b/libs/vr/libpdx/private/pdx/rpc/serializable.h
deleted file mode 100644
index 04a4352..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/serializable.h
+++ /dev/null
@@ -1,150 +0,0 @@
-#ifndef ANDROID_PDX_RPC_SERIALIZABLE_H_
-#define ANDROID_PDX_RPC_SERIALIZABLE_H_
-
-#include <cstddef>
-#include <string>
-#include <tuple>
-
-#include <pdx/message_reader.h>
-#include <pdx/message_writer.h>
-
-#include "macros.h"
-#include "serialization.h"
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// This file provides utilities to define serializable types for communication
-// between clients and services. Supporting efficient, typed communication
-// protocols is the primary goal, NOT providing a general-purpose solution for
-// all your C++ serialization needs. Features that are not aligned to the goals
-// are not supported, such as static/const member serialization and serializable
-// types with virtual methods (requiring a virtual destructor).
-
-// Captures the type and value of a pointer to member. Pointer to members are
-// essentially compile-time constant offsets that can be stored in the type
-// system without adding to the size of the structures they describe. This
-// library uses this property to implement a limited form of reflection for
-// serialization/deserialization functions.
-template <typename T, T>
-struct MemberPointer;
-
-template <typename Type, typename Class, Type Class::*Pointer>
-struct MemberPointer<Type Class::*, Pointer> {
-  // Type of the member pointer this type represents.
-  using PointerType = Type Class::*;
-
-  // Resolves a pointer to member with the given instance, yielding a
-  // reference to the member in that instance.
-  static Type& Resolve(Class& instance) { return (instance.*Pointer); }
-  static const Type& Resolve(const Class& instance) {
-    return (instance.*Pointer);
-  }
-};
-
-// Describes a set of members to be serialized/deserialized by this library. The
-// parameter pack MemberPointers takes a list of MemberPointer types that
-// describe each member to participate in serialization/deserialization.
-template <typename T, typename... MemberPointers>
-struct SerializableMembersType {
-  using Type = T;
-
-  // The number of member pointers described by this type.
-  enum : std::size_t { MemberCount = sizeof...(MemberPointers) };
-
-  // The member pointers described by this type.
-  using Members = std::tuple<MemberPointers...>;
-
-  // Accessor for individual member pointer types.
-  template <std::size_t Index>
-  using At = typename std::tuple_element<Index, Members>::type;
-};
-
-// Classes must do the following to correctly define a serializable type:
-//     1. Define a type called "SerializableMembers" as a template instantiation
-//        of SerializableMembersType, describing the members of the class to
-//        participate in serialization (presumably all of them). Use the macro
-//        PDX_SERIALIZABLE_MEMBERS(...) below to aid the correct type
-//        definition. This type should be private to prevent leaking member
-//        access information.
-//     2. Make SerializableTraits and HasSerilizableMembers types a friend of
-//        the class. The macro PDX_SERIALIZABLE_MEMEBRS(...) takes care of
-//        this automatically.
-//     3. Define a public default constructor, if necessary. Deserialization
-//        requires instances to be default-constructible.
-//
-// Example usage:
-//     class MySerializableType : public AnotherBaseType {
-//      public:
-//       MySerializableType();
-//       ...
-//      private:
-//       int a;
-//       string b;
-//       PDX_SERIALIZABLE_MEMBERS(MySerializableType, a, b);
-//     };
-//
-// Note that const and static member serialization is not supported.
-
-template <typename T>
-class SerializableTraits {
- public:
-  // Gets the serialized size of type T.
-  static std::size_t GetSerializedSize(const T& value) {
-    return GetEncodingSize(EncodeArrayType(SerializableMembers::MemberCount)) +
-           GetMembersSize<SerializableMembers>(value);
-  }
-
-  // Serializes type T.
-  static void SerializeObject(const T& value, MessageWriter* writer,
-                              void*& buffer) {
-    SerializeArrayEncoding(EncodeArrayType(SerializableMembers::MemberCount),
-                           SerializableMembers::MemberCount, buffer);
-    SerializeMembers<SerializableMembers>(value, writer, buffer);
-  }
-
-  // Deserializes type T.
-  static ErrorType DeserializeObject(T* value, MessageReader* reader,
-                                     const void*& start, const void* end) {
-    EncodingType encoding;
-    std::size_t size;
-
-    if (const auto error =
-            DeserializeArrayType(&encoding, &size, reader, start, end)) {
-      return error;
-    } else if (size != SerializableMembers::MemberCount) {
-      return ErrorCode::UNEXPECTED_TYPE_SIZE;
-    } else {
-      return DeserializeMembers<SerializableMembers>(value, reader, start, end);
-    }
-  }
-
- private:
-  using SerializableMembers = typename T::SerializableMembers;
-};
-
-// Utility macro to define a MemberPointer type for a member name.
-#define PDX_MEMBER_POINTER(type, member) \
-  ::android::pdx::rpc::MemberPointer<decltype(&type::member), &type::member>
-
-// Defines a list of MemberPointer types given a list of member names.
-#define PDX_MEMBERS(type, ... /*members*/) \
-  PDX_FOR_EACH_BINARY_LIST(PDX_MEMBER_POINTER, type, __VA_ARGS__)
-
-// Defines the serializable members of a type given a list of member names and
-// befriends SerializableTraits and HasSerializableMembers for the class. This
-// macro handles requirements #1 and #2 above.
-#define PDX_SERIALIZABLE_MEMBERS(type, ... /*members*/)                     \
-  template <typename T>                                                     \
-  friend class ::android::pdx::rpc::SerializableTraits;                     \
-  template <typename, typename>                                             \
-  friend struct ::android::pdx::rpc::HasSerializableMembers;                \
-  using SerializableMembers = ::android::pdx::rpc::SerializableMembersType< \
-      type, PDX_MEMBERS(type, __VA_ARGS__)>
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_SERIALIZABLE_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/serialization.h b/libs/vr/libpdx/private/pdx/rpc/serialization.h
deleted file mode 100644
index 914ea66..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/serialization.h
+++ /dev/null
@@ -1,2000 +0,0 @@
-#ifndef ANDROID_PDX_RPC_SERIALIZATION_H_
-#define ANDROID_PDX_RPC_SERIALIZATION_H_
-
-#include <cstdint>
-#include <cstring>
-#include <iterator>
-#include <map>
-#include <numeric>
-#include <sstream>
-#include <string>
-#include <tuple>
-#include <type_traits>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/message_reader.h>
-#include <pdx/message_writer.h>
-#include <pdx/trace.h>
-#include <pdx/utility.h>
-
-#include "array_wrapper.h"
-#include "default_initialization_allocator.h"
-#include "encoding.h"
-#include "pointer_wrapper.h"
-#include "string_wrapper.h"
-#include "variant.h"
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Automatic serialization/deserialization library based on MessagePack
-// (http://msgpack.org). This library provides top level Serialize() and
-// Deserialize() functions to encode/decode a variety of data types.
-//
-// The following data types are supported:
-//   * Standard signed integer types: int8_t, int16_t, int32_t, and int64_t.
-//   * Regular signed integer types equivalent to the standard types:
-//     signed char, short, int, long, and long long.
-//   * Standard unsigned integer types: uint8_t, uint16_t, uint32_t, and
-//     uint64_t.
-//   * Regular unsigned integer types equivalent to the standard types:
-//     unsigned char, unsigned short, unsigned int, unsigned long,
-//     and unsigned long long.
-//   * char without signed/unsigned qualifiers.
-//   * bool.
-//   * std::vector with value type of any supported type, including nesting.
-//   * std::string.
-//   * std::tuple with elements of any supported type, including nesting.
-//   * std::pair with elements of any supported type, including nesting.
-//   * std::map with keys and values of any supported type, including nesting.
-//   * std::unordered_map with keys and values of any supported type, including
-//     nesting.
-//   * std::array with values of any supported type, including nesting.
-//   * ArrayWrapper of any supported basic type.
-//   * BufferWrapper of any POD type.
-//   * StringWrapper of any supported char type.
-//   * User types with correctly defined SerializableMembers member type.
-//
-// Planned support for:
-//   * std::basic_string with all supported char types.
-
-// Counting template for managing template recursion.
-template <std::size_t N>
-struct Index {};
-
-// Forward declaration of traits type to access types with a SerializedMembers
-// member type.
-template <typename T>
-class SerializableTraits;
-
-template <typename T, typename... MemberPointers>
-struct SerializableMembersType;
-
-// Utility to deduce the template type from a derived type.
-template <template <typename...> class TT, typename... Ts>
-std::true_type DeduceTemplateType(const TT<Ts...>*);
-template <template <typename...> class TT>
-std::false_type DeduceTemplateType(...);
-
-// Utility determining whether template type TT<...> is a base of type T.
-template <template <typename...> class TT, typename T>
-using IsTemplateBaseOf = decltype(DeduceTemplateType<TT>(std::declval<T*>()));
-
-// Utility type for SFINAE in HasHasSerializableMembers.
-template <typename... Ts>
-using TrySerializableMembersType = void;
-
-// Determines whether type T has a member type named SerializableMembers of
-// template type SerializableMembersType.
-template <typename, typename = void>
-struct HasSerializableMembers : std::false_type {};
-template <typename T>
-struct HasSerializableMembers<
-    T, TrySerializableMembersType<typename T::SerializableMembers>>
-    : std::integral_constant<
-          bool, IsTemplateBaseOf<SerializableMembersType,
-                                 typename T::SerializableMembers>::value> {};
-
-// Utility to simplify overload enable expressions for types with correctly
-// defined SerializableMembers.
-template <typename T>
-using EnableIfHasSerializableMembers =
-    typename std::enable_if<HasSerializableMembers<T>::value>::type;
-
-// Utility to simplify overload enable expressions for enum types.
-template <typename T, typename ReturnType = void>
-using EnableIfEnum =
-    typename std::enable_if<std::is_enum<T>::value, ReturnType>::type;
-
-///////////////////////////////////////////////////////////////////////////////
-// Error Reporting //
-///////////////////////////////////////////////////////////////////////////////
-
-// Error codes returned by the deserialization code.
-enum class ErrorCode {
-  NO_ERROR = 0,
-  UNEXPECTED_ENCODING,
-  UNEXPECTED_TYPE_SIZE,
-  INSUFFICIENT_BUFFER,
-  INSUFFICIENT_DESTINATION_SIZE,
-  GET_FILE_DESCRIPTOR_FAILED,
-  GET_CHANNEL_HANDLE_FAILED,
-  INVALID_VARIANT_ELEMENT,
-};
-
-// Type for errors returned by the deserialization code.
-class ErrorType {
- public:
-  ErrorType() : error_code_(ErrorCode::NO_ERROR) {}
-
-  // ErrorType constructor for generic error codes. Explicitly not explicit,
-  // implicit conversion from ErrorCode to ErrorType is desirable behavior.
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  ErrorType(ErrorCode error_code) : error_code_(error_code) {}
-
-  // ErrorType constructor for encoding type errors.
-  ErrorType(ErrorCode error_code, EncodingClass encoding_class,
-            EncodingType encoding_type)
-      : error_code_(error_code) {
-    unexpected_encoding_.encoding_class = encoding_class;
-    unexpected_encoding_.encoding_type = encoding_type;
-  }
-
-  // Evaluates to true if the ErrorType represents an error.
-  explicit operator bool() const { return error_code_ != ErrorCode::NO_ERROR; }
-
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  operator ErrorCode() const { return error_code_; }
-  ErrorCode error_code() const { return error_code_; }
-
-  // Accessors for extra info about unexpected encoding errors.
-  EncodingClass encoding_class() const {
-    return unexpected_encoding_.encoding_class;
-  }
-  EncodingType encoding_type() const {
-    return unexpected_encoding_.encoding_type;
-  }
-
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  operator std::string() const {
-    std::ostringstream stream;
-
-    switch (error_code_) {
-      case ErrorCode::NO_ERROR:
-        return "NO_ERROR";
-      case ErrorCode::UNEXPECTED_ENCODING:
-        stream << "UNEXPECTED_ENCODING: " << static_cast<int>(encoding_class())
-               << ", " << static_cast<int>(encoding_type());
-        return stream.str();
-      case ErrorCode::UNEXPECTED_TYPE_SIZE:
-        return "UNEXPECTED_TYPE_SIZE";
-      case ErrorCode::INSUFFICIENT_BUFFER:
-        return "INSUFFICIENT_BUFFER";
-      case ErrorCode::INSUFFICIENT_DESTINATION_SIZE:
-        return "INSUFFICIENT_DESTINATION_SIZE";
-      default:
-        return "[Unknown Error]";
-    }
-  }
-
- private:
-  ErrorCode error_code_;
-
-  // Union of extra information for different error code types.
-  union {
-    // UNEXPECTED_ENCODING.
-    struct {
-      EncodingClass encoding_class;
-      EncodingType encoding_type;
-    } unexpected_encoding_;
-  };
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Object Size //
-///////////////////////////////////////////////////////////////////////////////
-
-inline constexpr std::size_t GetSerializedSize(const bool& b) {
-  return GetEncodingSize(EncodeType(b));
-}
-
-// Overloads of GetSerializedSize() for standard integer types.
-inline constexpr std::size_t GetSerializedSize(const char& c) {
-  return GetEncodingSize(EncodeType(c));
-}
-inline constexpr std::size_t GetSerializedSize(const std::uint8_t& i) {
-  return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::int8_t& i) {
-  return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::uint16_t& i) {
-  return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::int16_t& i) {
-  return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::uint32_t& i) {
-  return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::int32_t& i) {
-  return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::uint64_t& i) {
-  return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::int64_t& i) {
-  return GetEncodingSize(EncodeType(i));
-}
-
-inline constexpr std::size_t GetSerializedSize(const float& f) {
-  return GetEncodingSize(EncodeType(f));
-}
-inline constexpr std::size_t GetSerializedSize(const double& d) {
-  return GetEncodingSize(EncodeType(d));
-}
-
-// Overload for enum types.
-template <typename T>
-inline EnableIfEnum<T, std::size_t> GetSerializedSize(T v) {
-  return GetSerializedSize(static_cast<std::underlying_type_t<T>>(v));
-}
-
-// Forward declaration for nested definitions.
-inline std::size_t GetSerializedSize(const EmptyVariant&);
-template <typename... Types>
-inline std::size_t GetSerializedSize(const Variant<Types...>&);
-template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
-inline constexpr std::size_t GetSerializedSize(const T&);
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const PointerWrapper<T>&);
-inline constexpr std::size_t GetSerializedSize(const std::string&);
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const StringWrapper<T>&);
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const BufferWrapper<T>&);
-template <FileHandleMode Mode>
-inline constexpr std::size_t GetSerializedSize(const FileHandle<Mode>&);
-template <ChannelHandleMode Mode>
-inline constexpr std::size_t GetSerializedSize(const ChannelHandle<Mode>&);
-template <typename T, typename Allocator>
-inline std::size_t GetSerializedSize(const std::vector<T, Allocator>& v);
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline std::size_t GetSerializedSize(
-    const std::map<Key, T, Compare, Allocator>& m);
-template <typename Key, typename T, typename Hash, typename KeyEqual,
-          typename Allocator>
-inline std::size_t GetSerializedSize(
-    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>&);
-template <typename T>
-inline std::size_t GetSerializedSize(const ArrayWrapper<T>&);
-template <typename T, std::size_t Size>
-inline std::size_t GetSerializedSize(const std::array<T, Size>& v);
-template <typename T, typename U>
-inline std::size_t GetSerializedSize(const std::pair<T, U>& p);
-template <typename... T>
-inline std::size_t GetSerializedSize(const std::tuple<T...>& tuple);
-
-// Overload for empty variant type.
-inline std::size_t GetSerializedSize(const EmptyVariant& empty) {
-  return GetEncodingSize(EncodeType(empty));
-}
-
-// Overload for Variant types.
-template <typename... Types>
-inline std::size_t GetSerializedSize(const Variant<Types...>& variant) {
-  return GetEncodingSize(EncodeType(variant)) +
-         GetSerializedSize(variant.index()) +
-         variant.Visit(
-             [](const auto& value) { return GetSerializedSize(value); });
-}
-
-// Overload for structs/classes with SerializableMembers defined.
-template <typename T, typename Enabled>
-inline constexpr std::size_t GetSerializedSize(const T& value) {
-  return SerializableTraits<T>::GetSerializedSize(value);
-}
-
-// Overload for PointerWrapper.
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const PointerWrapper<T>& p) {
-  return GetSerializedSize(p.Dereference());
-}
-
-// Overload for std::string.
-inline constexpr std::size_t GetSerializedSize(const std::string& s) {
-  return GetEncodingSize(EncodeType(s)) +
-         s.length() * sizeof(std::string::value_type);
-}
-
-// Overload for StringWrapper.
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const StringWrapper<T>& s) {
-  return GetEncodingSize(EncodeType(s)) +
-         s.length() * sizeof(typename StringWrapper<T>::value_type);
-}
-
-// Overload for BufferWrapper types.
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const BufferWrapper<T>& b) {
-  return GetEncodingSize(EncodeType(b)) +
-         b.size() * sizeof(typename BufferWrapper<T>::value_type);
-}
-
-// Overload for FileHandle. FileHandle is encoded as a FIXEXT2, with a type code
-// of "FileHandle" and a signed 16-bit offset into the pushed fd array. Empty
-// FileHandles are encoded with an array index of -1.
-template <FileHandleMode Mode>
-inline constexpr std::size_t GetSerializedSize(const FileHandle<Mode>& fd) {
-  return GetEncodingSize(EncodeType(fd)) + sizeof(std::int16_t);
-}
-
-// Overload for ChannelHandle. ChannelHandle is encoded as a FIXEXT4, with a
-// type code of "ChannelHandle" and a signed 32-bit offset into the pushed
-// channel array. Empty ChannelHandles are encoded with an array index of -1.
-template <ChannelHandleMode Mode>
-inline constexpr std::size_t GetSerializedSize(
-    const ChannelHandle<Mode>& channel_handle) {
-  return GetEncodingSize(EncodeType(channel_handle)) + sizeof(std::int32_t);
-}
-
-// Overload for standard vector types.
-template <typename T, typename Allocator>
-inline std::size_t GetSerializedSize(const std::vector<T, Allocator>& v) {
-  return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
-                         [](const std::size_t& sum, const T& object) {
-                           return sum + GetSerializedSize(object);
-                         });
-}
-
-// Overload for standard map types.
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline std::size_t GetSerializedSize(
-    const std::map<Key, T, Compare, Allocator>& v) {
-  return std::accumulate(
-      v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
-      [](const std::size_t& sum, const std::pair<Key, T>& object) {
-        return sum + GetSerializedSize(object.first) +
-               GetSerializedSize(object.second);
-      });
-}
-
-// Overload for standard unordered_map types.
-template <typename Key, typename T, typename Hash, typename KeyEqual,
-          typename Allocator>
-inline std::size_t GetSerializedSize(
-    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& v) {
-  return std::accumulate(
-      v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
-      [](const std::size_t& sum, const std::pair<Key, T>& object) {
-        return sum + GetSerializedSize(object.first) +
-               GetSerializedSize(object.second);
-      });
-}
-
-// Overload for ArrayWrapper types.
-template <typename T>
-inline std::size_t GetSerializedSize(const ArrayWrapper<T>& v) {
-  return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
-                         [](const std::size_t& sum, const T& object) {
-                           return sum + GetSerializedSize(object);
-                         });
-}
-
-// Overload for std::array types.
-template <typename T, std::size_t Size>
-inline std::size_t GetSerializedSize(const std::array<T, Size>& v) {
-  return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
-                         [](const std::size_t& sum, const T& object) {
-                           return sum + GetSerializedSize(object);
-                         });
-}
-
-// Overload for std::pair.
-template <typename T, typename U>
-inline std::size_t GetSerializedSize(const std::pair<T, U>& p) {
-  return GetEncodingSize(EncodeType(p)) + GetSerializedSize(p.first) +
-         GetSerializedSize(p.second);
-}
-
-// Stops template recursion when the last tuple element is reached.
-template <typename... T>
-inline std::size_t GetTupleSize(const std::tuple<T...>&, Index<0>) {
-  return 0;
-}
-
-// Gets the size of each element in a tuple recursively.
-template <typename... T, std::size_t index>
-inline std::size_t GetTupleSize(const std::tuple<T...>& tuple, Index<index>) {
-  return GetTupleSize(tuple, Index<index - 1>()) +
-         GetSerializedSize(std::get<index - 1>(tuple));
-}
-
-// Overload for tuple types. Gets the size of the tuple, recursing
-// through the elements.
-template <typename... T>
-inline std::size_t GetSerializedSize(const std::tuple<T...>& tuple) {
-  return GetEncodingSize(EncodeType(tuple)) +
-         GetTupleSize(tuple, Index<sizeof...(T)>());
-}
-
-// Stops template recursion when the last member of a Serializable
-// type is reached.
-template <typename Members, typename T>
-inline std::size_t GetMemberSize(const T&, Index<0>) {
-  return 0;
-}
-
-// Gets the size of each member of a Serializable type recursively.
-template <typename Members, typename T, std::size_t index>
-inline std::size_t GetMemberSize(const T& object, Index<index>) {
-  return GetMemberSize<Members>(object, Index<index - 1>()) +
-         GetSerializedSize(Members::template At<index - 1>::Resolve(object));
-}
-
-// Gets the size of a type using the given SerializableMembersType
-// type.
-template <typename Members, typename T>
-inline std::size_t GetMembersSize(const T& object) {
-  return GetMemberSize<Members>(object, Index<Members::MemberCount>());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Object Serialization //
-///////////////////////////////////////////////////////////////////////////////
-
-//
-// SerializeRaw() converts a primitive array or type into a raw byte string.
-// These functions are named differently from SerializeObject() expressly to
-// avoid catch-all specialization of that template, which can be difficult to
-// detect otherwise.
-//
-
-inline void WriteRawData(void*& dest, const void* src, size_t size) {
-  memcpy(dest, src, size);
-  dest = static_cast<uint8_t*>(dest) + size;
-}
-
-// Serializes a primitive array into a raw byte string.
-template <typename T,
-          typename = typename std::enable_if<std::is_pod<T>::value>::type>
-inline void SerializeRaw(const T& value, void*& buffer) {
-  WriteRawData(buffer, &value, sizeof(value));
-}
-
-inline void SerializeEncoding(EncodingType encoding, void*& buffer) {
-  SerializeRaw(encoding, buffer);
-}
-
-inline void SerializeType(const bool& value, void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-}
-
-// Serializes the type code, extended type code, and size for
-// extension types.
-inline void SerializeExtEncoding(EncodingType encoding,
-                                 EncodingExtType ext_type, std::size_t size,
-                                 void*& buffer) {
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_EXT8) {
-    std::uint8_t length = size;
-    SerializeRaw(length, buffer);
-  } else if (encoding == ENCODING_TYPE_EXT16) {
-    std::uint16_t length = size;
-    SerializeRaw(length, buffer);
-  } else if (encoding == ENCODING_TYPE_EXT32) {
-    std::uint32_t length = size;
-    SerializeRaw(length, buffer);
-  } else /* if (IsFixextEncoding(encoding) */ {
-    // Encoding byte contains the fixext length, nothing else to do.
-  }
-  SerializeRaw(ext_type, buffer);
-}
-
-// Serializes the type code for file descriptor types.
-template <FileHandleMode Mode>
-inline void SerializeType(const FileHandle<Mode>& value, void*& buffer) {
-  SerializeExtEncoding(EncodeType(value), ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 2,
-                       buffer);
-}
-
-// Serializes the type code for channel handle types.
-template <ChannelHandleMode Mode>
-inline void SerializeType(const ChannelHandle<Mode>& handle, void*& buffer) {
-  SerializeExtEncoding(EncodeType(handle), ENCODING_EXT_TYPE_CHANNEL_HANDLE, 4,
-                       buffer);
-}
-
-// Serializes type code for variant types.
-template <typename... Types>
-inline void SerializeType(const Variant<Types...>& value, void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-}
-
-// Serializes the type code for string types.
-template <typename StringType>
-inline void SerializeStringType(const StringType& value, void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_STR8) {
-    std::uint8_t length = value.length();
-    SerializeRaw(length, buffer);
-  } else if (encoding == ENCODING_TYPE_STR16) {
-    std::uint16_t length = value.length();
-    SerializeRaw(length, buffer);
-  } else if (encoding == ENCODING_TYPE_STR32) {
-    std::uint32_t length = value.length();
-    SerializeRaw(length, buffer);
-  } else /* if (IsFixstrEncoding(encoding) */ {
-    // Encoding byte contains the fixstr length, nothing else to do.
-  }
-}
-
-// Serializes the type code for std::string and StringWrapper. These types are
-// interchangeable and must serialize to the same format.
-inline void SerializeType(const std::string& value, void*& buffer) {
-  SerializeStringType(value, buffer);
-}
-template <typename T>
-inline void SerializeType(const StringWrapper<T>& value, void*& buffer) {
-  SerializeStringType(value, buffer);
-}
-
-// Serializes the type code for bin types.
-inline void SerializeBinEncoding(EncodingType encoding, std::size_t size,
-                                 void*& buffer) {
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_BIN8) {
-    std::uint8_t length = size;
-    SerializeRaw(length, buffer);
-  } else if (encoding == ENCODING_TYPE_BIN16) {
-    std::uint16_t length = size;
-    SerializeRaw(length, buffer);
-  } else if (encoding == ENCODING_TYPE_BIN32) {
-    std::uint32_t length = size;
-    SerializeRaw(length, buffer);
-  } else {
-    // Invalid encoding for BIN type.
-  }
-}
-
-// Serializes the type code for BufferWrapper types.
-template <typename T>
-inline void SerializeType(const BufferWrapper<T>& value, void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeBinEncoding(
-      encoding, value.size() * sizeof(typename BufferWrapper<T>::value_type),
-      buffer);
-}
-
-// Serializes the array encoding type and length.
-inline void SerializeArrayEncoding(EncodingType encoding, std::size_t size,
-                                   void*& buffer) {
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_ARRAY16) {
-    std::uint16_t length = size;
-    SerializeRaw(length, buffer);
-  } else if (encoding == ENCODING_TYPE_ARRAY32) {
-    std::uint32_t length = size;
-    SerializeRaw(length, buffer);
-  } else /* if (IsFixarrayEncoding(encoding) */ {
-    // Encoding byte contains the fixarray length, nothing else to do.
-  }
-}
-
-// Serializes the map encoding type and length.
-inline void SerializeMapEncoding(EncodingType encoding, std::size_t size,
-                                 void*& buffer) {
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_MAP16) {
-    std::uint16_t length = size;
-    SerializeRaw(length, buffer);
-  } else if (encoding == ENCODING_TYPE_MAP32) {
-    std::uint32_t length = size;
-    SerializeRaw(length, buffer);
-  } else /* if (IsFixmapEncoding(encoding) */ {
-    // Encoding byte contains the fixmap length, nothing else to do.
-  }
-}
-
-// Serializes the type code for array types.
-template <typename ArrayType>
-inline void SerializeArrayType(const ArrayType& value, std::size_t size,
-                               void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeArrayEncoding(encoding, size, buffer);
-}
-
-// Serializes the type code for map types.
-template <typename MapType>
-inline void SerializeMapType(const MapType& value, std::size_t size,
-                             void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeMapEncoding(encoding, size, buffer);
-}
-
-// Serializes the type code for std::vector and ArrayWrapper. These types are
-// interchangeable and must serialize to the same format.
-template <typename T, typename Allocator>
-inline void SerializeType(const std::vector<T, Allocator>& value,
-                          void*& buffer) {
-  SerializeArrayType(value, value.size(), buffer);
-}
-template <typename T>
-inline void SerializeType(const ArrayWrapper<T>& value, void*& buffer) {
-  SerializeArrayType(value, value.size(), buffer);
-}
-
-// Serializes the type code for std::array. This type serializes to the same
-// format as std::vector and ArrayWrapper and is interchangeable in certain
-// situations.
-template <typename T, std::size_t Size>
-inline void SerializeType(const std::array<T, Size>& value, void*& buffer) {
-  SerializeArrayType(value, Size, buffer);
-}
-
-// Serializes the type code for std::map types.
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline void SerializeType(const std::map<Key, T, Compare, Allocator>& value,
-                          void*& buffer) {
-  SerializeMapType(value, value.size(), buffer);
-}
-
-// Serializes the type code for std::unordered_map types.
-template <typename Key, typename T, typename Hash, typename KeyEqual,
-          typename Allocator>
-inline void SerializeType(
-    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& value,
-    void*& buffer) {
-  SerializeMapType(value, value.size(), buffer);
-}
-
-// Serializes the type code for std::pair types.
-template <typename T, typename U>
-inline void SerializeType(const std::pair<T, U>& value, void*& buffer) {
-  SerializeArrayType(value, 2, buffer);
-}
-
-// Serializes the type code for std::tuple types.
-template <typename... T>
-inline void SerializeType(const std::tuple<T...>& value, void*& buffer) {
-  SerializeArrayType(value, sizeof...(T), buffer);
-}
-
-// Specialization of SerializeObject for boolean type.
-inline void SerializeObject(const bool& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  SerializeType(value, buffer);
-  // Encoding contains the boolean value, nothing else to do.
-}
-
-// Overloads of SerializeObject for float and double types.
-inline void SerializeObject(const float& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  SerializeRaw(value, buffer);
-}
-
-inline void SerializeObject(const double& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  SerializeRaw(value, buffer);
-}
-
-// Overloads of SerializeObject() for standard integer types.
-inline void SerializeObject(const char& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_UINT8) {
-    SerializeRaw(value, buffer);
-  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
-    // Encoding byte contains the value, nothing else to do.
-  }
-}
-
-inline void SerializeObject(const int8_t& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_INT8) {
-    SerializeRaw(value, buffer);
-  } else /* if (IsFixintEncoding(encoding) */ {
-    // Encoding byte contains the value, nothing else to do.
-  }
-}
-
-inline void SerializeObject(const uint8_t& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_UINT8) {
-    SerializeRaw(value, buffer);
-  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
-    // Encoding byte contains the value, nothing else to do.
-  }
-}
-
-inline void SerializeObject(const int16_t& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_INT8) {
-    const int8_t byte = value;
-    SerializeRaw(byte, buffer);
-  } else if (encoding == ENCODING_TYPE_INT16) {
-    SerializeRaw(value, buffer);
-  } else /* if (IsFixintEncoding(encoding) */ {
-    // Encoding byte contains the value, nothing else to do.
-  }
-}
-
-inline void SerializeObject(const uint16_t& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_UINT8) {
-    const uint8_t byte = value;
-    SerializeRaw(byte, buffer);
-  } else if (encoding == ENCODING_TYPE_UINT16) {
-    SerializeRaw(value, buffer);
-  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
-    // Encoding byte contains the value, nothing else to do.
-  }
-}
-
-inline void SerializeObject(const int32_t& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_INT8) {
-    const int8_t byte = value;
-    SerializeRaw(byte, buffer);
-  } else if (encoding == ENCODING_TYPE_INT16) {
-    const int16_t half = value;
-    SerializeRaw(half, buffer);
-  } else if (encoding == ENCODING_TYPE_INT32) {
-    SerializeRaw(value, buffer);
-  } else /* if (IsFixintEncoding(encoding) */ {
-    // Encoding byte contains the value, nothing else to do.
-  }
-}
-
-inline void SerializeObject(const uint32_t& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_UINT8) {
-    const uint8_t byte = value;
-    SerializeRaw(byte, buffer);
-  } else if (encoding == ENCODING_TYPE_UINT16) {
-    const uint16_t half = value;
-    SerializeRaw(half, buffer);
-  } else if (encoding == ENCODING_TYPE_UINT32) {
-    SerializeRaw(value, buffer);
-  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
-    // Encoding byte contains the value, nothing else to do.
-  }
-}
-
-inline void SerializeObject(const int64_t& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_INT8) {
-    const int8_t byte = value;
-    SerializeRaw(byte, buffer);
-  } else if (encoding == ENCODING_TYPE_INT16) {
-    const int16_t half = value;
-    SerializeRaw(half, buffer);
-  } else if (encoding == ENCODING_TYPE_INT32) {
-    const int32_t word = value;
-    SerializeRaw(word, buffer);
-  } else if (encoding == ENCODING_TYPE_INT64) {
-    SerializeRaw(value, buffer);
-  } else /* if (IsFixintEncoding(encoding) */ {
-    // Encoding byte contains the value, nothing else to do.
-  }
-}
-
-inline void SerializeObject(const uint64_t& value, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  const EncodingType encoding = EncodeType(value);
-  SerializeEncoding(encoding, buffer);
-  if (encoding == ENCODING_TYPE_UINT8) {
-    const uint8_t byte = value;
-    SerializeRaw(byte, buffer);
-  } else if (encoding == ENCODING_TYPE_UINT16) {
-    const uint16_t half = value;
-    SerializeRaw(half, buffer);
-  } else if (encoding == ENCODING_TYPE_UINT32) {
-    const uint32_t word = value;
-    SerializeRaw(word, buffer);
-  } else if (encoding == ENCODING_TYPE_UINT64) {
-    SerializeRaw(value, buffer);
-  } else /* if (IsUnsignedFixintEncoding(encoding) */ {
-    // Encoding byte contains the value, nothing else to do.
-  }
-}
-
-// Serialize enum types.
-template <typename T>
-inline EnableIfEnum<T> SerializeObject(const T& value, MessageWriter* writer,
-                                       void*& buffer) {
-  SerializeObject(static_cast<std::underlying_type_t<T>>(value), writer,
-                  buffer);
-}
-
-// Forward declaration for nested definitions.
-inline void SerializeObject(const EmptyVariant&, MessageWriter*, void*&);
-template <typename... Types>
-inline void SerializeObject(const Variant<Types...>&, MessageWriter*, void*&);
-template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
-inline void SerializeObject(const T&, MessageWriter*, void*&);
-template <typename T>
-inline void SerializeObject(const PointerWrapper<T>&, MessageWriter*, void*&);
-template <FileHandleMode Mode>
-inline void SerializeObject(const FileHandle<Mode>&, MessageWriter*, void*&);
-template <ChannelHandleMode Mode>
-inline void SerializeObject(const ChannelHandle<Mode>&, MessageWriter*, void*&);
-template <typename T, typename Allocator>
-inline void SerializeObject(const BufferWrapper<std::vector<T, Allocator>>&, MessageWriter*, void*&);
-template <typename T>
-inline void SerializeObject(const BufferWrapper<T*>&, MessageWriter*, void*&);
-inline void SerializeObject(const std::string&, MessageWriter*, void*&);
-template <typename T>
-inline void SerializeObject(const StringWrapper<T>&, MessageWriter*, void*&);
-template <typename T, typename Allocator>
-inline void SerializeObject(const std::vector<T, Allocator>&, MessageWriter*, void*&);
-template <typename T>
-inline void SerializeObject(const ArrayWrapper<T>&, MessageWriter*, void*&);
-template <typename T, std::size_t Size>
-inline void SerializeObject(const std::array<T, Size>&, MessageWriter*, void*&);
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline void SerializeObject(const std::map<Key, T, Compare, Allocator>&, MessageWriter*, void*&);
-template <typename Key, typename T, typename Hash, typename KeyEqual,
-          typename Allocator>
-inline void SerializeObject(
-    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>&, MessageWriter*, void*&);
-template <typename T, typename U>
-inline void SerializeObject(const std::pair<T, U>&, MessageWriter*, void*&);
-template <typename... T>
-inline void SerializeObject(const std::tuple<T...>&, MessageWriter*, void*&);
-
-// Overload for empty variant type.
-inline void SerializeObject(const EmptyVariant& empty,
-                            MessageWriter* /*writer*/, void*& buffer) {
-  const EncodingType encoding = EncodeType(empty);
-  SerializeEncoding(encoding, buffer);
-}
-
-// Overload for Variant types.
-template <typename... Types>
-inline void SerializeObject(const Variant<Types...>& variant,
-                            MessageWriter* writer, void*& buffer) {
-  SerializeType(variant, buffer);
-  SerializeObject(variant.index(), writer, buffer);
-  return variant.Visit([writer, &buffer](const auto& value) {
-    return SerializeObject(value, writer, buffer);
-  });
-}
-
-// Overload for serializable structure/class types.
-template <typename T, typename Enabled>
-inline void SerializeObject(const T& value, MessageWriter* writer,
-                            void*& buffer) {
-  SerializableTraits<T>::SerializeObject(value, writer, buffer);
-}
-
-// Serializes the payload of a PointerWrapper.
-template <typename T>
-inline void SerializeObject(const PointerWrapper<T>& pointer,
-                            MessageWriter* writer, void*& buffer) {
-  SerializeObject(pointer.Dereference(), writer, buffer);
-}
-
-// Serializes the payload of file descriptor types.
-template <FileHandleMode Mode>
-inline void SerializeObject(const FileHandle<Mode>& fd, MessageWriter* writer,
-                            void*& buffer) {
-  SerializeType(fd, buffer);
-  const Status<FileReference> status =
-      writer->GetOutputResourceMapper()->PushFileHandle(fd);
-  FileReference value = status ? status.get() : -status.error();
-  SerializeRaw(value, buffer);
-}
-
-// Serializes the payload of channel handle types.
-template <ChannelHandleMode Mode>
-inline void SerializeObject(const ChannelHandle<Mode>& handle,
-                            MessageWriter* writer, void*& buffer) {
-  SerializeType(handle, buffer);
-  const Status<ChannelReference> status =
-      writer->GetOutputResourceMapper()->PushChannelHandle(handle);
-  ChannelReference value = status ? status.get() : -status.error();
-  SerializeRaw(value, buffer);
-}
-
-// Serializes the payload of BufferWrapper types.
-template <typename T, typename Allocator>
-inline void SerializeObject(const BufferWrapper<std::vector<T, Allocator>>& b,
-                            MessageWriter* /*writer*/, void*& buffer) {
-  const auto value_type_size =
-      sizeof(typename BufferWrapper<std::vector<T, Allocator>>::value_type);
-  SerializeType(b, buffer);
-  WriteRawData(buffer, b.data(), b.size() * value_type_size);
-}
-template <typename T>
-inline void SerializeObject(const BufferWrapper<T*>& b,
-                            MessageWriter* /*writer*/, void*& buffer) {
-  const auto value_type_size = sizeof(typename BufferWrapper<T*>::value_type);
-  SerializeType(b, buffer);
-  WriteRawData(buffer, b.data(), b.size() * value_type_size);
-}
-
-// Serializes the payload of string types.
-template <typename StringType>
-inline void SerializeString(const StringType& s, void*& buffer) {
-  const auto value_type_size = sizeof(typename StringType::value_type);
-  SerializeType(s, buffer);
-  WriteRawData(buffer, s.data(), s.length() * value_type_size);
-}
-
-// Overload of SerializeObject() for std::string and StringWrapper. These types
-// are interchangeable and must serialize to the same format.
-inline void SerializeObject(const std::string& s, MessageWriter* /*writer*/,
-                            void*& buffer) {
-  SerializeString(s, buffer);
-}
-template <typename T>
-inline void SerializeObject(const StringWrapper<T>& s,
-                            MessageWriter* /*writer*/, void*& buffer) {
-  SerializeString(s, buffer);
-}
-
-// Serializes the payload of array types.
-template <typename ArrayType>
-inline void SerializeArray(const ArrayType& v, MessageWriter* writer,
-                           void*& buffer) {
-  SerializeType(v, buffer);
-  for (const auto& element : v)
-    SerializeObject(element, writer, buffer);
-}
-
-// Serializes the payload for map types.
-template <typename MapType>
-inline void SerializeMap(const MapType& v, MessageWriter* writer,
-                         void*& buffer) {
-  SerializeType(v, buffer);
-  for (const auto& element : v) {
-    SerializeObject(element.first, writer, buffer);
-    SerializeObject(element.second, writer, buffer);
-  }
-}
-
-// Overload of SerializeObject() for std::vector and ArrayWrapper types. These
-// types are interchangeable and must serialize to the same format.
-template <typename T, typename Allocator>
-inline void SerializeObject(const std::vector<T, Allocator>& v,
-                            MessageWriter* writer, void*& buffer) {
-  SerializeArray(v, writer, buffer);
-}
-template <typename T>
-inline void SerializeObject(const ArrayWrapper<T>& v, MessageWriter* writer,
-                            void*& buffer) {
-  SerializeArray(v, writer, buffer);
-}
-
-// Overload of SerializeObject() for std::array types. These types serialize to
-// the same format at std::vector and ArrayWrapper and are interchangeable in
-// certain situations.
-template <typename T, std::size_t Size>
-inline void SerializeObject(const std::array<T, Size>& v, MessageWriter* writer,
-                            void*& buffer) {
-  SerializeArray(v, writer, buffer);
-}
-
-// Overload of SerializeObject() for std::map types.
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline void SerializeObject(const std::map<Key, T, Compare, Allocator>& v,
-                            MessageWriter* writer, void*& buffer) {
-  SerializeMap(v, writer, buffer);
-}
-
-// Overload of SerializeObject() for std::unordered_map types.
-template <typename Key, typename T, typename Hash, typename KeyEqual,
-          typename Allocator>
-inline void SerializeObject(
-    const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& v,
-    MessageWriter* writer, void*& buffer) {
-  SerializeMap(v, writer, buffer);
-}
-
-// Overload of SerializeObject() for std:pair types.
-template <typename T, typename U>
-inline void SerializeObject(const std::pair<T, U>& pair, MessageWriter* writer,
-                            void*& buffer) {
-  SerializeType(pair, buffer);
-  SerializeObject(pair.first, writer, buffer);
-  SerializeObject(pair.second, writer, buffer);
-}
-
-// Stops template recursion when the last tuple element is reached.
-template <typename... T>
-inline void SerializeTuple(const std::tuple<T...>&, MessageWriter*, void*&,
-                           Index<0>) {}
-
-// Serializes each element of a tuple recursively.
-template <typename... T, std::size_t index>
-inline void SerializeTuple(const std::tuple<T...>& tuple, MessageWriter* writer,
-                           void*& buffer, Index<index>) {
-  SerializeTuple(tuple, writer, buffer, Index<index - 1>());
-  SerializeObject(std::get<index - 1>(tuple), writer, buffer);
-}
-
-// Overload of SerializeObject() for tuple types.
-template <typename... T>
-inline void SerializeObject(const std::tuple<T...>& tuple,
-                            MessageWriter* writer, void*& buffer) {
-  SerializeType(tuple, buffer);
-  SerializeTuple(tuple, writer, buffer, Index<sizeof...(T)>());
-}
-
-// Stops template recursion when the last member pointer is reached.
-template <typename Members, typename T>
-inline void SerializeMember(const T&, MessageWriter*, void*&, Index<0>) {}
-
-// Serializes each member pointer recursively.
-template <typename Members, typename T, std::size_t index>
-inline void SerializeMember(const T& object, MessageWriter* writer,
-                            void*& buffer, Index<index>) {
-  SerializeMember<Members>(object, writer, buffer, Index<index - 1>());
-  SerializeObject(Members::template At<index - 1>::Resolve(object), writer,
-                  buffer);
-}
-
-// Serializes the members of a type using the given SerializableMembersType
-// type.
-template <typename Members, typename T>
-inline void SerializeMembers(const T& object, MessageWriter* writer,
-                             void*& buffer) {
-  SerializeMember<Members>(object, writer, buffer,
-                           Index<Members::MemberCount>());
-}
-
-// Top level serialization function that replaces the buffer's contents.
-template <typename T>
-inline void Serialize(const T& object, MessageWriter* writer) {
-  PDX_TRACE_NAME("Serialize");
-  const std::size_t size = GetSerializedSize(object);
-
-  // Reserve the space needed for the object(s).
-  void* buffer = writer->GetNextWriteBufferSection(size);
-  SerializeObject(object, writer, buffer);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Object Deserialization //
-///////////////////////////////////////////////////////////////////////////////
-
-inline ErrorType ReadRawDataFromNextSection(void* dest, MessageReader* reader,
-                                            const void*& start,
-                                            const void*& end, size_t size) {
-  while (AdvancePointer(start, size) > end) {
-    auto remaining_size = PointerDistance(end, start);
-    if (remaining_size > 0) {
-      memcpy(dest, start, remaining_size);
-      dest = AdvancePointer(dest, remaining_size);
-      size -= remaining_size;
-    }
-    reader->ConsumeReadBufferSectionData(AdvancePointer(start, remaining_size));
-    std::tie(start, end) = reader->GetNextReadBufferSection();
-    if (start == end)
-      return ErrorCode::INSUFFICIENT_BUFFER;
-  }
-  memcpy(dest, start, size);
-  start = AdvancePointer(start, size);
-  return ErrorCode::NO_ERROR;
-}
-
-inline ErrorType ReadRawData(void* dest, MessageReader* /*reader*/,
-                             const void*& start, const void*& end,
-                             size_t size) {
-  if (PDX_UNLIKELY(AdvancePointer(start, size) > end)) {
-    // TODO(avakulenko): Enabling reading from next sections of input buffer
-    // (using ReadRawDataFromNextSection) screws up clang compiler optimizations
-    // (probably inefficient inlining) making the whole deserialization
-    // code path about twice as slow. Investigate and enable more generic
-    // deserialization code, but right now we don't really need/support this
-    // scenario, so I keep this commented out for the time being...
-
-    // return ReadRawDataFromNextSection(dest, reader, start, end, size);
-    return ErrorCode::INSUFFICIENT_BUFFER;
-  }
-  memcpy(dest, start, size);
-  start = AdvancePointer(start, size);
-  return ErrorCode::NO_ERROR;
-}
-
-// Deserializes a primitive object from raw bytes.
-template <typename T,
-          typename = typename std::enable_if<std::is_pod<T>::value>::type>
-inline ErrorType DeserializeRaw(T* value, MessageReader* reader,
-                                const void*& start, const void*& end) {
-  return ReadRawData(value, reader, start, end, sizeof(T));
-}
-
-// Utility to deserialize POD types when the serialized type is different
-// (smaller) than the target real type. This happens when values are serialized
-// into more compact encodings.
-template <typename SerializedType, typename RealType>
-ErrorType DeserializeValue(RealType* real_value, MessageReader* reader,
-                           const void*& start, const void*& end) {
-  SerializedType serialized_value;
-  if (const auto error =
-          DeserializeRaw(&serialized_value, reader, start, end)) {
-    return error;
-  } else {
-    *real_value = serialized_value;
-    return ErrorCode::NO_ERROR;
-  }
-}
-
-inline ErrorType DeserializeEncoding(EncodingType* encoding,
-                                     MessageReader* reader, const void*& start,
-                                     const void*& end) {
-  return DeserializeRaw(encoding, reader, start, end);
-}
-
-// Overload to deserialize bool type.
-inline ErrorType DeserializeObject(bool* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsBoolEncoding(encoding)) {
-    *value = (encoding == ENCODING_TYPE_TRUE);
-    return ErrorCode::NO_ERROR;
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_BOOL,
-                     encoding);
-  }
-}
-
-// Specializations to deserialize float and double types.
-inline ErrorType DeserializeObject(float* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsFloat32Encoding(encoding)) {
-    return DeserializeValue<float>(value, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_FLOAT,
-                     encoding);
-  }
-}
-
-inline ErrorType DeserializeObject(double* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsFloat32Encoding(encoding)) {
-    return DeserializeValue<float>(value, reader, start, end);
-  } else if (IsFloat64Encoding(encoding)) {
-    return DeserializeValue<double>(value, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_FLOAT,
-                     encoding);
-  }
-}
-
-// Specializations to deserialize standard integer types.
-inline ErrorType DeserializeObject(char* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsUnsignedFixintEncoding(encoding)) {
-    *value = static_cast<char>(encoding);
-    return ErrorCode::NO_ERROR;
-  } else if (IsUInt8Encoding(encoding)) {
-    return DeserializeValue<char>(value, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
-                     encoding);
-  }
-}
-
-inline ErrorType DeserializeObject(std::int8_t* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsFixintEncoding(encoding)) {
-    *value = static_cast<std::int8_t>(encoding);
-    return ErrorCode::NO_ERROR;
-  } else if (IsInt8Encoding(encoding)) {
-    return DeserializeValue<std::int8_t>(value, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
-                     encoding);
-  }
-}
-
-inline ErrorType DeserializeObject(std::uint8_t* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsUnsignedFixintEncoding(encoding)) {
-    *value = encoding;
-    return ErrorCode::NO_ERROR;
-  } else if (IsUInt8Encoding(encoding)) {
-    return DeserializeValue<std::uint8_t>(value, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
-                     encoding);
-  }
-}
-
-inline ErrorType DeserializeObject(std::int16_t* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsFixintEncoding(encoding)) {
-    *value = static_cast<std::int8_t>(encoding);
-    return ErrorCode::NO_ERROR;
-  } else if (IsInt8Encoding(encoding)) {
-    return DeserializeValue<std::int8_t>(value, reader, start, end);
-  } else if (IsInt16Encoding(encoding)) {
-    return DeserializeValue<std::int16_t>(value, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
-                     encoding);
-  }
-}
-
-inline ErrorType DeserializeObject(std::uint16_t* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsUnsignedFixintEncoding(encoding)) {
-    *value = encoding;
-    return ErrorCode::NO_ERROR;
-  } else if (IsUInt8Encoding(encoding)) {
-    return DeserializeValue<std::uint8_t>(value, reader, start, end);
-  } else if (IsUInt16Encoding(encoding)) {
-    return DeserializeValue<std::uint16_t>(value, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
-                     encoding);
-  }
-}
-
-inline ErrorType DeserializeObject(std::int32_t* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsFixintEncoding(encoding)) {
-    *value = static_cast<std::int8_t>(encoding);
-    return ErrorCode::NO_ERROR;
-  } else if (IsInt8Encoding(encoding)) {
-    return DeserializeValue<std::int8_t>(value, reader, start, end);
-  } else if (IsInt16Encoding(encoding)) {
-    return DeserializeValue<std::int16_t>(value, reader, start, end);
-  } else if (IsInt32Encoding(encoding)) {
-    return DeserializeValue<std::int32_t>(value, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
-                     encoding);
-  }
-}
-
-inline ErrorType DeserializeObject(std::uint32_t* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsUnsignedFixintEncoding(encoding)) {
-    *value = encoding;
-    return ErrorCode::NO_ERROR;
-  } else if (IsUInt8Encoding(encoding)) {
-    return DeserializeValue<std::uint8_t>(value, reader, start, end);
-  } else if (IsUInt16Encoding(encoding)) {
-    return DeserializeValue<std::uint16_t>(value, reader, start, end);
-  } else if (IsUInt32Encoding(encoding)) {
-    return DeserializeValue<std::uint32_t>(value, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
-                     encoding);
-  }
-}
-
-inline ErrorType DeserializeObject(std::int64_t* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsFixintEncoding(encoding)) {
-    *value = static_cast<std::int8_t>(encoding);
-    return ErrorCode::NO_ERROR;
-  } else if (IsInt8Encoding(encoding)) {
-    return DeserializeValue<std::int8_t>(value, reader, start, end);
-  } else if (IsInt16Encoding(encoding)) {
-    return DeserializeValue<std::int16_t>(value, reader, start, end);
-  } else if (IsInt32Encoding(encoding)) {
-    return DeserializeValue<std::int32_t>(value, reader, start, end);
-  } else if (IsInt64Encoding(encoding)) {
-    return DeserializeValue<std::int64_t>(value, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
-                     encoding);
-  }
-}
-
-inline ErrorType DeserializeObject(std::uint64_t* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (IsUnsignedFixintEncoding(encoding)) {
-    *value = encoding;
-    return ErrorCode::NO_ERROR;
-  } else if (IsUInt8Encoding(encoding)) {
-    return DeserializeValue<std::uint8_t>(value, reader, start, end);
-  } else if (IsUInt16Encoding(encoding)) {
-    return DeserializeValue<std::uint16_t>(value, reader, start, end);
-  } else if (IsUInt32Encoding(encoding)) {
-    return DeserializeValue<std::uint32_t>(value, reader, start, end);
-  } else if (IsUInt64Encoding(encoding)) {
-    return DeserializeValue<std::uint64_t>(value, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
-                     encoding);
-  }
-}
-
-template <typename T>
-inline EnableIfEnum<T, ErrorType> DeserializeObject(T* value,
-                                                    MessageReader* reader,
-                                                    const void*& start,
-                                                    const void*& end) {
-  std::underlying_type_t<T> enum_value;
-  ErrorType error = DeserializeObject(&enum_value, reader, start, end);
-  if (!error)
-    *value = static_cast<T>(enum_value);
-  return error;
-}
-
-// Forward declarations for nested definitions.
-template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
-inline ErrorType DeserializeObject(T*, MessageReader*, const void*&,
-                                   const void*&);
-template <typename T>
-inline ErrorType DeserializeObject(PointerWrapper<T>*, MessageReader*,
-                                   const void*&, const void*&);
-inline ErrorType DeserializeObject(LocalHandle*, MessageReader*, const void*&,
-                                   const void*&);
-inline ErrorType DeserializeObject(LocalChannelHandle*, MessageReader*,
-                                   const void*&, const void*&);
-template <typename T, typename Allocator>
-inline ErrorType DeserializeObject(BufferWrapper<std::vector<T, Allocator>>*,
-                                   MessageReader*, const void*&, const void*&);
-template <typename T>
-inline ErrorType DeserializeObject(BufferWrapper<T*>*, MessageReader*,
-                                   const void*&, const void*&);
-inline ErrorType DeserializeObject(std::string*, MessageReader*, const void*&,
-                                   const void*&);
-template <typename T>
-inline ErrorType DeserializeObject(StringWrapper<T>*, MessageReader*,
-                                   const void*&, const void*&);
-template <typename T, typename U>
-inline ErrorType DeserializeObject(std::pair<T, U>*, MessageReader*,
-                                   const void*&, const void*&);
-template <typename... T>
-inline ErrorType DeserializeObject(std::tuple<T...>*, MessageReader*,
-                                   const void*&, const void*&);
-template <typename T, typename Allocator>
-inline ErrorType DeserializeObject(std::vector<T, Allocator>*, MessageReader*,
-                                   const void*&, const void*&);
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline ErrorType DeserializeObject(std::map<Key, T, Compare, Allocator>*,
-                                   MessageReader*, const void*&, const void*&);
-template <typename Key, typename T, typename Hash, typename KeyEqual,
-          typename Allocator>
-inline ErrorType DeserializeObject(
-    std::unordered_map<Key, T, Hash, KeyEqual, Allocator>*, MessageReader*,
-    const void*&, const void*&);
-template <typename T>
-inline ErrorType DeserializeObject(ArrayWrapper<T>*, MessageReader*,
-                                   const void*&, const void*&);
-template <typename T, std::size_t Size>
-inline ErrorType DeserializeObject(std::array<T, Size>*, MessageReader*,
-                                   const void*&, const void*&);
-template <typename T, typename U>
-inline ErrorType DeserializeObject(std::pair<T, U>*, MessageReader*,
-                                   const void*&, const void*&);
-template <typename... T>
-inline ErrorType DeserializeObject(std::tuple<T...>*, MessageReader*,
-                                   const void*&, const void*&);
-inline ErrorType DeserializeObject(EmptyVariant*,
-                                   MessageReader*, const void*&,
-                                   const void*&);
-template <typename... Types>
-inline ErrorType DeserializeObject(Variant<Types...>*,
-                                   MessageReader*, const void*&,
-                                   const void*&);
-
-// Deserializes a Serializable type.
-template <typename T, typename Enable>
-inline ErrorType DeserializeObject(T* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  return SerializableTraits<T>::DeserializeObject(value, reader, start, end);
-}
-
-// Deserializes a PointerWrapper.
-template <typename T>
-inline ErrorType DeserializeObject(PointerWrapper<T>* pointer,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  return DeserializeObject(&pointer->Dereference(), reader, start, end);
-}
-
-// Deserializes the type code and size for extension types.
-inline ErrorType DeserializeExtType(EncodingType* encoding,
-                                    EncodingExtType* type, std::size_t* size,
-                                    MessageReader* reader, const void*& start,
-                                    const void*& end) {
-  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
-    return error;
-  } else if (IsFixextEncoding(*encoding)) {
-    *size = GetFixextSize(*encoding);
-  } else if (*encoding == ENCODING_TYPE_EXT8) {
-    if (const auto error =
-            DeserializeValue<std::uint8_t>(size, reader, start, end))
-      return error;
-  } else if (*encoding == ENCODING_TYPE_EXT16) {
-    if (const auto error =
-            DeserializeValue<std::uint16_t>(size, reader, start, end))
-      return error;
-  } else if (*encoding == ENCODING_TYPE_EXT32) {
-    if (const auto error =
-            DeserializeValue<std::uint32_t>(size, reader, start, end))
-      return error;
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
-                     *encoding);
-  }
-
-  // The extension type code follows the encoding and size.
-  return DeserializeRaw(type, reader, start, end);
-}
-
-// Deserializes a file handle and performs handle space translation, if
-// required.
-inline ErrorType DeserializeObject(LocalHandle* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  EncodingExtType type;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeExtType(&encoding, &type, &size, reader, start, end)) {
-    return error;
-  } else if (size != 2) {
-    return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_EXTENSION,
-                     encoding);
-  } else if (type == ENCODING_EXT_TYPE_FILE_DESCRIPTOR) {
-    // Read the encoded file descriptor value.
-    FileReference ref;
-    if (const auto error = DeserializeRaw(&ref, reader, start, end)) {
-      return error;
-    }
-
-    return reader->GetInputResourceMapper()->GetFileHandle(ref, value)
-               ? ErrorCode::NO_ERROR
-               : ErrorCode::GET_FILE_DESCRIPTOR_FAILED;
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
-                     encoding);
-  }
-}
-
-inline ErrorType DeserializeObject(LocalChannelHandle* value,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  EncodingType encoding;
-  EncodingExtType type;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeExtType(&encoding, &type, &size, reader, start, end)) {
-    return error;
-  } else if (size != 4) {
-    return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_EXTENSION,
-                     encoding);
-  } else if (type == ENCODING_EXT_TYPE_CHANNEL_HANDLE) {
-    // Read the encoded channel handle value.
-    ChannelReference ref;
-    if (const auto error = DeserializeRaw(&ref, reader, start, end)) {
-      return error;
-    }
-    return reader->GetInputResourceMapper()->GetChannelHandle(ref, value)
-               ? ErrorCode::NO_ERROR
-               : ErrorCode::GET_CHANNEL_HANDLE_FAILED;
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
-                     encoding);
-  }
-}
-
-// Deserializes the type code and size for bin types.
-inline ErrorType DeserializeBinType(EncodingType* encoding, std::size_t* size,
-                                    MessageReader* reader, const void*& start,
-                                    const void*& end) {
-  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
-    return error;
-  } else if (*encoding == ENCODING_TYPE_BIN8) {
-    return DeserializeValue<std::uint8_t>(size, reader, start, end);
-  } else if (*encoding == ENCODING_TYPE_BIN16) {
-    return DeserializeValue<std::uint16_t>(size, reader, start, end);
-  } else if (*encoding == ENCODING_TYPE_BIN32) {
-    return DeserializeValue<std::uint32_t>(size, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_BINARY,
-                     *encoding);
-  }
-}
-
-// Overload of DeserializeObject() for BufferWrapper types.
-template <typename T, typename Allocator>
-inline ErrorType DeserializeObject(
-    BufferWrapper<std::vector<T, Allocator>>* value, MessageReader* reader,
-    const void*& start, const void*& end) {
-  const auto value_type_size =
-      sizeof(typename BufferWrapper<std::vector<T, Allocator>>::value_type);
-  EncodingType encoding;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeBinType(&encoding, &size, reader, start, end))
-    return error;
-
-  // Try to resize the BufferWrapper to the size of the payload.
-  value->resize(size / value_type_size);
-
-  if (size > value->size() * value_type_size || size % value_type_size != 0) {
-    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
-  } else if (size == 0U) {
-    return ErrorCode::NO_ERROR;
-  } else {
-    return ReadRawData(value->data(), reader, start, end, size);
-  }
-}
-template <typename T>
-inline ErrorType DeserializeObject(BufferWrapper<T*>* value,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  const auto value_type_size = sizeof(typename BufferWrapper<T*>::value_type);
-  EncodingType encoding;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeBinType(&encoding, &size, reader, start, end))
-    return error;
-
-  // Try to resize the BufferWrapper to the size of the payload.
-  value->resize(size / value_type_size);
-
-  if (size > value->size() * value_type_size || size % value_type_size != 0) {
-    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
-  } else if (size == 0U) {
-    return ErrorCode::NO_ERROR;
-  } else {
-    return ReadRawData(value->data(), reader, start, end, size);
-  }
-}
-
-// Deserializes the type code and size for string types.
-inline ErrorType DeserializeStringType(EncodingType* encoding,
-                                       std::size_t* size, MessageReader* reader,
-                                       const void*& start, const void*& end) {
-  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
-    return error;
-  } else if (IsFixstrEncoding(*encoding)) {
-    *size = GetFixstrSize(*encoding);
-    return ErrorCode::NO_ERROR;
-  } else if (*encoding == ENCODING_TYPE_STR8) {
-    return DeserializeValue<std::uint8_t>(size, reader, start, end);
-  } else if (*encoding == ENCODING_TYPE_STR16) {
-    return DeserializeValue<std::uint16_t>(size, reader, start, end);
-  } else if (*encoding == ENCODING_TYPE_STR32) {
-    return DeserializeValue<std::uint32_t>(size, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_STRING,
-                     *encoding);
-  }
-}
-
-// Overload of DeserializeObject() for std::string types.
-inline ErrorType DeserializeObject(std::string* value, MessageReader* reader,
-                                   const void*& start, const void*& end) {
-  EncodingType encoding;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeStringType(&encoding, &size, reader, start, end)) {
-    return error;
-  } else if (size == 0U) {
-    value->clear();
-    return ErrorCode::NO_ERROR;
-  } else {
-    value->resize(size);
-    return ReadRawData(&(*value)[0], reader, start, end, size);
-  }
-}
-
-// Overload of DeserializeObject() for StringWrapper types.
-template <typename T>
-inline ErrorType DeserializeObject(StringWrapper<T>* value,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  const auto value_type_size = sizeof(typename StringWrapper<T>::value_type);
-  EncodingType encoding;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeStringType(&encoding, &size, reader, start, end))
-    return error;
-
-  // Try to resize the StringWrapper to the size of the payload
-  // string.
-  value->resize(size / value_type_size);
-
-  if (size > value->length() * value_type_size || size % value_type_size != 0) {
-    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
-  } else if (size == 0U) {
-    return ErrorCode::NO_ERROR;
-  } else {
-    return ReadRawData(value->data(), reader, start, end, size);
-  }
-}
-
-// Deserializes the type code and size of array types.
-inline ErrorType DeserializeArrayType(EncodingType* encoding, std::size_t* size,
-                                      MessageReader* reader, const void*& start,
-                                      const void*& end) {
-  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
-    return error;
-  } else if (IsFixarrayEncoding(*encoding)) {
-    *size = GetFixarraySize(*encoding);
-    return ErrorCode::NO_ERROR;
-  } else if (*encoding == ENCODING_TYPE_ARRAY16) {
-    return DeserializeValue<std::uint16_t>(size, reader, start, end);
-  } else if (*encoding == ENCODING_TYPE_ARRAY32) {
-    return DeserializeValue<std::uint32_t>(size, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_ARRAY,
-                     *encoding);
-  }
-}
-
-// Deserializes the type code and size of map types.
-inline ErrorType DeserializeMapType(EncodingType* encoding, std::size_t* size,
-                                    MessageReader* reader, const void*& start,
-                                    const void*& end) {
-  if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
-    return error;
-  } else if (IsFixmapEncoding(*encoding)) {
-    *size = GetFixmapSize(*encoding);
-    return ErrorCode::NO_ERROR;
-  } else if (*encoding == ENCODING_TYPE_MAP16) {
-    return DeserializeValue<std::uint16_t>(size, reader, start, end);
-  } else if (*encoding == ENCODING_TYPE_MAP32) {
-    return DeserializeValue<std::uint32_t>(size, reader, start, end);
-  } else {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_MAP,
-                     *encoding);
-  }
-}
-
-// Overload for std::vector types.
-template <typename T, typename Allocator>
-inline ErrorType DeserializeObject(std::vector<T, Allocator>* value,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  EncodingType encoding;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeArrayType(&encoding, &size, reader, start, end))
-    return error;
-
-  std::vector<T, Allocator> result(size);
-  for (std::size_t i = 0; i < size; i++) {
-    if (const auto error = DeserializeObject(&result[i], reader, start, end))
-      return error;
-  }
-
-  *value = std::move(result);
-  return ErrorCode::NO_ERROR;
-
-// TODO(eieio): Consider the benefits and trade offs of this alternative.
-#if 0
-  value->resize(size);
-  for (std::size_t i = 0; i < size; i++) {
-    if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
-      return error;
-  }
-  return ErrorCode::NO_ERROR;
-#endif
-}
-
-// Deserializes an EmptyVariant value.
-inline ErrorType DeserializeObject(EmptyVariant* /*empty*/,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  EncodingType encoding;
-
-  if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
-    return error;
-  } else if (encoding != ENCODING_TYPE_NIL) {
-    return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_MAP,
-                     encoding);
-  } else {
-    return ErrorCode::NO_ERROR;
-  }
-}
-
-// Deserializes a Variant type.
-template <typename... Types>
-inline ErrorType DeserializeObject(Variant<Types...>* variant,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  EncodingType encoding;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeMapType(&encoding, &size, reader, start, end)) {
-    return error;
-  }
-
-  if (size != 1)
-    return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_MAP,
-                     encoding);
-
-  std::int32_t type;
-  if (const auto error = DeserializeObject(&type, reader, start, end)) {
-    return error;
-  } else if (type < Variant<Types...>::kEmptyIndex ||
-             type >= static_cast<std::int32_t>(sizeof...(Types))) {
-    return ErrorCode::INVALID_VARIANT_ELEMENT;
-  } else {
-    variant->Become(type);
-    return variant->Visit([reader, &start, &end](auto&& value) {
-      return DeserializeObject(&value, reader, start, end);
-    });
-  }
-}
-
-// Deserializes map types.
-template <typename MapType>
-inline ErrorType DeserializeMap(MapType* value, MessageReader* reader,
-                                const void*& start, const void*& end) {
-  EncodingType encoding;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeMapType(&encoding, &size, reader, start, end))
-    return error;
-
-  MapType result;
-  for (std::size_t i = 0; i < size; i++) {
-    std::pair<typename MapType::key_type, typename MapType::mapped_type>
-        element;
-    if (const auto error =
-            DeserializeObject(&element.first, reader, start, end))
-      return error;
-    if (const auto error =
-            DeserializeObject(&element.second, reader, start, end))
-      return error;
-    result.emplace(std::move(element));
-  }
-
-  *value = std::move(result);
-  return ErrorCode::NO_ERROR;
-}
-
-// Overload for std::map types.
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline ErrorType DeserializeObject(std::map<Key, T, Compare, Allocator>* value,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  return DeserializeMap(value, reader, start, end);
-}
-
-// Overload for std::unordered_map types.
-template <typename Key, typename T, typename Hash, typename KeyEqual,
-          typename Allocator>
-inline ErrorType DeserializeObject(
-    std::unordered_map<Key, T, Hash, KeyEqual, Allocator>* value,
-    MessageReader* reader, const void*& start, const void*& end) {
-  return DeserializeMap(value, reader, start, end);
-}
-
-// Overload for ArrayWrapper types.
-template <typename T>
-inline ErrorType DeserializeObject(ArrayWrapper<T>* value,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  EncodingType encoding;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeArrayType(&encoding, &size, reader, start, end)) {
-    return error;
-  }
-
-  // Try to resize the wrapper.
-  value->resize(size);
-
-  // Make sure there is enough space in the ArrayWrapper for the
-  // payload.
-  if (size > value->capacity())
-    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
-
-  for (std::size_t i = 0; i < size; i++) {
-    if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
-      return error;
-  }
-
-  return ErrorCode::NO_ERROR;
-}
-
-// Overload for std::array types.
-template <typename T, std::size_t Size>
-inline ErrorType DeserializeObject(std::array<T, Size>* value,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  EncodingType encoding;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeArrayType(&encoding, &size, reader, start, end)) {
-    return error;
-  }
-
-  if (size != Size)
-    return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
-
-  for (std::size_t i = 0; i < size; i++) {
-    if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
-      return error;
-  }
-
-  return ErrorCode::NO_ERROR;
-}
-
-// Deserializes std::pair types.
-template <typename T, typename U>
-inline ErrorType DeserializeObject(std::pair<T, U>* value,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  EncodingType encoding;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeArrayType(&encoding, &size, reader, start, end)) {
-    return error;
-  } else if (size != 2) {
-    return ErrorCode::UNEXPECTED_TYPE_SIZE;
-  } else if (const auto error =
-                 DeserializeObject(&value->first, reader, start, end)) {
-    return error;
-  } else if (const auto error =
-                 DeserializeObject(&value->second, reader, start, end)) {
-    return error;
-  } else {
-    return ErrorCode::NO_ERROR;
-  }
-}
-
-// Stops template recursion when the last tuple element is reached.
-template <typename... T>
-inline ErrorType DeserializeTuple(std::tuple<T...>*, MessageReader*,
-                                  const void*&, const void*, Index<0>) {
-  return ErrorCode::NO_ERROR;
-}
-
-// Deserializes each element of a tuple recursively.
-template <typename... T, std::size_t index>
-inline ErrorType DeserializeTuple(std::tuple<T...>* tuple,
-                                  MessageReader* reader, const void*& start,
-                                  const void*& end, Index<index>) {
-  if (const auto error =
-          DeserializeTuple(tuple, reader, start, end, Index<index - 1>()))
-    return error;
-  else
-    return DeserializeObject(&std::get<index - 1>(*tuple), reader, start, end);
-}
-
-// Overload for standard tuple types.
-template <typename... T>
-inline ErrorType DeserializeObject(std::tuple<T...>* value,
-                                   MessageReader* reader, const void*& start,
-                                   const void*& end) {
-  EncodingType encoding;
-  std::size_t size;
-
-  if (const auto error =
-          DeserializeArrayType(&encoding, &size, reader, start, end)) {
-    return error;
-  } else if (size != sizeof...(T)) {
-    return ErrorCode::UNEXPECTED_TYPE_SIZE;
-  } else {
-    return DeserializeTuple(value, reader, start, end, Index<sizeof...(T)>());
-  }
-}
-
-// Stops template recursion when the last member of a Serializable type is
-// reached.
-template <typename Members, typename T>
-inline ErrorType DeserializeMember(T*, MessageReader*, const void*&,
-                                   const void*, Index<0>) {
-  return ErrorCode::NO_ERROR;
-}
-
-// Deserializes each member of a Serializable type recursively.
-template <typename Members, typename T, std::size_t index>
-inline ErrorType DeserializeMember(T* value, MessageReader* reader,
-                                   const void*& start, const void*& end,
-                                   Index<index>) {
-  if (const auto error = DeserializeMember<Members>(value, reader, start, end,
-                                                    Index<index - 1>()))
-    return error;
-  else
-    return DeserializeObject(&Members::template At<index - 1>::Resolve(*value),
-                             reader, start, end);
-}
-
-// Deserializes the members of a Serializable type using the given
-// SerializableMembersType type.
-template <typename Members, typename T>
-inline ErrorType DeserializeMembers(T* value, MessageReader* reader,
-                                    const void*& start, const void*& end) {
-  return DeserializeMember<Members>(value, reader, start, end,
-                                    Index<Members::MemberCount>());
-}
-
-// Top level deserialization function.
-template <typename T>
-inline ErrorType Deserialize(T* value, MessageReader* reader) {
-  PDX_TRACE_NAME("Deserialize");
-  MessageReader::BufferSection section = reader->GetNextReadBufferSection();
-  if (section.first == section.second)
-    return ErrorCode::INSUFFICIENT_BUFFER;
-  ErrorType error =
-      DeserializeObject(value, reader, section.first, section.second);
-  reader->ConsumeReadBufferSectionData(section.first);
-  return error;
-}
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_SERIALIZATION_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/string_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/string_wrapper.h
deleted file mode 100644
index 371ed89..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/string_wrapper.h
+++ /dev/null
@@ -1,129 +0,0 @@
-#ifndef ANDROID_PDX_RPC_STRING_WRAPPER_H_
-#define ANDROID_PDX_RPC_STRING_WRAPPER_H_
-
-#include <cstddef>
-#include <cstring>
-#include <string>
-#include <type_traits>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Wrapper class for C string buffers, providing an interface suitable for
-// SerializeObject and DeserializeObject. This class serializes to the same
-// format as std::basic_string, and may be substituted for std::basic_string
-// during serialization and deserialization. This substitution makes handling of
-// C strings more efficient by avoiding unnecessary copies when remote method
-// signatures specify std::basic_string arguments or return values.
-template <typename CharT = std::string::value_type,
-          typename Traits = std::char_traits<std::remove_cv_t<CharT>>>
-class StringWrapper {
- public:
-  // Define types in the style of STL strings to support STL operators.
-  typedef Traits traits_type;
-  typedef CharT value_type;
-  typedef std::size_t size_type;
-  typedef value_type& reference;
-  typedef const value_type& const_reference;
-  typedef value_type* pointer;
-  typedef const value_type* const_pointer;
-
-  StringWrapper() : buffer_(nullptr), capacity_(0), end_(0) {}
-
-  StringWrapper(pointer buffer, size_type capacity, size_type size)
-      : buffer_(&buffer[0]),
-        capacity_(capacity),
-        end_(capacity < size ? capacity : size) {}
-
-  StringWrapper(pointer buffer, size_type size)
-      : StringWrapper(buffer, size, size) {}
-
-  explicit StringWrapper(pointer buffer)
-      : StringWrapper(buffer, std::strlen(buffer)) {}
-
-  StringWrapper(const StringWrapper& other) { *this = other; }
-
-  StringWrapper(StringWrapper&& other) noexcept { *this = std::move(other); }
-
-  StringWrapper& operator=(const StringWrapper& other) {
-    if (&other == this) {
-      return *this;
-    } else {
-      buffer_ = other.buffer_;
-      capacity_ = other.capacity_;
-      end_ = other.end_;
-    }
-
-    return *this;
-  }
-
-  StringWrapper& operator=(StringWrapper&& other) noexcept {
-    if (&other == this) {
-      return *this;
-    } else {
-      buffer_ = other.buffer_;
-      capacity_ = other.capacity_;
-      end_ = other.end_;
-      other.buffer_ = nullptr;
-      other.capacity_ = 0;
-      other.end_ = 0;
-    }
-
-    return *this;
-  }
-
-  pointer data() { return buffer_; }
-  const_pointer data() const { return buffer_; }
-
-  pointer begin() { return &buffer_[0]; }
-  pointer end() { return &buffer_[end_]; }
-  const_pointer begin() const { return &buffer_[0]; }
-  const_pointer end() const { return &buffer_[end_]; }
-
-  size_type size() const { return end_; }
-  size_type length() const { return end_; }
-  size_type max_size() const { return capacity_; }
-  size_type capacity() const { return capacity_; }
-
-  void resize(size_type size) {
-    if (size <= capacity_)
-      end_ = size;
-    else
-      end_ = capacity_;
-  }
-
-  reference operator[](size_type pos) { return buffer_[pos]; }
-  const_reference operator[](size_type pos) const { return buffer_[pos]; }
-
- private:
-  pointer buffer_;
-  size_type capacity_;
-  size_type end_;
-};
-
-// Utility functions that infer the underlying type of the string, simplifying
-// the wrapper interface.
-
-// TODO(eieio): Wrapping std::basic_string is here for completeness, but is it
-// useful?
-template <typename T, typename... Any>
-StringWrapper<const T> WrapString(const std::basic_string<T, Any...>& s) {
-  return StringWrapper<const T>(s.c_str(), s.length());
-}
-
-template <typename T, typename SizeType = std::size_t>
-StringWrapper<T> WrapString(T* s, SizeType size) {
-  return StringWrapper<T>(s, size);
-}
-
-template <typename T>
-StringWrapper<T> WrapString(T* s) {
-  return StringWrapper<T>(s);
-}
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_STRING_WRAPPER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/thread_local_buffer.h b/libs/vr/libpdx/private/pdx/rpc/thread_local_buffer.h
deleted file mode 100644
index e5ef2aa..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/thread_local_buffer.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#ifndef ANDROID_PDX_RPC_THREAD_LOCAL_BUFFER_H_
-#define ANDROID_PDX_RPC_THREAD_LOCAL_BUFFER_H_
-
-#include <cstdint>
-#include <memory>
-#include <vector>
-
-#include <pdx/rpc/default_initialization_allocator.h>
-#include <pdx/trace.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility class to distinguish between different thread local entries or
-// "slots" in the thread local variable table. Each slot is uniquely identified
-// by (T,Index) and is independent of any other slot.
-template <typename T, std::size_t Index>
-struct ThreadLocalSlot;
-
-// Utility class to specify thread local slots using only a type.
-template <typename T>
-struct ThreadLocalTypeSlot;
-
-// Utility class to specify thread local slots using only an index.
-template <std::size_t Index>
-struct ThreadLocalIndexSlot;
-
-// Initial capacity of thread local buffer, unless otherwise specified.
-constexpr std::size_t InitialBufferCapacity = 4096;
-
-// Thread local slots for buffers used by this library to send, receive, and
-// reply to messages.
-using SendBuffer = ThreadLocalIndexSlot<0>;
-using ReceiveBuffer = ThreadLocalIndexSlot<1>;
-using ReplyBuffer = ThreadLocalIndexSlot<2>;
-
-// Provides a simple interface to thread local buffers for large IPC messages.
-// Slot provides multiple thread local slots for a given T, Allocator, Capacity
-// combination.
-template <typename T, typename Allocator = DefaultInitializationAllocator<T>,
-          std::size_t Capacity = InitialBufferCapacity,
-          typename Slot = ThreadLocalSlot<void, 0>>
-class ThreadLocalBuffer {
- public:
-  using BufferType = std::vector<T, Allocator>;
-  using ValueType = T;
-
-  // Reserves |capacity| number of elements of capacity in the underlying
-  // buffer. Call this during startup to avoid allocation during use.
-  static void Reserve(std::size_t capacity) {
-    PDX_TRACE_NAME("ThreadLocalBuffer::Reserve");
-    InitializeBuffer(capacity);
-    buffer_->reserve(capacity);
-  }
-
-  // Resizes the buffer to |size| elements.
-  static void Resize(std::size_t size) {
-    PDX_TRACE_NAME("ThreadLocalBuffer::Resize");
-    InitializeBuffer(size);
-    buffer_->resize(size);
-  }
-
-  // Gets a reference to the underlying buffer after reserving |capacity|
-  // elements. The current size of the buffer is left intact. The returned
-  // reference is valid until FreeBuffer() is called.
-  static BufferType& GetBuffer(std::size_t capacity = Capacity) {
-    PDX_TRACE_NAME("ThreadLocalBuffer::GetBuffer");
-    Reserve(capacity);
-    return *buffer_;
-  }
-
-  // Gets a reference to the underlying buffer after reserving |Capacity|
-  // elements. The current size of the buffer is set to zero. The returned
-  // reference is valid until FreeBuffer() is called.
-  static BufferType& GetEmptyBuffer() {
-    PDX_TRACE_NAME("ThreadLocalBuffer::GetEmptyBuffer");
-    Reserve(Capacity);
-    buffer_->clear();
-    return *buffer_;
-  }
-
-  // Gets a reference to the underlying buffer after resizing it to |size|
-  // elements. The returned reference is valid until FreeBuffer() is called.
-  static BufferType& GetSizedBuffer(std::size_t size = Capacity) {
-    PDX_TRACE_NAME("ThreadLocalBuffer::GetSizedBuffer");
-    Resize(size);
-    return *buffer_;
-  }
-
-  // Frees the underlying buffer. The buffer will be reallocated if any of the
-  // methods above are called.
-  static void FreeBuffer() {
-    if (buffer_) {
-      GetBufferGuard().reset(buffer_ = nullptr);
-    }
-  }
-
- private:
-  friend class ThreadLocalBufferTest;
-
-  static void InitializeBuffer(std::size_t capacity) {
-    if (!buffer_) {
-      GetBufferGuard().reset(buffer_ = new BufferType(capacity));
-    }
-  }
-
-  // Work around performance issues with thread-local dynamic initialization
-  // semantics by using a normal pointer in parallel with a std::unique_ptr. The
-  // std::unique_ptr is never dereferenced, only assigned, to avoid the high
-  // cost of dynamic initialization checks, while still providing automatic
-  // cleanup. The normal pointer provides fast access to the buffer object.
-  // Never dereference buffer_guard or performance could be severely impacted
-  // by slow implementations of TLS dynamic initialization.
-  static thread_local BufferType* buffer_;
-
-  static std::unique_ptr<BufferType>& GetBufferGuard() {
-    PDX_TRACE_NAME("ThreadLocalBuffer::GetBufferGuard");
-    static thread_local std::unique_ptr<BufferType> buffer_guard;
-    return buffer_guard;
-  }
-};
-
-// Instantiation of the static ThreadLocalBuffer::buffer_ member.
-template <typename T, typename Allocator, std::size_t Capacity, typename Slot>
-thread_local
-    typename ThreadLocalBuffer<T, Allocator, Capacity, Slot>::BufferType*
-        ThreadLocalBuffer<T, Allocator, Capacity, Slot>::buffer_;
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_RPC_THREAD_LOCAL_BUFFER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/type_operators.h b/libs/vr/libpdx/private/pdx/rpc/type_operators.h
deleted file mode 100644
index 811bd87..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/type_operators.h
+++ /dev/null
@@ -1,195 +0,0 @@
-#ifndef ANDROID_PDX_RPC_TYPE_OPERATORS_H_
-#define ANDROID_PDX_RPC_TYPE_OPERATORS_H_
-
-#include <array>
-#include <map>
-#include <type_traits>
-#include <unordered_map>
-#include <vector>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/rpc/array_wrapper.h>
-#include <pdx/rpc/buffer_wrapper.h>
-#include <pdx/rpc/copy_cv_reference.h>
-#include <pdx/rpc/pointer_wrapper.h>
-#include <pdx/rpc/string_wrapper.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Simplifies type expressions.
-template <typename T>
-using Decay = typename std::decay<T>::type;
-
-// Compares the underlying type of A and B.
-template <typename A, typename B>
-using IsEquivalent = typename std::is_same<Decay<A>, Decay<B>>::type;
-
-// Logical AND over template parameter pack.
-template <typename... T>
-struct And : std::false_type {};
-template <typename A, typename B>
-struct And<A, B> : std::integral_constant<bool, A::value && B::value> {};
-template <typename A, typename B, typename... Rest>
-struct And<A, B, Rest...> : And<A, And<B, Rest...>> {};
-
-// Determines whether A is convertible to B (serializes to the same format)
-// using these rules:
-//    1. std:vector<T, Any...> is convertible to ArrayWrapper<T>.
-//    2. ArrayWrapper<T> is convertible to std:vector<T, Any...>.
-//    3. std::basic_string<T, Any...> is convertible to StringWrapper<T>.
-//    4. StringWrapper<T> is convertible to std::basic_string<T, Any...>.
-//    5. BufferWrapper<T*> is convertible to BufferWrapper<std::vector<T,
-//    Any...>>.
-//    6. BufferWrapper<std::vector<T, ...>> is convertible to BufferWrapper<T*>.
-//    7. The value type T of A and B must match.
-
-// Compares A and B for convertibility. This base type determines convertibility
-// by equivalence of the underlying types of A and B. Specializations of this
-// type handle the rules for which complex types are convertible.
-template <typename A, typename B>
-struct IsConvertible : IsEquivalent<A, B> {};
-
-// Compares TT<A, ...> and TT<B, ...>; these are convertible if A and B are
-// convertible.
-template <template <typename, typename...> class TT, typename A, typename B,
-          typename... AnyA, typename... AnyB>
-struct IsConvertible<TT<A, AnyA...>, TT<B, AnyB...>>
-    : IsConvertible<Decay<A>, Decay<B>> {};
-
-// Compares TT<KeyA, ValueA, ...> and TT<KeyB, ValueB, ...>; these are
-// convertible if KeyA and KeyB are
-// convertible and ValueA and ValueB are convertible.
-template <template <typename, typename, typename...> class TT, typename KeyA,
-          typename ValueA, typename KeyB, typename ValueB, typename... AnyA,
-          typename... AnyB>
-struct IsConvertible<TT<KeyA, ValueA, AnyA...>, TT<KeyB, ValueB, AnyB...>>
-    : And<IsConvertible<Decay<KeyA>, Decay<KeyB>>,
-          IsConvertible<Decay<ValueA>, Decay<ValueB>>> {};
-
-// Compares two std::pairs to see if the corresponding elements are convertible.
-template <typename A, typename B, typename C, typename D>
-struct IsConvertible<std::pair<A, B>, std::pair<C, D>>
-    : And<IsConvertible<Decay<A>, Decay<C>>,
-          IsConvertible<Decay<B>, Decay<D>>> {};
-
-// Compares std::pair with a two-element std::tuple to see if the corresponding
-// elements are convertible.
-template <typename A, typename B, typename C, typename D>
-struct IsConvertible<std::pair<A, B>, std::tuple<C, D>>
-    : And<IsConvertible<Decay<A>, Decay<C>>,
-          IsConvertible<Decay<B>, Decay<D>>> {};
-template <typename A, typename B, typename C, typename D>
-struct IsConvertible<std::tuple<A, B>, std::pair<C, D>>
-    : And<IsConvertible<Decay<A>, Decay<C>>,
-          IsConvertible<Decay<B>, Decay<D>>> {};
-
-// Compares two std::tuples to see if the corresponding elements are
-// convertible.
-template <typename... A, typename... B>
-struct IsConvertible<std::tuple<A...>, std::tuple<B...>>
-    : And<IsConvertible<Decay<A>, Decay<B>>...> {};
-
-// Compares std::vector, std::array, and ArrayWrapper; these are convertible if
-// the value types are convertible.
-template <typename A, typename B, typename... Any>
-struct IsConvertible<std::vector<A, Any...>, ArrayWrapper<B>>
-    : IsConvertible<Decay<A>, Decay<B>> {};
-template <typename A, typename B, typename... Any>
-struct IsConvertible<ArrayWrapper<A>, std::vector<B, Any...>>
-    : IsConvertible<Decay<A>, Decay<B>> {};
-template <typename A, typename B, typename... Any, std::size_t Size>
-struct IsConvertible<std::vector<A, Any...>, std::array<B, Size>>
-    : IsConvertible<Decay<A>, Decay<B>> {};
-template <typename A, typename B, typename... Any, std::size_t Size>
-struct IsConvertible<std::array<A, Size>, std::vector<B, Any...>>
-    : IsConvertible<Decay<A>, Decay<B>> {};
-template <typename A, typename B, std::size_t Size>
-struct IsConvertible<ArrayWrapper<A>, std::array<B, Size>>
-    : IsConvertible<Decay<A>, Decay<B>> {};
-template <typename A, typename B, std::size_t Size>
-struct IsConvertible<std::array<A, Size>, ArrayWrapper<B>>
-    : IsConvertible<Decay<A>, Decay<B>> {};
-
-// Compares std::map and std::unordered_map; these are convertible if the keys
-// are convertible and the values are convertible.
-template <typename KeyA, typename ValueA, typename KeyB, typename ValueB,
-          typename... AnyA, typename... AnyB>
-struct IsConvertible<std::map<KeyA, ValueA, AnyA...>,
-                     std::unordered_map<KeyB, ValueB, AnyB...>>
-    : And<IsConvertible<Decay<KeyA>, Decay<KeyB>>,
-          IsConvertible<Decay<ValueA>, Decay<ValueB>>> {};
-template <typename KeyA, typename ValueA, typename KeyB, typename ValueB,
-          typename... AnyA, typename... AnyB>
-struct IsConvertible<std::unordered_map<KeyA, ValueA, AnyA...>,
-                     std::map<KeyB, ValueB, AnyB...>>
-    : And<IsConvertible<Decay<KeyA>, Decay<KeyB>>,
-          IsConvertible<Decay<ValueA>, Decay<ValueB>>> {};
-
-// Compares BufferWrapper<A*> and BufferWrapper<std::vector<B>>; these are
-// convertible if A and B are equivalent. Allocator types are not relevant to
-// convertibility.
-template <typename A, typename B, typename Allocator>
-struct IsConvertible<BufferWrapper<A*>,
-                     BufferWrapper<std::vector<B, Allocator>>>
-    : IsEquivalent<A, B> {};
-template <typename A, typename B, typename Allocator>
-struct IsConvertible<BufferWrapper<std::vector<A, Allocator>>,
-                     BufferWrapper<B*>> : IsEquivalent<A, B> {};
-template <typename A, typename B, typename AllocatorA, typename AllocatorB>
-struct IsConvertible<BufferWrapper<std::vector<A, AllocatorA>>,
-                     BufferWrapper<std::vector<B, AllocatorB>>>
-    : IsEquivalent<A, B> {};
-template <typename A, typename B>
-struct IsConvertible<BufferWrapper<A*>, BufferWrapper<B*>>
-    : IsEquivalent<A, B> {};
-
-// Compares std::basic_string<A, ...> and StringWrapper<B>; these are
-// convertible if A and B are equivalent.
-template <typename A, typename B, typename... Any>
-struct IsConvertible<std::basic_string<A, Any...>, StringWrapper<B>>
-    : IsEquivalent<A, B> {};
-template <typename A, typename B, typename... Any>
-struct IsConvertible<StringWrapper<A>, std::basic_string<B, Any...>>
-    : IsEquivalent<A, B> {};
-
-// Compares PointerWrapper<A> and B; these are convertible if A and B are
-// convertible.
-template <typename A, typename B>
-struct IsConvertible<PointerWrapper<A>, B> : IsConvertible<Decay<A>, Decay<B>> {
-};
-template <typename A, typename B>
-struct IsConvertible<A, PointerWrapper<B>> : IsConvertible<Decay<A>, Decay<B>> {
-};
-
-// LocalHandle is convertible to RemoteHandle on the service side. This means
-// that a RemoteHandle may be supplied by a service when the protocol calls for
-// a LocalHandle return value. The other way around is not safe and can leak
-// file descriptors. The ServicePayload class enforces this policy by only
-// supporting RemoteHandle for pushed handles.
-template <>
-struct IsConvertible<LocalHandle, RemoteHandle> : std::true_type {};
-template <>
-struct IsConvertible<LocalHandle, BorrowedHandle> : std::true_type {};
-
-template <>
-struct IsConvertible<LocalChannelHandle, RemoteChannelHandle> : std::true_type {
-};
-template <>
-struct IsConvertible<LocalChannelHandle, BorrowedChannelHandle>
-    : std::true_type {};
-
-// Conditionally "rewrites" type A as type B, including cv-reference qualifiers,
-// iff A is convertible to B.
-template <typename A, typename B>
-using ConditionalRewrite =
-    typename std::conditional<IsConvertible<Decay<A>, Decay<B>>::value,
-                              CopyCVReferenceType<A, B>, A>::type;
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-#endif  //  ANDROID_PDX_RPC_TYPE_OPERATORS_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/variant.h b/libs/vr/libpdx/private/pdx/rpc/variant.h
deleted file mode 100644
index a1292b0..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/variant.h
+++ /dev/null
@@ -1,760 +0,0 @@
-#ifndef ANDROID_PDX_RPC_VARIANT_H_
-#define ANDROID_PDX_RPC_VARIANT_H_
-
-#include <cstdint>
-#include <tuple>
-#include <type_traits>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Type tag denoting an empty variant.
-struct EmptyVariant {};
-
-namespace detail {
-
-// Type for matching tagged overloads.
-template <typename T>
-struct TypeTag {};
-
-// Determines the type of the I-th element of Types....
-template <std::size_t I, typename... Types>
-using TypeForIndex = std::tuple_element_t<I, std::tuple<Types...>>;
-
-// Determines the type tag for the I-th element of Types....
-template <std::size_t I, typename... Types>
-using TypeTagForIndex = TypeTag<TypeForIndex<I, Types...>>;
-
-// Similar to std::is_constructible except that it evaluates to false for bool
-// construction from pointer types: this helps prevent subtle to bugs caused by
-// assigning values that decay to pointers to Variants with bool elements.
-//
-// Here is an example of the problematic situation this trait avoids:
-//
-//  Variant<int, bool> v;
-//  const int array[3] = {1, 2, 3};
-//  v = array; // This is allowed by regular std::is_constructible.
-//
-template <typename...>
-struct IsConstructible;
-template <typename T, typename U>
-struct IsConstructible<T, U>
-    : std::integral_constant<bool,
-                             std::is_constructible<T, U>::value &&
-                                 !(std::is_same<std::decay_t<T>, bool>::value &&
-                                   std::is_pointer<std::decay_t<U>>::value)> {};
-template <typename T, typename... Args>
-struct IsConstructible<T, Args...> : std::is_constructible<T, Args...> {};
-
-// Enable if T(Args...) is well formed.
-template <typename R, typename T, typename... Args>
-using EnableIfConstructible =
-    typename std::enable_if<IsConstructible<T, Args...>::value, R>::type;
-// Enable if T(Args...) is not well formed.
-template <typename R, typename T, typename... Args>
-using EnableIfNotConstructible =
-    typename std::enable_if<!IsConstructible<T, Args...>::value, R>::type;
-
-// Determines whether T is an element of Types...;
-template <typename... Types>
-struct HasType : std::false_type {};
-template <typename T, typename U>
-struct HasType<T, U> : std::is_same<std::decay_t<T>, std::decay_t<U>> {};
-template <typename T, typename First, typename... Rest>
-struct HasType<T, First, Rest...>
-    : std::integral_constant<bool, HasType<T, First>::value ||
-                                       HasType<T, Rest...>::value> {};
-
-// Defines set operations on a set of Types...
-template <typename... Types>
-struct Set {
-  // Default specialization catches the empty set, which is always a subset.
-  template <typename...>
-  struct IsSubset : std::true_type {};
-  template <typename T>
-  struct IsSubset<T> : HasType<T, Types...> {};
-  template <typename First, typename... Rest>
-  struct IsSubset<First, Rest...>
-      : std::integral_constant<bool, IsSubset<First>::value &&
-                                         IsSubset<Rest...>::value> {};
-};
-
-// Determines the number of elements of Types... that are constructible from
-// From.
-template <typename... Types>
-struct ConstructibleCount;
-template <typename From, typename To>
-struct ConstructibleCount<From, To>
-    : std::integral_constant<std::size_t, IsConstructible<To, From>::value> {};
-template <typename From, typename First, typename... Rest>
-struct ConstructibleCount<From, First, Rest...>
-    : std::integral_constant<std::size_t,
-                             IsConstructible<First, From>::value +
-                                 ConstructibleCount<From, Rest...>::value> {};
-
-// Enable if T is an element of Types...
-template <typename R, typename T, typename... Types>
-using EnableIfElement =
-    typename std::enable_if<HasType<T, Types...>::value, R>::type;
-// Enable if T is not an element of Types...
-template <typename R, typename T, typename... Types>
-using EnableIfNotElement =
-    typename std::enable_if<!HasType<T, Types...>::value, R>::type;
-
-// Enable if T is convertible to an element of Types... T is considered
-// convertible IIF a single element of Types... is assignable from T and T is
-// not a direct element of Types...
-template <typename R, typename T, typename... Types>
-using EnableIfConvertible =
-    typename std::enable_if<!HasType<T, Types...>::value &&
-                                ConstructibleCount<T, Types...>::value == 1,
-                            R>::type;
-
-// Enable if T is assignable to an element of Types... T is considered
-// assignable IFF a single element of Types... is constructible from T or T is a
-// direct element of Types.... Note that T is REQUIRED to be an element of
-// Types... when multiple elements are constructible from T to prevent ambiguity
-// in conversion.
-template <typename R, typename T, typename... Types>
-using EnableIfAssignable =
-    typename std::enable_if<HasType<T, Types...>::value ||
-                                ConstructibleCount<T, Types...>::value == 1,
-                            R>::type;
-
-// Selects a type for SFINAE constructor selection.
-template <bool CondA, typename SelectA, typename SelectB>
-using Select = std::conditional_t<CondA, SelectA, SelectB>;
-
-// Recursive union type.
-template <typename... Types>
-union Union;
-
-// Specialization handling a singular type, terminating template recursion.
-template <typename Type>
-union Union<Type> {
-  Union() {}
-  ~Union() {}
-
-  template <typename T>
-  Union(std::int32_t index, std::int32_t* index_out, TypeTag<Type>, T&& value)
-      : first_(std::forward<T>(value)) {
-    *index_out = index;
-  }
-  template <typename T, typename = EnableIfAssignable<void, T, Type>>
-  Union(std::int32_t index, std::int32_t* index_out, T&& value)
-      : first_(std::forward<T>(value)) {
-    *index_out = index;
-  }
-  Union(const Union& other, std::int32_t index) {
-    if (index == 0)
-      new (&first_) Type(other.first_);
-  }
-  Union(Union&& other, std::int32_t index) {
-    if (index == 0)
-      new (&first_) Type(std::move(other.first_));
-  }
-  Union(const Union&) = delete;
-  Union(Union&&) = delete;
-  void operator=(const Union&) = delete;
-  void operator=(Union&&) = delete;
-
-  Type& get(TypeTag<Type>) { return first_; }
-  const Type& get(TypeTag<Type>) const { return first_; }
-  EmptyVariant get(TypeTag<EmptyVariant>) const { return {}; }
-  constexpr std::int32_t index(TypeTag<Type>) const { return 0; }
-
-  template <typename... Args>
-  std::int32_t Construct(TypeTag<Type>, Args&&... args) {
-    new (&first_) Type(std::forward<Args>(args)...);
-    return 0;
-  }
-  template <typename... Args>
-  EnableIfConstructible<std::int32_t, Type, Args...> Construct(Args&&... args) {
-    new (&first_) Type(std::forward<Args>(args)...);
-    return 0;
-  }
-
-  void Destruct(std::int32_t target_index) {
-    if (target_index == index(TypeTag<Type>{})) {
-      (&get(TypeTag<Type>{}))->~Type();
-    }
-  }
-
-  template <typename T>
-  bool Assign(TypeTag<Type>, std::int32_t target_index, T&& value) {
-    if (target_index == 0) {
-      first_ = std::forward<T>(value);
-      return true;
-    } else {
-      return false;
-    }
-  }
-  template <typename T>
-  EnableIfConstructible<bool, Type, T> Assign(std::int32_t target_index,
-                                              T&& value) {
-    if (target_index == 0) {
-      first_ = std::forward<T>(value);
-      return true;
-    } else {
-      return false;
-    }
-  }
-  template <typename T>
-  EnableIfNotConstructible<bool, Type, T> Assign(std::int32_t /*target_index*/,
-                                                 T&& /*value*/) {
-    return false;
-  }
-
-  template <typename Op>
-  decltype(auto) Visit(std::int32_t target_index, Op&& op) {
-    if (target_index == index(TypeTag<Type>{}))
-      return std::forward<Op>(op)(get(TypeTag<Type>{}));
-    else
-      return std::forward<Op>(op)(get(TypeTag<EmptyVariant>{}));
-  }
-  template <typename Op>
-  decltype(auto) Visit(std::int32_t target_index, Op&& op) const {
-    if (target_index == index(TypeTag<Type>{}))
-      return std::forward<Op>(op)(get(TypeTag<Type>{}));
-    else
-      return std::forward<Op>(op)(get(TypeTag<EmptyVariant>{}));
-  }
-
-  template <typename... Args>
-  bool Become(std::int32_t target_index, Args&&... args) {
-    if (target_index == index(TypeTag<Type>{})) {
-      Construct(TypeTag<Type>{}, std::forward<Args>(args)...);
-      return true;
-    } else {
-      return false;
-    }
-  }
-
- private:
-  Type first_;
-};
-
-// Specialization that recursively unions types from the paramater pack.
-template <typename First, typename... Rest>
-union Union<First, Rest...> {
-  Union() {}
-  ~Union() {}
-
-  template <typename T>
-  Union(std::int32_t index, std::int32_t* index_out, TypeTag<First>, T&& value)
-      : first_(std::forward<T>(value)) {
-    *index_out = index;
-  }
-  template <typename T, typename U>
-  Union(std::int32_t index, std::int32_t* index_out, TypeTag<T>, U&& value)
-      : rest_(index + 1, index_out, TypeTag<T>{}, std::forward<U>(value)) {}
-  Union(const Union& other, std::int32_t index) {
-    if (index == 0)
-      new (&first_) First(other.first_);
-    else
-      new (&rest_) Union<Rest...>(other.rest_, index - 1);
-  }
-  Union(Union&& other, std::int32_t index) {
-    if (index == 0)
-      new (&first_) First(std::move(other.first_));
-    else
-      new (&rest_) Union<Rest...>(std::move(other.rest_), index - 1);
-  }
-  Union(const Union&) = delete;
-  Union(Union&&) = delete;
-  void operator=(const Union&) = delete;
-  void operator=(Union&&) = delete;
-
-  struct FirstType {};
-  struct RestType {};
-  template <typename T>
-  using SelectConstructor =
-      Select<ConstructibleCount<T, First>::value == 1, FirstType, RestType>;
-
-  template <typename T>
-  Union(std::int32_t index, std::int32_t* index_out, T&& value)
-      : Union(index, index_out, std::forward<T>(value),
-              SelectConstructor<T>{}) {}
-
-  template <typename T>
-  Union(std::int32_t index, std::int32_t* index_out, T&& value, FirstType)
-      : first_(std::forward<T>(value)) {
-    *index_out = index;
-  }
-  template <typename T>
-  Union(std::int32_t index, std::int32_t* index_out, T&& value, RestType)
-      : rest_(index + 1, index_out, std::forward<T>(value)) {}
-
-  First& get(TypeTag<First>) { return first_; }
-  const First& get(TypeTag<First>) const { return first_; }
-  constexpr std::int32_t index(TypeTag<First>) const { return 0; }
-
-  template <typename T>
-  T& get(TypeTag<T>) {
-    return rest_.get(TypeTag<T>{});
-  }
-  template <typename T>
-  const T& get(TypeTag<T>) const {
-    return rest_.template get(TypeTag<T>{});
-  }
-  template <typename T>
-  constexpr std::int32_t index(TypeTag<T>) const {
-    return 1 + rest_.index(TypeTag<T>{});
-  }
-
-  template <typename... Args>
-  std::int32_t Construct(TypeTag<First>, Args&&... args) {
-    new (&first_) First(std::forward<Args>(args)...);
-    return 0;
-  }
-  template <typename T, typename... Args>
-  std::int32_t Construct(TypeTag<T>, Args&&... args) {
-    return 1 +
-           rest_.template Construct(TypeTag<T>{}, std::forward<Args>(args)...);
-  }
-
-  template <typename... Args>
-  EnableIfConstructible<std::int32_t, First, Args...> Construct(
-      Args&&... args) {
-    new (&first_) First(std::forward<Args>(args)...);
-    return 0;
-  }
-  template <typename... Args>
-  EnableIfNotConstructible<std::int32_t, First, Args...> Construct(
-      Args&&... args) {
-    return 1 + rest_.template Construct(std::forward<Args>(args)...);
-  }
-
-  void Destruct(std::int32_t target_index) {
-    if (target_index == index(TypeTag<First>{})) {
-      (get(TypeTag<First>{})).~First();
-    } else {
-      rest_.Destruct(target_index - 1);
-    }
-  }
-
-  template <typename T>
-  bool Assign(TypeTag<First>, std::int32_t target_index, T&& value) {
-    if (target_index == 0) {
-      first_ = std::forward<T>(value);
-      return true;
-    } else {
-      return false;
-    }
-  }
-  template <typename T, typename U>
-  bool Assign(TypeTag<T>, std::int32_t target_index, U&& value) {
-    return rest_.Assign(TypeTag<T>{}, target_index - 1, std::forward<U>(value));
-  }
-  template <typename T>
-  EnableIfConstructible<bool, First, T> Assign(std::int32_t target_index,
-                                               T&& value) {
-    if (target_index == 0) {
-      first_ = std::forward<T>(value);
-      return true;
-    } else {
-      return rest_.Assign(target_index - 1, std::forward<T>(value));
-    }
-  }
-  template <typename T>
-  EnableIfNotConstructible<bool, First, T> Assign(std::int32_t target_index,
-                                                  T&& value) {
-    return rest_.Assign(target_index - 1, std::forward<T>(value));
-  }
-
-  // Recursively traverses the union and calls Op on the active value when the
-  // active type is found. If the union is empty Op is called on EmptyVariant.
-  // TODO(eieio): This could be refactored into an array or jump table. It's
-  // unclear whether this would be more efficient for practical variant arity.
-  template <typename Op>
-  decltype(auto) Visit(std::int32_t target_index, Op&& op) {
-    if (target_index == index(TypeTag<First>{}))
-      return std::forward<Op>(op)(get(TypeTag<First>{}));
-    else
-      return rest_.Visit(target_index - 1, std::forward<Op>(op));
-  }
-  template <typename Op>
-  decltype(auto) Visit(std::int32_t target_index, Op&& op) const {
-    if (target_index == index(TypeTag<First>{}))
-      return std::forward<Op>(op)(get(TypeTag<First>{}));
-    else
-      return rest_.Visit(target_index - 1, std::forward<Op>(op));
-  }
-
-  template <typename... Args>
-  bool Become(std::int32_t target_index, Args&&... args) {
-    if (target_index == index(TypeTag<First>{})) {
-      Construct(TypeTag<First>{}, std::forward<Args>(args)...);
-      return true;
-    } else {
-      return rest_.Become(target_index - 1, std::forward<Args>(args)...);
-    }
-  }
-
- private:
-  First first_;
-  Union<Rest...> rest_;
-};
-
-}  // namespace detail
-
-// Variant is a type safe union that can store values of any of its element
-// types. A Variant is different than std::tuple in that it only stores one type
-// at a time or a special empty type. Variants are always default constructible
-// to empty, even when none of the element types are default constructible.
-template <typename... Types>
-class Variant {
- private:
-  // Convenience types.
-  template <typename T>
-  using TypeTag = detail::TypeTag<T>;
-  template <typename T>
-  using DecayedTypeTag = TypeTag<std::decay_t<T>>;
-  template <std::size_t I>
-  using TypeForIndex = detail::TypeForIndex<I, Types...>;
-  template <std::size_t I>
-  using TypeTagForIndex = detail::TypeTagForIndex<I, Types...>;
-  template <typename T>
-  using HasType = detail::HasType<T, Types...>;
-  template <typename R, typename T>
-  using EnableIfElement = detail::EnableIfElement<R, T, Types...>;
-  template <typename R, typename T>
-  using EnableIfConvertible = detail::EnableIfConvertible<R, T, Types...>;
-  template <typename R, typename T>
-  using EnableIfAssignable = detail::EnableIfAssignable<R, T, Types...>;
-
-  struct Direct {};
-  struct Convert {};
-  template <typename T>
-  using SelectConstructor = detail::Select<HasType<T>::value, Direct, Convert>;
-
-  // Constructs by type tag when T is an direct element of Types...
-  template <typename T>
-  explicit Variant(T&& value, Direct)
-      : value_(0, &index_, DecayedTypeTag<T>{}, std::forward<T>(value)) {}
-  // Conversion constructor when T is not a direct element of Types...
-  template <typename T>
-  explicit Variant(T&& value, Convert)
-      : value_(0, &index_, std::forward<T>(value)) {}
-
- public:
-  // Variants are default construcible, regardless of whether the elements are
-  // default constructible. Default consruction yields an empty Variant.
-  Variant() {}
-  explicit Variant(EmptyVariant) {}
-  ~Variant() { Destruct(); }
-
-  Variant(const Variant& other)
-      : index_{other.index_}, value_{other.value_, other.index_} {}
-  Variant(Variant&& other) noexcept
-      : index_{other.index_}, value_{std::move(other.value_), other.index_} {}
-
-// Recent Clang versions has a regression that produces bogus
-// unused-lambda-capture warning. Suppress the warning as a temporary
-// workaround. http://b/71356631
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-lambda-capture"
-  // Copy and move construction from Variant types. Each element of OtherTypes
-  // must be convertible to an element of Types.
-  template <typename... OtherTypes>
-  explicit Variant(const Variant<OtherTypes...>& other) {
-    other.Visit([this](const auto& value) { Construct(value); });
-  }
-#pragma clang diagnostic pop
-
-  template <typename... OtherTypes>
-  explicit Variant(Variant<OtherTypes...>&& other) {
-    other.Visit([this](auto&& value) { Construct(std::move(value)); });
-  }
-
-  Variant& operator=(const Variant& other) {
-    other.Visit([this](const auto& value) { *this = value; });
-    return *this;
-  }
-  Variant& operator=(Variant&& other) noexcept {
-    other.Visit([this](auto&& value) { *this = std::move(value); });
-    return *this;
-  }
-
-  // Construction from non-Variant types.
-  template <typename T, typename = EnableIfAssignable<void, T>>
-  explicit Variant(T&& value)
-      : Variant(std::forward<T>(value), SelectConstructor<T>{}) {}
-
-  // Performs assignment from type T belonging to Types. This overload takes
-  // priority to prevent implicit conversion in cases where T is implicitly
-  // convertible to multiple elements of Types.
-  template <typename T>
-  EnableIfElement<Variant&, T> operator=(T&& value) {
-    Assign(DecayedTypeTag<T>{}, std::forward<T>(value));
-    return *this;
-  }
-
-  // Performs assignment from type T not belonging to Types. This overload
-  // matches in cases where conversion is the only viable option.
-  template <typename T>
-  EnableIfConvertible<Variant&, T> operator=(T&& value) {
-    Assign(std::forward<T>(value));
-    return *this;
-  }
-
-  // Handles assignment from the empty type. This overload supports assignment
-  // in visitors using generic lambdas.
-  Variant& operator=(EmptyVariant) {
-    Destruct();
-    return *this;
-  }
-
-  // Assignment from Variant types. Each element of OtherTypes must be
-  // convertible to an element of Types. Forwards through non-Variant assignment
-  // operators to apply conversion checks.
-  template <typename... OtherTypes>
-  Variant& operator=(const Variant<OtherTypes...>& other) {
-    other.Visit([this](const auto& value) { *this = value; });
-    return *this;
-  }
-  template <typename... OtherTypes>
-  Variant& operator=(Variant<OtherTypes...>&& other) {
-    other.Visit([this](auto&& value) { *this = std::move(value); });
-    return *this;
-  }
-
-  // Becomes the target type, constructing a new element from the given
-  // arguments if necessary. No action is taken if the active element is already
-  // the target type. Otherwise the active element is destroyed and replaced by
-  // constructing an element of the new type using |Args|. An invalid target
-  // type index results in an empty Variant.
-  template <typename... Args>
-  void Become(std::int32_t target_index, Args&&... args) {
-    if (target_index != index()) {
-      Destruct();
-      index_ = value_.Become(target_index, std::forward<Args>(args)...)
-                   ? target_index
-                   : kEmptyIndex;
-    }
-  }
-
-  // Invokes |Op| on the active element. If the Variant is empty |Op| is invoked
-  // on EmptyVariant.
-  template <typename Op>
-  decltype(auto) Visit(Op&& op) {
-    return value_.Visit(index_, std::forward<Op>(op));
-  }
-  template <typename Op>
-  decltype(auto) Visit(Op&& op) const {
-    return value_.Visit(index_, std::forward<Op>(op));
-  }
-
-  // Index returned when the Variant is empty.
-  enum : std::int32_t { kEmptyIndex = -1 };
-
-  // Returns the index of the given type.
-  template <typename T>
-  constexpr std::int32_t index_of() const {
-    static_assert(HasType<T>::value, "T is not an element type of Variant.");
-    return value_.index(DecayedTypeTag<T>{});
-  }
-
-  // Returns the index of the active type. If the Variant is empty -1 is
-  // returned.
-  std::int32_t index() const { return index_; }
-
-  // Returns true if the given type is active, false otherwise.
-  template <typename T>
-  bool is() const {
-    static_assert(HasType<T>::value, "T is not an element type of Variant.");
-    return index() == index_of<T>();
-  }
-
-  // Returns true if the Variant is empty, false otherwise.
-  bool empty() const { return index() == kEmptyIndex; }
-
-  // Element accessors. Returns a pointer to the active value if the given
-  // type/index is active, otherwise nullptr is returned.
-  template <typename T>
-  T* get() {
-    if (is<T>())
-      return &value_.get(DecayedTypeTag<T>{});
-    else
-      return nullptr;
-  }
-  template <typename T>
-  const T* get() const {
-    if (is<T>())
-      return &value_.template get(DecayedTypeTag<T>{});
-    else
-      return nullptr;
-  }
-  template <std::size_t I>
-  TypeForIndex<I>* get() {
-    if (is<TypeForIndex<I>>())
-      return &value_.get(TypeTagForIndex<I>{});
-    else
-      return nullptr;
-  }
-  template <std::size_t I>
-  const TypeForIndex<I>* get() const {
-    if (is<TypeForIndex<I>>())
-      return &value_.template get(TypeTagForIndex<I>{});
-    else
-      return nullptr;
-  }
-
- private:
-  std::int32_t index_ = kEmptyIndex;
-  detail::Union<std::decay_t<Types>...> value_;
-
-  // Constructs an element from the given arguments and sets the Variant to the
-  // resulting type.
-  template <typename... Args>
-  void Construct(Args&&... args) {
-    index_ = value_.template Construct(std::forward<Args>(args)...);
-  }
-  void Construct(EmptyVariant) {}
-
-  // Destroys the active element of the Variant.
-  void Destruct() {
-    value_.Destruct(index_);
-    index_ = kEmptyIndex;
-  }
-
-  // Assigns the Variant when non-empty and the current type matches the target
-  // type, otherwise destroys the current value and constructs a element of the
-  // new type. Tagged assignment is used when T is an element of the Variant to
-  // prevent implicit conversion in cases where T is implicitly convertible to
-  // multiple element types.
-  template <typename T, typename U>
-  void Assign(TypeTag<T>, U&& value) {
-    if (!value_.template Assign(TypeTag<T>{}, index_, std::forward<U>(value))) {
-      Destruct();
-      Construct(TypeTag<T>{}, std::forward<U>(value));
-    }
-  }
-  template <typename T>
-  void Assign(T&& value) {
-    if (!value_.template Assign(index_, std::forward<T>(value))) {
-      Destruct();
-      Construct(std::forward<T>(value));
-    }
-  }
-};
-
-// Utility type to extract/convert values from a variant. This class simplifies
-// conditional logic to get/move/swap/action values from a variant when one or
-// more elements are compatible with the destination type.
-//
-// Example:
-//    Variant<int, bool, std::string> v(10);
-//    bool bool_value;
-//    if (IfAnyOf<int, bool>::Get(v, &bool_value)) {
-//      DoSomething(bool_value);
-//    } else {
-//      HandleInvalidType();
-//    }
-//    IfAnyOf<int>::Call(v, [](const auto& value) { DoSomething(value); });
-//
-template <typename... ValidTypes>
-struct IfAnyOf {
-  // Calls Op on the underlying value of the variant and returns true when the
-  // variant is a valid type, otherwise does nothing and returns false.
-  template <typename Op, typename... Types>
-  static bool Call(Variant<Types...>* variant, Op&& op) {
-    static_assert(
-        detail::Set<Types...>::template IsSubset<ValidTypes...>::value,
-        "ValidTypes may only contain element types from the Variant.");
-    return variant->Visit(CallOp<Op>{std::forward<Op>(op)});
-  }
-  template <typename Op, typename... Types>
-  static bool Call(const Variant<Types...>* variant, Op&& op) {
-    static_assert(
-        detail::Set<Types...>::template IsSubset<ValidTypes...>::value,
-        "ValidTypes may only contain element types from the Variant.");
-    return variant->Visit(CallOp<Op>{std::forward<Op>(op)});
-  }
-
-  // Gets/converts the underlying value of the variant to type T and returns
-  // true when the variant is a valid type, otherwise does nothing and returns
-  // false.
-  template <typename T, typename... Types>
-  static bool Get(const Variant<Types...>* variant, T* value_out) {
-    return Call(variant,
-                [value_out](const auto& value) { *value_out = value; });
-  }
-
-  // Moves the underlying value of the variant and returns true when the variant
-  // is a valid type, otherwise does nothing and returns false.
-  template <typename T, typename... Types>
-  static bool Take(Variant<Types...>* variant, T* value_out) {
-    return Call(variant,
-                [value_out](auto&& value) { *value_out = std::move(value); });
-  }
-
-  // Swaps the underlying value of the variant with |*value_out| and returns
-  // true when the variant is a valid type, otherwise does nothing and returns
-  // false.
-  template <typename T, typename... Types>
-  static bool Swap(Variant<Types...>* variant, T* value_out) {
-    return Call(variant,
-                [value_out](auto&& value) { std::swap(*value_out, value); });
-  }
-
- private:
-  template <typename Op>
-  struct CallOp {
-    Op&& op;
-    template <typename U>
-    detail::EnableIfNotElement<bool, U, ValidTypes...> operator()(U&&) {
-      return false;
-    }
-    template <typename U>
-    detail::EnableIfElement<bool, U, ValidTypes...> operator()(const U& value) {
-      std::forward<Op>(op)(value);
-      return true;
-    }
-    template <typename U>
-    detail::EnableIfElement<bool, U, ValidTypes...> operator()(U&& value) {
-      std::forward<Op>(op)(std::forward<U>(value));
-      return true;
-    }
-  };
-};
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-// Overloads of std::get<T> and std::get<I> for android::pdx::rpc::Variant.
-namespace std {
-
-template <typename T, typename... Types>
-inline T& get(::android::pdx::rpc::Variant<Types...>& v) {
-  return *v.template get<T>();
-}
-template <typename T, typename... Types>
-inline T&& get(::android::pdx::rpc::Variant<Types...>&& v) {
-  return std::move(*v.template get<T>());
-}
-template <typename T, typename... Types>
-inline const T& get(const ::android::pdx::rpc::Variant<Types...>& v) {
-  return *v.template get<T>();
-}
-template <std::size_t I, typename... Types>
-inline ::android::pdx::rpc::detail::TypeForIndex<I, Types...>& get(
-    ::android::pdx::rpc::Variant<Types...>& v) {
-  return *v.template get<I>();
-}
-template <std::size_t I, typename... Types>
-inline ::android::pdx::rpc::detail::TypeForIndex<I, Types...>&& get(
-    ::android::pdx::rpc::Variant<Types...>&& v) {
-  return std::move(*v.template get<I>());
-}
-template <std::size_t I, typename... Types>
-inline const ::android::pdx::rpc::detail::TypeForIndex<I, Types...>& get(
-    const ::android::pdx::rpc::Variant<Types...>& v) {
-  return *v.template get<I>();
-}
-
-}  // namespace std
-
-#endif  // ANDROID_PDX_RPC_VARIANT_H_
diff --git a/libs/vr/libpdx/private/pdx/service.h b/libs/vr/libpdx/private/pdx/service.h
deleted file mode 100644
index f5a2d5e..0000000
--- a/libs/vr/libpdx/private/pdx/service.h
+++ /dev/null
@@ -1,759 +0,0 @@
-#ifndef ANDROID_PDX_SERVICE_H_
-#define ANDROID_PDX_SERVICE_H_
-
-#include <errno.h>
-#include <log/log.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "pdx/channel_handle.h"
-#include "pdx/file_handle.h"
-#include "pdx/message_reader.h"
-#include "pdx/message_writer.h"
-#include "pdx/service_endpoint.h"
-
-namespace android {
-namespace pdx {
-
-class Service;
-
-namespace opcodes {
-
-/*
- * Reserved message opcodes used by libpdx. The reserved opcodes start at the
- * max positive signed integer for the system and go down.
- * In contrast, service opcodes start at zero and go up. This scheme leaves
- * most of the positive integer space for services, a tiny fraction of the
- * positive integer space for the framework, and the entire negative integer
- * space for the kernel.
- */
-#define PDX_OPCODE(name, n) name = ((-1U >> 1) - (n))  // 0x7fff..ffff - n
-
-enum {
-  // System message sent when a new client channel is open.
-  CHANNEL_OPEN = -1,
-  // System message sent when a channel is closed.
-  CHANNEL_CLOSE = -2,
-  // Request the service to reload system properties.
-  PDX_OPCODE(REPORT_SYSPROP_CHANGE, 0),
-  // Request the service to dump state and return it in a text buffer.
-  PDX_OPCODE(DUMP_STATE, 1),
-};
-
-}  // namespace opcodes
-
-/*
- * Base class of service-side per-channel context classes.
- */
-class Channel : public std::enable_shared_from_this<Channel> {
- public:
-  Channel() {}
-  virtual ~Channel() {}
-
-  /*
-   * Accessors to the pid of the last active client.
-   */
-  pid_t GetActiveProcessId() const { return client_pid_; }
-  void SetActiveProcessId(pid_t pid) { client_pid_ = pid; }
-
-  /*
-   * Utility to get a shared_ptr reference from the channel context pointer.
-   */
-  static std::shared_ptr<Channel> GetFromMessageInfo(const MessageInfo& info);
-
- private:
-  pid_t client_pid_ = 0;
-};
-
-/*
- * Message class represents an RPC message, and implicitly the blocked sender
- * waiting for a response. Every message should get a reply, at some point
- * (unless the endpoint is closed), to prevent clients from blocking
- * indefinitely. In order to enforce this and prevent leaking message ids,
- * Message automatically replies with an error to the client on destruction,
- * unless one of two things happens:
- *
- *     1. The service calls one of the reply methods before the Message is
- *        destroyed.
- *     2. The responsibility for the message is moved to another instance of
- *        Message, using either move construction or move assignment.
- *
- * The second case is useful for services that need to delay responding to a
- * sender until a later time. In this situation the service can move the
- * Message to another instance in a suitable data structure for later use. The
- * moved-to Message then takes on the same behavior and responsibilities
- * described above.
- */
-class Message : public OutputResourceMapper, public InputResourceMapper {
- public:
-  Message();
-  explicit Message(const MessageInfo& info);
-  ~Message();
-
-  /*
-   * Message objects support move construction and assignment.
-   */
-  Message(Message&& other) noexcept;
-  Message& operator=(Message&& other) noexcept;
-
-  /*
-   * Read/write payload, in either single buffer or iovec form.
-   */
-  Status<size_t> ReadVector(const iovec* vector, size_t vector_length);
-  Status<size_t> Read(void* buffer, size_t length);
-  Status<size_t> WriteVector(const iovec* vector, size_t vector_length);
-  Status<size_t> Write(const void* buffer, size_t length);
-
-  template <size_t N>
-  inline Status<size_t> ReadVector(const iovec (&vector)[N]) {
-    return ReadVector(vector, N);
-  }
-
-  template <size_t N>
-  inline Status<size_t> WriteVector(const iovec (&vector)[N]) {
-    return WriteVector(vector, N);
-  }
-
-  // Helper functions to read/write all requested bytes, and return EIO if not
-  // all were read/written.
-  Status<void> ReadVectorAll(const iovec* vector, size_t vector_length);
-  Status<void> WriteVectorAll(const iovec* vector, size_t vector_length);
-
-  inline Status<void> ReadAll(void* buffer, size_t length) {
-    Status<size_t> status = Read(buffer, length);
-    if (status && status.get() < length)
-      status.SetError(EIO);
-    Status<void> ret;
-    ret.PropagateError(status);
-    return ret;
-  }
-  inline Status<void> WriteAll(const void* buffer, size_t length) {
-    Status<size_t> status = Write(buffer, length);
-    if (status && status.get() < length)
-      status.SetError(EIO);
-    Status<void> ret;
-    ret.PropagateError(status);
-    return ret;
-  }
-
-  template <size_t N>
-  inline Status<void> ReadVectorAll(const iovec (&vector)[N]) {
-    return ReadVectorAll(vector, N);
-  }
-
-  template <size_t N>
-  inline Status<void> WriteVectorAll(const iovec (&vector)[N]) {
-    return WriteVectorAll(vector, N);
-  }
-
-  // OutputResourceMapper
-  Status<FileReference> PushFileHandle(const LocalHandle& handle) override;
-  Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override;
-  Status<FileReference> PushFileHandle(const RemoteHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      const LocalChannelHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      const BorrowedChannelHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      const RemoteChannelHandle& handle) override;
-
-  // InputResourceMapper
-  bool GetFileHandle(FileReference ref, LocalHandle* handle) override;
-  bool GetChannelHandle(ChannelReference ref,
-                        LocalChannelHandle* handle) override;
-
-  /*
-   * Various ways to reply to a message.
-   */
-  Status<void> Reply(int return_code);
-  Status<void> ReplyError(unsigned int error);
-  Status<void> ReplyFileDescriptor(unsigned int fd);
-  Status<void> Reply(const LocalHandle& handle);
-  Status<void> Reply(const BorrowedHandle& handle);
-  Status<void> Reply(const RemoteHandle& handle);
-  Status<void> Reply(const LocalChannelHandle& handle);
-  Status<void> Reply(const BorrowedChannelHandle& handle);
-  Status<void> Reply(const RemoteChannelHandle& handle);
-
-  template <typename T>
-  inline Status<void> Reply(const Status<T>& status) {
-    return status ? Reply(status.get()) : ReplyError(status.error());
-  }
-
-  inline Status<void> Reply(const Status<void>& status) {
-    return status ? Reply(0) : ReplyError(status.error());
-  }
-
-  /*
-   * Update the channel event bits with the given clear and set masks.
-   */
-  Status<void> ModifyChannelEvents(int clear_mask, int set_mask);
-
-  /*
-   * Create a new channel and push it as a file descriptor to the client. See
-   * Service::PushChannel() for a detail description of this method's operation.
-   */
-  Status<RemoteChannelHandle> PushChannel(
-      int flags, const std::shared_ptr<Channel>& channel, int* channel_id);
-
-  /*
-   * Create a new channel and push it as a file descriptor to the client. See
-   * Service::PushChannel() for a detail description of this method's operation.
-   */
-  Status<RemoteChannelHandle> PushChannel(
-      Service* service, int flags, const std::shared_ptr<Channel>& channel,
-      int* channel_id);
-
-  /*
-   * Check whether the |ref| is a reference to channel to this service.
-   * If the channel reference in question is valid, the Channel object is
-   * returned in |channel| when non-nullptr.
-   *
-   * Return values:
-   *  channel_id - id of the channel if the |ref| is a valid reference to
-   *               this service's channel.
-   * Errors:
-   *  EOPNOTSUPP - the file descriptor is not a channel or is a channel to
-   *  another service.
-   *  EBADF - the file descriptor is invalid.
-   *  FAULT - |channel_id| or |channel| are non-nullptr and point to invalid
-   *  memory addresses.
-   *  EINVAL - the value of |ref| is invalid or the message id for this
-   *           message is no longer valid.
-   */
-  Status<int> CheckChannel(ChannelReference ref,
-                           std::shared_ptr<Channel>* channel) const;
-
-  /*
-   * Overload of CheckChannel() that checks whether the channel reference is for
-   * a channel to the service |service|.
-   */
-  Status<int> CheckChannel(const Service* service, ChannelReference ref,
-                           std::shared_ptr<Channel>* channel) const;
-
-  /*
-   * Overload of CheckChannel() that automatically converts to shared pointers
-   * to types derived from Channel.
-   */
-  template <class C>
-  Status<int> CheckChannel(ChannelReference ref,
-                           std::shared_ptr<C>* channel) const {
-    std::shared_ptr<Channel> base_pointer;
-    const Status<int> ret =
-        CheckChannel(ref, channel ? &base_pointer : nullptr);
-    if (channel)
-      *channel = std::static_pointer_cast<C>(base_pointer);
-    return ret;
-  }
-
-  template <class C>
-  Status<int> CheckChannel(const Service* service, ChannelReference ref,
-                           std::shared_ptr<C>* channel) const {
-    std::shared_ptr<Channel> base_pointer;
-    const Status<int> ret =
-        CheckChannel(service, ref, channel ? &base_pointer : nullptr);
-    if (channel)
-      *channel = std::static_pointer_cast<C>(base_pointer);
-    return ret;
-  }
-
-  /*
-   * MessageInfo accessors.
-   */
-  pid_t GetProcessId() const;
-  pid_t GetThreadId() const;
-  uid_t GetEffectiveUserId() const;
-  gid_t GetEffectiveGroupId() const;
-  int GetChannelId() const;
-  int GetMessageId() const;
-  int GetOp() const;
-  int GetFlags() const;
-  size_t GetSendLength() const;
-  size_t GetReceiveLength() const;
-  size_t GetFileDescriptorCount() const;
-
-  /*
-   * Impulses are asynchronous and cannot be replied to. All impulses have this
-   * invalid message id.
-   */
-  enum { IMPULSE_MESSAGE_ID = -1 };
-
-  /*
-   * Returns true if this Message describes an asynchronous "impulse" message.
-   */
-  bool IsImpulse() const { return GetMessageId() == IMPULSE_MESSAGE_ID; }
-
-  /*
-   * Returns a pointer to the impulse payload. Impulses are a maximum of 32
-   * bytes in size and the start of the impulse payload is guaranteed to be
-   * 8-byte aligned. Use GetSendLength() to determine the payload size.
-   */
-  const std::uint8_t* ImpulseBegin() const;
-
-  /*
-   * Returns one byte past the end of the impulse payload, as conventional for
-   * STL iterators.
-   */
-  const std::uint8_t* ImpulseEnd() const;
-
-  /*
-   * Get/set the Channel object for the channel associated
-   * with this message. It is up to the caller to synchronize
-   * these in multi-threaded services.
-   */
-  std::shared_ptr<Channel> GetChannel() const;
-  Status<void> SetChannel(const std::shared_ptr<Channel>& channnel);
-
-  /*
-   * Get the Channel object for the channel associated with this message,
-   * automatically converted to the desired subclass of Channel.
-   */
-  template <class C>
-  std::shared_ptr<C> GetChannel() const {
-    return std::static_pointer_cast<C>(GetChannel());
-  }
-
-  /*
-   * Gets the service this message was received on. Returns nullptr if the
-   * service was destroyed.
-   */
-  std::shared_ptr<Service> GetService() const;
-
-  /*
-   * Raw access to the MessageInfo for this message.
-   */
-  const MessageInfo& GetInfo() const;
-
-  bool replied() const { return replied_; }
-  bool IsChannelExpired() const { return channel_.expired(); }
-  bool IsServiceExpired() const { return service_.expired(); }
-
-  /*
-   * Returns true if the message is non-empty; that is the message can be
-   * replied to using this instance.
-   */
-  explicit operator bool() const { return !replied_; }
-
-  const void* GetState() const { return state_; }
-  void* GetState() { return state_; }
-
- private:
-  friend class Service;
-
-  Message(const Message&) = delete;
-  void operator=(const Message&) = delete;
-  void Destroy();
-
-  std::weak_ptr<Service> service_;
-  std::weak_ptr<Channel> channel_;
-  MessageInfo info_;
-  void* state_{nullptr};
-  bool replied_;
-};
-
-// Base class for RPC services.
-class Service : public std::enable_shared_from_this<Service> {
- public:
-  Service(const std::string& name, std::unique_ptr<Endpoint> endpoint);
-  virtual ~Service();
-
-  /*
-   * Utility to get a shared_ptr reference from the service context pointer.
-   */
-  static std::shared_ptr<Service> GetFromMessageInfo(const MessageInfo& info);
-
-  /*
-   * Returns whether initialization was successful. Subclasses that override
-   * this must call this base method and AND the results with their own. This
-   * method is not intended to do any initialization work itself, only to
-   * signal success or failure.
-   */
-  virtual bool IsInitialized() const;
-
-  /*
-   * Called by defaultHandleMessage in response to a CHANNEL_OPEN message.
-   * This gives subclasses of Service a convenient hook to create per-channel
-   * context in the form of a Channel subclass.
-   *
-   * The Channel instance returned by this is used to set the channel context
-   * pointer for the channel that was just opened.
-   */
-  virtual std::shared_ptr<Channel> OnChannelOpen(Message& message);
-
-  /*
-   * Called by defaultHandleMessage in response to a CHANNEL_CLOSE message.
-   * This give subclasses of Service a convenient hook to clean up per-channel
-   * context.
-   */
-  virtual void OnChannelClose(Message& message,
-                              const std::shared_ptr<Channel>& channel);
-
-  /*
-   * Set the channel context for the given channel. This keeps a reference to
-   * the Channel object until the channel is closed or another call replaces
-   * the current value.
-   */
-  Status<void> SetChannel(int channel_id,
-                          const std::shared_ptr<Channel>& channel);
-
-  /*
-   * Get the channel context for the given channel id. This method should be
-   * used sparingly because of the performance characteristics of the underlying
-   * map; it is intended for limited, non-critical path access from outside of
-   * message dispatch. In most cases lookup by id should be unnecessary in a
-   * properly designed service; Message::GetChannel() should be used instead
-   * whenever an operation is in the context of a message.
-   *
-   * Again, if you lookup a channel context object for a service by id in a
-   * message handling path for the same service, you're probably doing something
-   * wrong.
-   */
-  std::shared_ptr<Channel> GetChannel(int channel_id) const;
-
-  /*
-   * Get a snapshot of the active channels for this service. This is the
-   * preferred way to access the set of channels because it avoids potential
-   * deadlocks and race conditions that may occur when operating on the channel
-   * map directly. However, it is more expensive than direct iteration because
-   * of dynamic memory allocation and shared pointer reference costs.
-   *
-   * Automatically converts returned items to shared pointers of the type
-   * std::shared_ptr<C>, where C is the subclass of Channel used by the service.
-   */
-  template <class C>
-  std::vector<std::shared_ptr<C>> GetChannels() const {
-    std::lock_guard<std::mutex> autolock(channels_mutex_);
-    std::vector<std::shared_ptr<C>> items;
-    items.reserve(channels_.size());
-
-    for (const auto& pair : channels_) {
-      items.push_back(std::static_pointer_cast<C>(pair.second));
-    }
-
-    return items;
-  }
-
-  /*
-   * Close a channel, signaling the client file object and freeing the channel
-   * id. Once closed, the client side of the channel always returns the error
-   * ESHUTDOWN and signals the poll/epoll events POLLHUP and POLLFREE.
-   *
-   * The internal reference to the Channel instance associated with the channel
-   * is removed, which may result in the Channel object being freed.
-   *
-   * OnChannelClosed is not called in response to this method call.
-   */
-  Status<void> CloseChannel(int channel_id);
-
-  /*
-   * Update the event bits for the given channel (given by id), using the
-   * given clear and set masks.
-   *
-   * This is useful for asynchronously signaling events that clients may be
-   * waiting for using select/poll/epoll.
-   */
-  Status<void> ModifyChannelEvents(int channel_id, int clear_mask,
-                                   int set_mask);
-
-  /*
-   * Create a new channel and push it as a file descriptor to the process
-   * sending the |message|. |flags| may be set to O_NONBLOCK and/or
-   * O_CLOEXEC to control the initial behavior of the new file descriptor (the
-   * sending process may change these later using fcntl()). The internal Channel
-   * instance associated with this channel is set to |channel|, which may be
-   * nullptr. The new channel id allocated for this channel is returned in
-   * |channel_id|, which may also be nullptr if not needed.
-   *
-   * On success, returns the remote channel handle for the new channel in the
-   * sending process' handle space. This MUST be returned to the sender via
-   * Message::Reply(), Message::Write(), or Message::WriteVector().
-   *
-   * On error, returns an errno code describing the cause of the error.
-   *
-   * Service::OnChannelCreate() is not called in response to the creation of the
-   * new channel.
-   */
-  Status<RemoteChannelHandle> PushChannel(
-      Message* message, int flags, const std::shared_ptr<Channel>& channel,
-      int* channel_id);
-
-  /*
-   * Check whether the |ref| is a reference to a channel to this service.
-   * If the channel reference in question is valid, the Channel object is
-   * returned in |channel| when non-nullptr.
-   *
-   * Return values:
-   *  channel_id - id of the channel if the channel reference.
-   * Errors:
-   *  EOPNOTSUPP - the file descriptor is not a channel or is a channel to
-   *  another service.
-   *  EBADF - the file descriptor is invalid.
-   *  FAULT - |channel_id| or |channel| are non-nullptr and point to invalid
-   *  memory addresses.
-   *  EINVAL - the value of |ref| is invalid or the message id for this
-   *  message is no longer valid.
-   */
-  Status<int> CheckChannel(const Message* message, ChannelReference ref,
-                           std::shared_ptr<Channel>* channel) const;
-
-  /*
-   * Overload of CheckChannel() that automatically converts to shared pointers
-   * of types derived from Channel.
-   */
-  template <class C>
-  Status<int> CheckChannel(const Message* message, ChannelReference ref,
-                           std::shared_ptr<C>* channel) const {
-    std::shared_ptr<Channel> base_pointer;
-    const Status<int> ret =
-        CheckChannel(message, ref, channel ? &base_pointer : nullptr);
-    if (channel)
-      *channel = std::static_pointer_cast<C>(base_pointer);
-    return ret;
-  }
-
-  /*
-   * Handle a message. Subclasses override this to receive messages and decide
-   * how to dispatch them.
-   *
-   * The default implementation simply calls defaultHandleMessage().
-   * Subclasses should call the same for any unrecognized message opcodes.
-   */
-  virtual Status<void> HandleMessage(Message& message);
-
-  /*
-   * Handle an asynchronous message. Subclasses override this to receive
-   * asynchronous "impulse" messages. Impulses have a limited-size payload that
-   * is transferred upfront with the message description.
-   */
-  virtual void HandleImpulse(Message& impulse);
-
-  /*
-   * The default message handler. It is important that all messages
-   * (eventually) get a reply. This method should be called by subclasses for
-   * any unrecognized opcodes or otherwise unhandled messages to prevent
-   * erroneous requests from blocking indefinitely.
-   *
-   * Provides default handling of CHANNEL_OPEN and CHANNEL_CLOSE, calling
-   * OnChannelOpen() and OnChannelClose(), respectively.
-   *
-   * For all other message opcodes, this method replies with ENOTSUP.
-   */
-  Status<void> DefaultHandleMessage(Message& message);
-
-  /*
-   * Called when system properties have changed. Subclasses should implement
-   * this method if they need to handle when system properties change.
-   */
-  virtual void OnSysPropChange();
-
-  /*
-   * Get the endpoint for the service.
-   */
-  Endpoint* endpoint() const { return endpoint_.get(); }
-
-  /*
-   * Cancels the endpoint, unblocking any receiver threads waiting in
-   * ReceiveAndDispatch().
-   */
-  Status<void> Cancel();
-
-  /*
-   * Iterator type for Channel map iterators.
-   */
-  using ChannelIterator =
-      std::unordered_map<int, std::shared_ptr<Channel>>::iterator;
-
-  /*
-   * Iterates over the Channel map and performs the action given by |action| on
-   * each channel map item (const ChannelIterator::value_type).
-   * |channels_mutex_| is not held; it is the responsibility of the caller to
-   * ensure serialization between threads that modify or iterate over the
-   * Channel map.
-   */
-  template <class A>
-  void ForEachChannelUnlocked(A action) const {
-    std::for_each(channels_.begin(), channels_.end(), action);
-  }
-
-  /*
-   * Iterates over the Channel map and performs the action given by |action| on
-   * each channel map item (const ChannelIterator::value_type).
-   * |channels_mutex_| is held to serialize access to the map; care must be
-   * taken to avoid recursively acquiring the mutex, for example, by calling
-   * Service::{GetChannel,SetChannel,CloseChannel,PushChannel}() or
-   * Message::SetChannel() in the action.
-   */
-  template <class A>
-  void ForEachChannel(A action) const {
-    std::lock_guard<std::mutex> autolock(channels_mutex_);
-    ForEachChannelUnlocked(action);
-  }
-
-  /*
-   * Return true if a channel with the given ID exists in the Channel map.
-   */
-  bool HasChannelId(int channel_id) const {
-    std::lock_guard<std::mutex> autolock(channels_mutex_);
-    return channels_.find(channel_id) != channels_.end();
-  }
-
-  /*
-   * Subclasses of Service may override this method to provide a text string
-   * describing the state of the service. This method is called by
-   * HandleSystemMessage in response to the standard
-   * DUMP_STATE message. The string returned to the dump state client is
-   * truncated to |max_length| and reflects the maximum size the client can
-   * handle.
-   */
-  virtual std::string DumpState(size_t max_length);
-
-  /*
-   * Receives a message on this Service instance's endpoint and dispatches it.
-   * If the endpoint is in blocking mode this call blocks until a message is
-   * received, a signal is delivered to this thread, or the service is canceled.
-   * If the endpoint is in non-blocking mode and a message is not pending this
-   * call returns immediately with ETIMEDOUT.
-   */
-  Status<void> ReceiveAndDispatch();
-
- private:
-  friend class Message;
-
-  Status<void> HandleSystemMessage(Message& message);
-
-  Service(const Service&);
-  void operator=(const Service&) = delete;
-
-  const std::string name_;
-  std::unique_ptr<Endpoint> endpoint_;
-
-  /*
-   * Maintains references to active channels.
-   */
-  mutable std::mutex channels_mutex_;
-  std::unordered_map<int, std::shared_ptr<Channel>> channels_;
-};
-
-/*
- * Utility base class for services. This template handles allocation and
- * initialization checks, reducing boiler plate code.
- */
-template <typename TYPE>
-class ServiceBase : public Service {
- public:
-  /*
-   * Static service allocation method that check for initialization errors.
-   * If errors are encountered these automatically clean up and return
-   * nullptr.
-   */
-  template <typename... Args>
-  static inline std::shared_ptr<TYPE> Create(Args&&... args) {
-    std::shared_ptr<TYPE> service(new TYPE(std::forward<Args>(args)...));
-    if (service->IsInitialized())
-      return service;
-    else
-      return nullptr;
-  }
-
- protected:
-  /*
-   * Shorthand for subclasses to refer to this base, particularly
-   * to call the base class constructor.
-   */
-  typedef ServiceBase<TYPE> BASE;
-
-  ServiceBase(const std::string& name, std::unique_ptr<Endpoint> endpoint)
-      : Service(name, std::move(endpoint)) {}
-};
-
-#ifndef STRINGIFY
-#define STRINGIFY2(s) #s
-#define STRINGIFY(s) STRINGIFY2(s)
-#endif
-
-#define PDX_ERROR_PREFIX "[" __FILE__ ":" STRINGIFY(__LINE__) "]"
-
-/*
- * Macros for replying to messages. Error handling can be tedious;
- * these macros make things a little cleaner.
- */
-#define CHECK_ERROR(cond, error, fmt, ...) \
-  do {                                     \
-    if ((cond)) {                          \
-      ALOGE(fmt, ##__VA_ARGS__);           \
-      goto error;                          \
-    }                                      \
-  } while (0)
-
-#define REPLY_ERROR(message, error, error_label)                              \
-  do {                                                                        \
-    auto __status = message.ReplyError(error);                                \
-    CHECK_ERROR(!__status, error_label,                                       \
-                PDX_ERROR_PREFIX " Failed to reply to message because: %s\n", \
-                __status.GetErrorMessage().c_str());                          \
-    goto error_label;                                                         \
-  } while (0)
-
-#define REPLY_ERROR_RETURN(message, error, ...)                          \
-  do {                                                                   \
-    auto __status = message.ReplyError(error);                           \
-    ALOGE_IF(!__status,                                                  \
-             PDX_ERROR_PREFIX " Failed to reply to message because: %s", \
-             __status.GetErrorMessage().c_str());                        \
-    return __VA_ARGS__;                                                  \
-  } while (0)
-
-#define REPLY_MESSAGE(message, message_return_code, error_label)              \
-  do {                                                                        \
-    auto __status = message.Reply(message_return_code);                       \
-    CHECK_ERROR(!__status, error_label,                                       \
-                PDX_ERROR_PREFIX " Failed to reply to message because: %s\n", \
-                __status.GetErrorMessage().c_str());                          \
-    goto error_label;                                                         \
-  } while (0)
-
-#define REPLY_SUCCESS(message, message_return_code, error_label) \
-  REPLY_MESSAGE(message, message_return_code, error_label)
-
-#define REPLY_MESSAGE_RETURN(message, message_return_code, ...)          \
-  do {                                                                   \
-    auto __status = message.Reply(message_return_code);                  \
-    ALOGE_IF(!__status,                                                  \
-             PDX_ERROR_PREFIX " Failed to reply to message because: %s", \
-             __status.GetErrorMessage().c_str());                        \
-    return __VA_ARGS__;                                                  \
-  } while (0)
-
-#define REPLY_SUCCESS_RETURN(message, message_return_code, ...) \
-  REPLY_MESSAGE_RETURN(message, message_return_code, __VA_ARGS__)
-
-#define REPLY_FD(message, push_fd, error_label)                               \
-  do {                                                                        \
-    auto __status = message.ReplyFileDescriptor(push_fd);                     \
-    CHECK_ERROR(!__status, error_label,                                       \
-                PDX_ERROR_PREFIX " Failed to reply to message because: %s\n", \
-                __status.GetErrorMessage().c_str());                          \
-    goto error_label;                                                         \
-  } while (0)
-
-#define REPLY_FD_RETURN(message, push_fd, ...)                           \
-  do {                                                                   \
-    auto __status = message.ReplyFileDescriptor(push_fd);                \
-    ALOGE_IF(__status < 0,                                               \
-             PDX_ERROR_PREFIX " Failed to reply to message because: %s", \
-             __status.GetErrorMessage().c_str());                        \
-    return __VA_ARGS__;                                                  \
-  } while (0)
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_SERVICE_H_
diff --git a/libs/vr/libpdx/private/pdx/service_dispatcher.h b/libs/vr/libpdx/private/pdx/service_dispatcher.h
deleted file mode 100644
index bd27000..0000000
--- a/libs/vr/libpdx/private/pdx/service_dispatcher.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef ANDROID_PDX_SERVICE_DISPATCHER_H_
-#define ANDROID_PDX_SERVICE_DISPATCHER_H_
-
-#include <memory>
-#include <mutex>
-#include <unordered_map>
-#include <vector>
-
-#include <pdx/file_handle.h>
-
-namespace android {
-namespace pdx {
-
-class Service;
-
-/*
- * ServiceDispatcher manages a list of Service instances and handles message
- * reception and dispatch to the services. This makes repetitive dispatch tasks
- * easier to implement.
- */
-class ServiceDispatcher {
- public:
-  // Get a new instance of ServiceDispatcher, or return nullptr if init failed.
-  static std::unique_ptr<ServiceDispatcher> Create();
-
-  ~ServiceDispatcher();
-
-  /*
-   * Adds a service to the list of services handled by this dispatcher. This
-   * will fail if any threads are blocked waiting for messages in this
-   * dispatcher.
-   *
-   * Returns 0 on success; -EEXIST if the service was already added.
-   */
-  int AddService(const std::shared_ptr<Service>& service);
-
-  /*
-   * Removes a service from this dispatcher. This will fail if any threads are
-   * blocked waiting for messages in this dispatcher.
-   *
-   * Returns 0 on success; -ENOENT if the service was not previously added;
-   * -EBUSY if there are threads in the dispatcher.
-   */
-  int RemoveService(const std::shared_ptr<Service>& service);
-
-  /*
-   * Receive and dispatch one set of messages. Multiple threads may enter this
-   * method to create an implicit thread pool, as described for
-   * enterDispatchLoop() below, however this method exits after one dispatch
-   * cycle, requiring an external loop. This is useful when other work needs
-   * to be done in the service dispatch loop.
-   */
-  int ReceiveAndDispatch();
-
-  /*
-   * Same as above with timeout in milliseconds. A negative value means
-   * infinite timeout, while a value of 0 means return immediately if no
-   * messages are available to receive.
-   */
-  int ReceiveAndDispatch(int timeout);
-
-  /*
-   * Receive and dispatch messages until canceled. When more than one thread
-   * enters this method it creates an implicit thread pool to dispatch messages.
-   * Explicit thread pools may be created by using a single dispatch thread that
-   * hands Message instances (via move assignment) over to a queue of threads
-   * (or perhaps one of several) to handle.
-   */
-  int EnterDispatchLoop();
-
-  /*
-   * Sets the canceled state of the dispatcher. When canceled is true, any
-   * threads blocked waiting for messages will return. This method waits until
-   * all dispatch threads have exited the dispatcher.
-   */
-  void SetCanceled(bool cancel);
-
-  /*
-   * Gets the canceled state of the dispatcher.
-   */
-  bool IsCanceled() const;
-
- private:
-  ServiceDispatcher();
-
-  // Internal thread accounting.
-  int ThreadEnter();
-  void ThreadExit();
-
-  std::mutex mutex_;
-  std::condition_variable condition_;
-  std::atomic<bool> canceled_{false};
-
-  std::vector<std::shared_ptr<Service>> services_;
-
-  int thread_count_ = 0;
-  LocalHandle event_fd_;
-  LocalHandle epoll_fd_;
-
-  ServiceDispatcher(const ServiceDispatcher&) = delete;
-  void operator=(const ServiceDispatcher&) = delete;
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_SERVICE_DISPATCHER_H_
diff --git a/libs/vr/libpdx/private/pdx/service_endpoint.h b/libs/vr/libpdx/private/pdx/service_endpoint.h
deleted file mode 100644
index d581894..0000000
--- a/libs/vr/libpdx/private/pdx/service_endpoint.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef ANDROID_PDX_ENDPOINT_H_
-#define ANDROID_PDX_ENDPOINT_H_
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/status.h>
-
-struct iovec;
-
-namespace android {
-namespace pdx {
-
-class Service;
-class Channel;
-class Message;
-
-struct MessageInfo {
-  int pid{0};
-  int tid{0};
-  int cid{0};
-  int mid{0};
-  int euid{0};
-  int egid{0};
-  int32_t op{0};
-  uint32_t flags{0};
-  Service* service{nullptr};
-  Channel* channel{nullptr};
-  size_t send_len{0};
-  size_t recv_len{0};
-  size_t fd_count{0};
-  uint64_t impulse[4] = {};
-};
-
-// Wrapper around transport endpoint. Abstracts the underlying transport APIs in
-// a way, that the underlying IPC can be substituted for another technology
-// without changing the Service, Client and Message classes of this library.
-class Endpoint {
- public:
-  virtual ~Endpoint() = default;
-
-  // Returns a tag that uniquely identifies a specific underlying IPC transport.
-  virtual uint32_t GetIpcTag() const = 0;
-
-  // Associates a Service instance with an endpoint by setting the service
-  // context pointer to the address of the Service. Only one Service may be
-  // associated with a given endpoint.
-  virtual Status<void> SetService(Service* service) = 0;
-
-  // Set the channel context for the given channel.
-  virtual Status<void> SetChannel(int channel_id, Channel* channel) = 0;
-
-  // Close a channel, signaling the client file object and freeing the channel
-  // id. Once closed, the client side of the channel always returns the error
-  // ESHUTDOWN and signals the poll/epoll events POLLHUP and POLLFREE.
-  virtual Status<void> CloseChannel(int channel_id) = 0;
-
-  // Update the event bits for the given channel (given by id), using the
-  // given clear and set masks.
-  virtual Status<void> ModifyChannelEvents(int channel_id, int clear_mask,
-                                           int set_mask) = 0;
-
-  // Create a new channel and push it as a file descriptor to the process
-  // sending the |message|. |flags| may be set to O_NONBLOCK and/or
-  // O_CLOEXEC to control the initial behavior of the new file descriptor (the
-  // sending process may change these later using fcntl()). The internal Channel
-  // instance associated with this channel is set to |channel|, which may be
-  // nullptr. The new channel id allocated for this channel is returned in
-  // |channel_id|, which may also be nullptr if not needed.
-  virtual Status<RemoteChannelHandle> PushChannel(Message* message, int flags,
-                                                  Channel* channel,
-                                                  int* channel_id) = 0;
-
-  // Check whether the |ref| is a reference to a channel to the service
-  // represented by the |endpoint|. If the channel reference in question is
-  // valid, the Channel object is returned in |channel| when non-nullptr and
-  // the channel ID is returned through the Status object.
-  virtual Status<int> CheckChannel(const Message* message, ChannelReference ref,
-                                   Channel** channel) = 0;
-
-  // Receives a message on the given endpoint file descriptor.
-  virtual Status<void> MessageReceive(Message* message) = 0;
-
-  // Replies to the message with a return code.
-  virtual Status<void> MessageReply(Message* message, int return_code) = 0;
-
-  // Replies to the message with a file descriptor.
-  virtual Status<void> MessageReplyFd(Message* message,
-                                      unsigned int push_fd) = 0;
-
-  // Replies to the message with a local channel handle.
-  virtual Status<void> MessageReplyChannelHandle(
-      Message* message, const LocalChannelHandle& handle) = 0;
-
-  // Replies to the message with a borrowed local channel handle.
-  virtual Status<void> MessageReplyChannelHandle(
-      Message* message, const BorrowedChannelHandle& handle) = 0;
-
-  // Replies to the message with a remote channel handle.
-  virtual Status<void> MessageReplyChannelHandle(
-      Message* message, const RemoteChannelHandle& handle) = 0;
-
-  // Reads message data into an array of memory buffers.
-  virtual Status<size_t> ReadMessageData(Message* message, const iovec* vector,
-                                         size_t vector_length) = 0;
-
-  // Sends reply data for message.
-  virtual Status<size_t> WriteMessageData(Message* message, const iovec* vector,
-                                          size_t vector_length) = 0;
-
-  // Records a file descriptor into the message buffer and returns the remapped
-  // reference to be sent to the remote process.
-  virtual Status<FileReference> PushFileHandle(Message* message,
-                                               const LocalHandle& handle) = 0;
-  virtual Status<FileReference> PushFileHandle(
-      Message* message, const BorrowedHandle& handle) = 0;
-  virtual Status<FileReference> PushFileHandle(Message* message,
-                                               const RemoteHandle& handle) = 0;
-  virtual Status<ChannelReference> PushChannelHandle(
-      Message* message, const LocalChannelHandle& handle) = 0;
-  virtual Status<ChannelReference> PushChannelHandle(
-      Message* message, const BorrowedChannelHandle& handle) = 0;
-  virtual Status<ChannelReference> PushChannelHandle(
-      Message* message, const RemoteChannelHandle& handle) = 0;
-
-  // Obtains a file descriptor/channel handle from a message for the given
-  // reference.
-  virtual LocalHandle GetFileHandle(Message* message,
-                                    FileReference ref) const = 0;
-  virtual LocalChannelHandle GetChannelHandle(Message* message,
-                                              ChannelReference ref) const = 0;
-
-  // Transport-specific message state management.
-  virtual void* AllocateMessageState() = 0;
-  virtual void FreeMessageState(void* state) = 0;
-
-  // Cancels the endpoint, unblocking any receiver threads waiting for a
-  // message.
-  virtual Status<void> Cancel() = 0;
-
-  // Returns an fd that can be used with epoll() to wait for incoming messages
-  // from this endpoint.
-  virtual int epoll_fd() const = 0;
-};
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_ENDPOINT_H_
diff --git a/libs/vr/libpdx/private/pdx/status.h b/libs/vr/libpdx/private/pdx/status.h
deleted file mode 100644
index 498dd6d..0000000
--- a/libs/vr/libpdx/private/pdx/status.h
+++ /dev/null
@@ -1,183 +0,0 @@
-#ifndef ANDROID_PDX_STATUS_H_
-#define ANDROID_PDX_STATUS_H_
-
-#include <algorithm>
-#include <memory>
-#include <string>
-
-namespace android {
-namespace pdx {
-
-// This is a helper class for constructing Status<T> with an error code.
-struct ErrorStatus {
- public:
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  ErrorStatus(int error) : error_{error} {}
-  int error() const { return error_; }
-
-  static std::string ErrorToString(int error_code);
-
- private:
-  int error_;
-};
-
-// Status<T> is a container class that can be used to return a value of type T
-// or error code to the caller.
-template <typename T>
-class Status {
- public:
-  // Default constructor so an empty Status object can be created.
-  Status() : error_{-1} {}
-
-  // Value copy/move constructors. These are intentionally not marked as
-  // explicit to allow direct value returns from functions without having
-  // to explicitly wrap them into Status<T>().
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  Status(const T& value) : value_{value} {}
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  Status(T&& value) : value_{std::move(value)} {}
-
-  // Constructor for storing an error code inside the Status object.
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  Status(const ErrorStatus& error_status) : error_{error_status.error()} {}
-
-  // Copy/move constructors. Move constructor leaves |other| object in empty
-  // state.
-  Status(const Status& other) = default;
-  Status(Status&& other) noexcept
-      : value_{std::move(other.value_)}, error_{other.error_} {
-    other.error_ = -1;
-  }
-
-  // Assignment operators.
-  Status& operator=(const Status& other) = default;
-  Status& operator=(Status&& other) noexcept {
-    error_ = other.error_;
-    value_ = std::move(other.value_);
-    other.error_ = -1;
-    T empty;
-    std::swap(other.value_, empty);
-    return *this;
-  }
-
-  // Change the value/error code of the status object directly.
-  void SetValue(T value) {
-    error_ = 0;
-    value_ = std::move(value);
-  }
-  void SetError(int error) {
-    error_ = error;
-    T empty;
-    std::swap(value_, empty);
-  }
-
-  // If |other| is in error state, copy the error code to this object.
-  // Returns true if error was propagated
-  template<typename U>
-  bool PropagateError(const Status<U>& other) {
-    if (!other.ok() && !other.empty()) {
-      SetError(other.error());
-      return true;
-    }
-    return false;
-  }
-
-  // Returns true if the status object contains valid value for type T.
-  // This means, the object is not empty and does not contain an error code.
-  bool ok() const { return error_ == 0; }
-
-  // Checks if the object is empty (doesn't contain a valid value nor an error).
-  bool empty() const { return error_ < 0; }
-
-  // Explicit bool conversion, equivalent to invoking ok().
-  explicit operator bool() const { return ok(); }
-
-  // Accessors for the value stored in Status. Calling when ok() is false leads
-  // to undefined behavior.
-  const T& get() const { return value_; }
-  T&& take() {
-    error_ = -1;
-    return std::move(value_);
-  }
-
-  // Returns the error code stored in the object. These codes are positive
-  // non-zero values.
-  // Can be called only when an error is actually stored (that is, the object
-  // is not empty nor containing a valid value).
-  int error() const { return std::max(error_, 0); }
-
-  // Returns the error code as ErrorStatus object. This is a helper method
-  // to aid in propagation of error codes between Status<T> of different types
-  // as in the following example:
-  //    Status<int> foo() {
-  //      Status<void> status = bar();
-  //      if(!status)
-  //        return status.error_status();
-  //      return 12;
-  //    }
-  inline ErrorStatus error_status() const { return ErrorStatus{error()}; }
-
-  // Returns the error message associated with error code stored in the object.
-  // The message is the same as the string returned by strerror(status.error()).
-  // Can be called only when an error is actually stored (that is, the object
-  // is not empty nor containing a valid value).
-  std::string GetErrorMessage() const {
-    std::string message;
-    if (error_ > 0)
-      message = ErrorStatus::ErrorToString(error_);
-    return message;
-  }
-
- private:
-  T value_{};
-  int error_{0};
-};
-
-// Specialization for status containing no other value but the error code.
-template <>
-class Status<void> {
- public:
-  Status() = default;
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  Status(const ErrorStatus& error_status) : error_{error_status.error()} {}
-  void SetValue() { error_ = 0; }
-  void SetError(int error) { error_ = error; }
-
-  template<typename U>
-  bool PropagateError(const Status<U>& other) {
-    if (!other.ok() && !other.empty()) {
-      SetError(other.error());
-      return true;
-    }
-    return false;
-  }
-
-  bool ok() const { return error_ == 0; }
-  bool empty() const { return false; }
-  explicit operator bool() const { return ok(); }
-  int error() const { return std::max(error_, 0); }
-  inline ErrorStatus error_status() const { return ErrorStatus{error()}; }
-  std::string GetErrorMessage() const {
-    std::string message;
-    if (error_ > 0)
-      message = ErrorStatus::ErrorToString(error_);
-    return message;
-  }
-
- private:
-  int error_{0};
-};
-
-// TODO(avakulenko): Remove these function once all callers of it are gone.
-inline int ReturnStatusOrError(const Status<void>& status) {
-  return status ? 0 : -status.error();
-}
-
-inline int ReturnStatusOrError(const Status<int>& status) {
-  return status ? status.get() : -status.error();
-}
-
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_STATUS_H_
diff --git a/libs/vr/libpdx/private/pdx/trace.h b/libs/vr/libpdx/private/pdx/trace.h
deleted file mode 100644
index c687fd6..0000000
--- a/libs/vr/libpdx/private/pdx/trace.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef ANDROID_PDX_TRACE_H_
-#define ANDROID_PDX_TRACE_H_
-
-#include <array>
-
-#include <utils/Trace.h>
-
-// Enables internal tracing in libpdx. This is disabled by default to avoid
-// spamming the trace buffers during normal trace activities. libpdx must be
-// built with this set to true to enable internal tracing.
-#ifndef PDX_LIB_TRACE_ENABLED
-#define PDX_LIB_TRACE_ENABLED false
-#endif
-
-namespace android {
-namespace pdx {
-
-// Utility to generate scoped tracers with arguments.
-class ScopedTraceArgs {
- public:
-  template <typename... Args>
-  ScopedTraceArgs(uint64_t tag, const char* format, Args&&... args)
-      : tag_{tag} {
-    if (atrace_is_tag_enabled(tag_)) {
-      std::array<char, 1024> buffer;
-      snprintf(buffer.data(), buffer.size(), format,
-               std::forward<Args>(args)...);
-      atrace_begin(tag_, buffer.data());
-    }
-  }
-
-  ~ScopedTraceArgs() { atrace_end(tag_); }
-
- private:
-  uint64_t tag_;
-
-  ScopedTraceArgs(const ScopedTraceArgs&) = delete;
-  void operator=(const ScopedTraceArgs&) = delete;
-};
-
-// Utility to generate scoped tracers.
-class ScopedTrace {
- public:
-  template <typename... Args>
-  ScopedTrace(uint64_t tag, bool enabled, const char* name)
-      : tag_{tag}, enabled_{enabled} {
-    if (enabled_)
-      atrace_begin(tag_, name);
-  }
-
-  ~ScopedTrace() {
-    if (enabled_)
-      atrace_end(tag_);
-  }
-
- private:
-  uint64_t tag_;
-  bool enabled_;
-
-  ScopedTrace(const ScopedTrace&) = delete;
-  void operator=(const ScopedTrace&) = delete;
-};
-
-}  // namespace pdx
-}  // namespace android
-
-// Macro to define a scoped tracer with arguments. Uses PASTE(x, y) macro
-// defined in utils/Trace.h.
-#define PDX_TRACE_FORMAT(format, ...)                         \
-  ::android::pdx::ScopedTraceArgs PASTE(__tracer, __LINE__) { \
-    ATRACE_TAG, format, ##__VA_ARGS__                         \
-  }
-
-// TODO(eieio): Rename this to PDX_LIB_TRACE_NAME() for internal use by libpdx
-// and rename internal uses inside the library. This version is only enabled
-// when PDX_LIB_TRACE_ENABLED is true.
-#define PDX_TRACE_NAME(name)                              \
-  ::android::pdx::ScopedTrace PASTE(__tracer, __LINE__) { \
-    ATRACE_TAG, PDX_LIB_TRACE_ENABLED, name               \
-  }
-
-#endif  // ANDROID_PDX_TRACE_H_
diff --git a/libs/vr/libpdx/private/pdx/utility.h b/libs/vr/libpdx/private/pdx/utility.h
deleted file mode 100644
index c9a0c21..0000000
--- a/libs/vr/libpdx/private/pdx/utility.h
+++ /dev/null
@@ -1,369 +0,0 @@
-#ifndef ANDROID_PDX_UTILITY_H_
-#define ANDROID_PDX_UTILITY_H_
-
-#include <cstdint>
-#include <cstdlib>
-#include <iterator>
-
-#include <pdx/rpc/sequence.h>
-
-// Utilities for testing object serialization.
-
-namespace android {
-namespace pdx {
-
-class ByteBuffer {
- public:
-  using iterator = uint8_t*;
-  using const_iterator = const uint8_t*;
-  using size_type = size_t;
-
-  ByteBuffer() = default;
-  ByteBuffer(const ByteBuffer& other) {
-    resize(other.size());
-    if (other.size())
-      memcpy(data_, other.data(), other.size());
-  }
-  ~ByteBuffer() { std::free(data_); }
-
-  ByteBuffer& operator=(const ByteBuffer& other) {
-    resize(other.size());
-    if (other.size())
-      memcpy(data_, other.data(), other.size());
-    return *this;
-  }
-
-  ByteBuffer& operator=(ByteBuffer&& other) noexcept {
-    std::swap(data_, other.data_);
-    std::swap(size_, other.size_);
-    std::swap(capacity_, other.capacity_);
-    other.clear();
-    return *this;
-  }
-
-  inline const uint8_t* data() const { return data_; }
-  inline uint8_t* data() { return data_; }
-  inline size_t size() const { return size_; }
-  inline size_t capacity() const { return capacity_; }
-
-  iterator begin() { return data_; }
-  const_iterator begin() const { return data_; }
-  iterator end() { return data_ + size_; }
-  const_iterator end() const { return data_ + size_; }
-
-  inline bool operator==(const ByteBuffer& other) const {
-    return size_ == other.size_ &&
-           (size_ == 0 || memcmp(data_, other.data_, size_) == 0);
-  }
-
-  inline bool operator!=(const ByteBuffer& other) const {
-    return !operator==(other);
-  }
-
-  inline void reserve(size_t size) {
-    if (size <= capacity_)
-      return;
-    // Find next power of 2 (assuming the size is 32 bits for now).
-    size--;
-    size |= size >> 1;
-    size |= size >> 2;
-    size |= size >> 4;
-    size |= size >> 8;
-    size |= size >> 16;
-    size++;
-    void* new_data = data_ ? std::realloc(data_, size) : std::malloc(size);
-    // TODO(avakulenko): Check for allocation failures.
-    data_ = static_cast<uint8_t*>(new_data);
-    capacity_ = size;
-  }
-
-  inline void resize(size_t size) {
-    reserve(size);
-    size_ = size;
-  }
-
-  inline uint8_t* grow_by(size_t size_delta) {
-    size_t old_size = size_;
-    resize(old_size + size_delta);
-    return data_ + old_size;
-  }
-
-  inline void clear() { size_ = 0; }
-
- private:
-  uint8_t* data_{nullptr};
-  size_t size_{0};
-  size_t capacity_{0};
-};
-
-// Utility functions to increment/decrement void pointers to data buffers.
-template <typename OFFSET_T>
-inline const void* AdvancePointer(const void* ptr, OFFSET_T offset) {
-  return static_cast<const uint8_t*>(ptr) + offset;
-}
-
-template <typename OFFSET_T>
-inline void* AdvancePointer(void* ptr, OFFSET_T offset) {
-  return static_cast<uint8_t*>(ptr) + offset;
-}
-
-inline ptrdiff_t PointerDistance(const void* end, const void* begin) {
-  return static_cast<const uint8_t*>(end) - static_cast<const uint8_t*>(begin);
-}
-
-// Utility to build sequences of types.
-template <typename, typename>
-struct AppendTypeSequence;
-
-template <typename T, typename... S, template <typename...> class TT>
-struct AppendTypeSequence<T, TT<S...>> {
-  using type = TT<S..., T>;
-};
-
-// Utility to generate repeated types.
-template <typename T, std::size_t N, template <typename...> class TT>
-struct RepeatedType {
-  using type = typename AppendTypeSequence<
-      T, typename RepeatedType<T, N - 1, TT>::type>::type;
-};
-
-template <typename T, template <typename...> class TT>
-struct RepeatedType<T, 0, TT> {
-  using type = TT<>;
-};
-
-template <typename V, typename S>
-inline V ReturnValueHelper(V value, S /*ignore*/) {
-  return value;
-}
-
-template <typename R, typename V, size_t... S>
-inline R GetNTupleHelper(V value, rpc::IndexSequence<S...>) {
-  return std::make_tuple(ReturnValueHelper(value, S)...);
-}
-
-// Returns an N-tuple of type std::tuple<T,...T> containing |value| in each
-// element.
-template <size_t N, typename T,
-          typename R = typename RepeatedType<T, N, std::tuple>::type>
-inline R GetNTuple(T value) {
-  return GetNTupleHelper<R>(value, rpc::MakeIndexSequence<N>{});
-}
-
-class NoOpOutputResourceMapper : public OutputResourceMapper {
- public:
-  Status<FileReference> PushFileHandle(const LocalHandle& handle) override {
-    return handle.Get();
-  }
-
-  Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override {
-    return handle.Get();
-  }
-
-  Status<FileReference> PushFileHandle(const RemoteHandle& handle) override {
-    return handle.Get();
-  }
-
-  Status<ChannelReference> PushChannelHandle(
-      const LocalChannelHandle& handle) override {
-    return handle.value();
-  }
-
-  Status<ChannelReference> PushChannelHandle(
-      const BorrowedChannelHandle& handle) override {
-    return handle.value();
-  }
-
-  Status<ChannelReference> PushChannelHandle(
-      const RemoteChannelHandle& handle) override {
-    return handle.value();
-  }
-};
-
-class NoOpInputResourceMapper : public InputResourceMapper {
- public:
-  bool GetFileHandle(FileReference ref, LocalHandle* handle) override {
-    *handle = LocalHandle{ref};
-    return true;
-  }
-
-  bool GetChannelHandle(ChannelReference ref,
-                        LocalChannelHandle* handle) override {
-    *handle = LocalChannelHandle{nullptr, ref};
-    return true;
-  }
-};
-
-class NoOpResourceMapper : public NoOpOutputResourceMapper,
-                           public NoOpInputResourceMapper {};
-
-// Simple implementation of the payload interface, required by
-// Serialize/Deserialize. This is intended for test cases, where compatibility
-// with std::vector is helpful.
-class Payload : public MessageWriter,
-                public MessageReader,
-                public OutputResourceMapper {
- public:
-  using BaseType = ByteBuffer;
-  using iterator = typename BaseType::iterator;
-  using const_iterator = typename BaseType::const_iterator;
-  using size_type = typename BaseType::size_type;
-
-  Payload() = default;
-  explicit Payload(size_type count, uint8_t value = 0) { Append(count, value); }
-  Payload(const Payload& other) : buffer_(other.buffer_) {}
-  Payload(const std::initializer_list<uint8_t>& initializer) {
-    buffer_.resize(initializer.size());
-    std::copy(initializer.begin(), initializer.end(), buffer_.begin());
-  }
-
-  Payload& operator=(const Payload& other) {
-    buffer_ = other.buffer_;
-    read_pos_ = 0;
-    return *this;
-  }
-  Payload& operator=(const std::initializer_list<uint8_t>& initializer) {
-    buffer_.resize(initializer.size());
-    std::copy(initializer.begin(), initializer.end(), buffer_.begin());
-    read_pos_ = 0;
-    return *this;
-  }
-
-  // Compares Payload with Payload.
-  bool operator==(const Payload& other) const {
-    return buffer_ == other.buffer_;
-  }
-  bool operator!=(const Payload& other) const {
-    return buffer_ != other.buffer_;
-  }
-
-  // Compares Payload with std::vector.
-  template <typename Type, typename AllocatorType>
-  typename std::enable_if<sizeof(Type) == sizeof(uint8_t), bool>::type
-  operator==(const std::vector<Type, AllocatorType>& other) const {
-    return buffer_.size() == other.size() &&
-           memcmp(buffer_.data(), other.data(), other.size()) == 0;
-  }
-  template <typename Type, typename AllocatorType>
-  typename std::enable_if<sizeof(Type) == sizeof(uint8_t), bool>::type
-  operator!=(const std::vector<Type, AllocatorType>& other) const {
-    return !operator!=(other);
-  }
-
-  iterator begin() { return buffer_.begin(); }
-  const_iterator begin() const { return buffer_.begin(); }
-  iterator end() { return buffer_.end(); }
-  const_iterator end() const { return buffer_.end(); }
-
-  void Append(size_type count, uint8_t value) {
-    auto* data = buffer_.grow_by(count);
-    std::fill(data, data + count, value);
-  }
-
-  void Clear() {
-    buffer_.clear();
-    file_handles_.clear();
-    read_pos_ = 0;
-  }
-
-  void Rewind() { read_pos_ = 0; }
-
-  uint8_t* Data() { return buffer_.data(); }
-  const uint8_t* Data() const { return buffer_.data(); }
-  size_type Size() const { return buffer_.size(); }
-
-  // MessageWriter
-  void* GetNextWriteBufferSection(size_t size) override {
-    return buffer_.grow_by(size);
-  }
-
-  OutputResourceMapper* GetOutputResourceMapper() override { return this; }
-
-  // OutputResourceMapper
-  Status<FileReference> PushFileHandle(const LocalHandle& handle) override {
-    if (handle) {
-      const int ref = file_handles_.size();
-      file_handles_.push_back(handle.Get());
-      return ref;
-    } else {
-      return handle.Get();
-    }
-  }
-
-  Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override {
-    if (handle) {
-      const int ref = file_handles_.size();
-      file_handles_.push_back(handle.Get());
-      return ref;
-    } else {
-      return handle.Get();
-    }
-  }
-
-  Status<FileReference> PushFileHandle(const RemoteHandle& handle) override {
-    return handle.Get();
-  }
-
-  Status<ChannelReference> PushChannelHandle(
-      const LocalChannelHandle& handle) override {
-    if (handle) {
-      const int ref = file_handles_.size();
-      file_handles_.push_back(handle.value());
-      return ref;
-    } else {
-      return handle.value();
-    }
-  }
-
-  Status<ChannelReference> PushChannelHandle(
-      const BorrowedChannelHandle& handle) override {
-    if (handle) {
-      const int ref = file_handles_.size();
-      file_handles_.push_back(handle.value());
-      return ref;
-    } else {
-      return handle.value();
-    }
-  }
-
-  Status<ChannelReference> PushChannelHandle(
-      const RemoteChannelHandle& handle) override {
-    return handle.value();
-  }
-
-  // MessageReader
-  BufferSection GetNextReadBufferSection() override {
-    return {buffer_.data() + read_pos_, &*buffer_.end()};
-  }
-
-  void ConsumeReadBufferSectionData(const void* new_start) override {
-    read_pos_ = PointerDistance(new_start, buffer_.data());
-  }
-
-  InputResourceMapper* GetInputResourceMapper() override {
-    return &input_resource_mapper_;
-  }
-
-  const int* FdArray() const { return file_handles_.data(); }
-  std::size_t FdCount() const { return file_handles_.size(); }
-
- private:
-  NoOpInputResourceMapper input_resource_mapper_;
-  ByteBuffer buffer_;
-  std::vector<int> file_handles_;
-  size_t read_pos_{0};
-};
-
-}  // namespace pdx
-}  // namespace android
-
-// Helper macros for branch prediction hinting.
-#ifdef __GNUC__
-#define PDX_LIKELY(x) __builtin_expect(!!(x), true)
-#define PDX_UNLIKELY(x) __builtin_expect(!!(x), false)
-#else
-#define PDX_LIKELY(x) (x)
-#define PDX_UNLIKELY(x) (x)
-#endif
-
-#endif  // ANDROID_PDX_UTILITY_H_
diff --git a/libs/vr/libpdx/serialization_tests.cpp b/libs/vr/libpdx/serialization_tests.cpp
deleted file mode 100644
index ee800f6..0000000
--- a/libs/vr/libpdx/serialization_tests.cpp
+++ /dev/null
@@ -1,2505 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <memory>
-#include <string>
-#include <thread>
-#include <utility>
-
-#include <gtest/gtest.h>
-#include <pdx/rpc/argument_encoder.h>
-#include <pdx/rpc/array_wrapper.h>
-#include <pdx/rpc/default_initialization_allocator.h>
-#include <pdx/rpc/payload.h>
-#include <pdx/rpc/serializable.h>
-#include <pdx/rpc/serialization.h>
-#include <pdx/rpc/string_wrapper.h>
-#include <pdx/utility.h>
-
-using namespace android::pdx;
-using namespace android::pdx::rpc;
-
-// Tests the serialization/deserialization of all supported types, verifying all
-// reasonable boundary conditions for types with multiple encodings.
-//
-// NOTE: Sometimes this file uses the construct "var = decltype(var)({...})"
-// instead of the equivalent "var = {...}" to construct vectors. This is to
-// prevent clang-format from producing annoyingly vertical code from long
-// initializers.
-
-// TODO(eieio): Automatically generate some of these tests?
-
-namespace {
-
-// Test data for serialization/deserialization of floats.
-const float kZeroFloat = 0.0f;
-const float kOneFloat = 1.0f;
-const auto kZeroFloatBytes = reinterpret_cast<const std::uint8_t*>(&kZeroFloat);
-const auto kOneFloatBytes = reinterpret_cast<const std::uint8_t*>(&kOneFloat);
-const double kZeroDouble = 0.0;
-const double kOneDouble = 1.0;
-const auto kZeroDoubleBytes =
-    reinterpret_cast<const std::uint8_t*>(&kZeroDouble);
-const auto kOneDoubleBytes = reinterpret_cast<const std::uint8_t*>(&kOneDouble);
-
-struct TestType {
-  enum class Foo { kFoo, kBar, kBaz };
-
-  int a;
-  float b;
-  std::string c;
-  Foo d;
-
-  TestType() {}
-  TestType(int a, float b, const std::string& c, Foo d)
-      : a(a), b(b), c(c), d(d) {}
-
-  // Make gtest expressions simpler by defining equality operator. This is not
-  // needed for serialization.
-  bool operator==(const TestType& other) const {
-    return a == other.a && b == other.b && c == other.c && d == other.d;
-  }
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(TestType, a, b, c, d);
-};
-
-template <typename FileHandleType>
-struct TestTemplateType {
-  FileHandleType fd;
-
-  TestTemplateType() {}
-  explicit TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
-
-  bool operator==(const TestTemplateType& other) const {
-    return fd.Get() == other.fd.Get();
-  }
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(TestTemplateType<FileHandleType>, fd);
-};
-
-// Utilities to generate test maps and payloads.
-template <typename MapType>
-MapType MakeMap(std::size_t size) {
-  MapType result;
-  for (std::size_t i = 0; i < size; i++) {
-    result.emplace(i, i);
-  }
-  return result;
-}
-
-template <typename MapType>
-void InsertKeyValue(MessageWriter* writer, std::size_t size) {
-  MapType map;
-  for (std::size_t i = 0; i < size; i++) {
-    map.emplace(i, i);
-  }
-  for (const auto& element : map) {
-    Serialize(element.first, writer);
-    Serialize(element.second, writer);
-  }
-}
-
-}  // anonymous namespace
-
-TEST(SerializableTypes, Constructor) {
-  TestType tt(1, 2.0, "three", TestType::Foo::kBar);
-  EXPECT_EQ(1, tt.a);
-  EXPECT_EQ(2.0, tt.b);
-  EXPECT_EQ("three", tt.c);
-  EXPECT_EQ(TestType::Foo::kBar, tt.d);
-}
-
-TEST(SerializationTest, bool) {
-  Payload result;
-  Payload expected;
-  bool value;
-
-  // True.
-  value = true;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_TRUE};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // False.
-  value = false;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FALSE};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, uint8_t) {
-  Payload result;
-  Payload expected;
-  uint8_t value;
-
-  // Min FIXINT.
-  value = 0;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXINT.
-  value = (1 << 7) - 1;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min UINT8.
-  value = (1 << 7);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT8, (1 << 7)};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max UINT8.
-  value = 0xff;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT8, 0xff};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, uint16_t) {
-  Payload result;
-  Payload expected;
-  uint16_t value;
-
-  // Min FIXINT.
-  value = 0;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXINT.
-  value = (1 << 7) - 1;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min UINT8.
-  value = (1 << 7);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT8, (1 << 7)};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max UINT8.
-  value = 0xff;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT8, 0xff};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min UINT16.
-  value = (1 << 8);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT16, 0, 1};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max UINT16.
-  value = 0xffff;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT16, 0xff, 0xff};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, uint32_t) {
-  Payload result;
-  Payload expected;
-  uint32_t value;
-
-  // Min FIXINT.
-  value = 0;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXINT.
-  value = (1 << 7) - 1;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min UINT8.
-  value = (1 << 7);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT8, (1 << 7)};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max UINT8.
-  value = 0xff;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT8, 0xff};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min UINT16.
-  value = (1 << 8);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT16, 0, 1};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max UINT16.
-  value = 0xffff;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT16, 0xff, 0xff};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min UINT32.
-  value = (1 << 16);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT32, 0, 0, 1, 0};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max UINT32.
-  value = 0xffffffff;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, uint64_t) {
-  Payload result;
-  Payload expected;
-  uint64_t value;
-
-  // Min FIXINT.
-  value = 0;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXINT.
-  value = (1 << 7) - 1;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min UINT8.
-  value = (1 << 7);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT8, (1 << 7)};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max UINT8.
-  value = 0xff;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT8, 0xff};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min UINT16.
-  value = (1 << 8);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT16, 0, 1};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max UINT16.
-  value = 0xffff;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT16, 0xff, 0xff};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min UINT32.
-  value = (1 << 16);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT32, 0, 0, 1, 0};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max UINT32.
-  value = 0xffffffff;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min UINT64.
-  value = (1ULL << 32);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_UINT64, 0, 0, 0, 0, 1, 0, 0, 0};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max UINT64.
-  value = 0xffffffffffffffffULL;
-  Serialize(value, &result);
-  expected = {
-      ENCODING_TYPE_UINT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, int8_t) {
-  Payload result;
-  Payload expected;
-  int8_t value;
-
-  // Min NEGATIVE FIXINT.
-  value = -32;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max NEGATIVE FIXINT.
-  value = -1;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min FIXINT.
-  value = 0;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXINT.
-  value = 127;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min INT8.
-  value = -128;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT8, 0x80};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max INT8.
-  value = -33;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT8, 0xdf};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, int16_t) {
-  Payload result;
-  Payload expected;
-  int16_t value;
-
-  // Min NEGATIVE FIXINT.
-  value = -32;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max NEGATIVE FIXINT.
-  value = -1;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min FIXINT.
-  value = 0;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXINT.
-  value = 127;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min INT8.
-  value = -128;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT8, 0x80};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max INT8.
-  value = -33;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT8, 0xdf};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min INT16.
-  value = -32768;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT16, 0x00, 0x80};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max INT16.
-  value = 32767;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT16, 0xff, 0x7f};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, int32_t) {
-  Payload result;
-  Payload expected;
-  int32_t value;
-
-  // Min NEGATIVE FIXINT.
-  value = -32;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max NEGATIVE FIXINT.
-  value = -1;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min FIXINT.
-  value = 0;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXINT.
-  value = 127;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min INT8.
-  value = -128;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT8, 0x80};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max INT8.
-  value = -33;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT8, 0xdf};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min INT16.
-  value = -32768;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT16, 0x00, 0x80};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max INT16.
-  value = 32767;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT16, 0xff, 0x7f};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min INT32.
-  value = -2147483648;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max INT32.
-  value = 2147483647;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, int64_t) {
-  Payload result;
-  Payload expected;
-  int64_t value;
-
-  // Min NEGATIVE FIXINT.
-  value = -32;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max NEGATIVE FIXINT.
-  value = -1;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min FIXINT.
-  value = 0;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXINT.
-  value = 127;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min INT8.
-  value = -128;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT8, 0x80};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max INT8.
-  value = -33;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT8, 0xdf};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min INT16.
-  value = -32768;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT16, 0x00, 0x80};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max INT16.
-  value = 32767;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT16, 0xff, 0x7f};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min INT32.
-  value = -2147483648;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max INT32.
-  value = 2147483647;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min INT64.
-  value = -9223372036854775808ULL;
-  Serialize(value, &result);
-  expected = {
-      ENCODING_TYPE_INT64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max INT64.
-  value = 9223372036854775807ULL;
-  Serialize(value, &result);
-  expected = {
-      ENCODING_TYPE_INT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, float) {
-  Payload result;
-  Payload expected;
-  float value;
-
-  value = 0.0f;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1],
-              kZeroFloatBytes[2], kZeroFloatBytes[3]};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  value = 1.0f;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FLOAT32, kOneFloatBytes[0], kOneFloatBytes[1],
-              kOneFloatBytes[2], kOneFloatBytes[3]};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, double) {
-  Payload result;
-  Payload expected;
-  double value;
-
-  value = 0.0f;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FLOAT64, kZeroDoubleBytes[0], kZeroDoubleBytes[1],
-              kZeroDoubleBytes[2],   kZeroDoubleBytes[3], kZeroDoubleBytes[4],
-              kZeroDoubleBytes[5],   kZeroDoubleBytes[6], kZeroDoubleBytes[7]};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  value = 1.0f;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FLOAT64, kOneDoubleBytes[0], kOneDoubleBytes[1],
-              kOneDoubleBytes[2],    kOneDoubleBytes[3], kOneDoubleBytes[4],
-              kOneDoubleBytes[5],    kOneDoubleBytes[6], kOneDoubleBytes[7]};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, Enum) {
-  Payload result;
-  Payload expected;
-
-  enum Foo { kFoo, kBar, kBaz };
-  Foo value = kBar;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, EnumClass) {
-  Payload result;
-  Payload expected;
-
-  enum class Foo { kFoo, kBar, kBaz };
-  Foo value = Foo::kBaz;
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, LocalHandle) {
-  Payload result;
-  Payload expected;
-  LocalHandle fd1;
-  LocalHandle fd2;
-
-  fd1 = LocalHandle(100);
-  Serialize(fd1, &result);
-  expected = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0};
-  EXPECT_EQ(expected, result);
-  EXPECT_EQ(1u, result.FdCount());
-  EXPECT_EQ(100, result.FdArray()[0]);
-  result.Clear();
-
-  fd2 = LocalHandle(200);
-  Serialize(std::forward_as_tuple(fd1, fd2), &result);
-  expected = decltype(expected)(
-      {ENCODING_TYPE_FIXARRAY_MIN + 2, ENCODING_TYPE_FIXEXT2,
-       ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0, ENCODING_TYPE_FIXEXT2,
-       ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 1, 0});
-  EXPECT_EQ(expected, result);
-  EXPECT_EQ(2u, result.FdCount());
-  EXPECT_EQ(100, result.FdArray()[0]);
-  EXPECT_EQ(200, result.FdArray()[1]);
-  result.Clear();
-
-  fd1.Release();  // Don't try to close fd 100.
-  fd2.Release();  // Don't try to close fd 200.
-
-  fd1 = LocalHandle(-2);
-  Serialize(fd1, &result);
-  expected = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xfe,
-              0xff};
-  EXPECT_EQ(expected, result);
-  EXPECT_EQ(0u, result.FdCount());
-  result.Clear();
-}
-
-TEST(SerializationTest, string) {
-  Payload result;
-  Payload expected;
-  std::string value;
-
-  // Min FIXSTR.
-  value = "";
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FIXSTR_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXSTR.
-  value = std::string((1 << 5) - 1, 'x');
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FIXSTR_MAX};
-  expected.Append((1 << 5) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min STR8.
-  value = std::string((1 << 5), 'x');
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_STR8, (1 << 5)};
-  expected.Append((1 << 5), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max STR8.
-  value = std::string((1 << 8) - 1, 'x');
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_STR8, (1 << 8) - 1};
-  expected.Append((1 << 8) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min STR16.
-  value = std::string((1 << 8), 'x');
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_STR16, 0x00, 0x01};
-  expected.Append((1 << 8), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max STR16.
-  value = std::string((1 << 16) - 1, 'x');
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_STR16, 0xff, 0xff};
-  expected.Append((1 << 16) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min STR32.
-  value = std::string((1 << 16), 'x');
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x01, 0x00};
-  expected.Append((1 << 16), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, StringWrapper) {
-  Payload result;
-  Payload expected;
-  std::string value;
-
-  // Min FIXSTR.
-  value = "";
-  Serialize(WrapString(value), &result);
-  expected = {ENCODING_TYPE_FIXSTR_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXSTR.
-  value = std::string((1 << 5) - 1, 'x');
-  Serialize(WrapString(value), &result);
-  expected = {ENCODING_TYPE_FIXSTR_MAX};
-  expected.Append((1 << 5) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min STR8.
-  value = std::string((1 << 5), 'x');
-  Serialize(WrapString(value), &result);
-  expected = {ENCODING_TYPE_STR8, (1 << 5)};
-  expected.Append((1 << 5), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max STR8.
-  value = std::string((1 << 8) - 1, 'x');
-  Serialize(WrapString(value), &result);
-  expected = {ENCODING_TYPE_STR8, (1 << 8) - 1};
-  expected.Append((1 << 8) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min STR16.
-  value = std::string((1 << 8), 'x');
-  Serialize(WrapString(value), &result);
-  expected = {ENCODING_TYPE_STR16, 0x00, 0x01};
-  expected.Append((1 << 8), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max STR16.
-  value = std::string((1 << 16) - 1, 'x');
-  Serialize(WrapString(value), &result);
-  expected = {ENCODING_TYPE_STR16, 0xff, 0xff};
-  expected.Append((1 << 16) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min STR32.
-  value = std::string((1 << 16), 'x');
-  Serialize(WrapString(value), &result);
-  expected = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x01, 0x00};
-  expected.Append((1 << 16), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, vector) {
-  Payload result;
-  Payload expected;
-  std::vector<uint8_t> value;
-
-  // Min FIXARRAY.
-  value = {};
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FIXARRAY_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXARRAY.
-  value = decltype(value)((1 << 4) - 1, 'x');
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FIXARRAY_MAX};
-  expected.Append((1 << 4) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min ARRAY16.
-  value = decltype(value)((1 << 4), 'x');
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00};
-  expected.Append((1 << 4), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max ARRAY16.
-  value = decltype(value)((1 << 16) - 1, 'x');
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
-  expected.Append((1 << 16) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min ARRAY32.
-  value = decltype(value)((1 << 16), 'x');
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
-  expected.Append((1 << 16), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, map) {
-  Payload result;
-  Payload expected;
-  std::map<std::uint32_t, std::uint32_t> value;
-
-  // Min FIXMAP.
-  value = {};
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FIXMAP_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXMAP.
-  value = MakeMap<decltype(value)>((1 << 4) - 1);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FIXMAP_MAX};
-  InsertKeyValue<decltype(value)>(&expected, (1 << 4) - 1);
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min MAP16.
-  value = MakeMap<decltype(value)>((1 << 4));
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_MAP16, 0x10, 0x00};
-  InsertKeyValue<decltype(value)>(&expected, (1 << 4));
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max MAP16.
-  value = MakeMap<decltype(value)>((1 << 16) - 1);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_MAP16, 0xff, 0xff};
-  InsertKeyValue<decltype(value)>(&expected, (1 << 16) - 1);
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min MAP32.
-  value = MakeMap<decltype(value)>((1 << 16));
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00};
-  InsertKeyValue<decltype(value)>(&expected, (1 << 16));
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, unordered_map) {
-  Payload result;
-  Payload expected;
-  std::unordered_map<std::uint32_t, std::uint32_t> value;
-
-  // Min FIXMAP.
-  value = {};
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FIXMAP_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXMAP.
-  value = MakeMap<decltype(value)>((1 << 4) - 1);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_FIXMAP_MAX};
-  InsertKeyValue<decltype(value)>(&expected, (1 << 4) - 1);
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min MAP16.
-  value = MakeMap<decltype(value)>((1 << 4));
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_MAP16, 0x10, 0x00};
-  InsertKeyValue<decltype(value)>(&expected, (1 << 4));
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max MAP16.
-  value = MakeMap<decltype(value)>((1 << 16) - 1);
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_MAP16, 0xff, 0xff};
-  InsertKeyValue<decltype(value)>(&expected, (1 << 16) - 1);
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min MAP32.
-  value = MakeMap<decltype(value)>((1 << 16));
-  Serialize(value, &result);
-  expected = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00};
-  InsertKeyValue<decltype(value)>(&expected, (1 << 16));
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, array) {
-  Payload result;
-  Payload expected;
-
-  // Min FIXARRAY.
-  std::array<std::uint8_t, 0> a0;
-  Serialize(a0, &result);
-  expected = {ENCODING_TYPE_FIXARRAY_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXARRAY.
-  std::array<std::uint8_t, (1 << 4) - 1> a1;
-  for (auto& element : a1)
-    element = 'x';
-  Serialize(a1, &result);
-  expected = {ENCODING_TYPE_FIXARRAY_MAX};
-  expected.Append((1 << 4) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min ARRAY16.
-  std::array<std::uint8_t, (1 << 4)> a2;
-  for (auto& element : a2)
-    element = 'x';
-  Serialize(a2, &result);
-  expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00};
-  expected.Append((1 << 4), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max ARRAY16.
-  std::array<std::uint8_t, (1 << 16) - 1> a3;
-  for (auto& element : a3)
-    element = 'x';
-  Serialize(a3, &result);
-  expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
-  expected.Append((1 << 16) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min ARRAY32.
-  std::array<std::uint8_t, (1 << 16)> a4;
-  for (auto& element : a4)
-    element = 'x';
-  Serialize(a4, &result);
-  expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
-  expected.Append((1 << 16), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, ArrayWrapper) {
-  Payload result;
-  Payload expected;
-  std::vector<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>> value;
-  ArrayWrapper<std::uint8_t> wrapper;
-
-  // Min FIXARRAY.
-  value = {};
-  Serialize(wrapper, &result);
-  expected = {ENCODING_TYPE_FIXARRAY_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXARRAY.
-  value = decltype(value)((1 << 4) - 1, 'x');
-  wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size());
-  Serialize(wrapper, &result);
-  expected = {ENCODING_TYPE_FIXARRAY_MAX};
-  expected.Append((1 << 4) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min ARRAY16.
-  value = decltype(value)((1 << 4), 'x');
-  wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size());
-  Serialize(wrapper, &result);
-  expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00};
-  expected.Append((1 << 4), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max ARRAY16.
-  value = decltype(value)((1 << 16) - 1, 'x');
-  wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size());
-  Serialize(wrapper, &result);
-  expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
-  expected.Append((1 << 16) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min ARRAY32.
-  value = decltype(value)((1 << 16), 'x');
-  wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size());
-  Serialize(wrapper, &result);
-  expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
-  expected.Append((1 << 16), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, pair) {
-  Payload result;
-  Payload expected;
-
-  auto p1 = std::make_pair(1, 2);
-  Serialize(p1, &result);
-  expected = {ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  auto p2 = std::make_pair('x', std::string("12345"));
-  Serialize(p2, &result);
-  expected = decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 2, 'x',
-                                 ENCODING_TYPE_FIXSTR_MIN + 5, '1', '2', '3',
-                                 '4', '5'});
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, tuple) {
-  Payload result;
-  Payload expected;
-
-  // Min FIXARRAY.
-  auto t1 = std::make_tuple();
-  Serialize(t1, &result);
-  expected = {ENCODING_TYPE_FIXARRAY_MIN};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Max FIXARRAY.
-  auto t2 = GetNTuple<15>('x');
-  Serialize(t2, &result);
-  expected = {ENCODING_TYPE_FIXARRAY_MAX};
-  expected.Append((1 << 4) - 1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min ARRAY16.
-  auto t3 = GetNTuple<(1 << 4)>('x');
-  Serialize(t3, &result);
-  expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00};
-  expected.Append((1 << 4), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-// Template instantiation depth is an issue for these tests. They are commented
-// out to document the expected behavior, even though tuples of this order are
-// not expected in practice.
-#if 0
-  // Max ARRAY16.
-  auto t4 = GetNTuple<(1 << 16)-1>('x');
-  Serialize(t4, &result);
-  expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
-  expected.Append((1 << 16)-1, 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // Min ARRAY32.
-  auto t5 = GetNTuple<(1 << 16)>('x');
-  Serialize(t5, &result);
-  expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
-  expected.Append((1 << 16), 'x');
-  EXPECT_EQ(expected, result);
-  result.Clear();
-#endif
-}
-
-// TODO(eieio): More exhaustive testing of type nesting.
-TEST(SerializationTest, NestedTuple) {
-  Payload result;
-  Payload expected;
-
-  auto t1 = std::make_tuple('x', std::make_tuple<int, int>(1, 2));
-  Serialize(t1, &result);
-  expected = decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 2, 'x',
-                                 ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2});
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  auto t2 = std::make_tuple('x', std::make_tuple<int, int>(1, 2),
-                            std::string("0123456789"));
-  Serialize(t2, &result);
-  expected = decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 3, 'x',
-                                 ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2,
-                                 ENCODING_TYPE_FIXSTR | 10, '0', '1', '2', '3',
-                                 '4', '5', '6', '7', '8', '9'});
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  auto t3 = std::make_tuple(0.0f, std::uint64_t(10ULL),
-                            std::vector<char>{'a', 'b', 'c'});
-  Serialize(t3, &result);
-  expected = decltype(expected)(
-      {ENCODING_TYPE_FIXARRAY_MIN + 3, ENCODING_TYPE_FLOAT32,
-       kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2],
-       kZeroFloatBytes[3], ENCODING_TYPE_POSITIVE_FIXINT_MIN + 10,
-       ENCODING_TYPE_FIXARRAY_MIN + 3, 'a', 'b', 'c'});
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, NestedMap) {
-  Payload result;
-  Payload expected;
-
-  std::map<int, std::pair<std::string, int>> m1 = {{0, {"a", 2}},
-                                                   {1, {"b", 10}}};
-  Serialize(m1, &result);
-  expected = decltype(expected)(
-      {ENCODING_TYPE_FIXMAP_MIN + 2, 0, ENCODING_TYPE_FIXARRAY_MIN + 2,
-       ENCODING_TYPE_FIXSTR_MIN + 1, 'a', 2, 1, ENCODING_TYPE_FIXARRAY_MIN + 2,
-       ENCODING_TYPE_FIXSTR_MIN + 1, 'b', 10});
-  EXPECT_EQ(expected, result);
-  result.Clear();
-}
-
-TEST(SerializationTest, Serializable) {
-  Payload result;
-  Payload expected;
-
-  TestType t1{10, 0.0, "12345", TestType::Foo::kBaz};
-  Serialize(t1, &result);
-  expected = decltype(expected)(
-      {ENCODING_TYPE_FIXARRAY_MIN + 4, 10, ENCODING_TYPE_FLOAT32,
-       kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2],
-       kZeroFloatBytes[3], ENCODING_TYPE_FIXSTR_MIN + 5, '1', '2', '3', '4',
-       '5', ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2});
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  TestTemplateType<LocalHandle> tt{LocalHandle(-1)};
-  Serialize(tt, &result);
-  expected =
-      decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 1, ENCODING_TYPE_FIXEXT2,
-                          ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xff, 0xff});
-  EXPECT_EQ(expected, result);
-}
-
-TEST(SerializationTest, Variant) {
-  Payload result;
-  Payload expected;
-
-  Variant<int, bool, float> v;
-
-  // Empty variant.
-  Serialize(v, &result);
-  expected = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_NEGATIVE_FIXINT_MAX,
-              ENCODING_TYPE_NIL};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  v = 10;
-  Serialize(v, &result);
-  expected = {ENCODING_TYPE_FIXMAP_MIN + 1,
-              ENCODING_TYPE_POSITIVE_FIXINT_MIN + 0,
-              ENCODING_TYPE_POSITIVE_FIXINT_MIN + 10};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  v = true;
-  Serialize(v, &result);
-  expected = {ENCODING_TYPE_FIXMAP_MIN + 1,
-              ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1, ENCODING_TYPE_TRUE};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  v = false;
-  Serialize(v, &result);
-  expected = {ENCODING_TYPE_FIXMAP_MIN + 1,
-              ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1, ENCODING_TYPE_FALSE};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  v = 1.0f;
-  Serialize(v, &result);
-  expected = {ENCODING_TYPE_FIXMAP_MIN + 1,
-              ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2,
-              ENCODING_TYPE_FLOAT32,
-              kOneFloatBytes[0],
-              kOneFloatBytes[1],
-              kOneFloatBytes[2],
-              kOneFloatBytes[3]};
-  EXPECT_EQ(expected, result);
-  result.Clear();
-
-  // TODO(eieio): Add more serialization tests for Variant.
-}
-
-TEST(DeserializationTest, bool) {
-  Payload buffer;
-  bool result = false;
-  ErrorType error;
-
-  // True.
-  buffer = {ENCODING_TYPE_TRUE};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(1, result);  // Gtest generates warning from bool literals.
-
-  // False.
-  buffer = {ENCODING_TYPE_FALSE};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0, result);  // Gtest generates warning from bool literals.
-}
-
-TEST(DeserializationTest, uint8_t) {
-  Payload buffer;
-  std::uint8_t result = 0;
-  ErrorType error;
-
-  // Min FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127U, result);
-
-  // Min UINT8.
-  buffer = {ENCODING_TYPE_UINT8, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max UINT8.
-  buffer = {ENCODING_TYPE_UINT8, 0xff};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0xffU, result);
-
-  // UINT16 out of range.
-  buffer = {ENCODING_TYPE_UINT16};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_UINT16, error.encoding_type());
-
-  // UINT32 out of range.
-  buffer = {ENCODING_TYPE_UINT32};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_UINT32, error.encoding_type());
-
-  // UINT64 out of range.
-  buffer = {ENCODING_TYPE_UINT64};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_UINT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, uint16_t) {
-  Payload buffer;
-  std::uint16_t result = 0;
-  ErrorType error;
-
-  // Min FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127U, result);
-
-  // Min UINT8.
-  buffer = {ENCODING_TYPE_UINT8, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max UINT8.
-  buffer = {ENCODING_TYPE_UINT8, 0xff};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0xffU, result);
-
-  // Min UINT16.
-  buffer = {ENCODING_TYPE_UINT16, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max UINT16.
-  buffer = {ENCODING_TYPE_UINT16, 0xff, 0xff};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0xffffU, result);
-
-  // UINT32 out of range.
-  buffer = {ENCODING_TYPE_UINT32};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_UINT32, error.encoding_type());
-
-  // UINT64 out of range.
-  buffer = {ENCODING_TYPE_UINT64};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_UINT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, uint32_t) {
-  Payload buffer;
-  std::uint32_t result = 0;
-  ErrorType error;
-
-  // Min FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127U, result);
-
-  // Min UINT8.
-  buffer = {ENCODING_TYPE_UINT8, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max UINT8.
-  buffer = {ENCODING_TYPE_UINT8, 0xff};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0xffU, result);
-
-  // Min UINT16.
-  buffer = {ENCODING_TYPE_UINT16, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max UINT16.
-  buffer = {ENCODING_TYPE_UINT16, 0xff, 0xff};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0xffffU, result);
-
-  // Min UINT32.
-  buffer = {ENCODING_TYPE_UINT32, 0x00, 0x00, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max UINT32.
-  buffer = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0xffffffffU, result);
-
-  // UINT64 out of range.
-  buffer = {ENCODING_TYPE_UINT64};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_UINT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, uint64_t) {
-  Payload buffer;
-  std::uint64_t result = 0;
-  ErrorType error;
-
-  // Min FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127U, result);
-
-  // Min UINT8.
-  buffer = {ENCODING_TYPE_UINT8, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max UINT8.
-  buffer = {ENCODING_TYPE_UINT8, 0xff};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0xffU, result);
-
-  // Min UINT16.
-  buffer = {ENCODING_TYPE_UINT16, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max UINT16.
-  buffer = {ENCODING_TYPE_UINT16, 0xff, 0xff};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0xffffU, result);
-
-  // Min UINT32.
-  buffer = {ENCODING_TYPE_UINT32, 0x00, 0x00, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max UINT32.
-  buffer = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0xffffffffU, result);
-
-  // Min UINT64.
-  buffer = {
-      ENCODING_TYPE_UINT64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0U, result);
-
-  // Max UINT64.
-  buffer = {
-      ENCODING_TYPE_UINT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0xffffffffffffffffUL, result);
-}
-
-TEST(DeserializationTest, int8_t) {
-  Payload buffer;
-  std::int8_t result = 0;
-  ErrorType error;
-
-  // Min NEGATIVE FIXINT.
-  buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-32, result);
-
-  // Max NEGATIVE FIXINT.
-  buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-1, result);
-
-  // Min FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0, result);
-
-  // Max FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127, result);
-
-  // Min INT8.
-  buffer = {ENCODING_TYPE_INT8, 0x80};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-128, result);
-
-  // Max INT8.
-  buffer = {ENCODING_TYPE_INT8, 0x7f};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127, result);
-
-  // INT16 out of range.
-  buffer = {ENCODING_TYPE_INT16};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_INT16, error.encoding_type());
-
-  // INT32 out of range.
-  buffer = {ENCODING_TYPE_INT32};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_INT32, error.encoding_type());
-
-  // INT64 out of range.
-  buffer = {ENCODING_TYPE_INT64};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_INT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, int16_t) {
-  Payload buffer;
-  std::int16_t result = 0;
-  ErrorType error;
-
-  // Min NEGATIVE FIXINT.
-  buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-32, result);
-
-  // Max NEGATIVE FIXINT.
-  buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-1, result);
-
-  // Min FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0, result);
-
-  // Max FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127, result);
-
-  // Min INT8.
-  buffer = {ENCODING_TYPE_INT8, 0x80};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-128, result);
-
-  // Max INT8.
-  buffer = {ENCODING_TYPE_INT8, 0x7f};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127, result);
-
-  // Min INT16.
-  buffer = {ENCODING_TYPE_INT16, 0x00, 0x80};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-32768, result);
-
-  // Max INT16.
-  buffer = {ENCODING_TYPE_INT16, 0xff, 0x7f};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(32767, result);
-
-  // INT32 out of range.
-  buffer = {ENCODING_TYPE_INT32};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_INT32, error.encoding_type());
-
-  // INT64 out of range.
-  buffer = {ENCODING_TYPE_INT64};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_INT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, int32_t) {
-  Payload buffer;
-  std::int32_t result = 0;
-  ErrorType error;
-
-  // Min NEGATIVE FIXINT.
-  buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-32, result);
-
-  // Max NEGATIVE FIXINT.
-  buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-1, result);
-
-  // Min FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0, result);
-
-  // Max FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127, result);
-
-  // Min INT8.
-  buffer = {ENCODING_TYPE_INT8, 0x80};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-128, result);
-
-  // Max INT8.
-  buffer = {ENCODING_TYPE_INT8, 0x7f};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127, result);
-
-  // Min INT16.
-  buffer = {ENCODING_TYPE_INT16, 0x00, 0x80};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-32768, result);
-
-  // Max INT16.
-  buffer = {ENCODING_TYPE_INT16, 0xff, 0x7f};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(32767, result);
-
-  // Min INT32.
-  buffer = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-2147483648, result);
-
-  // Max INT32.
-  buffer = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(2147483647, result);
-
-  // INT64 out of range.
-  buffer = {ENCODING_TYPE_INT64};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_INT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, int64_t) {
-  Payload buffer;
-  std::int64_t result = 0;
-  ErrorType error;
-
-  // Min NEGATIVE FIXINT.
-  buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-32, result);
-
-  // Max NEGATIVE FIXINT.
-  buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-1, result);
-
-  // Min FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0, result);
-
-  // Max FIXINT.
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127, result);
-
-  // Min INT8.
-  buffer = {ENCODING_TYPE_INT8, 0x80};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-128, result);
-
-  // Max INT8.
-  buffer = {ENCODING_TYPE_INT8, 0x7f};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(127, result);
-
-  // Min INT16.
-  buffer = {ENCODING_TYPE_INT16, 0x00, 0x80};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-32768, result);
-
-  // Max INT16.
-  buffer = {ENCODING_TYPE_INT16, 0xff, 0x7f};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(32767, result);
-
-  // Min INT32.
-  buffer = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-2147483648, result);
-
-  // Max INT32.
-  buffer = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(2147483647, result);
-
-  // Min INT64.
-  buffer = {
-      ENCODING_TYPE_INT64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  // Believe it or not, this is actually the correct way to specify the most
-  // negative signed long long.
-  EXPECT_EQ(-9223372036854775807LL - 1, result);
-
-  // Max INT64.
-  buffer = {
-      ENCODING_TYPE_INT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(9223372036854775807LL, result);
-}
-
-TEST(DeserializationTest, float) {
-  Payload buffer;
-  float result;
-  ErrorType error;
-
-  // FLOAT32.
-  buffer = {ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1],
-            kZeroFloatBytes[2], kZeroFloatBytes[3]};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(kZeroFloat, result);
-
-  // FLOAT32.
-  buffer = {ENCODING_TYPE_FLOAT32, kOneFloatBytes[0], kOneFloatBytes[1],
-            kOneFloatBytes[2], kOneFloatBytes[3]};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(kOneFloat, result);
-}
-
-TEST(DeserializationTest, double) {
-  Payload buffer;
-  double result;
-  ErrorType error;
-
-  // FLOAT32.
-  buffer = {ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1],
-            kZeroFloatBytes[2], kZeroFloatBytes[3]};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(kZeroDouble, result);
-
-  // FLOAT64.
-  buffer = {ENCODING_TYPE_FLOAT64, kZeroDoubleBytes[0], kZeroDoubleBytes[1],
-            kZeroDoubleBytes[2],   kZeroDoubleBytes[3], kZeroDoubleBytes[4],
-            kZeroDoubleBytes[5],   kZeroDoubleBytes[6], kZeroDoubleBytes[7]};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(kZeroDouble, result);
-
-  // FLOAT32.
-  buffer = {ENCODING_TYPE_FLOAT32, kOneFloatBytes[0], kOneFloatBytes[1],
-            kOneFloatBytes[2], kOneFloatBytes[3]};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(kOneDouble, result);
-
-  // FLOAT64.
-  buffer = {ENCODING_TYPE_FLOAT64, kOneDoubleBytes[0], kOneDoubleBytes[1],
-            kOneDoubleBytes[2],    kOneDoubleBytes[3], kOneDoubleBytes[4],
-            kOneDoubleBytes[5],    kOneDoubleBytes[6], kOneDoubleBytes[7]};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(kOneDouble, result);
-}
-
-TEST(DeserializationTest, Enum) {
-  Payload buffer;
-  enum Foo { kFoo, kBar, kBaz } result;
-  ErrorType error;
-
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(kBar, result);
-}
-
-TEST(DeserializationTest, EnumClass) {
-  Payload buffer;
-  enum Foo { kFoo, kBar, kBaz } result;
-  ErrorType error;
-
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(Foo::kBaz, result);
-}
-
-TEST(DeserializationTest, LocalHandle) {
-  Payload buffer;
-  LocalHandle result1;
-  LocalHandle result2;
-  ErrorType error;
-
-  buffer = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0};
-  error = Deserialize(&result1, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0, result1.Get());
-  result1.Release();  // Don't close fd 0.
-
-  std::tuple<LocalHandle&, LocalHandle&> t1(result1, result2);
-  buffer = decltype(buffer)(
-      {ENCODING_TYPE_FIXARRAY_MIN + 2, ENCODING_TYPE_FIXEXT2,
-       ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0, ENCODING_TYPE_FIXEXT2,
-       ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 1, 0});
-  error = Deserialize(&t1, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(0, result1.Get());
-  EXPECT_EQ(1, result2.Get());
-  result1.Release();  // Don't close fd 0.
-  result2.Release();  // Don't close fd 1.
-
-  buffer = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xfe,
-            0xff};
-  error = Deserialize(&result1, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(-2, result1.Get());
-}
-
-TEST(DeserializationTest, string) {
-  Payload buffer;
-  std::string result = "";
-  ErrorType error;
-
-  // Min FIXSTR.
-  buffer = {ENCODING_TYPE_FIXSTR_MIN};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ("", result);
-
-  // Max FIXSTR.
-  buffer = {ENCODING_TYPE_FIXSTR_MAX};
-  buffer.Append((1 << 5) - 1, 'x');
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(std::string((1 << 5) - 1, 'x'), result);
-
-  // Min STR8.
-  buffer = {ENCODING_TYPE_STR8, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ("", result);
-
-  // Max STR8.
-  buffer = {ENCODING_TYPE_STR8, 0xff};
-  buffer.Append(0xff, 'x');
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(std::string(0xff, 'x'), result);
-
-  // Min STR16.
-  buffer = {ENCODING_TYPE_STR16, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ("", result);
-
-  // Max STR16.
-  buffer = {ENCODING_TYPE_STR16, 0xff, 0xff};
-  buffer.Append(0xffff, 'x');
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(std::string(0xffff, 'x'), result);
-
-  // Min STR32.
-  buffer = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ("", result);
-
-  // Test STR32 with max STR16 + 1 bytes. It's not practical to test max
-  // STR32.
-  buffer = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x01, 0x00};
-  buffer.Append(0x10000, 'x');
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(std::string(0x10000, 'x'), result);
-}
-
-TEST(DeserializationTest, vector) {
-  Payload buffer;
-  std::vector<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>>
-      result;
-  Payload expected;
-  ErrorType error;
-
-  // Min FIXARRAY.
-  buffer = {ENCODING_TYPE_FIXARRAY_MIN};
-  error = Deserialize(&result, &buffer);
-  expected = {};
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Max FIXARRAY.
-  buffer = {ENCODING_TYPE_FIXARRAY_MAX};
-  buffer.Append((1 << 4) - 1, 1);
-  error = Deserialize(&result, &buffer);
-  expected = decltype(expected)((1 << 4) - 1, 1);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Min ARRAY16.
-  buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  expected = {};
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Max ARRAY16.
-  buffer = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
-  buffer.Append(0xffff, 1);
-  error = Deserialize(&result, &buffer);
-  expected = decltype(expected)(0xffff, 1);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Min ARRAY32.
-  buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  expected = {};
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // ARRAY32 with max ARRAY16 + 1. It's not practical to test max ARRAY32.
-  buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
-  buffer.Append(0x10000, 1);
-  error = Deserialize(&result, &buffer);
-  expected = decltype(expected)(0x10000, 1);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-}
-
-TEST(DeserializationTest, map) {
-  Payload buffer;
-  std::map<std::uint32_t, std::uint32_t> result;
-  std::map<std::uint32_t, std::uint32_t> expected;
-  ErrorType error;
-
-  // Min FIXMAP.
-  buffer = {ENCODING_TYPE_FIXMAP_MIN};
-  error = Deserialize(&result, &buffer);
-  expected = {};
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Size mismatch.
-  buffer = {ENCODING_TYPE_FIXMAP_MIN + 1};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::INSUFFICIENT_BUFFER, error);
-
-  // Max FIXMAP.
-  buffer = {ENCODING_TYPE_FIXMAP_MAX};
-  InsertKeyValue<decltype(result)>(&buffer, (1 << 4) - 1);
-  error = Deserialize(&result, &buffer);
-  expected = MakeMap<decltype(expected)>((1 << 4) - 1);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error) << std::string(error);
-  EXPECT_EQ(expected, result);
-
-  // Min MAP16.
-  buffer = {ENCODING_TYPE_MAP16, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  expected = {};
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Max MAP16.
-  buffer = {ENCODING_TYPE_MAP16, 0xff, 0xff};
-  InsertKeyValue<decltype(result)>(&buffer, (1 << 16) - 1);
-  error = Deserialize(&result, &buffer);
-  expected = MakeMap<decltype(expected)>((1 << 16) - 1);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Min MAP32.
-  buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  expected = {};
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // MAP32 with max MAP16 + 1. It's not practical to test max MAP32.
-  buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00};
-  InsertKeyValue<decltype(result)>(&buffer, (1 << 16));
-  error = Deserialize(&result, &buffer);
-  expected = MakeMap<decltype(expected)>((1 << 16));
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-}
-
-TEST(DeserializationTest, unordered_map) {
-  Payload buffer;
-  std::unordered_map<std::uint32_t, std::uint32_t> result;
-  std::unordered_map<std::uint32_t, std::uint32_t> expected;
-  ErrorType error;
-
-  // Min FIXMAP.
-  buffer = {ENCODING_TYPE_FIXMAP_MIN};
-  error = Deserialize(&result, &buffer);
-  expected = {};
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Size mismatch.
-  buffer = {ENCODING_TYPE_FIXMAP_MIN + 1};
-  error = Deserialize(&result, &buffer);
-  EXPECT_EQ(ErrorCode::INSUFFICIENT_BUFFER, error);
-
-  // Max FIXMAP.
-  buffer = {ENCODING_TYPE_FIXMAP_MAX};
-  InsertKeyValue<decltype(result)>(&buffer, (1 << 4) - 1);
-  error = Deserialize(&result, &buffer);
-  expected = MakeMap<decltype(expected)>((1 << 4) - 1);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Min MAP16.
-  buffer = {ENCODING_TYPE_MAP16, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  expected = {};
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Max MAP16.
-  buffer = {ENCODING_TYPE_MAP16, 0xff, 0xff};
-  InsertKeyValue<decltype(result)>(&buffer, (1 << 16) - 1);
-  error = Deserialize(&result, &buffer);
-  expected = MakeMap<decltype(expected)>((1 << 16) - 1);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Min MAP32.
-  buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x00, 0x00};
-  error = Deserialize(&result, &buffer);
-  expected = {};
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // MAP32 with max MAP16 + 1. It's not practical to test max MAP32.
-  buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00};
-  InsertKeyValue<decltype(result)>(&buffer, (1 << 16));
-  error = Deserialize(&result, &buffer);
-  expected = MakeMap<decltype(expected)>((1 << 16));
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-}
-
-TEST(DeserializationTest, array) {
-  Payload buffer;
-  ErrorType error;
-
-  // Min FIXARRAY.
-  buffer = {ENCODING_TYPE_FIXARRAY_MIN};
-  std::array<std::uint8_t, 0> a0;
-  error = Deserialize(&a0, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-
-  // Size mismatch.
-  buffer = {ENCODING_TYPE_FIXARRAY_MIN + 1};
-  error = Deserialize(&a0, &buffer);
-  EXPECT_EQ(ErrorCode::INSUFFICIENT_DESTINATION_SIZE, error);
-
-  // Max FIXARRAY.
-  buffer = {ENCODING_TYPE_FIXARRAY_MAX};
-  buffer.Append((1 << 4) - 1, 'x');
-  std::array<std::uint8_t, (1 << 4) - 1> a1, expected1;
-  for (auto& element : expected1)
-    element = 'x';
-  error = Deserialize(&a1, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected1, a1);
-
-  // Min ARRAY16.
-  buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00};
-  error = Deserialize(&a0, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-
-  // Max ARRAY16.
-  buffer = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
-  buffer.Append((1 << 16) - 1, 'x');
-  std::array<std::uint8_t, (1 << 16) - 1> a3, expected3;
-  for (auto& element : expected3)
-    element = 'x';
-  error = Deserialize(&a3, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected3, a3);
-
-  // Min ARRAY32.
-  buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00};
-  error = Deserialize(&a0, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-
-  // ARRAY32 with max ARRAY16 + 1. It's not practical to test max ARRAY32.
-  buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
-  buffer.Append((1 << 16), 'x');
-  std::array<std::uint8_t, (1 << 16)> a4, expected4;
-  for (auto& element : expected4)
-    element = 'x';
-  error = Deserialize(&a4, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected4, a4);
-}
-
-TEST(DeserializationTest, ArrayWrapper) {
-  Payload buffer;
-  std::vector<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>>
-      result;
-  std::vector<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>>
-      expected;
-  ErrorType error;
-
-  result.reserve(0x10000);
-  ArrayWrapper<std::uint8_t> wrapper(result.data(), result.capacity());
-
-  // Min FIXARRAY.
-  buffer = {ENCODING_TYPE_FIXARRAY_MIN};
-  error = Deserialize(&wrapper, &buffer);
-  expected = {};
-  result.resize(wrapper.size());
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Max FIXARRAY.
-  buffer = {ENCODING_TYPE_FIXARRAY_MAX};
-  buffer.Append((1 << 4) - 1, 1);
-  error = Deserialize(&wrapper, &buffer);
-  expected = decltype(expected)((1 << 4) - 1, 1);
-  result.resize(wrapper.size());
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Min ARRAY16.
-  buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00};
-  error = Deserialize(&wrapper, &buffer);
-  expected = {};
-  result.resize(wrapper.size());
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Max ARRAY16.
-  buffer = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
-  buffer.Append(0xffff, 1);
-  error = Deserialize(&wrapper, &buffer);
-  expected = decltype(expected)(0xffff, 1);
-  result.resize(wrapper.size());
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // Min ARRAY32.
-  buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00};
-  error = Deserialize(&wrapper, &buffer);
-  expected = {};
-  result.resize(wrapper.size());
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-
-  // ARRAY32 with max ARRAY16 + 1. It's not practical to test max ARRAY32.
-  buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
-  buffer.Append(0x10000, 1);
-  error = Deserialize(&wrapper, &buffer);
-  expected = decltype(expected)(0x10000, 1);
-  result.resize(wrapper.size());
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(expected, result);
-}
-
-TEST(DeserializationTest, pair) {
-  Payload buffer;
-  ErrorType error;
-
-  std::pair<int, int> p1;
-  buffer = {ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2};
-  error = Deserialize(&p1, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(std::make_pair(1, 2), p1);
-}
-
-TEST(DeserializationTest, tuple) {
-  Payload buffer;
-  ErrorType error;
-
-  // Min FIXARRAY.
-  std::tuple<> t1;
-  buffer = {ENCODING_TYPE_FIXARRAY_MIN};
-  error = Deserialize(&t1, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(std::make_tuple(), t1);  // Superfluous.
-
-  // Max FIXARRAY.
-  auto t2 = GetNTuple<15, int>(0);
-  buffer = {ENCODING_TYPE_FIXARRAY_MAX};
-  buffer.Append((1 << 4) - 1, 1);
-  error = Deserialize(&t2, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ((GetNTuple<15, int>(1)), t2);
-
-  // Min ARRAY16.
-  // Using t1 above.
-  buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00};
-  error = Deserialize(&t1, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(std::make_tuple(), t1);
-
-  // ARRAY16 at Max FIXARRAY + 1
-  auto t3 = GetNTuple<(1 << 4), int>(0);
-  buffer = {ENCODING_TYPE_ARRAY16, 0x10, 0x00};
-  buffer.Append((1 << 4), 1);
-  error = Deserialize(&t3, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ((GetNTuple<(1 << 4), int>(1)), t3);
-
-  // Min ARRAY32.
-  // Using t1 from above.
-  buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00};
-  error = Deserialize(&t1, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(std::make_tuple(), t1);
-
-  // ARRAY32 at Max FIXARRAY + 1
-  auto t4 = GetNTuple<(1 << 4), int>(0);
-  buffer = {ENCODING_TYPE_ARRAY32, 0x10, 0x00, 0x00, 0x00};
-  buffer.Append((1 << 4), 1);
-  error = Deserialize(&t4, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ((GetNTuple<(1 << 4), int>(1)), t4);
-
-  // Template instantiation depth is an issue for tuples with large numbers of
-  // elements. As these are not expected in practice, the limits of ARRAY16
-  // and ARRAY32 are not tested.
-}
-
-TEST(DeserializationTest, Serializable) {
-  Payload buffer;
-  ErrorType error;
-
-  buffer = decltype(buffer)(
-      {ENCODING_TYPE_FIXARRAY_MIN + 4, 10, ENCODING_TYPE_FLOAT32,
-       kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2],
-       kZeroFloatBytes[3], ENCODING_TYPE_FIXSTR_MIN + 5, '1', '2', '3', '4',
-       '5', ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1});
-  TestType t1;
-  error = Deserialize(&t1, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(TestType(10, 0.f, "12345", TestType::Foo::kBar), t1);
-
-  buffer =
-      decltype(buffer)({ENCODING_TYPE_FIXARRAY_MIN + 1, ENCODING_TYPE_FIXEXT2,
-                        ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xff, 0xff});
-  TestTemplateType<LocalHandle> tt;
-  error = Deserialize(&tt, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_EQ(TestTemplateType<LocalHandle>(LocalHandle(-1)), tt);
-}
-
-TEST(DeserializationTest, Variant) {
-  Payload buffer;
-  ErrorType error;
-
-  Variant<int, bool, float> v;
-
-  buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_NEGATIVE_FIXINT_MAX,
-            ENCODING_TYPE_NIL};
-  error = Deserialize(&v, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  EXPECT_TRUE(v.empty());
-
-  buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 0,
-            ENCODING_TYPE_POSITIVE_FIXINT_MIN + 10};
-  error = Deserialize(&v, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  ASSERT_TRUE(v.is<int>());
-  EXPECT_EQ(10, std::get<int>(v));
-
-  buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1,
-            ENCODING_TYPE_TRUE};
-  error = Deserialize(&v, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  ASSERT_TRUE(v.is<bool>());
-  EXPECT_EQ(true, std::get<bool>(v));
-
-  buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1,
-            ENCODING_TYPE_FALSE};
-  error = Deserialize(&v, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  ASSERT_TRUE(v.is<bool>());
-  EXPECT_EQ(false, std::get<bool>(v));
-
-  buffer = {ENCODING_TYPE_FIXMAP_MIN + 1,
-            ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2,
-            ENCODING_TYPE_FLOAT32,
-            kOneFloatBytes[0],
-            kOneFloatBytes[1],
-            kOneFloatBytes[2],
-            kOneFloatBytes[3]};
-  error = Deserialize(&v, &buffer);
-  EXPECT_EQ(ErrorCode::NO_ERROR, error);
-  ASSERT_TRUE(v.is<float>());
-  EXPECT_FLOAT_EQ(1.0, std::get<float>(v));
-
-  // TODO(eieio): Add more deserialization tests for Variant.
-}
-
-TEST(DeserializationTest, ErrorType) {
-  Payload buffer;
-  ErrorType error;
-
-  std::uint8_t u8;
-  buffer = {ENCODING_TYPE_STR8};
-  error = Deserialize(&u8, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
-  std::uint16_t u16;
-  buffer = {ENCODING_TYPE_STR8};
-  error = Deserialize(&u16, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
-  std::uint32_t u32;
-  buffer = {ENCODING_TYPE_STR8};
-  error = Deserialize(&u32, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
-  std::uint64_t u64;
-  buffer = {ENCODING_TYPE_STR8};
-  error = Deserialize(&u64, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
-  std::int8_t i8;
-  buffer = {ENCODING_TYPE_STR8};
-  error = Deserialize(&i8, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
-  std::int16_t i16;
-  buffer = {ENCODING_TYPE_STR8};
-  error = Deserialize(&i16, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
-  std::int32_t i32;
-  buffer = {ENCODING_TYPE_STR8};
-  error = Deserialize(&i32, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
-  std::int64_t i64;
-  buffer = {ENCODING_TYPE_STR8};
-  error = Deserialize(&i64, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
-  std::string s;
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT};
-  error = Deserialize(&s, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_STRING, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_POSITIVE_FIXINT, error.encoding_type());
-
-  std::vector<std::uint8_t> v;
-  buffer = {ENCODING_TYPE_POSITIVE_FIXINT};
-  error = Deserialize(&v, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_ARRAY, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_POSITIVE_FIXINT, error.encoding_type());
-
-  buffer = {ENCODING_TYPE_FIXARRAY_MIN + 1, ENCODING_TYPE_STR8};
-  error = Deserialize(&v, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
-  EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
-  EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
-  buffer = {ENCODING_TYPE_FIXARRAY_MIN + 2, 0, 1};
-  std::tuple<int> t;
-  error = Deserialize(&t, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_TYPE_SIZE, error);
-
-  buffer = {ENCODING_TYPE_FIXARRAY_MIN + 3, 0, 1, 2};
-  std::pair<int, int> p;
-  error = Deserialize(&p, &buffer);
-  EXPECT_EQ(ErrorCode::UNEXPECTED_TYPE_SIZE, error);
-}
diff --git a/libs/vr/libpdx/service.cpp b/libs/vr/libpdx/service.cpp
deleted file mode 100644
index 3769162..0000000
--- a/libs/vr/libpdx/service.cpp
+++ /dev/null
@@ -1,675 +0,0 @@
-#include "pdx/service.h"
-
-#include <fcntl.h>
-#include <log/log.h>
-#include <utils/misc.h>
-
-#include <algorithm>
-#include <cstdint>
-
-#include <pdx/trace.h>
-
-namespace android {
-namespace pdx {
-
-std::shared_ptr<Channel> Channel::GetFromMessageInfo(const MessageInfo& info) {
-  return info.channel ? info.channel->shared_from_this()
-                      : std::shared_ptr<Channel>();
-}
-
-Message::Message() : replied_(true) {}
-
-Message::Message(const MessageInfo& info)
-    : service_{Service::GetFromMessageInfo(info)},
-      channel_{Channel::GetFromMessageInfo(info)},
-      info_{info},
-      replied_{IsImpulse()} {
-  auto svc = service_.lock();
-  if (svc)
-    state_ = svc->endpoint()->AllocateMessageState();
-}
-
-// C++11 specifies the move semantics for shared_ptr but not weak_ptr. This
-// means we have to manually implement the desired move semantics for Message.
-Message::Message(Message&& other) noexcept { *this = std::move(other); }
-
-Message& Message::operator=(Message&& other) noexcept {
-  Destroy();
-  auto base = reinterpret_cast<std::uint8_t*>(&info_);
-  std::fill(&base[0], &base[sizeof(info_)], 0);
-  replied_ = true;
-  std::swap(service_, other.service_);
-  std::swap(channel_, other.channel_);
-  std::swap(info_, other.info_);
-  std::swap(state_, other.state_);
-  std::swap(replied_, other.replied_);
-  return *this;
-}
-
-Message::~Message() { Destroy(); }
-
-void Message::Destroy() {
-  auto svc = service_.lock();
-  if (svc) {
-    if (!replied_) {
-      ALOGE(
-          "ERROR: Service \"%s\" failed to reply to message: op=%d pid=%d "
-          "cid=%d\n",
-          svc->name_.c_str(), info_.op, info_.pid, info_.cid);
-      svc->DefaultHandleMessage(*this);
-    }
-    svc->endpoint()->FreeMessageState(state_);
-  }
-  state_ = nullptr;
-  service_.reset();
-  channel_.reset();
-}
-
-const std::uint8_t* Message::ImpulseBegin() const {
-  return reinterpret_cast<const std::uint8_t*>(info_.impulse);
-}
-
-const std::uint8_t* Message::ImpulseEnd() const {
-  return ImpulseBegin() + (IsImpulse() ? GetSendLength() : 0);
-}
-
-Status<size_t> Message::ReadVector(const struct iovec* vector,
-                                   size_t vector_length) {
-  PDX_TRACE_NAME("Message::ReadVector");
-  if (auto svc = service_.lock()) {
-    return svc->endpoint()->ReadMessageData(this, vector, vector_length);
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<void> Message::ReadVectorAll(const struct iovec* vector,
-                                    size_t vector_length) {
-  PDX_TRACE_NAME("Message::ReadVectorAll");
-  if (auto svc = service_.lock()) {
-    const auto status =
-        svc->endpoint()->ReadMessageData(this, vector, vector_length);
-    if (!status)
-      return status.error_status();
-    size_t size_to_read = 0;
-    for (size_t i = 0; i < vector_length; i++)
-      size_to_read += vector[i].iov_len;
-    if (status.get() < size_to_read)
-      return ErrorStatus{EIO};
-    return {};
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<size_t> Message::Read(void* buffer, size_t length) {
-  PDX_TRACE_NAME("Message::Read");
-  if (auto svc = service_.lock()) {
-    const struct iovec vector = {buffer, length};
-    return svc->endpoint()->ReadMessageData(this, &vector, 1);
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<size_t> Message::WriteVector(const struct iovec* vector,
-                                    size_t vector_length) {
-  PDX_TRACE_NAME("Message::WriteVector");
-  if (auto svc = service_.lock()) {
-    return svc->endpoint()->WriteMessageData(this, vector, vector_length);
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<void> Message::WriteVectorAll(const struct iovec* vector,
-                                     size_t vector_length) {
-  PDX_TRACE_NAME("Message::WriteVector");
-  if (auto svc = service_.lock()) {
-    const auto status =
-        svc->endpoint()->WriteMessageData(this, vector, vector_length);
-    if (!status)
-      return status.error_status();
-    size_t size_to_write = 0;
-    for (size_t i = 0; i < vector_length; i++)
-      size_to_write += vector[i].iov_len;
-    if (status.get() < size_to_write)
-      return ErrorStatus{EIO};
-    return {};
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<size_t> Message::Write(const void* buffer, size_t length) {
-  PDX_TRACE_NAME("Message::Write");
-  if (auto svc = service_.lock()) {
-    const struct iovec vector = {const_cast<void*>(buffer), length};
-    return svc->endpoint()->WriteMessageData(this, &vector, 1);
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<FileReference> Message::PushFileHandle(const LocalHandle& handle) {
-  PDX_TRACE_NAME("Message::PushFileHandle");
-  if (auto svc = service_.lock()) {
-    return svc->endpoint()->PushFileHandle(this, handle);
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<FileReference> Message::PushFileHandle(const BorrowedHandle& handle) {
-  PDX_TRACE_NAME("Message::PushFileHandle");
-  if (auto svc = service_.lock()) {
-    return svc->endpoint()->PushFileHandle(this, handle);
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<FileReference> Message::PushFileHandle(const RemoteHandle& handle) {
-  PDX_TRACE_NAME("Message::PushFileHandle");
-  if (auto svc = service_.lock()) {
-    return svc->endpoint()->PushFileHandle(this, handle);
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<ChannelReference> Message::PushChannelHandle(
-    const LocalChannelHandle& handle) {
-  PDX_TRACE_NAME("Message::PushChannelHandle");
-  if (auto svc = service_.lock()) {
-    return svc->endpoint()->PushChannelHandle(this, handle);
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<ChannelReference> Message::PushChannelHandle(
-    const BorrowedChannelHandle& handle) {
-  PDX_TRACE_NAME("Message::PushChannelHandle");
-  if (auto svc = service_.lock()) {
-    return svc->endpoint()->PushChannelHandle(this, handle);
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<ChannelReference> Message::PushChannelHandle(
-    const RemoteChannelHandle& handle) {
-  PDX_TRACE_NAME("Message::PushChannelHandle");
-  if (auto svc = service_.lock()) {
-    return svc->endpoint()->PushChannelHandle(this, handle);
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-bool Message::GetFileHandle(FileReference ref, LocalHandle* handle) {
-  PDX_TRACE_NAME("Message::GetFileHandle");
-  auto svc = service_.lock();
-  if (!svc)
-    return false;
-
-  if (ref >= 0) {
-    *handle = svc->endpoint()->GetFileHandle(this, ref);
-    if (!handle->IsValid())
-      return false;
-  } else {
-    *handle = LocalHandle{ref};
-  }
-  return true;
-}
-
-bool Message::GetChannelHandle(ChannelReference ref,
-                               LocalChannelHandle* handle) {
-  PDX_TRACE_NAME("Message::GetChannelHandle");
-  auto svc = service_.lock();
-  if (!svc)
-    return false;
-
-  if (ref >= 0) {
-    *handle = svc->endpoint()->GetChannelHandle(this, ref);
-    if (!handle->valid())
-      return false;
-  } else {
-    *handle = LocalChannelHandle{nullptr, ref};
-  }
-  return true;
-}
-
-Status<void> Message::Reply(int return_code) {
-  PDX_TRACE_NAME("Message::Reply");
-  auto svc = service_.lock();
-  if (!replied_ && svc) {
-    const auto ret = svc->endpoint()->MessageReply(this, return_code);
-    replied_ = ret.ok();
-    return ret;
-  } else {
-    return ErrorStatus{EINVAL};
-  }
-}
-
-Status<void> Message::ReplyFileDescriptor(unsigned int fd) {
-  PDX_TRACE_NAME("Message::ReplyFileDescriptor");
-  auto svc = service_.lock();
-  if (!replied_ && svc) {
-    const auto ret = svc->endpoint()->MessageReplyFd(this, fd);
-    replied_ = ret.ok();
-    return ret;
-  } else {
-    return ErrorStatus{EINVAL};
-  }
-}
-
-Status<void> Message::ReplyError(unsigned int error) {
-  PDX_TRACE_NAME("Message::ReplyError");
-  auto svc = service_.lock();
-  if (!replied_ && svc) {
-    const auto ret =
-        svc->endpoint()->MessageReply(this, -static_cast<int>(error));
-    replied_ = ret.ok();
-    return ret;
-  } else {
-    return ErrorStatus{EINVAL};
-  }
-}
-
-Status<void> Message::Reply(const LocalHandle& handle) {
-  PDX_TRACE_NAME("Message::ReplyFileHandle");
-  auto svc = service_.lock();
-  if (!replied_ && svc) {
-    Status<void> ret;
-
-    if (handle)
-      ret = svc->endpoint()->MessageReplyFd(this, handle.Get());
-    else
-      ret = svc->endpoint()->MessageReply(this, handle.Get());
-
-    replied_ = ret.ok();
-    return ret;
-  } else {
-    return ErrorStatus{EINVAL};
-  }
-}
-
-Status<void> Message::Reply(const BorrowedHandle& handle) {
-  PDX_TRACE_NAME("Message::ReplyFileHandle");
-  auto svc = service_.lock();
-  if (!replied_ && svc) {
-    Status<void> ret;
-
-    if (handle)
-      ret = svc->endpoint()->MessageReplyFd(this, handle.Get());
-    else
-      ret = svc->endpoint()->MessageReply(this, handle.Get());
-
-    replied_ = ret.ok();
-    return ret;
-  } else {
-    return ErrorStatus{EINVAL};
-  }
-}
-
-Status<void> Message::Reply(const RemoteHandle& handle) {
-  PDX_TRACE_NAME("Message::ReplyFileHandle");
-  auto svc = service_.lock();
-  if (!replied_ && svc) {
-    Status<void> ret = svc->endpoint()->MessageReply(this, handle.Get());
-    replied_ = ret.ok();
-    return ret;
-  } else {
-    return ErrorStatus{EINVAL};
-  }
-}
-
-Status<void> Message::Reply(const LocalChannelHandle& handle) {
-  auto svc = service_.lock();
-  if (!replied_ && svc) {
-    const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
-    replied_ = ret.ok();
-    return ret;
-  } else {
-    return ErrorStatus{EINVAL};
-  }
-}
-
-Status<void> Message::Reply(const BorrowedChannelHandle& handle) {
-  auto svc = service_.lock();
-  if (!replied_ && svc) {
-    const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
-    replied_ = ret.ok();
-    return ret;
-  } else {
-    return ErrorStatus{EINVAL};
-  }
-}
-
-Status<void> Message::Reply(const RemoteChannelHandle& handle) {
-  auto svc = service_.lock();
-  if (!replied_ && svc) {
-    const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
-    replied_ = ret.ok();
-    return ret;
-  } else {
-    return ErrorStatus{EINVAL};
-  }
-}
-
-Status<void> Message::ModifyChannelEvents(int clear_mask, int set_mask) {
-  PDX_TRACE_NAME("Message::ModifyChannelEvents");
-  if (auto svc = service_.lock()) {
-    return svc->endpoint()->ModifyChannelEvents(info_.cid, clear_mask,
-                                                set_mask);
-  } else {
-    return ErrorStatus{ESHUTDOWN};
-  }
-}
-
-Status<RemoteChannelHandle> Message::PushChannel(
-    int flags, const std::shared_ptr<Channel>& channel, int* channel_id) {
-  PDX_TRACE_NAME("Message::PushChannel");
-  if (auto svc = service_.lock()) {
-    return svc->PushChannel(this, flags, channel, channel_id);
-  } else {
-    return ErrorStatus(ESHUTDOWN);
-  }
-}
-
-Status<RemoteChannelHandle> Message::PushChannel(
-    Service* service, int flags, const std::shared_ptr<Channel>& channel,
-    int* channel_id) {
-  PDX_TRACE_NAME("Message::PushChannel");
-  return service->PushChannel(this, flags, channel, channel_id);
-}
-
-Status<int> Message::CheckChannel(ChannelReference ref,
-                                  std::shared_ptr<Channel>* channel) const {
-  PDX_TRACE_NAME("Message::CheckChannel");
-  if (auto svc = service_.lock()) {
-    return svc->CheckChannel(this, ref, channel);
-  } else {
-    return ErrorStatus(ESHUTDOWN);
-  }
-}
-
-Status<int> Message::CheckChannel(const Service* service, ChannelReference ref,
-                                  std::shared_ptr<Channel>* channel) const {
-  PDX_TRACE_NAME("Message::CheckChannel");
-  return service->CheckChannel(this, ref, channel);
-}
-
-pid_t Message::GetProcessId() const { return info_.pid; }
-
-pid_t Message::GetThreadId() const { return info_.tid; }
-
-uid_t Message::GetEffectiveUserId() const { return info_.euid; }
-
-gid_t Message::GetEffectiveGroupId() const { return info_.egid; }
-
-int Message::GetChannelId() const { return info_.cid; }
-
-int Message::GetMessageId() const { return info_.mid; }
-
-int Message::GetOp() const { return info_.op; }
-
-int Message::GetFlags() const { return info_.flags; }
-
-size_t Message::GetSendLength() const { return info_.send_len; }
-
-size_t Message::GetReceiveLength() const { return info_.recv_len; }
-
-size_t Message::GetFileDescriptorCount() const { return info_.fd_count; }
-
-std::shared_ptr<Channel> Message::GetChannel() const { return channel_.lock(); }
-
-Status<void> Message::SetChannel(const std::shared_ptr<Channel>& chan) {
-  channel_ = chan;
-  Status<void> status;
-  if (auto svc = service_.lock())
-    status = svc->SetChannel(info_.cid, chan);
-  return status;
-}
-
-std::shared_ptr<Service> Message::GetService() const { return service_.lock(); }
-
-const MessageInfo& Message::GetInfo() const { return info_; }
-
-Service::Service(const std::string& name, std::unique_ptr<Endpoint> endpoint)
-    : name_(name), endpoint_{std::move(endpoint)} {
-  if (!endpoint_)
-    return;
-
-  const auto status = endpoint_->SetService(this);
-  ALOGE_IF(!status, "Failed to set service context because: %s",
-           status.GetErrorMessage().c_str());
-}
-
-Service::~Service() {
-  if (endpoint_) {
-    const auto status = endpoint_->SetService(nullptr);
-    ALOGE_IF(!status, "Failed to clear service context because: %s",
-             status.GetErrorMessage().c_str());
-  }
-}
-
-std::shared_ptr<Service> Service::GetFromMessageInfo(const MessageInfo& info) {
-  return info.service ? info.service->shared_from_this()
-                      : std::shared_ptr<Service>();
-}
-
-bool Service::IsInitialized() const { return endpoint_.get() != nullptr; }
-
-std::shared_ptr<Channel> Service::OnChannelOpen(Message& /*message*/) {
-  return nullptr;
-}
-
-void Service::OnChannelClose(Message& /*message*/,
-                             const std::shared_ptr<Channel>& /*channel*/) {}
-
-Status<void> Service::SetChannel(int channel_id,
-                                 const std::shared_ptr<Channel>& channel) {
-  PDX_TRACE_NAME("Service::SetChannel");
-  std::lock_guard<std::mutex> autolock(channels_mutex_);
-
-  const auto status = endpoint_->SetChannel(channel_id, channel.get());
-  if (!status) {
-    ALOGE("%s::SetChannel: Failed to set channel context: %s\n", name_.c_str(),
-          status.GetErrorMessage().c_str());
-
-    // It's possible someone mucked with things behind our back by calling the C
-    // API directly. Since we know the channel id isn't valid, make sure we
-    // don't have it in the channels map.
-    if (status.error() == ENOENT)
-      channels_.erase(channel_id);
-  } else {
-    if (channel != nullptr)
-      channels_[channel_id] = channel;
-    else
-      channels_.erase(channel_id);
-  }
-  return status;
-}
-
-std::shared_ptr<Channel> Service::GetChannel(int channel_id) const {
-  PDX_TRACE_NAME("Service::GetChannel");
-  std::lock_guard<std::mutex> autolock(channels_mutex_);
-
-  auto search = channels_.find(channel_id);
-  if (search != channels_.end())
-    return search->second;
-  else
-    return nullptr;
-}
-
-Status<void> Service::CloseChannel(int channel_id) {
-  PDX_TRACE_NAME("Service::CloseChannel");
-  std::lock_guard<std::mutex> autolock(channels_mutex_);
-
-  const auto status = endpoint_->CloseChannel(channel_id);
-
-  // Always erase the map entry, in case someone mucked with things behind our
-  // back using the C API directly.
-  channels_.erase(channel_id);
-
-  return status;
-}
-
-Status<void> Service::ModifyChannelEvents(int channel_id, int clear_mask,
-                                          int set_mask) {
-  PDX_TRACE_NAME("Service::ModifyChannelEvents");
-  return endpoint_->ModifyChannelEvents(channel_id, clear_mask, set_mask);
-}
-
-Status<RemoteChannelHandle> Service::PushChannel(
-    Message* message, int flags, const std::shared_ptr<Channel>& channel,
-    int* channel_id) {
-  PDX_TRACE_NAME("Service::PushChannel");
-
-  std::lock_guard<std::mutex> autolock(channels_mutex_);
-
-  int channel_id_temp = -1;
-  Status<RemoteChannelHandle> ret =
-      endpoint_->PushChannel(message, flags, channel.get(), &channel_id_temp);
-  ALOGE_IF(!ret.ok(), "%s::PushChannel: Failed to push channel: %s",
-           name_.c_str(), strerror(ret.error()));
-
-  if (channel && channel_id_temp != -1)
-    channels_[channel_id_temp] = channel;
-  if (channel_id)
-    *channel_id = channel_id_temp;
-
-  return ret;
-}
-
-Status<int> Service::CheckChannel(const Message* message, ChannelReference ref,
-                                  std::shared_ptr<Channel>* channel) const {
-  PDX_TRACE_NAME("Service::CheckChannel");
-
-  // Synchronization to maintain consistency between the kernel's channel
-  // context pointer and the userspace channels_ map. Other threads may attempt
-  // to modify the map at the same time, which could cause the channel context
-  // pointer returned by the kernel to be invalid.
-  std::lock_guard<std::mutex> autolock(channels_mutex_);
-
-  Channel* channel_context = nullptr;
-  Status<int> ret = endpoint_->CheckChannel(
-      message, ref, channel ? &channel_context : nullptr);
-  if (ret && channel) {
-    if (channel_context)
-      *channel = channel_context->shared_from_this();
-    else
-      *channel = nullptr;
-  }
-
-  return ret;
-}
-
-std::string Service::DumpState(size_t /*max_length*/) { return ""; }
-
-Status<void> Service::HandleMessage(Message& message) {
-  return DefaultHandleMessage(message);
-}
-
-void Service::HandleImpulse(Message& /*impulse*/) {}
-
-Status<void> Service::HandleSystemMessage(Message& message) {
-  const MessageInfo& info = message.GetInfo();
-
-  switch (info.op) {
-    case opcodes::CHANNEL_OPEN: {
-      ALOGD("%s::OnChannelOpen: pid=%d cid=%d\n", name_.c_str(), info.pid,
-            info.cid);
-      message.SetChannel(OnChannelOpen(message));
-      return message.Reply(0);
-    }
-
-    case opcodes::CHANNEL_CLOSE: {
-      ALOGD("%s::OnChannelClose: pid=%d cid=%d\n", name_.c_str(), info.pid,
-            info.cid);
-      OnChannelClose(message, Channel::GetFromMessageInfo(info));
-      message.SetChannel(nullptr);
-      return message.Reply(0);
-    }
-
-    case opcodes::REPORT_SYSPROP_CHANGE:
-      ALOGD("%s:REPORT_SYSPROP_CHANGE: pid=%d cid=%d\n", name_.c_str(),
-            info.pid, info.cid);
-      OnSysPropChange();
-      android::report_sysprop_change();
-      return message.Reply(0);
-
-    case opcodes::DUMP_STATE: {
-      ALOGD("%s:DUMP_STATE: pid=%d cid=%d\n", name_.c_str(), info.pid,
-            info.cid);
-      auto response = DumpState(message.GetReceiveLength());
-      const size_t response_size = response.size() < message.GetReceiveLength()
-                                       ? response.size()
-                                       : message.GetReceiveLength();
-      const Status<size_t> status =
-          message.Write(response.data(), response_size);
-      if (status && status.get() < response_size)
-        return message.ReplyError(EIO);
-      else
-        return message.Reply(status);
-    }
-
-    default:
-      return ErrorStatus{EOPNOTSUPP};
-  }
-}
-
-Status<void> Service::DefaultHandleMessage(Message& message) {
-  const MessageInfo& info = message.GetInfo();
-
-  ALOGD_IF(TRACE, "Service::DefaultHandleMessage: pid=%d cid=%d op=%d\n",
-           info.pid, info.cid, info.op);
-
-  switch (info.op) {
-    case opcodes::CHANNEL_OPEN:
-    case opcodes::CHANNEL_CLOSE:
-    case opcodes::REPORT_SYSPROP_CHANGE:
-    case opcodes::DUMP_STATE:
-      return HandleSystemMessage(message);
-
-    default:
-      return message.ReplyError(EOPNOTSUPP);
-  }
-}
-
-void Service::OnSysPropChange() {}
-
-Status<void> Service::ReceiveAndDispatch() {
-  Message message;
-  const auto status = endpoint_->MessageReceive(&message);
-  if (!status) {
-    ALOGE("Failed to receive message: %s\n", status.GetErrorMessage().c_str());
-    return status;
-  }
-
-  std::shared_ptr<Service> service = message.GetService();
-
-  if (!service) {
-    ALOGE("Service::ReceiveAndDispatch: service context is NULL!!!\n");
-    // Don't block the sender indefinitely in this error case.
-    endpoint_->MessageReply(&message, -EINVAL);
-    return ErrorStatus{EINVAL};
-  }
-
-  if (message.IsImpulse()) {
-    service->HandleImpulse(message);
-    return {};
-  } else if (service->HandleSystemMessage(message)) {
-    return {};
-  } else {
-    return service->HandleMessage(message);
-  }
-}
-
-Status<void> Service::Cancel() { return endpoint_->Cancel(); }
-
-}  // namespace pdx
-}  // namespace android
diff --git a/libs/vr/libpdx/service_dispatcher.cpp b/libs/vr/libpdx/service_dispatcher.cpp
deleted file mode 100644
index ba0d69c..0000000
--- a/libs/vr/libpdx/service_dispatcher.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-#include <pdx/service_dispatcher.h>
-
-#include <errno.h>
-#include <log/log.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-
-#include <pdx/service.h>
-#include <pdx/service_endpoint.h>
-
-static const int kMaxEventsPerLoop = 128;
-
-namespace android {
-namespace pdx {
-
-std::unique_ptr<ServiceDispatcher> ServiceDispatcher::Create() {
-  std::unique_ptr<ServiceDispatcher> dispatcher{new ServiceDispatcher()};
-  if (!dispatcher->epoll_fd_ || !dispatcher->event_fd_) {
-    dispatcher.reset();
-  }
-
-  return dispatcher;
-}
-
-ServiceDispatcher::ServiceDispatcher() {
-  event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-  if (!event_fd_) {
-    ALOGE("Failed to create event fd because: %s\n", strerror(errno));
-    return;
-  }
-
-  epoll_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
-  if (!epoll_fd_) {
-    ALOGE("Failed to create epoll fd because: %s\n", strerror(errno));
-    return;
-  }
-
-  // Use "this" as a unique pointer to distinguish the event fd from all
-  // the other entries that point to instances of Service.
-  epoll_event event;
-  event.events = EPOLLIN;
-  event.data.ptr = this;
-
-  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, event_fd_.Get(), &event) < 0) {
-    ALOGE("Failed to add event fd to epoll fd because: %s\n", strerror(errno));
-
-    // Close the fds here and signal failure to the factory method.
-    event_fd_.Close();
-    epoll_fd_.Close();
-  }
-}
-
-ServiceDispatcher::~ServiceDispatcher() { SetCanceled(true); }
-
-int ServiceDispatcher::ThreadEnter() {
-  std::lock_guard<std::mutex> autolock(mutex_);
-
-  if (canceled_)
-    return -EBUSY;
-
-  thread_count_++;
-  return 0;
-}
-
-void ServiceDispatcher::ThreadExit() {
-  std::lock_guard<std::mutex> autolock(mutex_);
-  thread_count_--;
-  condition_.notify_one();
-}
-
-int ServiceDispatcher::AddService(const std::shared_ptr<Service>& service) {
-  std::lock_guard<std::mutex> autolock(mutex_);
-
-  epoll_event event;
-  event.events = EPOLLIN;
-  event.data.ptr = service.get();
-
-  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, service->endpoint()->epoll_fd(),
-                &event) < 0) {
-    ALOGE("Failed to add service to dispatcher because: %s\n", strerror(errno));
-    return -errno;
-  }
-
-  services_.push_back(service);
-  return 0;
-}
-
-int ServiceDispatcher::RemoveService(const std::shared_ptr<Service>& service) {
-  std::lock_guard<std::mutex> autolock(mutex_);
-
-  // It's dangerous to remove a service while other threads may be using it.
-  if (thread_count_ > 0)
-    return -EBUSY;
-
-  epoll_event ee;  // See BUGS in man 2 epoll_ctl.
-  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, service->endpoint()->epoll_fd(),
-                &ee) < 0) {
-    ALOGE("Failed to remove service from dispatcher because: %s\n",
-          strerror(errno));
-    return -errno;
-  }
-
-  services_.erase(std::remove(services_.begin(), services_.end(), service),
-                  services_.end());
-  return 0;
-}
-
-int ServiceDispatcher::ReceiveAndDispatch() { return ReceiveAndDispatch(-1); }
-
-int ServiceDispatcher::ReceiveAndDispatch(int timeout) {
-  int ret = ThreadEnter();
-  if (ret < 0)
-    return ret;
-
-  epoll_event events[kMaxEventsPerLoop];
-
-  int count = epoll_wait(epoll_fd_.Get(), events, kMaxEventsPerLoop, timeout);
-  if (count <= 0) {
-    ALOGE_IF(count < 0, "Failed to wait for epoll events because: %s\n",
-             strerror(errno));
-    ThreadExit();
-    return count < 0 ? -errno : -ETIMEDOUT;
-  }
-
-  for (int i = 0; i < count; i++) {
-    if (events[i].data.ptr == this) {
-      ThreadExit();
-      return -EBUSY;
-    } else {
-      Service* service = static_cast<Service*>(events[i].data.ptr);
-
-      ALOGI_IF(TRACE, "Dispatching message: fd=%d\n",
-               service->endpoint()->epoll_fd());
-      service->ReceiveAndDispatch();
-    }
-  }
-
-  ThreadExit();
-  return 0;
-}
-
-int ServiceDispatcher::EnterDispatchLoop() {
-  int ret = ThreadEnter();
-  if (ret < 0)
-    return ret;
-
-  epoll_event events[kMaxEventsPerLoop];
-
-  while (!IsCanceled()) {
-    int count = epoll_wait(epoll_fd_.Get(), events, kMaxEventsPerLoop, -1);
-    if (count < 0 && errno != EINTR) {
-      ALOGE("Failed to wait for epoll events because: %s\n", strerror(errno));
-      ThreadExit();
-      return -errno;
-    }
-
-    for (int i = 0; i < count; i++) {
-      if (events[i].data.ptr == this) {
-        ThreadExit();
-        return -EBUSY;
-      } else {
-        Service* service = static_cast<Service*>(events[i].data.ptr);
-
-        ALOGI_IF(TRACE, "Dispatching message: fd=%d\n",
-                 service->endpoint()->epoll_fd());
-        service->ReceiveAndDispatch();
-      }
-    }
-  }
-
-  ThreadExit();
-  return 0;
-}
-
-void ServiceDispatcher::SetCanceled(bool cancel) {
-  std::unique_lock<std::mutex> lock(mutex_);
-  canceled_ = cancel;
-
-  if (canceled_ && thread_count_ > 0) {
-    eventfd_write(event_fd_.Get(), 1);  // Signal threads to quit.
-
-    condition_.wait(lock, [this] { return !(canceled_ && thread_count_ > 0); });
-
-    eventfd_t value;
-    eventfd_read(event_fd_.Get(), &value);  // Unsignal.
-  }
-}
-
-bool ServiceDispatcher::IsCanceled() const { return canceled_; }
-
-}  // namespace pdx
-}  // namespace android
diff --git a/libs/vr/libpdx/service_tests.cpp b/libs/vr/libpdx/service_tests.cpp
deleted file mode 100644
index 938d737..0000000
--- a/libs/vr/libpdx/service_tests.cpp
+++ /dev/null
@@ -1,809 +0,0 @@
-#include <pdx/service.h>
-
-#include <memory>
-#include <string>
-
-#include <gmock/gmock.h>
-#include <pdx/mock_service_endpoint.h>
-
-using android::pdx::BorrowedChannelHandle;
-using android::pdx::BorrowedHandle;
-using android::pdx::Channel;
-using android::pdx::ChannelReference;
-using android::pdx::ErrorStatus;
-using android::pdx::FileReference;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Message;
-using android::pdx::MessageInfo;
-using android::pdx::MockEndpoint;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::RemoteHandle;
-using android::pdx::Service;
-using android::pdx::Status;
-
-using testing::A;
-using testing::ByMove;
-using testing::DoAll;
-using testing::Invoke;
-using testing::Matcher;
-using testing::Ref;
-using testing::Return;
-using testing::SetArgPointee;
-using testing::WithArg;
-using testing::WithoutArgs;
-using testing::_;
-
-namespace {
-
-// Helper functions to construct fake void pointers for tests.
-inline void* IntToPtr(intptr_t addr) { return reinterpret_cast<void*>(addr); }
-
-// Helper matchers for working with iovec structures in tests.
-// Simple matcher for one element iovec array:
-// EXPECT_CALL(mock, method(IoVecMatcher(ptr, size)));
-MATCHER_P2(IoVecMatcher, ptr, size, "") {
-  return arg->iov_base == ptr && arg->iov_len == size;
-}
-
-// Matcher for an array of iovecs:
-// EXPECT_CALL(mock,
-//             method(IoVecMatcher(IoVecArray{{ptr1, size1}, {ptr2, size2}})));
-using IoVecArray = std::vector<iovec>;
-MATCHER_P(IoVecMatcher, iovec_array, "") {
-  auto local_arg = arg;
-  for (const iovec& item : iovec_array) {
-    if (local_arg->iov_base != item.iov_base || local_arg->iov_len != item.iov_len)
-      return false;
-    local_arg++;
-  }
-  return true;
-}
-
-using IoVecData = std::vector<std::string>;
-MATCHER_P(IoVecDataMatcher, iovec_data, "") {
-  auto local_arg = arg;
-  for (const std::string& item : iovec_data) {
-    std::string data{reinterpret_cast<const char*>(local_arg->iov_base),
-                     local_arg->iov_len};
-    if (data != item)
-      return false;
-    local_arg++;
-  }
-  return true;
-}
-
-MATCHER_P(FileHandleMatcher, value, "") { return arg.Get() == value; }
-MATCHER_P(ChannelHandleMatcher, value, "") { return arg.value() == value; }
-
-enum : int {
-  kTestPid = 1,
-  kTestTid,
-  kTestCid,
-  kTestMid,
-  kTestEuid,
-  kTestEgid,
-  kTestOp,
-};
-
-class MockService : public Service {
- public:
-  using Service::Service;
-  MOCK_METHOD1(OnChannelOpen, std::shared_ptr<Channel>(Message& message));
-  MOCK_METHOD2(OnChannelClose,
-               void(Message& message, const std::shared_ptr<Channel>& channel));
-  MOCK_METHOD1(HandleMessage, Status<void>(Message& message));
-  MOCK_METHOD1(HandleImpulse, void(Message& impulse));
-  MOCK_METHOD0(OnSysPropChange, void());
-  MOCK_METHOD1(DumpState, std::string(size_t max_length));
-};
-
-class ServiceTest : public testing::Test {
- public:
-  ServiceTest() {
-    auto endpoint = std::make_unique<testing::StrictMock<MockEndpoint>>();
-    EXPECT_CALL(*endpoint, SetService(_))
-        .Times(2)
-        .WillRepeatedly(Return(Status<void>{}));
-    service_ = std::make_shared<MockService>("MockSvc", std::move(endpoint));
-  }
-
-  MockEndpoint* endpoint() {
-    return static_cast<MockEndpoint*>(service_->endpoint());
-  }
-
-  void SetupMessageInfo(MessageInfo* info, int32_t op, bool impulse = false) {
-    info->pid = kTestPid;
-    info->tid = kTestTid;
-    info->cid = kTestCid;
-    info->mid = impulse ? Message::IMPULSE_MESSAGE_ID : kTestMid;
-    info->euid = kTestEuid;
-    info->egid = kTestEgid;
-    info->op = op;
-    info->flags = 0;
-    info->service = service_.get();
-    info->channel = nullptr;
-    info->send_len = 0;
-    info->recv_len = 0;
-    info->fd_count = 0;
-    memset(info->impulse, 0, sizeof(info->impulse));
-  }
-
-  void SetupMessageInfoAndDefaultExpectations(MessageInfo* info, int32_t op,
-                                              bool impulse = false) {
-    SetupMessageInfo(info, op, impulse);
-    EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(kState));
-    EXPECT_CALL(*endpoint(), FreeMessageState(kState));
-  }
-
-  void ExpectDefaultHandleMessage() {
-    EXPECT_CALL(*endpoint(), MessageReply(_, -EOPNOTSUPP))
-        .WillOnce(Return(Status<void>{}));
-  }
-
-  std::shared_ptr<MockService> service_;
-  void* kState = IntToPtr(123456);
-};
-
-class ServiceMessageTest : public ServiceTest {
- public:
-  ServiceMessageTest() {
-    MessageInfo info;
-    SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
-    message_ = std::make_unique<Message>(info);
-  }
-
-  std::unique_ptr<Message> message_;
-};
-
-}  // anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// Service class tests
-///////////////////////////////////////////////////////////////////////////////
-
-TEST_F(ServiceTest, IsInitialized) {
-  EXPECT_TRUE(service_->IsInitialized());
-  service_ = std::make_shared<MockService>("MockSvc2", nullptr);
-  EXPECT_FALSE(service_->IsInitialized());
-}
-
-TEST_F(ServiceTest, ConstructMessage) {
-  MessageInfo info;
-  SetupMessageInfo(&info, kTestOp);
-  auto test_channel = std::make_shared<Channel>();
-  info.channel = test_channel.get();
-  EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(kState));
-
-  Message message{info};
-
-  EXPECT_FALSE(message.IsImpulse());
-  EXPECT_EQ(kTestPid, message.GetProcessId());
-  EXPECT_EQ(kTestTid, message.GetThreadId());
-  EXPECT_EQ(kTestCid, message.GetChannelId());
-  EXPECT_EQ(kTestMid, message.GetMessageId());
-  EXPECT_EQ((unsigned) kTestEuid, message.GetEffectiveUserId());
-  EXPECT_EQ((unsigned) kTestEgid, message.GetEffectiveGroupId());
-  EXPECT_EQ(kTestOp, message.GetOp());
-  EXPECT_EQ(service_, message.GetService());
-  EXPECT_EQ(test_channel, message.GetChannel());
-  EXPECT_FALSE(message.replied());
-  EXPECT_FALSE(message.IsChannelExpired());
-  EXPECT_FALSE(message.IsServiceExpired());
-  EXPECT_EQ(kState, message.GetState());
-
-  ExpectDefaultHandleMessage();
-  EXPECT_CALL(*endpoint(), FreeMessageState(kState));
-}
-
-TEST_F(ServiceTest, ConstructImpulseMessage) {
-  MessageInfo info;
-  SetupMessageInfo(&info, kTestOp, true);
-  auto test_channel = std::make_shared<Channel>();
-  info.channel = test_channel.get();
-  EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(nullptr));
-
-  Message message{info};
-
-  EXPECT_TRUE(message.IsImpulse());
-  EXPECT_EQ(kTestOp, message.GetOp());
-  EXPECT_EQ(service_, message.GetService());
-  EXPECT_EQ(test_channel, message.GetChannel());
-  EXPECT_TRUE(message.replied());
-  EXPECT_FALSE(message.IsChannelExpired());
-  EXPECT_FALSE(message.IsServiceExpired());
-
-  // DefaultHandleMessage should not be called here.
-  EXPECT_CALL(*endpoint(), FreeMessageState(nullptr));
-}
-
-TEST_F(ServiceTest, HandleMessageChannelOpen) {
-  MessageInfo info;
-  SetupMessageInfoAndDefaultExpectations(&info,
-                                         android::pdx::opcodes::CHANNEL_OPEN);
-  Message message{info};
-
-  auto channel = std::make_shared<Channel>();
-  EXPECT_CALL(*service_, OnChannelOpen(Ref(message))).WillOnce(Return(channel));
-  EXPECT_CALL(*endpoint(), SetChannel(kTestCid, channel.get()))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
-      .WillOnce(Return(Status<void>{}));
-
-  EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageChannelClose) {
-  MessageInfo info;
-  SetupMessageInfoAndDefaultExpectations(&info,
-                                         android::pdx::opcodes::CHANNEL_CLOSE);
-  auto channel = std::make_shared<Channel>();
-  info.channel = channel.get();
-  Message message{info};
-
-  EXPECT_CALL(*service_, OnChannelClose(Ref(message), channel));
-  EXPECT_CALL(*endpoint(), SetChannel(kTestCid, nullptr))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
-      .WillOnce(Return(Status<void>{}));
-
-  EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageOnSysPropChange) {
-  MessageInfo info;
-  SetupMessageInfoAndDefaultExpectations(
-      &info, android::pdx::opcodes::REPORT_SYSPROP_CHANGE);
-  Message message{info};
-
-  EXPECT_CALL(*service_, OnSysPropChange());
-  EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
-      .WillOnce(Return(Status<void>{}));
-
-  EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageOnDumpState) {
-  const size_t kRecvBufSize = 1000;
-  MessageInfo info;
-  SetupMessageInfoAndDefaultExpectations(&info,
-                                         android::pdx::opcodes::DUMP_STATE);
-  info.recv_len = kRecvBufSize;
-  Message message{info};
-
-  const std::string kReply = "foo";
-  EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
-  EXPECT_CALL(
-      *endpoint(),
-      WriteMessageData(&message, IoVecDataMatcher(IoVecData{kReply}), 1))
-      .WillOnce(Return(kReply.size()));
-  EXPECT_CALL(*endpoint(), MessageReply(&message, kReply.size()))
-      .WillOnce(Return(Status<void>{}));
-
-  EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageOnDumpStateTooLarge) {
-  const size_t kRecvBufSize = 3;
-  MessageInfo info;
-  SetupMessageInfoAndDefaultExpectations(&info,
-                                         android::pdx::opcodes::DUMP_STATE);
-  info.recv_len = kRecvBufSize;
-  Message message{info};
-
-  const std::string kReply = "0123456789";
-  const std::string kActualReply = kReply.substr(0, kRecvBufSize);
-  EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
-  EXPECT_CALL(
-      *endpoint(),
-      WriteMessageData(&message, IoVecDataMatcher(IoVecData{kActualReply}), 1))
-      .WillOnce(Return(kActualReply.size()));
-  EXPECT_CALL(*endpoint(), MessageReply(&message, kActualReply.size()))
-      .WillOnce(Return(Status<void>{}));
-
-  EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageOnDumpStateFail) {
-  const size_t kRecvBufSize = 1000;
-  MessageInfo info;
-  SetupMessageInfoAndDefaultExpectations(&info,
-                                         android::pdx::opcodes::DUMP_STATE);
-  info.recv_len = kRecvBufSize;
-  Message message{info};
-
-  const std::string kReply = "foo";
-  EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
-  EXPECT_CALL(
-      *endpoint(),
-      WriteMessageData(&message, IoVecDataMatcher(IoVecData{kReply}), 1))
-      .WillOnce(Return(1));
-  EXPECT_CALL(*endpoint(), MessageReply(&message, -EIO))
-      .WillOnce(Return(Status<void>{}));
-
-  EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageCustom) {
-  MessageInfo info;
-  SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
-  Message message{info};
-
-  EXPECT_CALL(*endpoint(), MessageReply(&message, -EOPNOTSUPP))
-      .WillOnce(Return(Status<void>{}));
-
-  EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, ReplyMessageWithoutService) {
-  MessageInfo info;
-  SetupMessageInfo(&info, kTestOp);
-  EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(nullptr));
-
-  Message message{info};
-
-  EXPECT_FALSE(message.IsServiceExpired());
-  service_.reset();
-  EXPECT_TRUE(message.IsServiceExpired());
-
-  EXPECT_EQ(EINVAL, message.Reply(12).error());
-}
-
-TEST_F(ServiceTest, ReceiveAndDispatchMessage) {
-  MessageInfo info;
-  SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
-  ExpectDefaultHandleMessage();
-
-  auto on_receive = [&info](Message* message) -> Status<void> {
-    *message = Message{info};
-    return {};
-  };
-  EXPECT_CALL(*endpoint(), MessageReceive(_)).WillOnce(Invoke(on_receive));
-  EXPECT_CALL(*service_, HandleMessage(_)).WillOnce(Return(Status<void>{}));
-
-  EXPECT_TRUE(service_->ReceiveAndDispatch());
-}
-
-TEST_F(ServiceTest, ReceiveAndDispatchImpulse) {
-  MessageInfo info;
-  SetupMessageInfoAndDefaultExpectations(&info, kTestOp, true);
-
-  auto on_receive = [&info](Message* message) -> Status<void> {
-    *message = Message{info};
-    return {};
-  };
-  EXPECT_CALL(*endpoint(), MessageReceive(_)).WillOnce(Invoke(on_receive));
-  EXPECT_CALL(*service_, HandleImpulse(_));
-
-  EXPECT_TRUE(service_->ReceiveAndDispatch());
-}
-
-TEST_F(ServiceTest, Cancel) {
-  EXPECT_CALL(*endpoint(), Cancel()).WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(service_->Cancel());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Message class tests
-///////////////////////////////////////////////////////////////////////////////
-
-TEST_F(ServiceMessageTest, Reply) {
-  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), 12))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_FALSE(message_->replied());
-  EXPECT_TRUE(message_->Reply(12));
-  EXPECT_TRUE(message_->replied());
-
-  EXPECT_EQ(EINVAL, message_->Reply(12).error());  // Already replied.
-}
-
-TEST_F(ServiceMessageTest, ReplyFail) {
-  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), 12))
-      .WillOnce(Return(ErrorStatus{EIO}));
-  EXPECT_EQ(EIO, message_->Reply(12).error());
-
-  ExpectDefaultHandleMessage();
-}
-
-TEST_F(ServiceMessageTest, ReplyError) {
-  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -12))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->ReplyError(12));
-}
-
-TEST_F(ServiceMessageTest, ReplyFileDescriptor) {
-  EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), 5))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->ReplyFileDescriptor(5));
-}
-
-TEST_F(ServiceMessageTest, ReplyLocalFileHandle) {
-  const int kFakeFd = 12345;
-  LocalHandle handle{kFakeFd};
-  EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), kFakeFd))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->Reply(handle));
-  handle.Release();  // Make sure we do not close the fake file descriptor.
-}
-
-TEST_F(ServiceMessageTest, ReplyLocalFileHandleError) {
-  LocalHandle handle{-EINVAL};
-  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EINVAL))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyBorrowedFileHandle) {
-  const int kFakeFd = 12345;
-  BorrowedHandle handle{kFakeFd};
-  EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), kFakeFd))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyBorrowedFileHandleError) {
-  BorrowedHandle handle{-EACCES};
-  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EACCES))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyRemoteFileHandle) {
-  RemoteHandle handle{123};
-  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), handle.Get()))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyRemoteFileHandleError) {
-  RemoteHandle handle{-EIO};
-  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EIO))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyLocalChannelHandle) {
-  LocalChannelHandle handle{nullptr, 12345};
-  EXPECT_CALL(*endpoint(), MessageReplyChannelHandle(
-                               message_.get(), A<const LocalChannelHandle&>()))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyBorrowedChannelHandle) {
-  BorrowedChannelHandle handle{12345};
-  EXPECT_CALL(*endpoint(),
-              MessageReplyChannelHandle(message_.get(),
-                                        A<const BorrowedChannelHandle&>()))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyRemoteChannelHandle) {
-  RemoteChannelHandle handle{12345};
-  EXPECT_CALL(*endpoint(), MessageReplyChannelHandle(
-                               message_.get(), A<const RemoteChannelHandle&>()))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyStatusInt) {
-  Status<int> status{123};
-  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), status.get()))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->Reply(status));
-}
-
-TEST_F(ServiceMessageTest, ReplyStatusError) {
-  Status<int> status{ErrorStatus{EIO}};
-  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -status.error()))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->Reply(status));
-}
-
-TEST_F(ServiceMessageTest, Read) {
-  ExpectDefaultHandleMessage();
-  void* const kDataBuffer = IntToPtr(12345);
-  const size_t kDataSize = 100;
-  EXPECT_CALL(
-      *endpoint(),
-      ReadMessageData(message_.get(), IoVecMatcher(kDataBuffer, kDataSize), 1))
-      .WillOnce(Return(50))
-      .WillOnce(Return(ErrorStatus{EACCES}));
-  EXPECT_EQ(50u, message_->Read(kDataBuffer, kDataSize).get());
-  EXPECT_EQ(EACCES, message_->Read(kDataBuffer, kDataSize).error());
-}
-
-TEST_F(ServiceMessageTest, ReadVector) {
-  ExpectDefaultHandleMessage();
-  char buffer1[10];
-  char buffer2[20];
-  iovec vec[] = {{buffer1, sizeof(buffer1)}, {buffer2, sizeof(buffer2)}};
-  EXPECT_CALL(*endpoint(),
-              ReadMessageData(
-                  message_.get(),
-                  IoVecMatcher(IoVecArray{std::begin(vec), std::end(vec)}), 2))
-      .WillOnce(Return(30))
-      .WillOnce(Return(15))
-      .WillOnce(Return(ErrorStatus{EBADF}));
-  EXPECT_EQ(30u, message_->ReadVector(vec, 2).get());
-  EXPECT_EQ(15u, message_->ReadVector(vec).get());
-  EXPECT_EQ(EBADF, message_->ReadVector(vec).error());
-}
-
-TEST_F(ServiceMessageTest, Write) {
-  ExpectDefaultHandleMessage();
-  void* const kDataBuffer = IntToPtr(12345);
-  const size_t kDataSize = 100;
-  EXPECT_CALL(
-      *endpoint(),
-      WriteMessageData(message_.get(), IoVecMatcher(kDataBuffer, kDataSize), 1))
-      .WillOnce(Return(50))
-      .WillOnce(Return(ErrorStatus{EBADMSG}));
-  EXPECT_EQ(50u, message_->Write(kDataBuffer, kDataSize).get());
-  EXPECT_EQ(EBADMSG, message_->Write(kDataBuffer, kDataSize).error());
-}
-
-TEST_F(ServiceMessageTest, WriteVector) {
-  ExpectDefaultHandleMessage();
-  char buffer1[10];
-  char buffer2[20];
-  iovec vec[] = {{buffer1, sizeof(buffer1)}, {buffer2, sizeof(buffer2)}};
-  EXPECT_CALL(*endpoint(),
-              WriteMessageData(
-                  message_.get(),
-                  IoVecMatcher(IoVecArray{std::begin(vec), std::end(vec)}), 2))
-      .WillOnce(Return(30))
-      .WillOnce(Return(15))
-      .WillOnce(Return(ErrorStatus{EIO}));
-  EXPECT_EQ(30u, message_->WriteVector(vec, 2).get());
-  EXPECT_EQ(15u, message_->WriteVector(vec).get());
-  EXPECT_EQ(EIO, message_->WriteVector(vec, 2).error());
-}
-
-TEST_F(ServiceMessageTest, PushLocalFileHandle) {
-  ExpectDefaultHandleMessage();
-  const int kFakeFd = 12345;
-  LocalHandle handle{kFakeFd};
-  EXPECT_CALL(*endpoint(),
-              PushFileHandle(message_.get(), Matcher<const LocalHandle&>(
-                                                 FileHandleMatcher(kFakeFd))))
-      .WillOnce(Return(12))
-      .WillOnce(Return(ErrorStatus{EIO}));
-  EXPECT_EQ(12, message_->PushFileHandle(handle).get());
-  EXPECT_EQ(EIO, message_->PushFileHandle(handle).error());
-  handle.Release();  // Make sure we do not close the fake file descriptor.
-}
-
-TEST_F(ServiceMessageTest, PushBorrowedFileHandle) {
-  ExpectDefaultHandleMessage();
-  const int kFakeFd = 12345;
-  BorrowedHandle handle{kFakeFd};
-  EXPECT_CALL(*endpoint(),
-              PushFileHandle(message_.get(), Matcher<const BorrowedHandle&>(
-                                                 FileHandleMatcher(kFakeFd))))
-      .WillOnce(Return(13))
-      .WillOnce(Return(ErrorStatus{EACCES}));
-  EXPECT_EQ(13, message_->PushFileHandle(handle).get());
-  EXPECT_EQ(EACCES, message_->PushFileHandle(handle).error());
-}
-
-TEST_F(ServiceMessageTest, PushRemoteFileHandle) {
-  ExpectDefaultHandleMessage();
-  const int kFakeFd = 12345;
-  RemoteHandle handle{kFakeFd};
-  EXPECT_CALL(*endpoint(),
-              PushFileHandle(message_.get(), Matcher<const RemoteHandle&>(
-                                                 FileHandleMatcher(kFakeFd))))
-      .WillOnce(Return(kFakeFd))
-      .WillOnce(Return(ErrorStatus{EIO}));
-  EXPECT_EQ(kFakeFd, message_->PushFileHandle(handle).get());
-  EXPECT_EQ(EIO, message_->PushFileHandle(handle).error());
-}
-
-TEST_F(ServiceMessageTest, PushLocalChannelHandle) {
-  ExpectDefaultHandleMessage();
-  int32_t kValue = 12345;
-  LocalChannelHandle handle{nullptr, kValue};
-  EXPECT_CALL(*endpoint(), PushChannelHandle(message_.get(),
-                                             Matcher<const LocalChannelHandle&>(
-                                                 ChannelHandleMatcher(kValue))))
-      .WillOnce(Return(7))
-      .WillOnce(Return(ErrorStatus{EIO}));
-  EXPECT_EQ(7, message_->PushChannelHandle(handle).get());
-  EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
-}
-
-TEST_F(ServiceMessageTest, PushBorrowedChannelHandle) {
-  ExpectDefaultHandleMessage();
-  int32_t kValue = 12345;
-  BorrowedChannelHandle handle{kValue};
-  EXPECT_CALL(
-      *endpoint(),
-      PushChannelHandle(message_.get(), Matcher<const BorrowedChannelHandle&>(
-                                            ChannelHandleMatcher(kValue))))
-      .WillOnce(Return(8))
-      .WillOnce(Return(ErrorStatus{EIO}));
-  EXPECT_EQ(8, message_->PushChannelHandle(handle).get());
-  EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
-}
-
-TEST_F(ServiceMessageTest, PushRemoteChannelHandle) {
-  ExpectDefaultHandleMessage();
-  int32_t kValue = 12345;
-  RemoteChannelHandle handle{kValue};
-  EXPECT_CALL(
-      *endpoint(),
-      PushChannelHandle(message_.get(), Matcher<const RemoteChannelHandle&>(
-                                            ChannelHandleMatcher(kValue))))
-      .WillOnce(Return(kValue))
-      .WillOnce(Return(ErrorStatus{EIO}));
-  EXPECT_EQ(kValue, message_->PushChannelHandle(handle).get());
-  EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
-}
-
-TEST_F(ServiceMessageTest, GetFileHandle) {
-  ExpectDefaultHandleMessage();
-  auto make_file_handle = [](FileReference ref) { return LocalHandle{ref}; };
-  EXPECT_CALL(*endpoint(), GetFileHandle(message_.get(), _))
-      .WillOnce(WithArg<1>(Invoke(make_file_handle)));
-  LocalHandle handle;
-  FileReference kRef = 12345;
-  EXPECT_TRUE(message_->GetFileHandle(kRef, &handle));
-  EXPECT_EQ(kRef, handle.Get());
-  handle.Release();  // Make sure we do not close the fake file descriptor.
-}
-
-TEST_F(ServiceMessageTest, GetFileHandleInvalid) {
-  ExpectDefaultHandleMessage();
-  LocalHandle handle;
-  FileReference kRef = -12;
-  EXPECT_TRUE(message_->GetFileHandle(kRef, &handle));
-  EXPECT_EQ(kRef, handle.Get());
-}
-
-TEST_F(ServiceMessageTest, GetFileHandleError) {
-  ExpectDefaultHandleMessage();
-  EXPECT_CALL(*endpoint(), GetFileHandle(message_.get(), _))
-      .WillOnce(WithoutArgs(Invoke([] { return LocalHandle{-EIO}; })));
-  LocalHandle handle;
-  FileReference kRef = 12345;
-  EXPECT_FALSE(message_->GetFileHandle(kRef, &handle));
-  EXPECT_EQ(-EIO, handle.Get());
-}
-
-TEST_F(ServiceMessageTest, GetChannelHandle) {
-  ExpectDefaultHandleMessage();
-  auto make_channel_handle = [](ChannelReference ref) {
-    return LocalChannelHandle{nullptr, ref};
-  };
-  EXPECT_CALL(*endpoint(), GetChannelHandle(message_.get(), _))
-      .WillOnce(WithArg<1>(Invoke(make_channel_handle)));
-  LocalChannelHandle handle;
-  ChannelReference kRef = 12345;
-  EXPECT_TRUE(message_->GetChannelHandle(kRef, &handle));
-  EXPECT_EQ(kRef, handle.value());
-}
-
-TEST_F(ServiceMessageTest, GetChannelHandleInvalid) {
-  ExpectDefaultHandleMessage();
-  LocalChannelHandle handle;
-  ChannelReference kRef = -12;
-  EXPECT_TRUE(message_->GetChannelHandle(kRef, &handle));
-  EXPECT_EQ(-12, handle.value());
-}
-
-TEST_F(ServiceMessageTest, GetChannelHandleError) {
-  ExpectDefaultHandleMessage();
-  EXPECT_CALL(*endpoint(), GetChannelHandle(message_.get(), _))
-      .WillOnce(WithoutArgs(Invoke([] {
-        return LocalChannelHandle{nullptr, -EIO};
-      })));
-  LocalChannelHandle handle;
-  ChannelReference kRef = 12345;
-  EXPECT_FALSE(message_->GetChannelHandle(kRef, &handle));
-  EXPECT_EQ(-EIO, handle.value());
-}
-
-TEST_F(ServiceMessageTest, ModifyChannelEvents) {
-  ExpectDefaultHandleMessage();
-  int kClearMask = 1;
-  int kSetMask = 2;
-  EXPECT_CALL(*endpoint(), ModifyChannelEvents(kTestCid, kClearMask, kSetMask))
-      .WillOnce(Return(Status<void>{}));
-  EXPECT_TRUE(message_->ModifyChannelEvents(kClearMask, kSetMask));
-}
-
-TEST_F(ServiceMessageTest, PushChannelSameService) {
-  ExpectDefaultHandleMessage();
-  int kFlags = 123;
-  int32_t kValue = 12;
-  EXPECT_CALL(*endpoint(), PushChannel(message_.get(), kFlags, nullptr, _))
-      .WillOnce(DoAll(SetArgPointee<3>(kTestCid),
-                      Return(ByMove(RemoteChannelHandle{kValue}))));
-  int channel_id = -1;
-  auto status = message_->PushChannel(kFlags, nullptr, &channel_id);
-  ASSERT_TRUE(status);
-  EXPECT_EQ(kValue, status.get().value());
-  EXPECT_EQ(kTestCid, channel_id);
-}
-
-TEST_F(ServiceMessageTest, PushChannelFailure) {
-  ExpectDefaultHandleMessage();
-  int kFlags = 123;
-  EXPECT_CALL(*endpoint(), PushChannel(message_.get(), kFlags, nullptr, _))
-      .WillOnce(Return(ByMove(ErrorStatus{EIO})));
-  int channel_id = -1;
-  auto status = message_->PushChannel(kFlags, nullptr, &channel_id);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EIO, status.error());
-}
-
-TEST_F(ServiceMessageTest, PushChannelDifferentService) {
-  ExpectDefaultHandleMessage();
-  auto endpoint2 = std::make_unique<testing::StrictMock<MockEndpoint>>();
-  EXPECT_CALL(*endpoint2, SetService(_))
-      .Times(2)
-      .WillRepeatedly(Return(Status<void>{}));
-  auto service2 =
-      std::make_shared<MockService>("MockSvc2", std::move(endpoint2));
-
-  int kFlags = 123;
-  int32_t kValue = 12;
-  EXPECT_CALL(*static_cast<MockEndpoint*>(service2->endpoint()),
-              PushChannel(message_.get(), kFlags, nullptr, _))
-      .WillOnce(DoAll(SetArgPointee<3>(kTestCid),
-                      Return(ByMove(RemoteChannelHandle{kValue}))));
-  int channel_id = -1;
-  auto status =
-      message_->PushChannel(service2.get(), kFlags, nullptr, &channel_id);
-  ASSERT_TRUE(status);
-  EXPECT_EQ(kValue, status.get().value());
-  EXPECT_EQ(kTestCid, channel_id);
-}
-
-TEST_F(ServiceMessageTest, CheckChannelSameService) {
-  ExpectDefaultHandleMessage();
-
-  auto test_channel = std::make_shared<Channel>();
-  ChannelReference kRef = 123;
-  EXPECT_CALL(*endpoint(), CheckChannel(message_.get(), kRef, _))
-      .WillOnce(DoAll(SetArgPointee<2>(test_channel.get()), Return(kTestCid)));
-  std::shared_ptr<Channel> channel;
-  auto status = message_->CheckChannel(kRef, &channel);
-  ASSERT_TRUE(status);
-  EXPECT_EQ(kTestCid, status.get());
-  EXPECT_EQ(test_channel, channel);
-}
-
-TEST_F(ServiceMessageTest, CheckChannelFailure) {
-  ExpectDefaultHandleMessage();
-  ChannelReference kRef = 123;
-  EXPECT_CALL(*endpoint(), CheckChannel(message_.get(), kRef, _))
-      .WillOnce(Return(ByMove(ErrorStatus{EOPNOTSUPP})));
-  std::shared_ptr<Channel> channel;
-  auto status = message_->CheckChannel(kRef, &channel);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EOPNOTSUPP, status.error());
-}
-
-TEST_F(ServiceMessageTest, CheckChannelDifferentService) {
-  ExpectDefaultHandleMessage();
-  auto endpoint2 = std::make_unique<testing::StrictMock<MockEndpoint>>();
-  EXPECT_CALL(*endpoint2, SetService(_))
-      .Times(2)
-      .WillRepeatedly(Return(Status<void>{}));
-  auto service2 =
-      std::make_shared<MockService>("MockSvc2", std::move(endpoint2));
-
-  auto test_channel = std::make_shared<Channel>();
-  ChannelReference kRef = 123;
-  EXPECT_CALL(*static_cast<MockEndpoint*>(service2->endpoint()),
-              CheckChannel(message_.get(), kRef, _))
-      .WillOnce(DoAll(SetArgPointee<2>(test_channel.get()), Return(kTestCid)));
-  std::shared_ptr<Channel> channel;
-  auto status = message_->CheckChannel(service2.get(), kRef, &channel);
-  ASSERT_TRUE(status);
-  EXPECT_EQ(kTestCid, status.get());
-  EXPECT_EQ(test_channel, channel);
-}
diff --git a/libs/vr/libpdx/status.cpp b/libs/vr/libpdx/status.cpp
deleted file mode 100644
index c275daf..0000000
--- a/libs/vr/libpdx/status.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "pdx/status.h"
-
-#include <pdx/rpc/serialization.h>
-#include <string.h>
-
-namespace android {
-namespace pdx {
-
-std::string ErrorStatus::ErrorToString(int error_code) {
-  char message[1024] = {};
-  return strerror_r(error_code, message, sizeof(message));
-}
-
-}  // namespace pdx
-}  // namespace android
diff --git a/libs/vr/libpdx/status_tests.cpp b/libs/vr/libpdx/status_tests.cpp
deleted file mode 100644
index 772c529..0000000
--- a/libs/vr/libpdx/status_tests.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-#include <pdx/status.h>
-
-#include <gtest/gtest.h>
-
-#include <memory>
-
-using android::pdx::ErrorStatus;
-using android::pdx::Status;
-
-TEST(Status, DefaultInit) {
-  Status<int> status;
-  EXPECT_FALSE(status.ok());
-  EXPECT_TRUE(status.empty());
-  EXPECT_EQ(0, status.get());
-  EXPECT_EQ(0, status.error());
-}
-
-TEST(Status, InitalizeSuccess) {
-  Status<int> status_int{0};
-  EXPECT_FALSE(status_int.empty());
-  EXPECT_TRUE(status_int.ok());
-  EXPECT_EQ(0, status_int.get());
-  status_int = Status<int>(3);
-  EXPECT_FALSE(status_int.empty());
-  EXPECT_TRUE(status_int.ok());
-  EXPECT_EQ(3, status_int.get());
-  status_int = Status<int>(-3);
-  EXPECT_FALSE(status_int.empty());
-  EXPECT_TRUE(status_int.ok());
-  EXPECT_EQ(-3, status_int.get());
-
-  Status<std::string> status_str{"foo"};
-  EXPECT_FALSE(status_str.empty());
-  EXPECT_TRUE(status_str.ok());
-  EXPECT_EQ("foo", status_str.get());
-}
-
-TEST(Status, InitalizeError) {
-  Status<int> status_int = ErrorStatus(12);
-  EXPECT_FALSE(status_int.empty());
-  EXPECT_FALSE(status_int.ok());
-  EXPECT_EQ(0, status_int.get());
-  EXPECT_EQ(12, status_int.error());
-
-  Status<std::string> status_str = ErrorStatus(EIO);
-  EXPECT_FALSE(status_str.empty());
-  EXPECT_FALSE(status_str.ok());
-  EXPECT_EQ(EIO, status_str.error());
-}
-
-TEST(Status, ErrorMessage) {
-  Status<int> status = ErrorStatus(EIO);
-  EXPECT_EQ(status.GetErrorMessage(), strerror(EIO));
-
-  status = ErrorStatus(EINVAL);
-  EXPECT_EQ(status.GetErrorMessage(), strerror(EINVAL));
-}
-
-TEST(Status, Copy) {
-  Status<int> status1;
-  Status<int> status2;
-
-  status1 = Status<int>{12};
-  status2 = ErrorStatus(13);
-  EXPECT_FALSE(status1.empty());
-  EXPECT_FALSE(status2.empty());
-  EXPECT_TRUE(status1.ok());
-  EXPECT_FALSE(status2.ok());
-  EXPECT_EQ(12, status1.get());
-  EXPECT_EQ(0, status1.error());
-  EXPECT_EQ(0, status2.get());
-  EXPECT_EQ(13, status2.error());
-
-  status1 = status2;
-  EXPECT_FALSE(status1.empty());
-  EXPECT_FALSE(status2.empty());
-  EXPECT_FALSE(status1.ok());
-  EXPECT_FALSE(status2.ok());
-  EXPECT_EQ(0, status1.get());
-  EXPECT_EQ(13, status1.error());
-  EXPECT_EQ(0, status2.get());
-  EXPECT_EQ(13, status2.error());
-}
-
-TEST(Status, Move) {
-  Status<std::unique_ptr<int>> status1;
-  Status<std::unique_ptr<int>> status2;
-
-  status1 = Status<std::unique_ptr<int>>{std::make_unique<int>(int{11})};
-  status2 = Status<std::unique_ptr<int>>{std::make_unique<int>(int{12})};
-  EXPECT_FALSE(status1.empty());
-  EXPECT_FALSE(status2.empty());
-  EXPECT_TRUE(status1.ok());
-  EXPECT_TRUE(status2.ok());
-  EXPECT_EQ(11, *status1.get());
-  EXPECT_EQ(12, *status2.get());
-
-  Status<std::unique_ptr<int>> status3 = std::move(status2);
-  EXPECT_FALSE(status1.empty());
-  EXPECT_TRUE(status2.empty());
-  EXPECT_FALSE(status3.empty());
-  EXPECT_TRUE(status1.ok());
-  EXPECT_FALSE(status2.ok());
-  EXPECT_TRUE(status3.ok());
-  EXPECT_EQ(11, *status1.get());
-  EXPECT_EQ(nullptr, status2.get());
-  EXPECT_EQ(12, *status3.get());
-
-  std::swap(status1, status3);
-  EXPECT_EQ(12, *status1.get());
-  EXPECT_EQ(11, *status3.get());
-
-  status3 = std::move(status1);
-  EXPECT_TRUE(status1.empty());
-  EXPECT_EQ(12, *status3.get());
-}
-
-TEST(Status, Take) {
-  Status<std::unique_ptr<int>> status{std::make_unique<int>(int{123})};
-  EXPECT_FALSE(status.empty());
-  EXPECT_NE(nullptr, status.get());
-
-  auto data = status.take();
-  EXPECT_TRUE(status.empty());
-  EXPECT_EQ(nullptr, status.get());
-  EXPECT_EQ(123, *data);
-}
diff --git a/libs/vr/libpdx/thread_local_buffer_tests.cpp b/libs/vr/libpdx/thread_local_buffer_tests.cpp
deleted file mode 100644
index 6cdaf10..0000000
--- a/libs/vr/libpdx/thread_local_buffer_tests.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-#include <memory>
-#include <string>
-#include <thread>
-#include <utility>
-
-#include <gtest/gtest.h>
-#include <pdx/rpc/message_buffer.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-class ThreadLocalBufferTest {
- public:
-  // Returns the unique address of the thread-local buffer. Used to test the
-  // correct behavior of the type-based thread local storage slot mapping
-  // mechanism.
-  template <typename Slot>
-  static std::uintptr_t GetSlotAddress() {
-    return reinterpret_cast<std::uintptr_t>(&MessageBuffer<Slot>::buffer_);
-  }
-
-  // Returns the raw value of the thread local buffer. Used to test the behavior
-  // of backing buffer initialization.
-  template <typename Slot>
-  static std::uintptr_t GetSlotValue() {
-    return reinterpret_cast<std::uintptr_t>(MessageBuffer<Slot>::buffer_);
-  }
-};
-
-}  // namespace rpc
-}  // namespace pdx
-}  // namespace android
-
-using namespace android::pdx::rpc;
-
-namespace {
-
-struct TypeTagA;
-struct TypeTagB;
-
-constexpr std::size_t kSendBufferIndex = 0;
-constexpr std::size_t kReceiveBufferIndex = 1;
-
-using SendSlotA = ThreadLocalSlot<TypeTagA, kSendBufferIndex>;
-using SendSlotB = ThreadLocalSlot<TypeTagB, kSendBufferIndex>;
-using ReceiveSlotA = ThreadLocalSlot<TypeTagA, kReceiveBufferIndex>;
-using ReceiveSlotB = ThreadLocalSlot<TypeTagB, kReceiveBufferIndex>;
-
-}  // anonymous namespace
-
-// Tests that index and type-based thread-local slot addressing works by
-// checking that the slot address is the same when the same index/type
-// combination is used and different when different combinations are used.
-TEST(ThreadLocalBufferTest, TypeSlots) {
-  auto id1 = ThreadLocalBufferTest::GetSlotAddress<SendSlotA>();
-  auto id2 = ThreadLocalBufferTest::GetSlotAddress<ReceiveSlotA>();
-  auto id3 = ThreadLocalBufferTest::GetSlotAddress<SendSlotB>();
-  auto id4 = ThreadLocalBufferTest::GetSlotAddress<ReceiveSlotB>();
-
-  EXPECT_NE(id1, id2);
-  EXPECT_NE(id3, id4);
-  EXPECT_NE(id1, id3);
-  EXPECT_NE(id2, id4);
-
-  auto id1_alias = ThreadLocalBufferTest::GetSlotAddress<SendSlotA>();
-  auto id2_alias = ThreadLocalBufferTest::GetSlotAddress<ReceiveSlotA>();
-  auto id3_alias = ThreadLocalBufferTest::GetSlotAddress<SendSlotB>();
-  auto id4_alias = ThreadLocalBufferTest::GetSlotAddress<ReceiveSlotB>();
-
-  EXPECT_EQ(id1, id1_alias);
-  EXPECT_EQ(id2, id2_alias);
-  EXPECT_EQ(id3, id3_alias);
-  EXPECT_EQ(id4, id4_alias);
-}
-
-// Tests that different threads get different buffers for the same slot address.
-TEST(ThreadLocalBufferTest, ThreadSlots) {
-  auto id1 = ThreadLocalBufferTest::GetSlotAddress<SendBuffer>();
-  std::uintptr_t id2 = 0U;
-
-  std::thread thread([&id2]() mutable {
-    id2 = ThreadLocalBufferTest::GetSlotAddress<SendBuffer>();
-  });
-  thread.join();
-
-  EXPECT_NE(0U, id1);
-  EXPECT_NE(0U, id2);
-  EXPECT_NE(id1, id2);
-}
-
-// Tests that thread-local buffers are allocated at the first buffer request.
-TEST(ThreadLocalBufferTest, InitialValue) {
-  struct TypeTagX;
-  using SendSlotX = ThreadLocalSlot<TypeTagX, kSendBufferIndex>;
-
-  auto value1 = ThreadLocalBufferTest::GetSlotValue<SendSlotX>();
-  MessageBuffer<SendSlotX>::GetBuffer();
-  auto value2 = ThreadLocalBufferTest::GetSlotValue<SendSlotX>();
-
-  EXPECT_EQ(0U, value1);
-  EXPECT_NE(0U, value2);
-}
-
-// Tests that the underlying buffers are the same for a given index/type pair
-// and different across index/type combinations.
-TEST(ThreadLocalBufferTest, BackingBuffer) {
-  auto& buffer1 = MessageBuffer<SendSlotA>::GetBuffer();
-  auto& buffer2 = MessageBuffer<SendSlotA>::GetBuffer();
-  auto& buffer3 = MessageBuffer<SendSlotB>::GetBuffer();
-  auto& buffer4 = MessageBuffer<SendSlotB>::GetBuffer();
-
-  EXPECT_EQ(buffer1.data(), buffer2.data());
-  EXPECT_EQ(buffer3.data(), buffer4.data());
-  EXPECT_NE(buffer1.data(), buffer3.data());
-  EXPECT_NE(buffer2.data(), buffer4.data());
-}
diff --git a/libs/vr/libpdx/variant_tests.cpp b/libs/vr/libpdx/variant_tests.cpp
deleted file mode 100644
index a977fd3..0000000
--- a/libs/vr/libpdx/variant_tests.cpp
+++ /dev/null
@@ -1,1153 +0,0 @@
-#include <array>
-#include <cstdint>
-#include <functional>
-#include <memory>
-#include <string>
-#include <type_traits>
-
-#include <gtest/gtest.h>
-#include <pdx/rpc/variant.h>
-
-using namespace android::pdx;
-using namespace android::pdx::rpc;
-
-namespace {
-
-struct BaseType {
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  BaseType(int value) : value(value) {}
-  int value;
-};
-
-struct DerivedType : BaseType {
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  DerivedType(int value) : BaseType{value} {};
-};
-
-template <typename T>
-class TestType {
- public:
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  TestType(const T& value) : value_(value) {}
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  TestType(T&& value) : value_(std::move(value)) {}
-  TestType(const TestType&) = default;
-  TestType(TestType&&) = default;
-
-  TestType& operator=(const TestType&) = default;
-  TestType& operator=(TestType&&) = default;
-
-  const T& get() const { return value_; }
-  T&& take() { return std::move(value_); }
-
- private:
-  T value_;
-};
-
-template <typename T>
-class InstrumentType {
- public:
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  InstrumentType(const T& value) : value_(value) { constructor_count_++; }
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  InstrumentType(T&& value) : value_(std::move(value)) { constructor_count_++; }
-  InstrumentType(const InstrumentType& other) : value_(other.value_) {
-    constructor_count_++;
-  }
-  InstrumentType(InstrumentType&& other) : value_(std::move(other.value_)) {
-    constructor_count_++;
-  }
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  InstrumentType(const TestType<T>& other) : value_(other.get()) {
-    constructor_count_++;
-  }
-  // NOLINTNEXTLINE(google-explicit-constructor)
-  InstrumentType(TestType<T>&& other) : value_(other.take()) {
-    constructor_count_++;
-  }
-  ~InstrumentType() { destructor_count_++; }
-
-  InstrumentType& operator=(const InstrumentType& other) {
-    copy_assignment_count_++;
-    value_ = other.value_;
-    return *this;
-  }
-  InstrumentType& operator=(InstrumentType&& other) {
-    move_assignment_count_++;
-    value_ = std::move(other.value_);
-    return *this;
-  }
-
-  InstrumentType& operator=(const TestType<T>& other) {
-    copy_assignment_count_++;
-    value_ = other.get();
-    return *this;
-  }
-  InstrumentType& operator=(TestType<T>&& other) {
-    move_assignment_count_++;
-    value_ = other.take();
-    return *this;
-  }
-
-  static std::size_t constructor_count() { return constructor_count_; }
-  static std::size_t destructor_count() { return destructor_count_; }
-  static std::size_t move_assignment_count() { return move_assignment_count_; }
-  static std::size_t copy_assignment_count() { return copy_assignment_count_; }
-
-  const T& get() const { return value_; }
-  T&& take() { return std::move(value_); }
-
-  static void clear() {
-    constructor_count_ = 0;
-    destructor_count_ = 0;
-    move_assignment_count_ = 0;
-    copy_assignment_count_ = 0;
-  }
-
- private:
-  T value_;
-
-  static std::size_t constructor_count_;
-  static std::size_t destructor_count_;
-  static std::size_t move_assignment_count_;
-  static std::size_t copy_assignment_count_;
-};
-
-template <typename T>
-std::size_t InstrumentType<T>::constructor_count_ = 0;
-template <typename T>
-std::size_t InstrumentType<T>::destructor_count_ = 0;
-template <typename T>
-std::size_t InstrumentType<T>::move_assignment_count_ = 0;
-template <typename T>
-std::size_t InstrumentType<T>::copy_assignment_count_ = 0;
-
-}  // anonymous namespace
-
-TEST(Variant, Assignment) {
-  // Assert basic type properties.
-  {
-    Variant<int, bool, float> v;
-    ASSERT_EQ(-1, v.index());
-    ASSERT_FALSE(v.is<int>());
-    ASSERT_FALSE(v.is<bool>());
-    ASSERT_FALSE(v.is<float>());
-  }
-
-  {
-    Variant<int, bool, float> v;
-    v = 10;
-    ASSERT_EQ(0, v.index());
-    ASSERT_TRUE(v.is<int>());
-    ASSERT_FALSE(v.is<bool>());
-    ASSERT_FALSE(v.is<float>());
-    EXPECT_EQ(10, std::get<int>(v));
-  }
-
-  {
-    Variant<int, bool, float> v;
-    v = false;
-    ASSERT_EQ(1, v.index());
-    ASSERT_FALSE(v.is<int>());
-    ASSERT_TRUE(v.is<bool>());
-    ASSERT_FALSE(v.is<float>());
-    EXPECT_EQ(false, std::get<bool>(v));
-  }
-
-  {
-    Variant<int, bool, float> v;
-    v = 1.0f;
-    ASSERT_EQ(2, v.index());
-    ASSERT_FALSE(v.is<int>());
-    ASSERT_FALSE(v.is<bool>());
-    ASSERT_TRUE(v.is<float>());
-    EXPECT_FLOAT_EQ(1.0f, std::get<float>(v));
-  }
-
-  {
-    Variant<int, bool, float> v;
-    // ERROR: More than one type is implicitly convertible from double.
-    // v = 1.0;
-    v = static_cast<float>(1.0);
-  }
-
-  {
-    Variant<int, bool, float> v;
-
-    double x = 1.1;
-    v = static_cast<float>(x);
-    ASSERT_EQ(2, v.index());
-    ASSERT_FALSE(v.is<int>());
-    ASSERT_FALSE(v.is<bool>());
-    ASSERT_TRUE(v.is<float>());
-    EXPECT_FLOAT_EQ(1.1, std::get<float>(v));
-  }
-
-  {
-    Variant<int, std::string> v;
-    ASSERT_EQ(-1, v.index());
-    ASSERT_FALSE(v.is<int>());
-    ASSERT_FALSE(v.is<std::string>());
-  }
-
-  {
-    Variant<int, std::string> v;
-    v = 20;
-    ASSERT_EQ(0, v.index());
-    ASSERT_TRUE(v.is<int>());
-    ASSERT_FALSE(v.is<std::string>());
-    EXPECT_EQ(20, std::get<int>(v));
-  }
-
-  {
-    Variant<int, std::string> v;
-    v = std::string("test");
-    ASSERT_EQ(1, v.index());
-    ASSERT_FALSE(v.is<int>());
-    ASSERT_TRUE(v.is<std::string>());
-    EXPECT_EQ("test", std::get<std::string>(v));
-  }
-
-  {
-    Variant<int, std::string> v;
-    v = "test";
-    ASSERT_EQ(1, v.index());
-    ASSERT_FALSE(v.is<int>());
-    ASSERT_TRUE(v.is<std::string>());
-    EXPECT_EQ("test", std::get<std::string>(v));
-  }
-
-  {
-    Variant<const char*> v1;
-    Variant<std::string> v2;
-
-    v1 = "test";
-    ASSERT_TRUE(v1.is<const char*>());
-    v2 = v1;
-    ASSERT_TRUE(v2.is<std::string>());
-    EXPECT_EQ("test", std::get<std::string>(v2));
-  }
-
-  {
-    Variant<int> a(1);
-    Variant<int> b;
-    ASSERT_TRUE(!a.empty());
-    ASSERT_TRUE(b.empty());
-
-    a = b;
-    ASSERT_TRUE(a.empty());
-    ASSERT_TRUE(b.empty());
-  }
-
-  {
-    Variant<int*, char*> v;
-
-    // ERROR: More than one type is implicitly convertible from nullptr.
-    // v = nullptr;
-
-    v = static_cast<int*>(nullptr);
-    EXPECT_TRUE(v.is<int*>());
-
-    v = static_cast<char*>(nullptr);
-    EXPECT_TRUE(v.is<char*>());
-  }
-
-  {
-    Variant<int*, char*> v;
-    int a = 10;
-    char b = 20;
-
-    v = &b;
-    ASSERT_TRUE(v.is<char*>());
-    EXPECT_EQ(&b, std::get<char*>(v));
-    EXPECT_EQ(b, *std::get<char*>(v));
-
-    v = &a;
-    ASSERT_TRUE(v.is<int*>());
-    EXPECT_EQ(&a, std::get<int*>(v));
-    EXPECT_EQ(a, *std::get<int*>(v));
-  }
-
-  {
-    using IntRef = std::reference_wrapper<int>;
-    Variant<IntRef> v;
-    int a = 10;
-
-    v = a;
-    ASSERT_TRUE(v.is<IntRef>());
-    EXPECT_EQ(a, std::get<IntRef>(v));
-
-    a = 20;
-    EXPECT_EQ(a, std::get<IntRef>(v));
-  }
-}
-
-TEST(Variant, MoveAssignment) {
-  {
-    Variant<std::string> v;
-    std::string s = "test";
-    v = std::move(s);
-
-    EXPECT_TRUE(s.empty());
-    ASSERT_TRUE(v.is<std::string>());
-    EXPECT_EQ("test", std::get<std::string>(v));
-  }
-
-  {
-    Variant<std::string> v("test");
-    std::string s = "fizz";
-    s = std::move(std::get<std::string>(v));
-
-    ASSERT_TRUE(v.is<std::string>());
-    EXPECT_TRUE(std::get<std::string>(v).empty());
-    EXPECT_EQ("test", s);
-  }
-
-  {
-    Variant<std::string> a("test");
-    Variant<std::string> b;
-
-    b = std::move(a);
-    ASSERT_TRUE(a.is<std::string>());
-    ASSERT_TRUE(b.is<std::string>());
-    EXPECT_TRUE(std::get<std::string>(a).empty());
-    EXPECT_EQ("test", std::get<std::string>(b));
-  }
-
-  {
-    Variant<std::string> a("test");
-    Variant<std::string> b("fizz");
-
-    b = std::move(a);
-    ASSERT_TRUE(a.is<std::string>());
-    ASSERT_TRUE(b.is<std::string>());
-    EXPECT_TRUE(std::get<std::string>(a).empty());
-    EXPECT_EQ("test", std::get<std::string>(b));
-  }
-
-  {
-    Variant<int, std::string> a("test");
-    Variant<int, std::string> b(10);
-
-    b = std::move(a);
-    ASSERT_TRUE(a.is<std::string>());
-    ASSERT_TRUE(b.is<std::string>());
-    EXPECT_TRUE(std::get<std::string>(a).empty());
-    EXPECT_EQ("test", std::get<std::string>(b));
-  }
-
-  {
-    Variant<int, std::string> a(10);
-    Variant<int, std::string> b("test");
-
-    b = std::move(a);
-    ASSERT_TRUE(a.is<int>());
-    ASSERT_TRUE(b.is<int>());
-    EXPECT_EQ(10, std::get<int>(a));
-    EXPECT_EQ(10, std::get<int>(b));
-  }
-}
-
-TEST(Variant, Constructor) {
-  {
-    Variant<int, bool, float> v(true);
-    EXPECT_TRUE(v.is<bool>());
-  }
-
-  {
-    Variant<int, bool, float> v(10);
-    EXPECT_TRUE(v.is<int>());
-  }
-
-  {
-    Variant<int, bool, float> v(10.1f);
-    EXPECT_TRUE(v.is<float>());
-  }
-
-  {
-    Variant<float, std::string> v(10.);
-    EXPECT_TRUE(v.is<float>());
-  }
-
-  {
-    TestType<int> i(1);
-    Variant<int, bool, float> v(i.take());
-    ASSERT_TRUE(v.is<int>());
-    EXPECT_EQ(1, std::get<int>(v));
-  }
-
-  {
-    TestType<int> i(1);
-    Variant<int, bool, float> v(i.get());
-    ASSERT_TRUE(v.is<int>());
-    EXPECT_EQ(1, std::get<int>(v));
-  }
-
-  {
-    TestType<bool> b(true);
-    Variant<int, bool, float> v(b.take());
-    ASSERT_TRUE(v.is<bool>());
-    EXPECT_EQ(true, std::get<bool>(v));
-  }
-
-  {
-    TestType<bool> b(true);
-    Variant<int, bool, float> v(b.get());
-    ASSERT_TRUE(v.is<bool>());
-    EXPECT_EQ(true, std::get<bool>(v));
-  }
-
-  {
-    Variant<const char*> c("test");
-    Variant<std::string> s(c);
-    ASSERT_TRUE(s.is<std::string>());
-    EXPECT_EQ("test", std::get<std::string>(s));
-  }
-
-  {
-    Variant<int, bool, float> a(true);
-    Variant<int, bool, float> b(a);
-
-    ASSERT_TRUE(b.is<bool>());
-  }
-
-  {
-    using IntRef = std::reference_wrapper<int>;
-    int a = 10;
-    Variant<IntRef> v(a);
-    TestType<IntRef> t(a);
-
-    ASSERT_TRUE(v.is<IntRef>());
-    EXPECT_EQ(a, std::get<IntRef>(v));
-    EXPECT_EQ(a, t.get());
-
-    a = 20;
-    EXPECT_EQ(a, std::get<IntRef>(v));
-    EXPECT_EQ(a, t.get());
-  }
-}
-
-// Verify correct ctor/dtor and assignment behavior used an instrumented type.
-TEST(Variant, CopyMoveConstructAssign) {
-  {
-    InstrumentType<int>::clear();
-
-    // Default construct to empty, no InstrumentType activity.
-    Variant<int, InstrumentType<int>> v;
-    ASSERT_EQ(0u, InstrumentType<int>::constructor_count());
-    ASSERT_EQ(0u, InstrumentType<int>::destructor_count());
-    ASSERT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    ASSERT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from int type, no InstrumentType activity.
-    Variant<int, InstrumentType<int>> v;
-    v = 10;
-    EXPECT_EQ(0u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from int type, no InstrumentType activity.
-    Variant<int, InstrumentType<int>> v(10);
-    EXPECT_EQ(0u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from temporary, temporary ctor/dtor.
-    Variant<int, InstrumentType<int>> v;
-    v = InstrumentType<int>(25);
-    EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(1u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from temporary, temporary ctor/dtor.
-    Variant<int, InstrumentType<int>> v(InstrumentType<int>(25));
-    EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(1u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from temporary, temporary ctor/dtor.
-    Variant<int, InstrumentType<int>> v(InstrumentType<int>(25));
-
-    // Assign from temporary, temporary ctor/dtor.
-    v = InstrumentType<int>(35);
-    EXPECT_EQ(3u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(2u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(1u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from temporary, temporary ctor/dtor.
-    Variant<int, InstrumentType<int>> v(InstrumentType<int>(25));
-
-    // dtor.
-    v = 10;
-    EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(2u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from temporary, temporary ctor/dtor.
-    Variant<int, InstrumentType<int>> v(InstrumentType<int>(25));
-
-    EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(1u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-  EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
-  EXPECT_EQ(2u, InstrumentType<int>::destructor_count());
-  EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-  EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from other temporary.
-    Variant<int, InstrumentType<int>> v(TestType<int>(10));
-    EXPECT_EQ(1u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from other temporary.
-    Variant<int, InstrumentType<int>> v(TestType<int>(10));
-    // Assign from other temporary.
-    v = TestType<int>(11);
-    EXPECT_EQ(1u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(1u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from other temporary.
-    Variant<int, InstrumentType<int>> v(TestType<int>(10));
-    // Assign from empty Variant.
-    v = Variant<int, InstrumentType<int>>();
-    EXPECT_EQ(1u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(1u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    TestType<int> other(10);
-    // Construct from other.
-    Variant<int, InstrumentType<int>> v(other);
-
-    EXPECT_EQ(1u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from other temporary.
-    Variant<int, InstrumentType<int>> v(TestType<int>(0));
-    TestType<int> other(10);
-    // Assign from other.
-    v = other;
-    EXPECT_EQ(1u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(1u, InstrumentType<int>::copy_assignment_count());
-  }
-
-  {
-    InstrumentType<int>::clear();
-
-    // Construct from temporary, temporary ctor/dtor.
-    Variant<int, InstrumentType<int>> v(InstrumentType<int>(25));
-
-    // Assign EmptyVariant.
-    v = EmptyVariant{};
-
-    EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
-    EXPECT_EQ(2u, InstrumentType<int>::destructor_count());
-    EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-    EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-  }
-  EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
-  EXPECT_EQ(2u, InstrumentType<int>::destructor_count());
-  EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
-  EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-}
-
-TEST(Variant, MoveConstructor) {
-  {
-    std::unique_ptr<int> pointer = std::make_unique<int>(10);
-    Variant<std::unique_ptr<int>> v(std::move(pointer));
-    ASSERT_TRUE(v.is<std::unique_ptr<int>>());
-    EXPECT_TRUE(std::get<std::unique_ptr<int>>(v) != nullptr);
-    EXPECT_TRUE(pointer == nullptr);
-  }
-
-  {
-    Variant<std::unique_ptr<int>> a(std::make_unique<int>(10));
-    Variant<std::unique_ptr<int>> b(std::move(a));
-
-    ASSERT_TRUE(a.is<std::unique_ptr<int>>());
-    ASSERT_TRUE(b.is<std::unique_ptr<int>>());
-    EXPECT_TRUE(std::get<std::unique_ptr<int>>(a) == nullptr);
-    EXPECT_TRUE(std::get<std::unique_ptr<int>>(b) != nullptr);
-  }
-}
-
-TEST(Variant, IndexOf) {
-  Variant<int, bool, float> v1;
-
-  EXPECT_EQ(0, v1.index_of<int>());
-  EXPECT_EQ(1, v1.index_of<bool>());
-  EXPECT_EQ(2, v1.index_of<float>());
-
-  Variant<int, bool, float, int> v2;
-
-  EXPECT_EQ(0, v2.index_of<int>());
-  EXPECT_EQ(1, v2.index_of<bool>());
-  EXPECT_EQ(2, v2.index_of<float>());
-}
-
-struct Visitor {
-  int int_value = 0;
-  bool bool_value = false;
-  float float_value = 0.0;
-  bool empty_value = false;
-
-  void Visit(int value) { int_value = value; }
-  void Visit(bool value) { bool_value = value; }
-  void Visit(float value) { float_value = value; }
-  void Visit(EmptyVariant) { empty_value = true; }
-};
-
-TEST(Variant, Visit) {
-  {
-    Variant<int, bool, float> v(10);
-    EXPECT_TRUE(v.is<int>());
-
-    Visitor visitor;
-    v.Visit([&visitor](const auto& value) { visitor.Visit(value); });
-    EXPECT_EQ(10, visitor.int_value);
-
-    visitor = {};
-    v = true;
-    v.Visit([&visitor](const auto& value) { visitor.Visit(value); });
-    EXPECT_EQ(true, visitor.bool_value);
-  }
-
-  {
-    Variant<int, bool, float> v;
-    EXPECT_EQ(-1, v.index());
-
-    Visitor visitor;
-    v.Visit([&visitor](const auto& value) { visitor.Visit(value); });
-    EXPECT_TRUE(visitor.empty_value);
-  }
-
-  {
-    Variant<std::string> v("test");
-    ASSERT_TRUE(v.is<std::string>());
-    EXPECT_FALSE(std::get<std::string>(v).empty());
-
-    v.Visit([](auto&& value) {
-      std::remove_reference_t<decltype(value)> empty;
-      std::swap(empty, value);
-    });
-    ASSERT_TRUE(v.is<std::string>());
-    EXPECT_TRUE(std::get<std::string>(v).empty());
-  }
-}
-
-TEST(Variant, Become) {
-  {
-    Variant<int, bool, float> v;
-
-    v.Become(0);
-    EXPECT_TRUE(v.is<int>());
-
-    v.Become(1);
-    EXPECT_TRUE(v.is<bool>());
-
-    v.Become(2);
-    EXPECT_TRUE(v.is<float>());
-
-    v.Become(3);
-    EXPECT_TRUE(v.empty());
-
-    v.Become(-1);
-    EXPECT_TRUE(v.empty());
-
-    v.Become(-2);
-    EXPECT_TRUE(v.empty());
-  }
-
-  {
-    Variant<int, bool, float> v;
-
-    v.Become(0, 10);
-    ASSERT_TRUE(v.is<int>());
-    EXPECT_EQ(10, std::get<int>(v));
-
-    v.Become(1, true);
-    ASSERT_TRUE(v.is<bool>());
-    EXPECT_EQ(true, std::get<bool>(v));
-
-    v.Become(2, 2.0f);
-    ASSERT_TRUE(v.is<float>());
-    EXPECT_FLOAT_EQ(2.0f, std::get<float>(v));
-
-    v.Become(3, 10);
-    EXPECT_TRUE(v.empty());
-
-    v.Become(-1, 10);
-    EXPECT_TRUE(v.empty());
-
-    v.Become(-2, 20);
-    EXPECT_TRUE(v.empty());
-  }
-
-  {
-    Variant<std::string> v;
-
-    v.Become(0);
-    ASSERT_TRUE(v.is<std::string>());
-    EXPECT_TRUE(std::get<std::string>(v).empty());
-  }
-
-  {
-    Variant<std::string> v;
-
-    v.Become(0, "test");
-    ASSERT_TRUE(v.is<std::string>());
-    EXPECT_EQ("test", std::get<std::string>(v));
-  }
-
-  {
-    Variant<std::string> v("foo");
-
-    v.Become(0, "bar");
-    ASSERT_TRUE(v.is<std::string>());
-    EXPECT_EQ("foo", std::get<std::string>(v));
-  }
-}
-
-TEST(Variant, Swap) {
-  {
-    Variant<std::string> a;
-    Variant<std::string> b;
-
-    std::swap(a, b);
-    EXPECT_TRUE(a.empty());
-    EXPECT_TRUE(b.empty());
-  }
-
-  {
-    Variant<std::string> a("1");
-    Variant<std::string> b;
-
-    std::swap(a, b);
-    EXPECT_TRUE(a.empty());
-    EXPECT_TRUE(!b.empty());
-    ASSERT_TRUE(b.is<std::string>());
-    EXPECT_EQ("1", std::get<std::string>(b));
-  }
-
-  {
-    Variant<std::string> a;
-    Variant<std::string> b("1");
-
-    std::swap(a, b);
-    EXPECT_TRUE(!a.empty());
-    EXPECT_TRUE(b.empty());
-    ASSERT_TRUE(a.is<std::string>());
-    EXPECT_EQ("1", std::get<std::string>(a));
-  }
-
-  {
-    Variant<std::string> a("1");
-    Variant<std::string> b("2");
-
-    std::swap(a, b);
-    ASSERT_TRUE(a.is<std::string>());
-    ASSERT_TRUE(b.is<std::string>());
-    EXPECT_EQ("2", std::get<std::string>(a));
-    EXPECT_EQ("1", std::get<std::string>(b));
-  }
-
-  {
-    Variant<int, std::string> a(10);
-    Variant<int, std::string> b("1");
-
-    std::swap(a, b);
-    ASSERT_TRUE(a.is<std::string>());
-    ASSERT_TRUE(b.is<int>());
-    EXPECT_EQ("1", std::get<std::string>(a));
-    EXPECT_EQ(10, std::get<int>(b));
-  }
-
-  {
-    Variant<int, std::string> a("1");
-    Variant<int, std::string> b(10);
-
-    std::swap(a, b);
-    ASSERT_TRUE(a.is<int>());
-    ASSERT_TRUE(b.is<std::string>());
-    EXPECT_EQ(10, std::get<int>(a));
-    EXPECT_EQ("1", std::get<std::string>(b));
-  }
-}
-
-TEST(Variant, Get) {
-  {
-    Variant<int, bool, float, int> v;
-
-    EXPECT_EQ(nullptr, &std::get<int>(v));
-    EXPECT_EQ(nullptr, &std::get<bool>(v));
-    EXPECT_EQ(nullptr, &std::get<float>(v));
-    EXPECT_EQ(nullptr, &std::get<0>(v));
-    EXPECT_EQ(nullptr, &std::get<1>(v));
-    EXPECT_EQ(nullptr, &std::get<2>(v));
-    EXPECT_EQ(nullptr, &std::get<3>(v));
-  }
-
-  {
-    Variant<int, bool, float, int> v;
-    v = 9;
-    ASSERT_TRUE(v.is<int>())
-        << "Expected type " << v.index_of<int>() << " got type " << v.index();
-    EXPECT_EQ(9, std::get<int>(v));
-    EXPECT_EQ(9, std::get<0>(v));
-
-    std::get<int>(v) = 10;
-    EXPECT_EQ(10, std::get<int>(v));
-    EXPECT_EQ(10, std::get<0>(v));
-
-    std::get<0>(v) = 11;
-    EXPECT_EQ(11, std::get<int>(v));
-    EXPECT_EQ(11, std::get<0>(v));
-
-    std::get<3>(v) = 12;
-    EXPECT_EQ(12, std::get<int>(v));
-    EXPECT_EQ(12, std::get<3>(v));
-  }
-
-  {
-    Variant<int, bool, float, int> v;
-    v = false;
-    ASSERT_TRUE(v.is<bool>())
-        << "Expected type " << v.index_of<bool>() << " got type " << v.index();
-    EXPECT_EQ(false, std::get<bool>(v));
-    EXPECT_EQ(false, std::get<1>(v));
-
-    std::get<bool>(v) = true;
-    EXPECT_EQ(true, std::get<bool>(v));
-    EXPECT_EQ(true, std::get<1>(v));
-
-    std::get<bool>(v) = false;
-    EXPECT_EQ(false, std::get<bool>(v));
-    EXPECT_EQ(false, std::get<1>(v));
-
-    std::get<1>(v) = true;
-    EXPECT_EQ(true, std::get<bool>(v));
-    EXPECT_EQ(true, std::get<1>(v));
-
-    std::get<1>(v) = false;
-    EXPECT_EQ(false, std::get<bool>(v));
-    EXPECT_EQ(false, std::get<1>(v));
-  }
-
-  {
-    Variant<int, bool, float, int> v;
-    v = 1.0f;
-    ASSERT_TRUE(v.is<float>())
-        << "Expected type " << v.index_of<float>() << " got type " << v.index();
-    EXPECT_EQ(2, v.index());
-    EXPECT_FLOAT_EQ(1.0, std::get<float>(v));
-    EXPECT_FLOAT_EQ(1.0, std::get<2>(v));
-
-    std::get<float>(v) = 1.1;
-    EXPECT_FLOAT_EQ(1.1, std::get<float>(v));
-    EXPECT_FLOAT_EQ(1.1, std::get<2>(v));
-
-    std::get<float>(v) = -3.0;
-    EXPECT_FLOAT_EQ(-3.0, std::get<float>(v));
-    EXPECT_FLOAT_EQ(-3.0, std::get<2>(v));
-
-    std::get<2>(v) = 1.1;
-    EXPECT_FLOAT_EQ(1.1, std::get<float>(v));
-    EXPECT_FLOAT_EQ(1.1, std::get<2>(v));
-
-    std::get<2>(v) = -3.0;
-    EXPECT_FLOAT_EQ(-3.0, std::get<float>(v));
-    EXPECT_FLOAT_EQ(-3.0, std::get<2>(v));
-  }
-
-  {
-    Variant<std::unique_ptr<int>> v(std::make_unique<int>(10));
-    std::unique_ptr<int> pointer = std::move(std::get<std::unique_ptr<int>>(v));
-    ASSERT_FALSE(v.empty());
-    EXPECT_TRUE(pointer != nullptr);
-    EXPECT_TRUE(std::get<std::unique_ptr<int>>(v) == nullptr);
-  }
-
-  {
-    Variant<std::string> v("test");
-    std::string s = std::get<std::string>(std::move(v));
-    EXPECT_EQ("test", s);
-  }
-}
-
-TEST(Variant, IfAnyOf) {
-  {
-    Variant<int, float> v(10);
-    ASSERT_TRUE(v.is<int>());
-
-    bool b = false;
-    EXPECT_TRUE(IfAnyOf<int>::Get(&v, &b));
-    EXPECT_TRUE(b);
-
-    float f = 0.0f;
-    EXPECT_TRUE((IfAnyOf<int, float>::Get(&v, &f)));
-    EXPECT_FLOAT_EQ(10.f, f);
-  }
-
-  {
-    const Variant<int, float> v(10);
-    ASSERT_TRUE(v.is<int>());
-
-    bool b = false;
-    EXPECT_TRUE(IfAnyOf<int>::Get(&v, &b));
-    EXPECT_TRUE(b);
-
-    float f = 0.0f;
-    EXPECT_TRUE((IfAnyOf<int, float>::Get(&v, &f)));
-    EXPECT_FLOAT_EQ(10.f, f);
-  }
-
-  {
-    Variant<int, float> v(10);
-    ASSERT_TRUE(v.is<int>());
-
-    bool b = false;
-    EXPECT_TRUE(IfAnyOf<int>::Call(&v, [&b](const auto& value) { b = value; }));
-    EXPECT_TRUE(b);
-
-    float f = 0.0f;
-    EXPECT_TRUE((
-        IfAnyOf<int, float>::Call(&v, [&f](const auto& value) { f = value; })));
-    EXPECT_FLOAT_EQ(10.f, f);
-  }
-
-  {
-    Variant<std::unique_ptr<int>, int> v(std::make_unique<int>(10));
-    ASSERT_TRUE(v.is<std::unique_ptr<int>>());
-    const int* original_v = std::get<std::unique_ptr<int>>(v).get();
-
-    std::unique_ptr<int> u(std::make_unique<int>(20));
-
-    EXPECT_TRUE(IfAnyOf<std::unique_ptr<int>>::Take(&v, &u));
-    ASSERT_TRUE(v.is<std::unique_ptr<int>>());
-    EXPECT_TRUE(std::get<std::unique_ptr<int>>(v) == nullptr);
-    EXPECT_EQ(u.get(), original_v);
-  }
-
-  {
-    Variant<std::unique_ptr<DerivedType>, int> v(
-        std::make_unique<DerivedType>(10));
-    ASSERT_TRUE(v.is<std::unique_ptr<DerivedType>>());
-    const DerivedType* original_v =
-        std::get<std::unique_ptr<DerivedType>>(v).get();
-
-    std::unique_ptr<BaseType> u(std::make_unique<BaseType>(20));
-
-    EXPECT_TRUE(IfAnyOf<std::unique_ptr<DerivedType>>::Take(&v, &u));
-    ASSERT_TRUE(v.is<std::unique_ptr<DerivedType>>());
-    EXPECT_TRUE(std::get<std::unique_ptr<DerivedType>>(v) == nullptr);
-    EXPECT_EQ(u.get(), original_v);
-  }
-
-  {
-    Variant<std::unique_ptr<int>, int> v(std::make_unique<int>(10));
-    ASSERT_TRUE(v.is<std::unique_ptr<int>>());
-    const int* original_v = std::get<std::unique_ptr<int>>(v).get();
-
-    std::unique_ptr<int> u(std::make_unique<int>(20));
-
-    EXPECT_TRUE(IfAnyOf<std::unique_ptr<int>>::Call(
-        &v, [&u](auto&& value) { u = std::move(value); }));
-    ASSERT_TRUE(v.is<std::unique_ptr<int>>());
-    EXPECT_TRUE(std::get<std::unique_ptr<int>>(v) == nullptr);
-    EXPECT_EQ(u.get(), original_v);
-  }
-
-  {
-    Variant<int, bool, float> v(true);
-    ASSERT_TRUE(v.is<bool>());
-
-    float f = 0.f;
-    EXPECT_FALSE((IfAnyOf<int, float>::Get(&v, &f)));
-    EXPECT_FLOAT_EQ(0.f, f);
-  }
-
-  {
-    Variant<std::string, int> v("foo");
-    ASSERT_TRUE(v.is<std::string>());
-
-    std::string s = "bar";
-    EXPECT_TRUE(IfAnyOf<std::string>::Swap(&v, &s));
-    ASSERT_TRUE(v.is<std::string>());
-    EXPECT_EQ("bar", std::get<std::string>(v));
-    EXPECT_EQ("foo", s);
-  }
-
-  {
-    Variant<std::string, const char*> v(static_cast<const char*>("foo"));
-    ASSERT_TRUE(v.is<const char*>());
-
-    std::string s = "bar";
-    EXPECT_TRUE((IfAnyOf<std::string, const char*>::Take(&v, &s)));
-    ASSERT_TRUE(v.is<const char*>());
-    EXPECT_EQ("foo", std::get<const char*>(v));
-    EXPECT_EQ("foo", s);
-
-    v = std::string("bar");
-    ASSERT_TRUE(v.is<std::string>());
-
-    EXPECT_TRUE((IfAnyOf<std::string, const char*>::Take(&v, &s)));
-    ASSERT_TRUE(v.is<std::string>());
-    EXPECT_EQ("bar", s);
-  }
-
-  {
-    Variant<std::string, const char*> v;
-    ASSERT_TRUE(v.empty());
-
-    std::string s = "bar";
-    EXPECT_FALSE((IfAnyOf<std::string, const char*>::Take(&v, &s)));
-    EXPECT_EQ("bar", s);
-  }
-
-  {
-    Variant<std::string, const char*> v(static_cast<const char*>("test"));
-    ASSERT_TRUE(v.is<const char*>());
-
-    std::string s;
-    EXPECT_FALSE(IfAnyOf<>::Take(&v, &s));
-    EXPECT_TRUE(s.empty());
-  }
-}
-
-TEST(Variant, ConstVolatile) {
-  {
-    Variant<const int> v(10);
-    ASSERT_TRUE(v.is<const int>());
-    EXPECT_EQ(10, std::get<const int>(v));
-  }
-
-  {
-    Variant<const std::string> v("test");
-    ASSERT_TRUE(v.is<const std::string>());
-    EXPECT_EQ("test", std::get<const std::string>(v));
-  }
-
-  {
-    Variant<volatile int, std::string> v(10);
-    ASSERT_TRUE(v.is<volatile int>());
-    EXPECT_EQ(10, std::get<volatile int>(v));
-  }
-}
-
-TEST(Variant, HasType) {
-  EXPECT_TRUE((detail::HasType<int, int, float, bool>::value));
-  EXPECT_FALSE((detail::HasType<char, int, float, bool>::value));
-  EXPECT_FALSE(detail::HasType<>::value);
-
-  EXPECT_TRUE((detail::HasType<int&, int, float, bool>::value));
-  EXPECT_FALSE((detail::HasType<char&, int, float, bool>::value));
-}
-
-TEST(Variant, IsConstructible) {
-  using ArrayType = const float[3];
-  struct ImplicitBool {
-    // NOLINTNEXTLINE(google-explicit-constructor)
-    operator bool() const { return true; }
-  };
-  struct ExplicitBool {
-    explicit operator bool() const { return true; }
-  };
-  struct NonBool {};
-  struct TwoArgs {
-    TwoArgs(int, bool) {}
-  };
-
-  EXPECT_FALSE((detail::IsConstructible<bool, ArrayType>::value));
-  EXPECT_TRUE((detail::IsConstructible<bool, int>::value));
-  EXPECT_TRUE((detail::IsConstructible<bool, ImplicitBool>::value));
-  EXPECT_TRUE((detail::IsConstructible<bool, ExplicitBool>::value));
-  EXPECT_FALSE((detail::IsConstructible<bool, NonBool>::value));
-  EXPECT_TRUE((detail::IsConstructible<TwoArgs, int, bool>::value));
-  EXPECT_FALSE((detail::IsConstructible<TwoArgs, int, std::string>::value));
-  EXPECT_FALSE((detail::IsConstructible<TwoArgs, int>::value));
-}
-
-TEST(Variant, Set) {
-  EXPECT_TRUE((detail::Set<int, bool, float>::template IsSubset<int, bool,
-                                                                float>::value));
-  EXPECT_TRUE(
-      (detail::Set<int, bool, float>::template IsSubset<bool, float>::value));
-  EXPECT_TRUE((detail::Set<int, bool, float>::template IsSubset<float>::value));
-  EXPECT_TRUE((detail::Set<int, bool, float>::template IsSubset<>::value));
-
-  EXPECT_FALSE(
-      (detail::Set<int, bool, float>::template IsSubset<int, bool, float,
-                                                        char>::value));
-  EXPECT_FALSE((detail::Set<int, bool, float>::template IsSubset<bool, float,
-                                                                 char>::value));
-  EXPECT_FALSE(
-      (detail::Set<int, bool, float>::template IsSubset<float, char>::value));
-  EXPECT_FALSE((detail::Set<int, bool, float>::template IsSubset<char>::value));
-
-  EXPECT_TRUE(detail::Set<>::template IsSubset<>::value);
-  EXPECT_FALSE(detail::Set<>::template IsSubset<int>::value);
-  EXPECT_FALSE((detail::Set<>::template IsSubset<int, float>::value));
-}
diff --git a/libs/vr/libpdx_default_transport/Android.bp b/libs/vr/libpdx_default_transport/Android.bp
deleted file mode 100644
index a5758b5..0000000
--- a/libs/vr/libpdx_default_transport/Android.bp
+++ /dev/null
@@ -1,88 +0,0 @@
-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_defaults {
-    name: "pdx_default_transport_compiler_defaults",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-}
-
-cc_defaults {
-    name: "pdx_default_transport_lib_defaults",
-    export_include_dirs: ["private"],
-    whole_static_libs: ["libpdx"],
-}
-
-cc_defaults {
-    name: "pdx_use_transport_servicefs",
-    export_include_dirs: ["private/servicefs"],
-    whole_static_libs: [
-        "libpdx_servicefs",
-        "libservicefs",
-    ],
-}
-
-cc_defaults {
-    name: "pdx_use_transport_uds",
-    export_include_dirs: ["private/uds"],
-    whole_static_libs: ["libpdx_uds"],
-}
-
-cc_library_shared {
-    name: "libpdx_default_transport",
-    defaults: [
-        "pdx_default_transport_compiler_defaults",
-        "pdx_default_transport_lib_defaults",
-        "pdx_use_transport_uds",
-    ],
-    shared_libs: [
-        "libbase",
-        "libbinder",
-        "libcutils",
-        "liblog",
-        "libutils",
-        "libselinux",
-    ],
-}
-
-cc_binary {
-    name: "pdx_tool",
-    system_ext_specific: true,
-    defaults: ["pdx_default_transport_compiler_defaults"],
-    srcs: [
-        "pdx_tool.cpp",
-    ],
-    shared_libs: [
-        "libbinder",
-        "libcutils",
-        "liblog",
-        "libpdx_default_transport",
-    ],
-}
-
-// Benchmarks.
-cc_binary {
-    name: "pdx_benchmarks",
-    defaults: ["pdx_default_transport_compiler_defaults"],
-    srcs: [
-        "pdx_benchmarks.cpp",
-    ],
-    shared_libs: [
-        "libbase",
-        "libbinder",
-        "libchrome",
-        "libcutils",
-        "liblog",
-        "libutils",
-        "libpdx_default_transport",
-    ],
-}
diff --git a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
deleted file mode 100644
index 5c9e74c..0000000
--- a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
+++ /dev/null
@@ -1,1090 +0,0 @@
-// Use ALWAYS at the tag level. Control is performed manually during command
-// line processing.
-#define ATRACE_TAG ATRACE_TAG_ALWAYS
-#include <utils/Trace.h>
-
-#include <base/files/file_util.h>
-#include <base/logging.h>
-#include <base/strings/string_split.h>
-#include <errno.h>
-#include <getopt.h>
-#include <pdx/client.h>
-#include <pdx/default_transport/client_channel_factory.h>
-#include <pdx/default_transport/service_endpoint.h>
-#include <pdx/rpc/buffer_wrapper.h>
-#include <pdx/rpc/default_initialization_allocator.h>
-#include <pdx/rpc/message_buffer.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/rpc/serializable.h>
-#include <pdx/service.h>
-#include <sys/prctl.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <atomic>
-#include <cstdlib>
-#include <functional>
-#include <future>
-#include <iomanip>
-#include <ios>
-#include <iostream>
-#include <memory>
-#include <numeric>
-#include <sstream>
-#include <string>
-#include <thread>
-#include <vector>
-
-using android::pdx::Channel;
-using android::pdx::ClientBase;
-using android::pdx::Endpoint;
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::Service;
-using android::pdx::ServiceBase;
-using android::pdx::default_transport::ClientChannelFactory;
-using android::pdx::Status;
-using android::pdx::Transaction;
-using android::pdx::rpc::BufferWrapper;
-using android::pdx::rpc::DefaultInitializationAllocator;
-using android::pdx::rpc::MessageBuffer;
-using android::pdx::rpc::DispatchRemoteMethod;
-using android::pdx::rpc::RemoteMethodReturn;
-using android::pdx::rpc::ReplyBuffer;
-using android::pdx::rpc::Void;
-using android::pdx::rpc::WrapBuffer;
-
-namespace {
-
-constexpr size_t kMaxMessageSize = 4096 * 1024;
-
-std::string GetServicePath(const std::string& path, int instance_id) {
-  return path + std::to_string(instance_id);
-}
-
-void SetThreadName(const std::string& name) {
-  prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name.c_str()), 0, 0, 0);
-}
-
-constexpr uint64_t kNanosPerSecond = 1000000000LLU;
-
-uint64_t GetClockNs() {
-  timespec t;
-  clock_gettime(CLOCK_MONOTONIC, &t);
-  return kNanosPerSecond * t.tv_sec + t.tv_nsec;
-}
-
-template <typename T>
-ssize_t ssizeof(const T&) {
-  return static_cast<ssize_t>(sizeof(T));
-}
-
-class SchedStats {
- public:
-  SchedStats() : SchedStats(gettid()) {}
-  explicit SchedStats(pid_t task_id) : task_id_(task_id) {}
-  SchedStats(const SchedStats&) = default;
-  SchedStats& operator=(const SchedStats&) = default;
-
-  void Update() {
-    const std::string stats_path =
-        "/proc/" + std::to_string(task_id_) + "/schedstat";
-
-    std::string line;
-    base::ReadFileToString(base::FilePath{stats_path}, &line);
-    std::vector<std::string> stats = base::SplitString(
-        line, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-
-    CHECK_EQ(3u, stats.size());
-
-    // Calculate the deltas since the last update. Each value is absolute since
-    // the task started.
-    uint64_t current_cpu_time_ns = std::stoull(stats[0]);
-    uint64_t current_wait_ns = std::stoull(stats[1]);
-    uint64_t current_timeslices = std::stoull(stats[2]);
-    cpu_time_ns_ = current_cpu_time_ns - last_cpu_time_ns_;
-    wait_ns_ = current_wait_ns - last_wait_ns_;
-    timeslices_ = current_timeslices - last_timeslices_;
-    last_cpu_time_ns_ = current_cpu_time_ns;
-    last_wait_ns_ = current_wait_ns;
-    last_timeslices_ = current_timeslices;
-  }
-
-  pid_t task_id() const { return task_id_; }
-  uint64_t cpu_time_ns() const { return cpu_time_ns_; }
-  uint64_t wait_ns() const { return wait_ns_; }
-  uint64_t timeslices() const { return timeslices_; }
-
-  double cpu_time_s() const {
-    return static_cast<double>(cpu_time_ns_) / kNanosPerSecond;
-  }
-  double wait_s() const {
-    return static_cast<double>(wait_ns_) / kNanosPerSecond;
-  }
-
- private:
-  int32_t task_id_;
-  uint64_t cpu_time_ns_ = 0;
-  uint64_t last_cpu_time_ns_ = 0;
-  uint64_t wait_ns_ = 0;
-  uint64_t last_wait_ns_ = 0;
-  uint64_t timeslices_ = 0;
-  uint64_t last_timeslices_ = 0;
-
-  PDX_SERIALIZABLE_MEMBERS(SchedStats, task_id_, cpu_time_ns_, wait_ns_,
-                           timeslices_);
-};
-
-// Opcodes for client/service protocol.
-struct BenchmarkOps {
-  enum : int {
-    Nop,
-    Read,
-    Write,
-    Echo,
-    Stats,
-    WriteVector,
-    EchoVector,
-    Quit,
-  };
-};
-
-struct BenchmarkRPC {
-  PDX_REMOTE_METHOD(Stats, BenchmarkOps::Stats,
-                    std::tuple<uint64_t, uint64_t, SchedStats>(Void));
-  PDX_REMOTE_METHOD(WriteVector, BenchmarkOps::WriteVector,
-                    int(const BufferWrapper<std::vector<uint8_t>> data));
-  PDX_REMOTE_METHOD(EchoVector, BenchmarkOps::EchoVector,
-                    BufferWrapper<std::vector<uint8_t>>(
-                        const BufferWrapper<std::vector<uint8_t>> data));
-};
-
-struct BenchmarkResult {
-  int thread_id = 0;
-  int service_id = 0;
-  double time_delta_s = 0.0;
-  uint64_t bytes_sent = 0;
-  SchedStats sched_stats = {};
-};
-
-// Global command line option values.
-struct Options {
-  bool verbose = false;
-  int threads = 1;
-  int opcode = BenchmarkOps::Read;
-  int blocksize = 1;
-  int count = 1;
-  int instances = 1;
-  int timeout = 1;
-  int warmup = 0;
-} ProgramOptions;
-
-// Command line option names.
-const char kOptionService[] = "service";
-const char kOptionClient[] = "client";
-const char kOptionVerbose[] = "verbose";
-const char kOptionOpcode[] = "op";
-const char kOptionBlocksize[] = "bs";
-const char kOptionCount[] = "count";
-const char kOptionThreads[] = "threads";
-const char kOptionInstances[] = "instances";
-const char kOptionTimeout[] = "timeout";
-const char kOptionTrace[] = "trace";
-const char kOptionWarmup[] = "warmup";
-
-// getopt() long options.
-static option long_options[] = {
-    {kOptionService, required_argument, 0, 0},
-    {kOptionClient, required_argument, 0, 0},
-    {kOptionVerbose, no_argument, 0, 0},
-    {kOptionOpcode, required_argument, 0, 0},
-    {kOptionBlocksize, required_argument, 0, 0},
-    {kOptionCount, required_argument, 0, 0},
-    {kOptionThreads, required_argument, 0, 0},
-    {kOptionInstances, required_argument, 0, 0},
-    {kOptionTimeout, required_argument, 0, 0},
-    {kOptionTrace, no_argument, 0, 0},
-    {kOptionWarmup, required_argument, 0, 0},
-    {0, 0, 0, 0},
-};
-
-// Parses the argument for kOptionOpcode and sets the value of
-// ProgramOptions.opcode.
-void ParseOpcodeOption(const std::string& argument) {
-  if (argument == "read") {
-    ProgramOptions.opcode = BenchmarkOps::Read;
-  } else if (argument == "write") {
-    ProgramOptions.opcode = BenchmarkOps::Write;
-  } else if (argument == "echo") {
-    ProgramOptions.opcode = BenchmarkOps::Echo;
-  } else if (argument == "writevec") {
-    ProgramOptions.opcode = BenchmarkOps::WriteVector;
-  } else if (argument == "echovec") {
-    ProgramOptions.opcode = BenchmarkOps::EchoVector;
-  } else if (argument == "quit") {
-    ProgramOptions.opcode = BenchmarkOps::Quit;
-  } else if (argument == "nop") {
-    ProgramOptions.opcode = BenchmarkOps::Nop;
-  } else if (argument == "stats") {
-    ProgramOptions.opcode = BenchmarkOps::Stats;
-  } else {
-    ProgramOptions.opcode = std::stoi(argument);
-  }
-}
-
-// Implements the service side of the benchmark.
-class BenchmarkService : public ServiceBase<BenchmarkService> {
- public:
-  std::shared_ptr<Channel> OnChannelOpen(Message& message) override {
-    VLOG(1) << "BenchmarkService::OnChannelCreate: cid="
-            << message.GetChannelId();
-    return nullptr;
-  }
-
-  void OnChannelClose(Message& message,
-                      const std::shared_ptr<Channel>& /*channel*/) override {
-    VLOG(1) << "BenchmarkService::OnChannelClose: cid="
-            << message.GetChannelId();
-  }
-
-  Status<void> HandleMessage(Message& message) override {
-    ATRACE_NAME("BenchmarkService::HandleMessage");
-
-    switch (message.GetOp()) {
-      case BenchmarkOps::Nop:
-        VLOG(1) << "BenchmarkService::HandleMessage: op=nop";
-        {
-          ATRACE_NAME("Reply");
-          CHECK(message.Reply(0));
-        }
-        return {};
-
-      case BenchmarkOps::Write: {
-        VLOG(1) << "BenchmarkService::HandleMessage: op=write send_length="
-                << message.GetSendLength()
-                << " receive_length=" << message.GetReceiveLength();
-
-        Status<void> status;
-        if (message.GetSendLength())
-          status = message.ReadAll(send_buffer.data(), message.GetSendLength());
-
-        {
-          ATRACE_NAME("Reply");
-          if (!status)
-            CHECK(message.ReplyError(status.error()));
-          else
-            CHECK(message.Reply(message.GetSendLength()));
-        }
-        return {};
-      }
-
-      case BenchmarkOps::Read: {
-        VLOG(1) << "BenchmarkService::HandleMessage: op=read send_length="
-                << message.GetSendLength()
-                << " receive_length=" << message.GetReceiveLength();
-
-        Status<void> status;
-        if (message.GetReceiveLength()) {
-          status = message.WriteAll(receive_buffer.data(),
-                                    message.GetReceiveLength());
-        }
-
-        {
-          ATRACE_NAME("Reply");
-          if (!status)
-            CHECK(message.ReplyError(status.error()));
-          else
-            CHECK(message.Reply(message.GetReceiveLength()));
-        }
-        return {};
-      }
-
-      case BenchmarkOps::Echo: {
-        VLOG(1) << "BenchmarkService::HandleMessage: op=echo send_length="
-                << message.GetSendLength()
-                << " receive_length=" << message.GetReceiveLength();
-
-        Status<void> status;
-        if (message.GetSendLength())
-          status = message.ReadAll(send_buffer.data(), message.GetSendLength());
-
-        if (!status) {
-          CHECK(message.ReplyError(status.error()));
-          return {};
-        }
-
-        if (message.GetSendLength()) {
-          status =
-              message.WriteAll(send_buffer.data(), message.GetSendLength());
-        }
-
-        {
-          ATRACE_NAME("Reply");
-          if (!status)
-            CHECK(message.ReplyError(status.error()));
-          else
-            CHECK(message.Reply(message.GetSendLength()));
-        }
-        return {};
-      }
-
-      case BenchmarkOps::Stats: {
-        VLOG(1) << "BenchmarkService::HandleMessage: op=echo send_length="
-                << message.GetSendLength()
-                << " receive_length=" << message.GetReceiveLength();
-
-        // Snapshot the stats when the message is received.
-        const uint64_t receive_time_ns = GetClockNs();
-        sched_stats_.Update();
-
-        // Use the RPC system to return the results.
-        RemoteMethodReturn<BenchmarkRPC::Stats>(
-            message, BenchmarkRPC::Stats::Return{receive_time_ns, GetClockNs(),
-                                                 sched_stats_});
-        return {};
-      }
-
-      case BenchmarkOps::WriteVector:
-        VLOG(1) << "BenchmarkService::HandleMessage: op=writevec send_length="
-                << message.GetSendLength()
-                << " receive_length=" << message.GetReceiveLength();
-
-        DispatchRemoteMethod<BenchmarkRPC::WriteVector>(
-            *this, &BenchmarkService::OnWriteVector, message, kMaxMessageSize);
-        return {};
-
-      case BenchmarkOps::EchoVector:
-        VLOG(1) << "BenchmarkService::HandleMessage: op=echovec send_length="
-                << message.GetSendLength()
-                << " receive_length=" << message.GetReceiveLength();
-
-        DispatchRemoteMethod<BenchmarkRPC::EchoVector>(
-            *this, &BenchmarkService::OnEchoVector, message, kMaxMessageSize);
-        return {};
-
-      case BenchmarkOps::Quit:
-        Cancel();
-        return ErrorStatus{ESHUTDOWN};
-
-      default:
-        VLOG(1) << "BenchmarkService::HandleMessage: default case; op="
-                << message.GetOp();
-        return Service::DefaultHandleMessage(message);
-    }
-  }
-
-  // Updates the scheduler stats from procfs for this thread.
-  void UpdateSchedStats() { sched_stats_.Update(); }
-
- private:
-  friend BASE;
-
-  explicit BenchmarkService(std::unique_ptr<Endpoint> endpoint)
-      : BASE("BenchmarkService", std::move(endpoint)),
-        send_buffer(kMaxMessageSize),
-        receive_buffer(kMaxMessageSize) {}
-
-  std::vector<uint8_t> send_buffer;
-  std::vector<uint8_t> receive_buffer;
-
-  // Each service thread has its own scheduler stats object.
-  static thread_local SchedStats sched_stats_;
-
-  using BufferType = BufferWrapper<
-      std::vector<uint8_t, DefaultInitializationAllocator<uint8_t>>>;
-
-  int OnWriteVector(Message&, const BufferType& data) { return data.size(); }
-  BufferType OnEchoVector(Message&, BufferType&& data) {
-    return std::move(data);
-  }
-
-  BenchmarkService(const BenchmarkService&) = delete;
-  void operator=(const BenchmarkService&) = delete;
-};
-
-thread_local SchedStats BenchmarkService::sched_stats_;
-
-// Implements the client side of the benchmark.
-class BenchmarkClient : public ClientBase<BenchmarkClient> {
- public:
-  int Nop() {
-    ATRACE_NAME("BenchmarkClient::Nop");
-    VLOG(1) << "BenchmarkClient::Nop";
-    Transaction transaction{*this};
-    return ReturnStatusOrError(transaction.Send<int>(BenchmarkOps::Nop));
-  }
-
-  int Write(const void* buffer, size_t length) {
-    ATRACE_NAME("BenchmarkClient::Write");
-    VLOG(1) << "BenchmarkClient::Write: buffer=" << buffer
-            << " length=" << length;
-    Transaction transaction{*this};
-    return ReturnStatusOrError(
-        transaction.Send<int>(BenchmarkOps::Write, buffer, length, nullptr, 0));
-    // return write(endpoint_fd(), buffer, length);
-  }
-
-  int Read(void* buffer, size_t length) {
-    ATRACE_NAME("BenchmarkClient::Read");
-    VLOG(1) << "BenchmarkClient::Read: buffer=" << buffer
-            << " length=" << length;
-    Transaction transaction{*this};
-    return ReturnStatusOrError(
-        transaction.Send<int>(BenchmarkOps::Read, nullptr, 0, buffer, length));
-    // return read(endpoint_fd(), buffer, length);
-  }
-
-  int Echo(const void* send_buffer, size_t send_length, void* receive_buffer,
-           size_t receive_length) {
-    ATRACE_NAME("BenchmarkClient::Echo");
-    VLOG(1) << "BenchmarkClient::Echo: send_buffer=" << send_buffer
-            << " send_length=" << send_length
-            << " receive_buffer=" << receive_buffer
-            << " receive_length=" << receive_length;
-    Transaction transaction{*this};
-    return ReturnStatusOrError(
-        transaction.Send<int>(BenchmarkOps::Echo, send_buffer, send_length,
-                              receive_buffer, receive_length));
-  }
-
-  int Stats(std::tuple<uint64_t, uint64_t, SchedStats>* stats_out) {
-    ATRACE_NAME("BenchmarkClient::Stats");
-    VLOG(1) << "BenchmarkClient::Stats";
-
-    auto status = InvokeRemoteMethodInPlace<BenchmarkRPC::Stats>(stats_out);
-    return status ? 0 : -status.error();
-  }
-
-  int WriteVector(const BufferWrapper<std::vector<uint8_t>>& data) {
-    ATRACE_NAME("BenchmarkClient::Stats");
-    VLOG(1) << "BenchmarkClient::Stats";
-
-    auto status = InvokeRemoteMethod<BenchmarkRPC::WriteVector>(data);
-    return ReturnStatusOrError(status);
-  }
-
-  template <typename T>
-  int WriteVector(const BufferWrapper<T>& data) {
-    ATRACE_NAME("BenchmarkClient::WriteVector");
-    VLOG(1) << "BenchmarkClient::WriteVector";
-
-    auto status = InvokeRemoteMethod<BenchmarkRPC::WriteVector>(data);
-    return ReturnStatusOrError(status);
-  }
-
-  template <typename T, typename U>
-  int EchoVector(const BufferWrapper<T>& data, BufferWrapper<U>* data_out) {
-    ATRACE_NAME("BenchmarkClient::EchoVector");
-    VLOG(1) << "BenchmarkClient::EchoVector";
-
-    MessageBuffer<ReplyBuffer>::Reserve(kMaxMessageSize - 1);
-    auto status =
-        InvokeRemoteMethodInPlace<BenchmarkRPC::EchoVector>(data_out, data);
-    return status ? 0 : -status.error();
-  }
-
-  int Quit() {
-    VLOG(1) << "BenchmarkClient::Quit";
-    Transaction transaction{*this};
-    return ReturnStatusOrError(transaction.Send<int>(BenchmarkOps::Echo));
-  }
-
- private:
-  friend BASE;
-
-  explicit BenchmarkClient(const std::string& service_path)
-      : BASE(ClientChannelFactory::Create(service_path),
-             ProgramOptions.timeout) {}
-
-  BenchmarkClient(const BenchmarkClient&) = delete;
-  void operator=(const BenchmarkClient&) = delete;
-};
-
-// Creates a benchmark service at |path| and dispatches messages.
-int ServiceCommand(const std::string& path) {
-  if (path.empty())
-    return -EINVAL;
-
-  // Start the requested number of dispatch threads.
-  std::vector<std::thread> dispatch_threads;
-  int service_count = ProgramOptions.instances;
-  int service_id_counter = 0;
-  int thread_id_counter = 0;
-  std::atomic<bool> done(false);
-
-  while (service_count--) {
-    std::cerr << "Starting service instance " << service_id_counter
-              << std::endl;
-    auto service = BenchmarkService::Create(
-        android::pdx::default_transport::Endpoint::CreateAndBindSocket(
-            GetServicePath(path, service_id_counter),
-            android::pdx::default_transport::Endpoint::kBlocking));
-    if (!service) {
-      std::cerr << "Failed to create service instance!!" << std::endl;
-      done = true;
-      break;
-    }
-
-    int thread_count = ProgramOptions.threads;
-    while (thread_count--) {
-      std::cerr << "Starting dispatch thread " << thread_id_counter
-                << " service " << service_id_counter << std::endl;
-
-      dispatch_threads.emplace_back(
-          [&](const int thread_id, const int service_id,
-              const std::shared_ptr<BenchmarkService>& local_service) {
-            SetThreadName("service" + std::to_string(service_id));
-
-            // Read the initial schedstats for this thread from procfs.
-            local_service->UpdateSchedStats();
-
-            ATRACE_NAME("BenchmarkService::Dispatch");
-            while (!done) {
-              auto ret = local_service->ReceiveAndDispatch();
-              if (!ret) {
-                if (ret.error() != ESHUTDOWN) {
-                  std::cerr << "Error while dispatching message on thread "
-                            << thread_id << " service " << service_id << ": "
-                            << ret.GetErrorMessage() << std::endl;
-                } else {
-                  std::cerr << "Quitting thread " << thread_id << " service "
-                            << service_id << std::endl;
-                }
-                done = true;
-                return;
-              }
-            }
-          },
-          thread_id_counter++, service_id_counter, service);
-    }
-
-    service_id_counter++;
-  }
-
-  // Wait for the dispatch threads to exit.
-  for (auto& thread : dispatch_threads) {
-    thread.join();
-  }
-
-  return 0;
-}
-
-int ClientCommand(const std::string& path) {
-  // Start the requested number of client threads.
-  std::vector<std::thread> client_threads;
-  std::vector<std::future<BenchmarkResult>> client_results;
-  int service_count = ProgramOptions.instances;
-  int thread_id_counter = 0;
-  int service_id_counter = 0;
-
-  // Aggregate statistics, updated when worker threads exit.
-  std::atomic<uint64_t> total_bytes(0);
-  std::atomic<uint64_t> total_time_ns(0);
-
-  // Samples for variance calculation.
-  std::vector<uint64_t> latency_samples_ns(
-      ProgramOptions.instances * ProgramOptions.threads * ProgramOptions.count);
-  const size_t samples_per_thread = ProgramOptions.count;
-
-  std::vector<uint8_t> send_buffer(ProgramOptions.blocksize);
-  std::vector<uint8_t> receive_buffer(kMaxMessageSize);
-
-  // Barriers for synchronizing thread start.
-  std::vector<std::future<void>> ready_barrier_futures;
-  std::promise<void> go_barrier_promise;
-  std::future<void> go_barrier_future = go_barrier_promise.get_future();
-
-  // Barrier for synchronizing thread tear down.
-  std::promise<void> done_barrier_promise;
-  std::future<void> done_barrier_future = done_barrier_promise.get_future();
-
-  while (service_count--) {
-    int thread_count = ProgramOptions.threads;
-    while (thread_count--) {
-      std::cerr << "Starting client thread " << thread_id_counter << " service "
-                << service_id_counter << std::endl;
-
-      std::promise<BenchmarkResult> result_promise;
-      client_results.push_back(result_promise.get_future());
-
-      std::promise<void> ready_barrier_promise;
-      ready_barrier_futures.push_back(ready_barrier_promise.get_future());
-
-      client_threads.emplace_back(
-          [&](const int thread_id, const int service_id,
-              std::promise<BenchmarkResult> result, std::promise<void> ready) {
-            SetThreadName("client" + std::to_string(thread_id) + "/" +
-                          std::to_string(service_id));
-
-            ATRACE_NAME("BenchmarkClient::Dispatch");
-
-            auto client =
-                BenchmarkClient::Create(GetServicePath(path, service_id));
-            if (!client) {
-              std::cerr << "Failed to create client for service " << service_id
-                        << std::endl;
-              return -ENOMEM;
-            }
-
-            uint64_t* thread_samples =
-                &latency_samples_ns[samples_per_thread * thread_id];
-
-            // Per-thread statistics.
-            uint64_t bytes_sent = 0;
-            uint64_t time_start_ns;
-            uint64_t time_end_ns;
-            SchedStats sched_stats;
-
-            // Signal ready and wait for go.
-            ready.set_value();
-            go_barrier_future.wait();
-
-            // Warmup the scheduler.
-            int warmup = ProgramOptions.warmup;
-            while (warmup--) {
-              for (int i = 0; i < 1000000; i++)
-                ;
-            }
-
-            sched_stats.Update();
-            time_start_ns = GetClockNs();
-
-            int count = ProgramOptions.count;
-            while (count--) {
-              uint64_t iteration_start_ns = GetClockNs();
-
-              switch (ProgramOptions.opcode) {
-                case BenchmarkOps::Nop: {
-                  const int ret = client->Nop();
-                  if (ret < 0) {
-                    std::cerr << "Failed to send nop: " << strerror(-ret)
-                              << std::endl;
-                    return ret;
-                  } else {
-                    VLOG(1) << "Success";
-                  }
-                  break;
-                }
-
-                case BenchmarkOps::Read: {
-                  const int ret = client->Read(receive_buffer.data(),
-                                               ProgramOptions.blocksize);
-                  if (ret < 0) {
-                    std::cerr << "Failed to read: " << strerror(-ret)
-                              << std::endl;
-                    return ret;
-                  } else if (ret != ProgramOptions.blocksize) {
-                    std::cerr << "Expected ret=" << ProgramOptions.blocksize
-                              << "; actual ret=" << ret << std::endl;
-                    return -EINVAL;
-                  } else {
-                    VLOG(1) << "Success";
-                    bytes_sent += ret;
-                  }
-                  break;
-                }
-
-                case BenchmarkOps::Write: {
-                  const int ret =
-                      client->Write(send_buffer.data(), send_buffer.size());
-                  if (ret < 0) {
-                    std::cerr << "Failed to write: " << strerror(-ret)
-                              << std::endl;
-                    return ret;
-                  } else if (ret != ProgramOptions.blocksize) {
-                    std::cerr << "Expected ret=" << ProgramOptions.blocksize
-                              << "; actual ret=" << ret << std::endl;
-                    return -EINVAL;
-                  } else {
-                    VLOG(1) << "Success";
-                    bytes_sent += ret;
-                  }
-                  break;
-                }
-
-                case BenchmarkOps::Echo: {
-                  const int ret = client->Echo(
-                      send_buffer.data(), send_buffer.size(),
-                      receive_buffer.data(), receive_buffer.size());
-                  if (ret < 0) {
-                    std::cerr << "Failed to echo: " << strerror(-ret)
-                              << std::endl;
-                    return ret;
-                  } else if (ret != ProgramOptions.blocksize) {
-                    std::cerr << "Expected ret=" << ProgramOptions.blocksize
-                              << "; actual ret=" << ret << std::endl;
-                    return -EINVAL;
-                  } else {
-                    VLOG(1) << "Success";
-                    bytes_sent += ret * 2;
-                  }
-                  break;
-                }
-
-                case BenchmarkOps::Stats: {
-                  std::tuple<uint64_t, uint64_t, SchedStats> stats;
-                  const int ret = client->Stats(&stats);
-                  if (ret < 0) {
-                    std::cerr << "Failed to get stats: " << strerror(-ret)
-                              << std::endl;
-                    return ret;
-                  } else {
-                    VLOG(1) << "Success";
-                    std::cerr
-                        << "Round trip: receive_time_ns=" << std::get<0>(stats)
-                        << " reply_time_ns=" << std::get<1>(stats)
-                        << " cpu_time_s=" << std::get<2>(stats).cpu_time_s()
-                        << " wait_s=" << std::get<2>(stats).wait_s()
-                        << std::endl;
-                  }
-                  break;
-                }
-
-                case BenchmarkOps::WriteVector: {
-                  const int ret = client->WriteVector(
-                      WrapBuffer(send_buffer.data(), ProgramOptions.blocksize));
-                  if (ret < 0) {
-                    std::cerr << "Failed to write vector: " << strerror(-ret)
-                              << std::endl;
-                    return ret;
-                  } else {
-                    VLOG(1) << "Success";
-                    bytes_sent += ret;
-                  }
-                  break;
-                }
-
-                case BenchmarkOps::EchoVector: {
-                  thread_local BufferWrapper<std::vector<
-                      uint8_t, DefaultInitializationAllocator<uint8_t>>>
-                      response_buffer;
-                  const int ret = client->EchoVector(
-                      WrapBuffer(send_buffer.data(), ProgramOptions.blocksize),
-                      &response_buffer);
-                  if (ret < 0) {
-                    std::cerr << "Failed to echo vector: " << strerror(-ret)
-                              << std::endl;
-                    return ret;
-                  } else {
-                    VLOG(1) << "Success";
-                    bytes_sent += send_buffer.size() + response_buffer.size();
-                  }
-                  break;
-                }
-
-                case BenchmarkOps::Quit: {
-                  const int ret = client->Quit();
-                  if (ret < 0 && ret != -ESHUTDOWN) {
-                    std::cerr << "Failed to send quit: " << strerror(-ret);
-                    return ret;
-                  } else {
-                    VLOG(1) << "Success";
-                  }
-                  break;
-                }
-
-                default:
-                  std::cerr
-                      << "Invalid client operation: " << ProgramOptions.opcode
-                      << std::endl;
-                  return -EINVAL;
-              }
-
-              uint64_t iteration_end_ns = GetClockNs();
-              uint64_t iteration_delta_ns =
-                  iteration_end_ns - iteration_start_ns;
-              thread_samples[count] = iteration_delta_ns;
-
-              if (iteration_delta_ns > (kNanosPerSecond / 100)) {
-                SchedStats stats = sched_stats;
-                stats.Update();
-                std::cerr << "Thread " << thread_id << " iteration_delta_s="
-                          << (static_cast<double>(iteration_delta_ns) /
-                              kNanosPerSecond)
-                          << " " << stats.cpu_time_s() << " " << stats.wait_s()
-                          << std::endl;
-              }
-            }
-
-            time_end_ns = GetClockNs();
-            sched_stats.Update();
-
-            const double time_delta_s =
-                static_cast<double>(time_end_ns - time_start_ns) /
-                kNanosPerSecond;
-
-            total_bytes += bytes_sent;
-            total_time_ns += time_end_ns - time_start_ns;
-
-            result.set_value(
-                {thread_id, service_id, time_delta_s, bytes_sent, sched_stats});
-            done_barrier_future.wait();
-
-            return 0;
-          },
-          thread_id_counter++, service_id_counter, std::move(result_promise),
-          std::move(ready_barrier_promise));
-    }
-
-    service_id_counter++;
-  }
-
-  // Wait for workers to be ready.
-  std::cerr << "Waiting for workers to be ready..." << std::endl;
-  for (auto& ready : ready_barrier_futures)
-    ready.wait();
-
-  // Signal workers to go.
-  std::cerr << "Kicking off benchmark." << std::endl;
-  go_barrier_promise.set_value();
-
-  // Wait for all the worker threas to finish.
-  for (auto& result : client_results)
-    result.wait();
-
-  // Report worker thread results.
-  for (auto& result : client_results) {
-    BenchmarkResult benchmark_result = result.get();
-    std::cerr << std::fixed << "Thread " << benchmark_result.thread_id
-              << " service " << benchmark_result.service_id << ":" << std::endl;
-    std::cerr << "\t " << benchmark_result.bytes_sent << " bytes in "
-              << benchmark_result.time_delta_s << " seconds ("
-              << std::setprecision(0) << (benchmark_result.bytes_sent / 1024.0 /
-                                          benchmark_result.time_delta_s)
-              << " K/s; " << std::setprecision(3)
-              << (ProgramOptions.count / benchmark_result.time_delta_s)
-              << " txn/s; " << std::setprecision(9)
-              << (benchmark_result.time_delta_s / ProgramOptions.count)
-              << " s/txn)" << std::endl;
-    std::cerr << "\tStats: " << benchmark_result.sched_stats.cpu_time_s() << " "
-              << (benchmark_result.sched_stats.cpu_time_s() /
-                  ProgramOptions.count)
-              << " " << benchmark_result.sched_stats.wait_s() << " "
-              << (benchmark_result.sched_stats.wait_s() / ProgramOptions.count)
-              << " " << benchmark_result.sched_stats.timeslices() << std::endl;
-  }
-
-  // Signal worker threads to exit.
-  done_barrier_promise.set_value();
-
-  // Wait for the worker threads to exit.
-  for (auto& thread : client_threads) {
-    thread.join();
-  }
-
-  // Report aggregate results.
-  const int total_threads = ProgramOptions.threads * ProgramOptions.instances;
-  const int iterations = ProgramOptions.count;
-  const double total_time_s =
-      static_cast<double>(total_time_ns) / kNanosPerSecond;
-  // This is about how much wall time it took to completely transfer all the
-  // paylaods.
-  const double average_time_s = total_time_s / total_threads;
-
-  const uint64_t min_sample_time_ns =
-      *std::min_element(latency_samples_ns.begin(), latency_samples_ns.end());
-  const double min_sample_time_s =
-      static_cast<double>(min_sample_time_ns) / kNanosPerSecond;
-
-  const uint64_t max_sample_time_ns =
-      *std::max_element(latency_samples_ns.begin(), latency_samples_ns.end());
-  const double max_sample_time_s =
-      static_cast<double>(max_sample_time_ns) / kNanosPerSecond;
-
-  const double total_sample_time_s =
-      std::accumulate(latency_samples_ns.begin(), latency_samples_ns.end(), 0.0,
-                      [](double s, uint64_t ns) {
-                        return s + static_cast<double>(ns) / kNanosPerSecond;
-                      });
-  const double average_sample_time_s =
-      total_sample_time_s / latency_samples_ns.size();
-
-  const double sum_of_squared_deviations = std::accumulate(
-      latency_samples_ns.begin(), latency_samples_ns.end(), 0.0,
-      [&](double s, uint64_t ns) {
-        const double delta =
-            static_cast<double>(ns) / kNanosPerSecond - average_sample_time_s;
-        return s + delta * delta;
-      });
-  const double variance = sum_of_squared_deviations / latency_samples_ns.size();
-  const double standard_deviation = std::sqrt(variance);
-
-  const int num_buckets = 200;
-  const uint64_t sample_range_ns = max_sample_time_ns - min_sample_time_ns;
-  const uint64_t ns_per_bucket = sample_range_ns / num_buckets;
-  std::array<uint64_t, num_buckets> sample_buckets = {{0}};
-
-  // Count samples in each bucket range.
-  for (uint64_t sample_ns : latency_samples_ns) {
-    sample_buckets[(sample_ns - min_sample_time_ns) / (ns_per_bucket + 1)] += 1;
-  }
-
-  // Calculate population percentiles.
-  const uint64_t percent_50 =
-      static_cast<uint64_t>(latency_samples_ns.size() * 0.5);
-  const uint64_t percent_90 =
-      static_cast<uint64_t>(latency_samples_ns.size() * 0.9);
-  const uint64_t percent_95 =
-      static_cast<uint64_t>(latency_samples_ns.size() * 0.95);
-  const uint64_t percent_99 =
-      static_cast<uint64_t>(latency_samples_ns.size() * 0.99);
-
-  uint64_t sample_count = 0;
-  double latency_50th_percentile_s, latency_90th_percentile_s,
-      latency_95th_percentile_s, latency_99th_percentile_s;
-  for (int i = 0; i < num_buckets; i++) {
-    // Report the midpoint of the bucket range as the value of the
-    // corresponding
-    // percentile.
-    const double bucket_midpoint_time_s =
-        (ns_per_bucket * i + 0.5 * ns_per_bucket + min_sample_time_ns) /
-        kNanosPerSecond;
-    if (sample_count < percent_50 &&
-        (sample_count + sample_buckets[i]) >= percent_50) {
-      latency_50th_percentile_s = bucket_midpoint_time_s;
-    }
-    if (sample_count < percent_90 &&
-        (sample_count + sample_buckets[i]) >= percent_90) {
-      latency_90th_percentile_s = bucket_midpoint_time_s;
-    }
-    if (sample_count < percent_95 &&
-        (sample_count + sample_buckets[i]) >= percent_95) {
-      latency_95th_percentile_s = bucket_midpoint_time_s;
-    }
-    if (sample_count < percent_99 &&
-        (sample_count + sample_buckets[i]) >= percent_99) {
-      latency_99th_percentile_s = bucket_midpoint_time_s;
-    }
-    sample_count += sample_buckets[i];
-  }
-
-  std::cerr << std::fixed << "Total throughput over " << total_threads
-            << " threads:\n\t " << total_bytes << " bytes in " << average_time_s
-            << " seconds (" << std::setprecision(0)
-            << (total_bytes / 1024.0 / average_time_s) << " K/s; "
-            << std::setprecision(3)
-            << (iterations * total_threads / average_time_s)
-            << std::setprecision(9) << " txn/s; "
-            << (average_time_s / (iterations * total_threads)) << " s/txn)"
-            << std::endl;
-  std::cerr << "Sample statistics: " << std::endl;
-  std::cerr << total_sample_time_s << " s total sample time" << std::endl;
-  std::cerr << average_sample_time_s << " s avg" << std::endl;
-  std::cerr << standard_deviation << " s std dev" << std::endl;
-  std::cerr << min_sample_time_s << " s min" << std::endl;
-  std::cerr << max_sample_time_s << " s max" << std::endl;
-  std::cerr << "Latency percentiles:" << std::endl;
-  std::cerr << "50th: " << latency_50th_percentile_s << " s" << std::endl;
-  std::cerr << "90th: " << latency_90th_percentile_s << " s" << std::endl;
-  std::cerr << "95th: " << latency_95th_percentile_s << " s" << std::endl;
-  std::cerr << "99th: " << latency_99th_percentile_s << " s" << std::endl;
-
-  std::cout << total_time_ns << " " << std::fixed << std::setprecision(9)
-            << average_sample_time_s << " " << std::fixed
-            << std::setprecision(9) << standard_deviation << std::endl;
-  return 0;
-}
-
-int Usage(const std::string& command_name) {
-  // clang-format off
-  std::cout << "Usage: " << command_name << " [options]" << std::endl;
-  std::cout << "\t--verbose                   : Use verbose messages." << std::endl;
-  std::cout << "\t--service <endpoint path>   : Start service at the given path." << std::endl;
-  std::cout << "\t--client <endpoint path>    : Start client to the given path." << std::endl;
-  std::cout << "\t--op <read | write | echo>  : Sepcify client operation mode." << std::endl;
-  std::cout << "\t--bs <block size bytes>     : Sepcify block size to use." << std::endl;
-  std::cout << "\t--count <count>             : Sepcify number of transactions to make." << std::endl;
-  std::cout << "\t--instances <count>         : Specify number of service instances." << std::endl;
-  std::cout << "\t--threads <count>           : Sepcify number of threads per instance." << std::endl;
-  std::cout << "\t--timeout <timeout ms | -1> : Timeout to wait for services." << std::endl;
-  std::cout << "\t--trace                     : Enable systrace logging." << std::endl;
-  std::cout << "\t--warmup <iterations>       : Busy loops before running benchmarks." << std::endl;
-  // clang-format on
-  return -1;
-}
-
-}  // anonymous namespace
-
-int main(int argc, char** argv) {
-  logging::LoggingSettings logging_settings;
-  logging_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
-  logging::InitLogging(logging_settings);
-
-  int getopt_code;
-  int option_index;
-  std::string option = "";
-  std::string command = "";
-  std::string command_argument = "";
-  bool tracing_enabled = false;
-
-  // Process command line options.
-  while ((getopt_code =
-              getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
-    option = long_options[option_index].name;
-    VLOG(1) << "option=" << option;
-    switch (getopt_code) {
-      case 0:
-        if (option == kOptionVerbose) {
-          ProgramOptions.verbose = true;
-          logging::SetMinLogLevel(-1);
-        } else if (option == kOptionOpcode) {
-          ParseOpcodeOption(optarg);
-        } else if (option == kOptionBlocksize) {
-          ProgramOptions.blocksize = std::stoi(optarg);
-          if (ProgramOptions.blocksize < 0) {
-            std::cerr << "Invalid blocksize argument: "
-                      << ProgramOptions.blocksize << std::endl;
-            return -EINVAL;
-          }
-        } else if (option == kOptionCount) {
-          ProgramOptions.count = std::stoi(optarg);
-          if (ProgramOptions.count < 1) {
-            std::cerr << "Invalid count argument: " << ProgramOptions.count
-                      << std::endl;
-            return -EINVAL;
-          }
-        } else if (option == kOptionThreads) {
-          ProgramOptions.threads = std::stoi(optarg);
-          if (ProgramOptions.threads < 1) {
-            std::cerr << "Invalid threads argument: " << ProgramOptions.threads
-                      << std::endl;
-            return -EINVAL;
-          }
-        } else if (option == kOptionInstances) {
-          ProgramOptions.instances = std::stoi(optarg);
-          if (ProgramOptions.instances < 1) {
-            std::cerr << "Invalid instances argument: "
-                      << ProgramOptions.instances << std::endl;
-            return -EINVAL;
-          }
-        } else if (option == kOptionTimeout) {
-          ProgramOptions.timeout = std::stoi(optarg);
-        } else if (option == kOptionTrace) {
-          tracing_enabled = true;
-        } else if (option == kOptionWarmup) {
-          ProgramOptions.warmup = std::stoi(optarg);
-        } else {
-          command = option;
-          if (optarg)
-            command_argument = optarg;
-        }
-        break;
-    }
-  }
-
-  // Setup ATRACE/systrace based on command line.
-  atrace_setup();
-  atrace_set_tracing_enabled(tracing_enabled);
-
-  VLOG(1) << "command=" << command << " command_argument=" << command_argument;
-
-  if (command == "") {
-    return Usage(argv[0]);
-  } else if (command == kOptionService) {
-    return ServiceCommand(command_argument);
-  } else if (command == kOptionClient) {
-    return ClientCommand(command_argument);
-  } else {
-    return Usage(argv[0]);
-  }
-}
diff --git a/libs/vr/libpdx_default_transport/pdx_tool.cpp b/libs/vr/libpdx_default_transport/pdx_tool.cpp
deleted file mode 100644
index 60eedb3..0000000
--- a/libs/vr/libpdx_default_transport/pdx_tool.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-#include <errno.h>
-#include <ftw.h>
-#include <getopt.h>
-#include <pdx/client.h>
-#include <pdx/service.h>
-#include <sys/stat.h>
-
-#include <algorithm>
-#include <vector>
-
-#include <pdx/default_transport/client_channel_factory.h>
-
-using android::pdx::default_transport::ClientChannelFactory;
-
-namespace {
-
-constexpr long kClientTimeoutMs = 0;  // Don't wait for non-existent services.
-constexpr int kDumpBufferSize = 2 * 4096;  // Two pages.
-
-class ControlClient : public android::pdx::ClientBase<ControlClient> {
- public:
-  explicit ControlClient(const std::string& service_path, long timeout_ms);
-
-  void Reload();
-  std::string Dump();
-
- private:
-  friend BASE;
-
-  ControlClient(const ControlClient&) = delete;
-  void operator=(const ControlClient&) = delete;
-};
-
-bool option_verbose = false;
-
-static struct option long_options[] = {
-    {"reload", required_argument, 0, 0},
-    {"dump", required_argument, 0, 0},
-    {"verbose", no_argument, 0, 0},
-    {0, 0, 0, 0},
-};
-
-#define printf_verbose(fmt, ... /*args*/) \
-  do {                                    \
-    if (option_verbose)                   \
-      printf(fmt, ##__VA_ARGS__);         \
-  } while (0)
-
-void HexDump(const void* pointer, size_t length);
-
-ControlClient::ControlClient(const std::string& service_path, long timeout_ms)
-    : BASE{ClientChannelFactory::Create(service_path), timeout_ms} {}
-
-void ControlClient::Reload() {
-  android::pdx::Transaction trans{*this};
-  auto status = trans.Send<void>(android::pdx::opcodes::REPORT_SYSPROP_CHANGE,
-                                 nullptr, 0, nullptr, 0);
-  if (!status) {
-    fprintf(stderr, "Failed to send reload: %s\n",
-            status.GetErrorMessage().c_str());
-  }
-}
-
-std::string ControlClient::Dump() {
-  android::pdx::Transaction trans{*this};
-  std::vector<char> buffer(kDumpBufferSize);
-  auto status = trans.Send<int>(android::pdx::opcodes::DUMP_STATE, nullptr, 0,
-                                buffer.data(), buffer.size());
-
-  printf_verbose("ControlClient::Dump: ret=%d\n", ReturnStatusOrError(status));
-
-  if (!status) {
-    fprintf(stderr, "Failed to send dump request: %s\n",
-            status.GetErrorMessage().c_str());
-    return "";
-  } else if (status.get() > static_cast<ssize_t>(buffer.capacity())) {
-    fprintf(stderr, "Service returned a larger size than requested: %d\n",
-            status.get());
-    return "";
-  }
-
-  if (option_verbose)
-    HexDump(buffer.data(), status.get());
-
-  return std::string(buffer.data(), status.get());
-}
-
-int Usage(const std::string& command_name) {
-  printf("Usage: %s [options]\n", command_name.c_str());
-  printf("\t--verbose                      : Use verbose messages.\n");
-  printf(
-      "\t--reload <all | service path>  : Ask service(s) to reload system "
-      "properties.\n");
-  printf("\t--dump <all | service path>    : Dump service(s) state.\n");
-  return -1;
-}
-
-typedef int (*CallbackType)(const char* path, const struct stat* sb,
-                            int type_flag, FTW* ftw_buffer);
-
-int ReloadCommandCallback(const char* path, const struct stat* sb,
-                          int type_flag, FTW* ftw_buffer);
-int DumpCommandCallback(const char* path, const struct stat* sb, int type_flag,
-                        FTW* ftw_buffer);
-
-void CallOnAllFiles(CallbackType callback, const std::string& base_path) {
-  const int kMaxDepth = 32;
-  nftw(base_path.c_str(), callback, kMaxDepth, FTW_PHYS);
-}
-
-int ReloadCommand(const std::string& service_path) {
-  printf_verbose("ReloadCommand: service_path=%s\n", service_path.c_str());
-
-  if (service_path == "" || service_path == "all") {
-    CallOnAllFiles(ReloadCommandCallback,
-                   ClientChannelFactory::GetRootEndpointPath());
-    return 0;
-  } else {
-    auto client = ControlClient::Create(service_path, kClientTimeoutMs);
-    if (!client) {
-      fprintf(stderr, "Failed to open service at \"%s\".\n",
-              service_path.c_str());
-      return -1;
-    }
-
-    client->Reload();
-    return 0;
-  }
-}
-
-int DumpCommand(const std::string& service_path) {
-  printf_verbose("DumpCommand: service_path=%s\n", service_path.c_str());
-
-  if (service_path == "" || service_path == "all") {
-    CallOnAllFiles(DumpCommandCallback,
-                   ClientChannelFactory::GetRootEndpointPath());
-    return 0;
-  } else {
-    auto client = ControlClient::Create(service_path, kClientTimeoutMs);
-    if (!client) {
-      fprintf(stderr, "Failed to open service at \"%s\".\n",
-              service_path.c_str());
-      return -1;
-    }
-
-    std::string response = client->Dump();
-    if (!response.empty()) {
-      printf(
-          "--------------------------------------------------------------------"
-          "---\n");
-      printf("%s:\n", service_path.c_str());
-      printf("%s\n", response.c_str());
-    }
-    return 0;
-  }
-}
-
-int ReloadCommandCallback(const char* path, const struct stat*, int type_flag,
-                          FTW*) {
-  if (type_flag == FTW_F)
-    ReloadCommand(path);
-  return 0;
-}
-
-int DumpCommandCallback(const char* path, const struct stat*, int type_flag,
-                        FTW*) {
-  if (type_flag == FTW_F)
-    DumpCommand(path);
-  return 0;
-}
-
-void HexDump(const void* pointer, size_t length) {
-  uintptr_t address = reinterpret_cast<uintptr_t>(pointer);
-
-  for (size_t count = 0; count < length; count += 16, address += 16) {
-    printf("0x%08lx: ", static_cast<unsigned long>(address));
-
-    for (size_t i = 0; i < 16u; i++) {
-      if (i < std::min(length - count, static_cast<size_t>(16))) {
-        printf("%02x ", *reinterpret_cast<const uint8_t*>(address + i));
-      } else {
-        printf("   ");
-      }
-    }
-
-    printf("|");
-
-    for (size_t i = 0; i < 16u; i++) {
-      if (i < std::min(length - count, static_cast<size_t>(16))) {
-        char c = *reinterpret_cast<const char*>(address + i);
-        if (isalnum(c) || c == ' ') {
-          printf("%c", c);
-        } else {
-          printf(".");
-        }
-      } else {
-        printf(" ");
-      }
-    }
-
-    printf("|\n");
-  }
-}
-
-}  // anonymous namespace
-
-int main(int argc, char** argv) {
-  int getopt_code;
-  int option_index;
-  std::string option = "";
-  std::string command = "";
-  std::string command_argument = "";
-
-  // Process command line options.
-  while ((getopt_code =
-              getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
-    option = long_options[option_index].name;
-    printf_verbose("option=%s\n", option.c_str());
-    switch (getopt_code) {
-      case 0:
-        if (option == "verbose") {
-          option_verbose = true;
-        } else {
-          command = option;
-          if (optarg)
-            command_argument = optarg;
-        }
-        break;
-    }
-  }
-
-  printf_verbose("command=%s command_argument=%s\n", command.c_str(),
-                 command_argument.c_str());
-
-  if (command == "") {
-    return Usage(argv[0]);
-  } else if (command == "reload") {
-    return ReloadCommand(command_argument);
-  } else if (command == "dump") {
-    return DumpCommand(command_argument);
-  } else {
-    return Usage(argv[0]);
-  }
-}
diff --git a/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h b/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h
deleted file mode 100644
index 3ebab86..0000000
--- a/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h
+++ /dev/null
@@ -1,92 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_
-
-#include <ftw.h>
-
-#include <pdx/client.h>
-#include <pdx/default_transport/client_channel_factory.h>
-#include <pdx/service.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-class ServiceUtility : public ClientBase<ServiceUtility> {
- public:
-  Status<int> ReloadSystemProperties() {
-    Transaction transaction{*this};
-    return ReturnStatusOrError(
-        transaction.Send<int>(opcodes::REPORT_SYSPROP_CHANGE));
-  }
-
-  static std::string GetRootEndpointPath() {
-    return ClientChannelFactory::GetRootEndpointPath();
-  }
-  static std::string GetEndpointPath(const std::string& endpoint_path) {
-    return ClientChannelFactory::GetEndpointPath(endpoint_path);
-  }
-
-  // Traverses the PDX service path space and sends a message to reload system
-  // properties to each service endpoint it finds along the way.
-  // NOTE: This method is used by atrace to poke PDX services. Please avoid
-  // unnecessary changes to this mechanism to minimize impact on atrace.
-  static bool PokeServices() {
-    const int kMaxDepth = 16;
-    const int result =
-        nftw(GetRootEndpointPath().c_str(), PokeService, kMaxDepth, FTW_PHYS);
-    return result == 0 ? true : false;
-  }
-
- private:
-  friend BASE;
-
-  explicit ServiceUtility(const std::string& endpoint_path,
-                          int* error = nullptr)
-      : BASE(ClientChannelFactory::Create(endpoint_path), 0) {
-    if (error)
-      *error = Client::error();
-  }
-
-  // Sends the sysprop_change message to the service at fpath, so it re-reads
-  // its system properties. Returns 0 on success or a negated errno code on
-  // failure.
-  // NOTE: This method is used by atrace to poke PDX services. Please avoid
-  // unnecessary changes to this mechanism to minimize impact on atrace.
-  static int PokeService(const char* fpath, const struct stat* /*sb*/,
-                         int typeflag, struct FTW* /*ftwbuf*/) {
-    const bool kIgnoreErrors = true;
-
-    if (typeflag == FTW_F) {
-      int error;
-      auto utility = ServiceUtility::Create(fpath, &error);
-      if (!utility) {
-        if (error != -ECONNREFUSED) {
-          ALOGE("ServiceUtility::PokeService: Failed to open %s: %s.", fpath,
-                strerror(-error));
-        }
-        return kIgnoreErrors ? 0 : error;
-      }
-
-      auto status = utility->ReloadSystemProperties();
-      if (!status) {
-        ALOGE(
-            "ServiceUtility::PokeService: Failed to send sysprop change to %s: "
-            "%s",
-            fpath, status.GetErrorMessage().c_str());
-        return kIgnoreErrors ? 0 : -status.error();
-      }
-    }
-
-    return 0;
-  }
-
-  ServiceUtility(const ServiceUtility&) = delete;
-  void operator=(const ServiceUtility&) = delete;
-};
-
-}  // namespace default_transport
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_
diff --git a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_manager.h b/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_manager.h
deleted file mode 100644
index 11163b3..0000000
--- a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_manager.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_MANAGER_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_MANAGER_H_
-
-#include <servicefs/channel_manager.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ChannelManager = ::android::pdx::servicefs::ChannelManager;
-
-}  // namespace default_transport
-}  // namespace pdx
-}  // namespace android
-
-
-#endif  // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_MANAGER_H_
diff --git a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_parcelable.h b/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_parcelable.h
deleted file mode 100644
index a8623b2..0000000
--- a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_parcelable.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_PARCELABLE_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_PARCELABLE_H_
-
-#include <servicefs/channel_parcelable.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ChannelParcelable = ::android::pdx::servicefs::ChannelParcelable;
-
-}  // namespace default_transport
-}  // namespace pdx
-}  // namespace android
-
-
-#endif  // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_PARCELABLE_H_
diff --git a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel.h b/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel.h
deleted file mode 100644
index d171780..0000000
--- a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_H_
-
-#include <servicefs/client_channel.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ClientChannel = ::android::pdx::servicefs::ClientChannel;
-
-}  // namespace default_transport
-}  // namespace pdx
-}  // namespace android
-
-
-#endif  // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_H_
diff --git a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel_factory.h b/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel_factory.h
deleted file mode 100644
index 77b5cac..0000000
--- a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel_factory.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_FACTORY_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_FACTORY_H_
-
-#include <servicefs/client_channel_factory.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ClientChannelFactory = ::android::pdx::servicefs::ClientChannelFactory;
-
-}  // namespace default_transport
-}  // namespace pdx
-}  // namespace android
-
-
-#endif  // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_FACTORY_H_
diff --git a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/service_endpoint.h b/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/service_endpoint.h
deleted file mode 100644
index 8f413c1..0000000
--- a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/service_endpoint.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_SERVICE_ENDPOINT_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_SERVICE_ENDPOINT_H_
-
-#include <servicefs/service_endpoint.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using Endpoint = ::android::pdx::servicefs::Endpoint;
-
-}  // namespace default_transport
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_PDX_SERVICE_ENDPOINT_H_
diff --git a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_manager.h b/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_manager.h
deleted file mode 100644
index f34636f..0000000
--- a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_manager.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_MANAGER_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_MANAGER_H_
-
-#include <uds/channel_manager.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ChannelManager = ::android::pdx::uds::ChannelManager;
-
-}  // namespace default_transport
-}  // namespace pdx
-}  // namespace android
-
-
-#endif  // ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_MANAGER_H_
diff --git a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_parcelable.h b/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_parcelable.h
deleted file mode 100644
index bcd74e6..0000000
--- a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_parcelable.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_PARCELABLE_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_PARCELABLE_H_
-
-#include <uds/channel_parcelable.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ChannelParcelable = ::android::pdx::uds::ChannelParcelable;
-
-}  // namespace default_transport
-}  // namespace pdx
-}  // namespace android
-
-
-#endif  // ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_PARCELABLE_H_
diff --git a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel.h b/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel.h
deleted file mode 100644
index bf632d7..0000000
--- a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_H_
-
-#include <uds/client_channel.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ClientChannel = ::android::pdx::uds::ClientChannel;
-
-}  // namespace default_transport
-}  // namespace pdx
-}  // namespace android
-
-
-#endif  // ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_H_
diff --git a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel_factory.h b/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel_factory.h
deleted file mode 100644
index e5c4e30..0000000
--- a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel_factory.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_FACTORY_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_FACTORY_H_
-
-#include <uds/client_channel_factory.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ClientChannelFactory = ::android::pdx::uds::ClientChannelFactory;
-
-}  // namespace default_transport
-}  // namespace pdx
-}  // namespace android
-
-
-#endif  // ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_FACTORY_H_
diff --git a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/service_endpoint.h b/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/service_endpoint.h
deleted file mode 100644
index 1fd6103..0000000
--- a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/service_endpoint.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_UDS_SERVICE_ENDPOINT_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_UDS_SERVICE_ENDPOINT_H_
-
-#include <uds/service_endpoint.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using Endpoint = ::android::pdx::uds::Endpoint;
-
-}  // namespace default_transport
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_DEFAULT_TRANSPORT_UDS_PDX_SERVICE_ENDPOINT_H_
diff --git a/libs/vr/libpdx_uds/Android.bp b/libs/vr/libpdx_uds/Android.bp
deleted file mode 100644
index 7f88daf..0000000
--- a/libs/vr/libpdx_uds/Android.bp
+++ /dev/null
@@ -1,67 +0,0 @@
-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_library_static {
-    name: "libpdx_uds",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-DLOG_TAG=\"libpdx_uds\"",
-        "-DTRACE=0",
-    ],
-    export_include_dirs: ["private"],
-    local_include_dirs: ["private"],
-    srcs: [
-        "channel_event_set.cpp",
-        "channel_manager.cpp",
-        "channel_parcelable.cpp",
-        "client_channel_factory.cpp",
-        "client_channel.cpp",
-        "ipc_helper.cpp",
-        "service_endpoint.cpp",
-    ],
-    static_libs: [
-        "libcutils",
-        "libbase",
-        "libpdx",
-    ],
-    shared_libs: [
-        "libbinder",
-        "libselinux",
-    ],
-}
-
-cc_test {
-    name: "libpdx_uds_tests",
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-    ],
-    srcs: [
-        "client_channel_tests.cpp",
-        "ipc_helper_tests.cpp",
-        "remote_method_tests.cpp",
-        "service_framework_tests.cpp",
-    ],
-    static_libs: [
-        "libgmock",
-        "libpdx_uds",
-        "libpdx",
-    ],
-    shared_libs: [
-        "libbase",
-        "libcutils",
-        "liblog",
-        "libutils",
-        "libbinder",
-        "libselinux",
-    ],
-}
diff --git a/libs/vr/libpdx_uds/channel_event_set.cpp b/libs/vr/libpdx_uds/channel_event_set.cpp
deleted file mode 100644
index c68968e..0000000
--- a/libs/vr/libpdx_uds/channel_event_set.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-#include "private/uds/channel_event_set.h"
-
-#include <errno.h>
-#include <log/log.h>
-#include <poll.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-
-#include <uds/ipc_helper.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-namespace {
-
-template <typename FileHandleType>
-Status<void> SetupHandle(int fd, FileHandleType* handle,
-                         const char* error_name) {
-  const int error = errno;
-  handle->Reset(fd);
-  if (!*handle) {
-    ALOGE("SetupHandle: Failed to setup %s handle: %s", error_name,
-          strerror(error));
-    return ErrorStatus{error};
-  }
-  return {};
-}
-
-}  // anonymous namespace
-
-ChannelEventSet::ChannelEventSet() {
-  const int flags = EFD_CLOEXEC | EFD_NONBLOCK;
-  LocalHandle pollin_event_fd, pollhup_event_fd;
-
-  if (!SetupHandle(eventfd(0, flags), &pollin_event_fd, "pollin_event") ||
-      !SetupHandle(eventfd(0, flags), &pollhup_event_fd, "pollhup_event")) {
-    return;
-  }
-
-  pollin_event_fd_ = std::move(pollin_event_fd);
-  pollhup_event_fd_ = std::move(pollhup_event_fd);
-}
-
-int ChannelEventSet::ModifyEvents(int clear_mask, int set_mask) {
-  ALOGD_IF(TRACE, "ChannelEventSet::ModifyEvents: clear_mask=%x set_mask=%x",
-           clear_mask, set_mask);
-  const int old_bits = event_bits_;
-  const int new_bits = (event_bits_ & ~clear_mask) | set_mask;
-  event_bits_ = new_bits;
-  eventfd_t value;
-
-  // Calculate which bits changed and how. Bits that haven't changed since last
-  // modification will not change the state of an eventfd.
-  const int set_bits = new_bits & ~old_bits;
-  const int clear_bits = ~new_bits & old_bits;
-
-  if (set_bits & EPOLLIN)
-    eventfd_write(pollin_event_fd_.Get(), 1);
-  else if (clear_bits & EPOLLIN)
-    eventfd_read(pollin_event_fd_.Get(), &value);
-
-  if (set_bits & EPOLLHUP)
-    eventfd_write(pollhup_event_fd_.Get(), 1);
-  else if (clear_bits & EPOLLHUP)
-    eventfd_read(pollhup_event_fd_.Get(), &value);
-
-  return 0;
-}
-
-ChannelEventReceiver::ChannelEventReceiver(LocalHandle data_fd,
-                                           LocalHandle pollin_event_fd,
-                                           LocalHandle pollhup_event_fd) {
-  LocalHandle epoll_fd;
-  if (!SetupHandle(epoll_create1(EPOLL_CLOEXEC), &epoll_fd, "epoll")) {
-    return;
-  }
-
-  epoll_event event;
-  event.events = EPOLLHUP | EPOLLRDHUP;
-  event.data.u32 = 0;
-  if (epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, data_fd.Get(), &event) < 0) {
-    const int error = errno;
-    ALOGE("ChannelEventSet::ChannelEventSet: Failed to add data_fd: %s",
-          strerror(error));
-    return;
-  }
-
-  event.events = EPOLLIN;
-  event.data.u32 = 0;
-  if (epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, pollin_event_fd.Get(), &event) <
-      0) {
-    const int error = errno;
-    ALOGE("ChannelEventSet::ChannelEventSet: Failed to add pollin_event_fd: %s",
-          strerror(error));
-    return;
-  }
-
-  event.events = EPOLLIN;
-  event.data.u32 = 0;
-  if (epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, pollhup_event_fd.Get(), &event) <
-      0) {
-    const int error = errno;
-    ALOGE(
-        "ChannelEventSet::ChannelEventSet: Failed to add pollhup_event_fd: %s",
-        strerror(error));
-    return;
-  }
-
-  pollin_event_fd_ = std::move(pollin_event_fd);
-  pollhup_event_fd_ = std::move(pollhup_event_fd);
-  data_fd_ = std::move(data_fd);
-  epoll_fd_ = std::move(epoll_fd);
-}
-
-Status<int> ChannelEventReceiver::PollPendingEvents(int timeout_ms) const {
-  std::array<pollfd, 3> pfds = {{{pollin_event_fd_.Get(), POLLIN, 0},
-                                 {pollhup_event_fd_.Get(), POLLIN, 0},
-                                 {data_fd_.Get(), POLLHUP | POLLRDHUP, 0}}};
-  if (RETRY_EINTR(poll(pfds.data(), pfds.size(), timeout_ms)) < 0) {
-    const int error = errno;
-    ALOGE(
-        "ChannelEventReceiver::PollPendingEvents: Failed to poll for events: "
-        "%s",
-        strerror(error));
-    return ErrorStatus{error};
-  }
-
-  const int event_mask =
-      ((pfds[0].revents & POLLIN) ? EPOLLIN : 0) |
-      ((pfds[1].revents & POLLIN) ? EPOLLHUP : 0) |
-      ((pfds[2].revents & (POLLHUP | POLLRDHUP)) ? EPOLLHUP : 0);
-  return {event_mask};
-}
-
-Status<int> ChannelEventReceiver::GetPendingEvents() const {
-  constexpr long kTimeoutMs = 0;
-  return PollPendingEvents(kTimeoutMs);
-}
-
-std::vector<ClientChannel::EventSource> ChannelEventReceiver::GetEventSources()
-    const {
-  return {{data_fd_.Get(), EPOLLHUP | EPOLLRDHUP},
-          {pollin_event_fd_.Get(), EPOLLIN},
-          {pollhup_event_fd_.Get(), POLLIN}};
-}
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
diff --git a/libs/vr/libpdx_uds/channel_manager.cpp b/libs/vr/libpdx_uds/channel_manager.cpp
deleted file mode 100644
index 43ebe05..0000000
--- a/libs/vr/libpdx_uds/channel_manager.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <uds/channel_manager.h>
-
-#include <log/log.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-ChannelManager& ChannelManager::Get() {
-  static ChannelManager instance;
-  return instance;
-}
-
-void ChannelManager::CloseHandle(int32_t handle) {
-  std::lock_guard<std::mutex> autolock(mutex_);
-  auto channel = channels_.find(handle);
-  if (channel == channels_.end()) {
-    ALOGE("Invalid channel handle: %d", handle);
-  } else {
-    channels_.erase(channel);
-  }
-}
-
-LocalChannelHandle ChannelManager::CreateHandle(LocalHandle data_fd,
-                                                LocalHandle pollin_event_fd,
-                                                LocalHandle pollhup_event_fd) {
-  if (data_fd && pollin_event_fd && pollhup_event_fd) {
-    std::lock_guard<std::mutex> autolock(mutex_);
-    const int32_t handle = data_fd.Get();
-    channels_.emplace(
-        handle,
-        ChannelEventReceiver{std::move(data_fd), std::move(pollin_event_fd),
-                             std::move(pollhup_event_fd)});
-    return LocalChannelHandle(this, handle);
-  } else {
-    ALOGE(
-        "ChannelManager::CreateHandle: Invalid arguments: data_fd=%d "
-        "pollin_event_fd=%d pollhup_event_fd=%d",
-        data_fd.Get(), pollin_event_fd.Get(), pollhup_event_fd.Get());
-    return LocalChannelHandle(nullptr, -1);
-  }
-}
-
-ChannelEventReceiver* ChannelManager::GetChannelData(int32_t handle) {
-  std::lock_guard<std::mutex> autolock(mutex_);
-  auto channel = channels_.find(handle);
-  return channel != channels_.end() ? &channel->second : nullptr;
-}
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
diff --git a/libs/vr/libpdx_uds/channel_parcelable.cpp b/libs/vr/libpdx_uds/channel_parcelable.cpp
deleted file mode 100644
index 5156846..0000000
--- a/libs/vr/libpdx_uds/channel_parcelable.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-#include "uds/channel_parcelable.h"
-
-#include <binder/Parcel.h>
-#include <uds/channel_manager.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-namespace {
-
-static constexpr uint32_t kUdsMagicParcelHeader = 0x7564736d;  // 'udsm'.
-
-}  // namespace
-
-ChannelParcelable::ChannelParcelable(LocalHandle data_fd,
-                                     LocalHandle pollin_event_fd,
-                                     LocalHandle pollhup_event_fd)
-    : data_fd_{std::move(data_fd)},
-      pollin_event_fd_{std::move(pollin_event_fd)},
-      pollhup_event_fd_{std::move(pollhup_event_fd)} {}
-
-bool ChannelParcelable::IsValid() const {
-  return !!data_fd_ && !!pollin_event_fd_ && !!pollhup_event_fd_;
-}
-
-LocalChannelHandle ChannelParcelable::TakeChannelHandle() {
-  if (!IsValid()) {
-    ALOGE("ChannelParcelable::TakeChannelHandle: Invalid channel parcel.");
-    return {};  // Returns an empty channel handle.
-  }
-
-  return ChannelManager::Get().CreateHandle(std::move(data_fd_),
-                                            std::move(pollin_event_fd_),
-                                            std::move(pollhup_event_fd_));
-}
-
-status_t ChannelParcelable::writeToParcel(Parcel* parcel) const {
-  status_t res = OK;
-
-  if (!IsValid()) {
-    ALOGE("ChannelParcelable::writeToParcel: Invalid channel parcel.");
-    return BAD_VALUE;
-  }
-
-  res = parcel->writeUint32(kUdsMagicParcelHeader);
-  if (res != OK) {
-    ALOGE("ChannelParcelable::writeToParcel: Cannot write magic: res=%d.", res);
-    return res;
-  }
-
-  res = parcel->writeFileDescriptor(data_fd_.Get());
-  if (res != OK) {
-    ALOGE("ChannelParcelable::writeToParcel: Cannot write data fd: res=%d.",
-          res);
-    return res;
-  }
-
-  res = parcel->writeFileDescriptor(pollin_event_fd_.Get());
-  if (res != OK) {
-    ALOGE(
-        "ChannelParcelable::writeToParcel: Cannot write pollin event fd: "
-        "res=%d.",
-        res);
-    return res;
-  }
-
-  res = parcel->writeFileDescriptor(pollhup_event_fd_.Get());
-  if (res != OK) {
-    ALOGE(
-        "ChannelParcelable::writeToParcel: Cannot write pollhup event fd: "
-        "res=%d.",
-        res);
-    return res;
-  }
-
-  return res;
-}
-
-status_t ChannelParcelable::readFromParcel(const Parcel* parcel) {
-  uint32_t magic = 0;
-  status_t res = OK;
-
-  if (IsValid()) {
-    ALOGE(
-        "ChannelParcelable::readFromParcel: This channel parcel is already "
-        "initailzied.");
-    return ALREADY_EXISTS;
-  }
-
-  res = parcel->readUint32(&magic);
-  if (res != OK) {
-    ALOGE("ChannelParcelable::readFromParcel: Failed to read magic: res=%d.",
-          res);
-    return res;
-  }
-
-  if (magic != kUdsMagicParcelHeader) {
-    ALOGE(
-        "ChannelParcelable::readFromParcel: Unknown magic: 0x%x, epxected: "
-        "0x%x",
-        magic, kUdsMagicParcelHeader);
-    return BAD_VALUE;
-  }
-
-  // TODO(b/69010509): We have to dup() the FD from android::Parcel as it
-  // doesn't support taking out the FD's ownership. We can remove the dup() here
-  // once android::Parcel support such operation.
-  data_fd_.Reset(dup(parcel->readFileDescriptor()));
-  pollin_event_fd_.Reset(dup(parcel->readFileDescriptor()));
-  pollhup_event_fd_.Reset(dup(parcel->readFileDescriptor()));
-  if (!IsValid()) {
-    ALOGE(
-        "ChannelParcelable::readFromParcel: Cannot read fd from parcel: "
-        "data_fd=%d, pollin_event_fd=%d, pollhup_event_fd=%d.",
-        data_fd_.Get(), pollin_event_fd_.Get(), pollhup_event_fd_.Get());
-    return DEAD_OBJECT;
-  }
-
-  return res;
-}
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
diff --git a/libs/vr/libpdx_uds/client_channel.cpp b/libs/vr/libpdx_uds/client_channel.cpp
deleted file mode 100644
index 6073c3c..0000000
--- a/libs/vr/libpdx_uds/client_channel.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-#include "uds/channel_parcelable.h"
-#include "uds/client_channel.h"
-
-#include <errno.h>
-#include <log/log.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-
-#include <pdx/client.h>
-#include <pdx/service_endpoint.h>
-#include <uds/ipc_helper.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-namespace {
-
-struct TransactionState {
-  bool GetLocalFileHandle(int index, LocalHandle* handle) {
-    if (index < 0) {
-      handle->Reset(index);
-    } else if (static_cast<size_t>(index) < response.file_descriptors.size()) {
-      *handle = std::move(response.file_descriptors[index]);
-    } else {
-      return false;
-    }
-    return true;
-  }
-
-  bool GetLocalChannelHandle(int index, LocalChannelHandle* handle) {
-    if (index < 0) {
-      *handle = LocalChannelHandle{nullptr, index};
-    } else if (static_cast<size_t>(index) < response.channels.size()) {
-      auto& channel_info = response.channels[index];
-      *handle = ChannelManager::Get().CreateHandle(
-          std::move(channel_info.data_fd),
-          std::move(channel_info.pollin_event_fd),
-          std::move(channel_info.pollhup_event_fd));
-    } else {
-      return false;
-    }
-    return true;
-  }
-
-  FileReference PushFileHandle(BorrowedHandle handle) {
-    if (!handle)
-      return handle.Get();
-    request.file_descriptors.push_back(std::move(handle));
-    return request.file_descriptors.size() - 1;
-  }
-
-  ChannelReference PushChannelHandle(BorrowedChannelHandle handle) {
-    if (!handle)
-      return handle.value();
-
-    if (auto* channel_data =
-            ChannelManager::Get().GetChannelData(handle.value())) {
-      ChannelInfo<BorrowedHandle> channel_info{
-          channel_data->data_fd(), channel_data->pollin_event_fd(),
-          channel_data->pollhup_event_fd()};
-      request.channels.push_back(std::move(channel_info));
-      return request.channels.size() - 1;
-    } else {
-      return -1;
-    }
-  }
-
-  RequestHeader<BorrowedHandle> request;
-  ResponseHeader<LocalHandle> response;
-};
-
-Status<void> ReadAndDiscardData(const BorrowedHandle& socket_fd, size_t size) {
-  while (size > 0) {
-    // If there is more data to read in the message than the buffers provided
-    // by the caller, read and discard the extra data from the socket.
-    char buffer[1024];
-    size_t size_to_read = std::min(sizeof(buffer), size);
-    auto status = ReceiveData(socket_fd, buffer, size_to_read);
-    if (!status)
-      return status;
-    size -= size_to_read;
-  }
-  // We still want to return EIO error to the caller in case we had unexpected
-  // data in the socket stream.
-  return ErrorStatus(EIO);
-}
-
-Status<void> SendRequest(const BorrowedHandle& socket_fd,
-                         TransactionState* transaction_state, int opcode,
-                         const iovec* send_vector, size_t send_count,
-                         size_t max_recv_len) {
-  size_t send_len = CountVectorSize(send_vector, send_count);
-  InitRequest(&transaction_state->request, opcode, send_len, max_recv_len,
-              false);
-  if (send_len == 0) {
-    send_vector = nullptr;
-    send_count = 0;
-  }
-  return SendData(socket_fd, transaction_state->request, send_vector,
-                  send_count);
-}
-
-Status<void> ReceiveResponse(const BorrowedHandle& socket_fd,
-                             TransactionState* transaction_state,
-                             const iovec* receive_vector, size_t receive_count,
-                             size_t max_recv_len) {
-  auto status = ReceiveData(socket_fd, &transaction_state->response);
-  if (!status)
-    return status;
-
-  if (transaction_state->response.recv_len > 0) {
-    std::vector<iovec> read_buffers;
-    size_t size_remaining = 0;
-    if (transaction_state->response.recv_len != max_recv_len) {
-      // If the receive buffer not exactly the size of data available, recreate
-      // the vector list to consume the data exactly since ReceiveDataVector()
-      // validates that the number of bytes received equals the number of bytes
-      // requested.
-      size_remaining = transaction_state->response.recv_len;
-      for (size_t i = 0; i < receive_count && size_remaining > 0; i++) {
-        read_buffers.push_back(receive_vector[i]);
-        iovec& last_vec = read_buffers.back();
-        if (last_vec.iov_len > size_remaining)
-          last_vec.iov_len = size_remaining;
-        size_remaining -= last_vec.iov_len;
-      }
-      receive_vector = read_buffers.data();
-      receive_count = read_buffers.size();
-    }
-    status = ReceiveDataVector(socket_fd, receive_vector, receive_count);
-    if (status && size_remaining > 0)
-      status = ReadAndDiscardData(socket_fd, size_remaining);
-  }
-  return status;
-}
-
-}  // anonymous namespace
-
-ClientChannel::ClientChannel(LocalChannelHandle channel_handle)
-    : channel_handle_{std::move(channel_handle)} {
-  channel_data_ = ChannelManager::Get().GetChannelData(channel_handle_.value());
-}
-
-std::unique_ptr<pdx::ClientChannel> ClientChannel::Create(
-    LocalChannelHandle channel_handle) {
-  return std::unique_ptr<pdx::ClientChannel>{
-      new ClientChannel{std::move(channel_handle)}};
-}
-
-ClientChannel::~ClientChannel() {
-  if (channel_handle_)
-    shutdown(channel_handle_.value(), SHUT_WR);
-}
-
-void* ClientChannel::AllocateTransactionState() { return new TransactionState; }
-
-void ClientChannel::FreeTransactionState(void* state) {
-  delete static_cast<TransactionState*>(state);
-}
-
-Status<void> ClientChannel::SendImpulse(int opcode, const void* buffer,
-                                        size_t length) {
-  std::unique_lock<std::mutex> lock(socket_mutex_);
-  Status<void> status;
-  android::pdx::uds::RequestHeader<BorrowedHandle> request;
-  if (length > request.impulse_payload.size() ||
-      (buffer == nullptr && length != 0)) {
-    status.SetError(EINVAL);
-    return status;
-  }
-
-  InitRequest(&request, opcode, length, 0, true);
-  memcpy(request.impulse_payload.data(), buffer, length);
-  return SendData(BorrowedHandle{channel_handle_.value()}, request);
-}
-
-Status<int> ClientChannel::SendAndReceive(void* transaction_state, int opcode,
-                                          const iovec* send_vector,
-                                          size_t send_count,
-                                          const iovec* receive_vector,
-                                          size_t receive_count) {
-  std::unique_lock<std::mutex> lock(socket_mutex_);
-  Status<int> result;
-  if ((send_vector == nullptr && send_count != 0) ||
-      (receive_vector == nullptr && receive_count != 0)) {
-    result.SetError(EINVAL);
-    return result;
-  }
-
-  auto* state = static_cast<TransactionState*>(transaction_state);
-  size_t max_recv_len = CountVectorSize(receive_vector, receive_count);
-
-  auto status = SendRequest(BorrowedHandle{channel_handle_.value()}, state,
-                            opcode, send_vector, send_count, max_recv_len);
-  if (status) {
-    status = ReceiveResponse(BorrowedHandle{channel_handle_.value()}, state,
-                             receive_vector, receive_count, max_recv_len);
-  }
-  if (!result.PropagateError(status)) {
-    const int return_code = state->response.ret_code;
-    if (return_code >= 0)
-      result.SetValue(return_code);
-    else
-      result.SetError(-return_code);
-  }
-  return result;
-}
-
-Status<int> ClientChannel::SendWithInt(void* transaction_state, int opcode,
-                                       const iovec* send_vector,
-                                       size_t send_count,
-                                       const iovec* receive_vector,
-                                       size_t receive_count) {
-  return SendAndReceive(transaction_state, opcode, send_vector, send_count,
-                        receive_vector, receive_count);
-}
-
-Status<LocalHandle> ClientChannel::SendWithFileHandle(
-    void* transaction_state, int opcode, const iovec* send_vector,
-    size_t send_count, const iovec* receive_vector, size_t receive_count) {
-  Status<int> int_status =
-      SendAndReceive(transaction_state, opcode, send_vector, send_count,
-                     receive_vector, receive_count);
-  Status<LocalHandle> status;
-  if (status.PropagateError(int_status))
-    return status;
-
-  auto* state = static_cast<TransactionState*>(transaction_state);
-  LocalHandle handle;
-  if (state->GetLocalFileHandle(int_status.get(), &handle)) {
-    status.SetValue(std::move(handle));
-  } else {
-    status.SetError(EINVAL);
-  }
-  return status;
-}
-
-Status<LocalChannelHandle> ClientChannel::SendWithChannelHandle(
-    void* transaction_state, int opcode, const iovec* send_vector,
-    size_t send_count, const iovec* receive_vector, size_t receive_count) {
-  Status<int> int_status =
-      SendAndReceive(transaction_state, opcode, send_vector, send_count,
-                     receive_vector, receive_count);
-  Status<LocalChannelHandle> status;
-  if (status.PropagateError(int_status))
-    return status;
-
-  auto* state = static_cast<TransactionState*>(transaction_state);
-  LocalChannelHandle handle;
-  if (state->GetLocalChannelHandle(int_status.get(), &handle)) {
-    status.SetValue(std::move(handle));
-  } else {
-    status.SetError(EINVAL);
-  }
-  return status;
-}
-
-FileReference ClientChannel::PushFileHandle(void* transaction_state,
-                                            const LocalHandle& handle) {
-  auto* state = static_cast<TransactionState*>(transaction_state);
-  return state->PushFileHandle(handle.Borrow());
-}
-
-FileReference ClientChannel::PushFileHandle(void* transaction_state,
-                                            const BorrowedHandle& handle) {
-  auto* state = static_cast<TransactionState*>(transaction_state);
-  return state->PushFileHandle(handle.Duplicate());
-}
-
-ChannelReference ClientChannel::PushChannelHandle(
-    void* transaction_state, const LocalChannelHandle& handle) {
-  auto* state = static_cast<TransactionState*>(transaction_state);
-  return state->PushChannelHandle(handle.Borrow());
-}
-
-ChannelReference ClientChannel::PushChannelHandle(
-    void* transaction_state, const BorrowedChannelHandle& handle) {
-  auto* state = static_cast<TransactionState*>(transaction_state);
-  return state->PushChannelHandle(handle.Duplicate());
-}
-
-bool ClientChannel::GetFileHandle(void* transaction_state, FileReference ref,
-                                  LocalHandle* handle) const {
-  auto* state = static_cast<TransactionState*>(transaction_state);
-  return state->GetLocalFileHandle(ref, handle);
-}
-
-bool ClientChannel::GetChannelHandle(void* transaction_state,
-                                     ChannelReference ref,
-                                     LocalChannelHandle* handle) const {
-  auto* state = static_cast<TransactionState*>(transaction_state);
-  return state->GetLocalChannelHandle(ref, handle);
-}
-
-std::unique_ptr<pdx::ChannelParcelable> ClientChannel::TakeChannelParcelable()
-    {
-  if (!channel_handle_)
-    return nullptr;
-
-  if (auto* channel_data =
-          ChannelManager::Get().GetChannelData(channel_handle_.value())) {
-    auto fds = channel_data->TakeFds();
-    auto parcelable = std::make_unique<ChannelParcelable>(
-        std::move(std::get<0>(fds)), std::move(std::get<1>(fds)),
-        std::move(std::get<2>(fds)));
-
-    // Here we need to explicitly close the channel handle so that the channel
-    // won't get shutdown in the destructor, while the FDs in ChannelParcelable
-    // can keep the channel alive so that new client can be created from it
-    // later.
-    channel_handle_.Close();
-    return parcelable;
-  } else {
-    return nullptr;
-  }
-}
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
diff --git a/libs/vr/libpdx_uds/client_channel_factory.cpp b/libs/vr/libpdx_uds/client_channel_factory.cpp
deleted file mode 100644
index 09dc7be..0000000
--- a/libs/vr/libpdx_uds/client_channel_factory.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-#include <uds/client_channel_factory.h>
-
-#include <errno.h>
-#include <log/log.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <chrono>
-#include <thread>
-
-#include <uds/channel_manager.h>
-#include <uds/client_channel.h>
-#include <uds/ipc_helper.h>
-
-using std::chrono::duration_cast;
-using std::chrono::steady_clock;
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-std::string ClientChannelFactory::GetRootEndpointPath() {
-  return "/dev/socket/pdx";
-}
-
-std::string ClientChannelFactory::GetEndpointPath(
-    const std::string& endpoint_path) {
-  std::string path;
-  if (!endpoint_path.empty()) {
-    if (endpoint_path.front() == '/')
-      path = endpoint_path;
-    else
-      path = GetRootEndpointPath() + '/' + endpoint_path;
-  }
-  return path;
-}
-
-ClientChannelFactory::ClientChannelFactory(const std::string& endpoint_path)
-    : endpoint_path_{GetEndpointPath(endpoint_path)} {}
-
-ClientChannelFactory::ClientChannelFactory(LocalHandle socket)
-    : socket_{std::move(socket)} {}
-
-std::unique_ptr<pdx::ClientChannelFactory> ClientChannelFactory::Create(
-    const std::string& endpoint_path) {
-  return std::unique_ptr<pdx::ClientChannelFactory>{
-      new ClientChannelFactory{endpoint_path}};
-}
-
-std::unique_ptr<pdx::ClientChannelFactory> ClientChannelFactory::Create(
-    LocalHandle socket) {
-  return std::unique_ptr<pdx::ClientChannelFactory>{
-      new ClientChannelFactory{std::move(socket)}};
-}
-
-Status<std::unique_ptr<pdx::ClientChannel>> ClientChannelFactory::Connect(
-    int64_t timeout_ms) const {
-  Status<void> status;
-
-  bool connected = socket_.IsValid();
-  if (!connected) {
-    socket_.Reset(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0));
-    LOG_ALWAYS_FATAL_IF(
-        endpoint_path_.empty(),
-        "ClientChannelFactory::Connect: unspecified socket path");
-  }
-
-  if (!socket_) {
-    ALOGE("ClientChannelFactory::Connect: socket error: %s", strerror(errno));
-    return ErrorStatus(errno);
-  }
-
-  bool use_timeout = (timeout_ms >= 0);
-  auto now = steady_clock::now();
-  auto time_end = now + std::chrono::milliseconds{timeout_ms};
-
-  int max_eaccess = 5;  // Max number of times to retry when EACCES returned.
-  while (!connected) {
-    int64_t timeout = -1;
-    if (use_timeout) {
-      auto remaining = time_end - now;
-      timeout = duration_cast<std::chrono::milliseconds>(remaining).count();
-      if (timeout < 0)
-        return ErrorStatus(ETIMEDOUT);
-    }
-    sockaddr_un remote;
-    remote.sun_family = AF_UNIX;
-    strncpy(remote.sun_path, endpoint_path_.c_str(), sizeof(remote.sun_path));
-    remote.sun_path[sizeof(remote.sun_path) - 1] = '\0';
-    ALOGD("ClientChannelFactory: Waiting for endpoint at %s", remote.sun_path);
-    status = WaitForEndpoint(endpoint_path_, timeout);
-    if (!status)
-      return ErrorStatus(status.error());
-
-    ALOGD("ClientChannelFactory: Connecting to %s", remote.sun_path);
-    int ret = RETRY_EINTR(connect(
-        socket_.Get(), reinterpret_cast<sockaddr*>(&remote), sizeof(remote)));
-    if (ret == -1) {
-      ALOGD("ClientChannelFactory: Connect error %d: %s", errno,
-            strerror(errno));
-      // if |max_eaccess| below reaches zero when errno is EACCES, the control
-      // flows into the next "else if" statement and a permanent error is
-      // returned from this function.
-      if (errno == ECONNREFUSED || (errno == EACCES && max_eaccess-- > 0)) {
-        // Connection refused/Permission denied can be the result of connecting
-        // too early (the service socket is created but its access rights are
-        // not set or not being listened to yet).
-        ALOGD("ClientChannelFactory: %s, waiting...", strerror(errno));
-        using namespace std::literals::chrono_literals;
-        std::this_thread::sleep_for(100ms);
-      } else if (errno != ENOENT && errno != ENOTDIR) {
-        // ENOENT/ENOTDIR might mean that the socket file/directory containing
-        // it has been just deleted. Try to wait for its creation and do not
-        // return an error immediately.
-        ALOGE(
-            "ClientChannelFactory::Connect: Failed to initialize connection "
-            "when connecting: %s",
-            strerror(errno));
-        return ErrorStatus(errno);
-      }
-    } else {
-      connected = true;
-      ALOGD("ClientChannelFactory: Connected successfully to %s...",
-            remote.sun_path);
-      ChannelConnectionInfo<LocalHandle> connection_info;
-      status = ReceiveData(socket_.Borrow(), &connection_info);
-      if (!status)
-        return status.error_status();
-      socket_ = std::move(connection_info.channel_fd);
-      if (!socket_) {
-        ALOGE("ClientChannelFactory::Connect: Failed to obtain channel socket");
-        return ErrorStatus(EIO);
-      }
-    }
-    if (use_timeout)
-      now = steady_clock::now();
-  }  // while (!connected)
-
-  RequestHeader<BorrowedHandle> request;
-  InitRequest(&request, opcodes::CHANNEL_OPEN, 0, 0, false);
-
-  status = SendData(socket_.Borrow(), request);
-  if (!status)
-    return status.error_status();
-
-  ResponseHeader<LocalHandle> response;
-  status = ReceiveData(socket_.Borrow(), &response);
-  if (!status)
-    return status.error_status();
-  else if (response.ret_code < 0 || response.channels.size() != 1)
-    return ErrorStatus(EIO);
-
-  LocalHandle pollin_event_fd = std::move(response.channels[0].pollin_event_fd);
-  LocalHandle pollhup_event_fd =
-      std::move(response.channels[0].pollhup_event_fd);
-
-  if (!pollin_event_fd || !pollhup_event_fd) {
-    ALOGE(
-        "ClientChannelFactory::Connect: Required fd was not returned from the "
-        "service: pollin_event_fd=%d pollhup_event_fd=%d",
-        pollin_event_fd.Get(), pollhup_event_fd.Get());
-    return ErrorStatus(EIO);
-  }
-
-  return ClientChannel::Create(ChannelManager::Get().CreateHandle(
-      std::move(socket_), std::move(pollin_event_fd),
-      std::move(pollhup_event_fd)));
-}
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
diff --git a/libs/vr/libpdx_uds/client_channel_tests.cpp b/libs/vr/libpdx_uds/client_channel_tests.cpp
deleted file mode 100644
index c9c5d15..0000000
--- a/libs/vr/libpdx_uds/client_channel_tests.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-#include <uds/client_channel.h>
-
-#include <sys/socket.h>
-
-#include <algorithm>
-#include <limits>
-#include <random>
-#include <thread>
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <pdx/client.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-
-#include <uds/client_channel_factory.h>
-#include <uds/service_endpoint.h>
-
-using testing::Return;
-using testing::_;
-
-using android::pdx::ClientBase;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Message;
-using android::pdx::ServiceBase;
-using android::pdx::ServiceDispatcher;
-using android::pdx::Status;
-using android::pdx::rpc::DispatchRemoteMethod;
-using android::pdx::uds::ClientChannel;
-using android::pdx::uds::ClientChannelFactory;
-using android::pdx::uds::Endpoint;
-
-namespace {
-
-struct TestProtocol {
-  using DataType = int8_t;
-  enum {
-    kOpSum = 0,
-  };
-  PDX_REMOTE_METHOD(Sum, kOpSum, int64_t(const std::vector<DataType>&));
-};
-
-class TestService : public ServiceBase<TestService> {
- public:
-  explicit TestService(std::unique_ptr<Endpoint> endpoint)
-      : ServiceBase{"TestService", std::move(endpoint)} {}
-
-  Status<void> HandleMessage(Message& message) override {
-    switch (message.GetOp()) {
-      case TestProtocol::kOpSum:
-        DispatchRemoteMethod<TestProtocol::Sum>(*this, &TestService::OnSum,
-                                                message);
-        return {};
-
-      default:
-        return Service::HandleMessage(message);
-    }
-  }
-
-  int64_t OnSum(Message& /*message*/,
-                const std::vector<TestProtocol::DataType>& data) {
-    return std::accumulate(data.begin(), data.end(), int64_t{0});
-  }
-};
-
-class TestClient : public ClientBase<TestClient> {
- public:
-  using ClientBase::ClientBase;
-
-  int64_t Sum(const std::vector<TestProtocol::DataType>& data) {
-    auto status = InvokeRemoteMethod<TestProtocol::Sum>(data);
-    return status ? status.get() : -1;
-  }
-};
-
-class TestServiceRunner {
- public:
-  explicit TestServiceRunner(LocalHandle channel_socket) {
-    auto endpoint = Endpoint::CreateFromSocketFd(LocalHandle{});
-    endpoint->RegisterNewChannelForTests(std::move(channel_socket));
-    service_ = TestService::Create(std::move(endpoint));
-    dispatcher_ = ServiceDispatcher::Create();
-    dispatcher_->AddService(service_);
-    dispatch_thread_ = std::thread(
-        std::bind(&ServiceDispatcher::EnterDispatchLoop, dispatcher_.get()));
-  }
-
-  ~TestServiceRunner() {
-    dispatcher_->SetCanceled(true);
-    dispatch_thread_.join();
-    dispatcher_->RemoveService(service_);
-  }
-
- private:
-  std::shared_ptr<TestService> service_;
-  std::unique_ptr<ServiceDispatcher> dispatcher_;
-  std::thread dispatch_thread_;
-};
-
-class ClientChannelTest : public testing::Test {
- public:
-  void SetUp() override {
-    int channel_sockets[2] = {};
-    ASSERT_EQ(
-        0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, channel_sockets));
-    LocalHandle service_channel{channel_sockets[0]};
-    LocalHandle client_channel{channel_sockets[1]};
-
-    service_runner_.reset(new TestServiceRunner{std::move(service_channel)});
-    auto factory = ClientChannelFactory::Create(std::move(client_channel));
-    auto status = factory->Connect(android::pdx::Client::kInfiniteTimeout);
-    ASSERT_TRUE(status);
-    client_ = TestClient::Create(status.take());
-  }
-
-  void TearDown() override {
-    service_runner_.reset();
-    client_.reset();
-  }
-
- protected:
-  std::unique_ptr<TestServiceRunner> service_runner_;
-  std::shared_ptr<TestClient> client_;
-};
-
-TEST_F(ClientChannelTest, MultithreadedClient) {
-  constexpr int kNumTestThreads = 8;
-  constexpr size_t kDataSize = 1000;  // Try to keep RPC buffer size below 4K.
-
-  std::random_device rd;
-  std::mt19937 gen{rd()};
-  std::uniform_int_distribution<TestProtocol::DataType> dist{
-      std::numeric_limits<TestProtocol::DataType>::min(),
-      std::numeric_limits<TestProtocol::DataType>::max()};
-
-  auto worker = [](std::shared_ptr<TestClient> client,
-                   std::vector<TestProtocol::DataType> data) {
-    constexpr int kMaxIterations = 500;
-    int64_t expected = std::accumulate(data.begin(), data.end(), int64_t{0});
-    for (int i = 0; i < kMaxIterations; i++) {
-      ASSERT_EQ(expected, client->Sum(data));
-    }
-  };
-
-  // Start client threads.
-  std::vector<TestProtocol::DataType> data;
-  data.resize(kDataSize);
-  std::vector<std::thread> threads;
-  for (int i = 0; i < kNumTestThreads; i++) {
-    std::generate(data.begin(), data.end(),
-                  [&dist, &gen]() { return dist(gen); });
-    threads.emplace_back(worker, client_, data);
-  }
-
-  // Wait for threads to finish.
-  for (auto& thread : threads)
-    thread.join();
-}
-
-}  // namespace
diff --git a/libs/vr/libpdx_uds/ipc_helper.cpp b/libs/vr/libpdx_uds/ipc_helper.cpp
deleted file mode 100644
index f85b3bb..0000000
--- a/libs/vr/libpdx_uds/ipc_helper.cpp
+++ /dev/null
@@ -1,543 +0,0 @@
-#include "uds/ipc_helper.h"
-
-#include <alloca.h>
-#include <errno.h>
-#include <log/log.h>
-#include <poll.h>
-#include <string.h>
-#include <sys/inotify.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-
-#include <algorithm>
-
-#include <pdx/service.h>
-#include <pdx/utility.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-namespace {
-
-constexpr size_t kMaxFdCount =
-    256;  // Total of 1KiB of data to transfer these FDs.
-
-// Default implementations of Send/Receive interfaces to use standard socket
-// send/sendmsg/recv/recvmsg functions.
-class SocketSender : public SendInterface {
- public:
-  ssize_t Send(int socket_fd, const void* data, size_t size,
-               int flags) override {
-    return send(socket_fd, data, size, flags);
-  }
-  ssize_t SendMessage(int socket_fd, const msghdr* msg, int flags) override {
-    return sendmsg(socket_fd, msg, flags);
-  }
-} g_socket_sender;
-
-class SocketReceiver : public RecvInterface {
- public:
-  ssize_t Receive(int socket_fd, void* data, size_t size, int flags) override {
-    return recv(socket_fd, data, size, flags);
-  }
-  ssize_t ReceiveMessage(int socket_fd, msghdr* msg, int flags) override {
-    return recvmsg(socket_fd, msg, flags);
-  }
-} g_socket_receiver;
-
-}  // anonymous namespace
-
-// Helper wrappers around send()/sendmsg() which repeat send() calls on data
-// that was not sent with the initial call to send/sendmsg. This is important to
-// handle transmissions interrupted by signals.
-Status<void> SendAll(SendInterface* sender, const BorrowedHandle& socket_fd,
-                     const void* data, size_t size) {
-  Status<void> ret;
-  const uint8_t* ptr = static_cast<const uint8_t*>(data);
-  while (size > 0) {
-    ssize_t size_written =
-        RETRY_EINTR(sender->Send(socket_fd.Get(), ptr, size, MSG_NOSIGNAL));
-    if (size_written < 0) {
-      ret.SetError(errno);
-      ALOGE("SendAll: Failed to send data over socket: %s",
-            ret.GetErrorMessage().c_str());
-      break;
-    }
-    size -= size_written;
-    ptr += size_written;
-  }
-  return ret;
-}
-
-Status<void> SendMsgAll(SendInterface* sender, const BorrowedHandle& socket_fd,
-                        const msghdr* msg) {
-  Status<void> ret;
-  ssize_t sent_size =
-      RETRY_EINTR(sender->SendMessage(socket_fd.Get(), msg, MSG_NOSIGNAL));
-  if (sent_size < 0) {
-    ret.SetError(errno);
-    ALOGE("SendMsgAll: Failed to send data over socket: %s",
-          ret.GetErrorMessage().c_str());
-    return ret;
-  }
-
-  ssize_t chunk_start_offset = 0;
-  for (size_t i = 0; i < msg->msg_iovlen; i++) {
-    ssize_t chunk_end_offset = chunk_start_offset + msg->msg_iov[i].iov_len;
-    if (sent_size < chunk_end_offset) {
-      size_t offset_within_chunk = sent_size - chunk_start_offset;
-      size_t data_size = msg->msg_iov[i].iov_len - offset_within_chunk;
-      const uint8_t* chunk_base =
-          static_cast<const uint8_t*>(msg->msg_iov[i].iov_base);
-      ret = SendAll(sender, socket_fd, chunk_base + offset_within_chunk,
-                    data_size);
-      if (!ret)
-        break;
-      sent_size += data_size;
-    }
-    chunk_start_offset = chunk_end_offset;
-  }
-  return ret;
-}
-
-// Helper wrappers around recv()/recvmsg() which repeat recv() calls on data
-// that was not received with the initial call to recvmsg(). This is important
-// to handle transmissions interrupted by signals as well as the case when
-// initial data did not arrive in a single chunk over the socket (e.g. socket
-// buffer was full at the time of transmission, and only portion of initial
-// message was sent and the rest was blocked until the buffer was cleared by the
-// receiving side).
-Status<void> RecvMsgAll(RecvInterface* receiver,
-                        const BorrowedHandle& socket_fd, msghdr* msg) {
-  Status<void> ret;
-  ssize_t size_read = RETRY_EINTR(receiver->ReceiveMessage(
-      socket_fd.Get(), msg, MSG_WAITALL | MSG_CMSG_CLOEXEC));
-  if (size_read < 0) {
-    ret.SetError(errno);
-    ALOGE("RecvMsgAll: Failed to receive data from socket: %s",
-          ret.GetErrorMessage().c_str());
-    return ret;
-  } else if (size_read == 0) {
-    ret.SetError(ESHUTDOWN);
-    ALOGW("RecvMsgAll: Socket has been shut down");
-    return ret;
-  }
-
-  ssize_t chunk_start_offset = 0;
-  for (size_t i = 0; i < msg->msg_iovlen; i++) {
-    ssize_t chunk_end_offset = chunk_start_offset + msg->msg_iov[i].iov_len;
-    if (size_read < chunk_end_offset) {
-      size_t offset_within_chunk = size_read - chunk_start_offset;
-      size_t data_size = msg->msg_iov[i].iov_len - offset_within_chunk;
-      uint8_t* chunk_base = static_cast<uint8_t*>(msg->msg_iov[i].iov_base);
-      ret = RecvAll(receiver, socket_fd, chunk_base + offset_within_chunk,
-                    data_size);
-      if (!ret)
-        break;
-      size_read += data_size;
-    }
-    chunk_start_offset = chunk_end_offset;
-  }
-  return ret;
-}
-
-Status<void> RecvAll(RecvInterface* receiver, const BorrowedHandle& socket_fd,
-                     void* data, size_t size) {
-  Status<void> ret;
-  uint8_t* ptr = static_cast<uint8_t*>(data);
-  while (size > 0) {
-    ssize_t size_read = RETRY_EINTR(receiver->Receive(
-        socket_fd.Get(), ptr, size, MSG_WAITALL | MSG_CMSG_CLOEXEC));
-    if (size_read < 0) {
-      ret.SetError(errno);
-      ALOGE("RecvAll: Failed to receive data from socket: %s",
-            ret.GetErrorMessage().c_str());
-      break;
-    } else if (size_read == 0) {
-      ret.SetError(ESHUTDOWN);
-      ALOGW("RecvAll: Socket has been shut down");
-      break;
-    }
-    size -= size_read;
-    ptr += size_read;
-  }
-  return ret;
-}
-
-uint32_t kMagicPreamble = 0x7564736d;  // 'udsm'.
-
-struct MessagePreamble {
-  uint32_t magic{0};
-  uint32_t data_size{0};
-  uint32_t fd_count{0};
-};
-
-Status<void> SendPayload::Send(const BorrowedHandle& socket_fd) {
-  return Send(socket_fd, nullptr);
-}
-
-Status<void> SendPayload::Send(const BorrowedHandle& socket_fd,
-                               const ucred* cred, const iovec* data_vec,
-                               size_t vec_count) {
-  if (file_handles_.size() > kMaxFdCount) {
-    ALOGE(
-        "SendPayload::Send: Trying to send too many file descriptors (%zu), "
-        "max allowed = %zu",
-        file_handles_.size(), kMaxFdCount);
-    return ErrorStatus{EINVAL};
-  }
-
-  SendInterface* sender = sender_ ? sender_ : &g_socket_sender;
-  MessagePreamble preamble;
-  preamble.magic = kMagicPreamble;
-  preamble.data_size = buffer_.size();
-  preamble.fd_count = file_handles_.size();
-
-  msghdr msg = {};
-  msg.msg_iovlen = 2 + vec_count;
-  msg.msg_iov = static_cast<iovec*>(alloca(sizeof(iovec) * msg.msg_iovlen));
-  msg.msg_iov[0].iov_base = &preamble;
-  msg.msg_iov[0].iov_len = sizeof(preamble);
-  msg.msg_iov[1].iov_base = buffer_.data();
-  msg.msg_iov[1].iov_len = buffer_.size();
-  for (size_t i = 0; i < vec_count; i++)
-    msg.msg_iov[i + 2] = data_vec[i];
-
-  if (cred || !file_handles_.empty()) {
-    const size_t fd_bytes = file_handles_.size() * sizeof(int);
-    msg.msg_controllen = (cred ? CMSG_SPACE(sizeof(ucred)) : 0) +
-                         (fd_bytes == 0 ? 0 : CMSG_SPACE(fd_bytes));
-    msg.msg_control = alloca(msg.msg_controllen);
-
-    cmsghdr* control = CMSG_FIRSTHDR(&msg);
-    if (cred) {
-      control->cmsg_level = SOL_SOCKET;
-      control->cmsg_type = SCM_CREDENTIALS;
-      control->cmsg_len = CMSG_LEN(sizeof(ucred));
-      memcpy(CMSG_DATA(control), cred, sizeof(ucred));
-      control = CMSG_NXTHDR(&msg, control);
-    }
-
-    if (fd_bytes) {
-      control->cmsg_level = SOL_SOCKET;
-      control->cmsg_type = SCM_RIGHTS;
-      control->cmsg_len = CMSG_LEN(fd_bytes);
-      memcpy(CMSG_DATA(control), file_handles_.data(), fd_bytes);
-    }
-  }
-
-  return SendMsgAll(sender, socket_fd, &msg);
-}
-
-// MessageWriter
-void* SendPayload::GetNextWriteBufferSection(size_t size) {
-  return buffer_.grow_by(size);
-}
-
-OutputResourceMapper* SendPayload::GetOutputResourceMapper() { return this; }
-
-// OutputResourceMapper
-Status<FileReference> SendPayload::PushFileHandle(const LocalHandle& handle) {
-  if (handle) {
-    const int ref = file_handles_.size();
-    file_handles_.push_back(handle.Get());
-    return ref;
-  } else {
-    return handle.Get();
-  }
-}
-
-Status<FileReference> SendPayload::PushFileHandle(
-    const BorrowedHandle& handle) {
-  if (handle) {
-    const int ref = file_handles_.size();
-    file_handles_.push_back(handle.Get());
-    return ref;
-  } else {
-    return handle.Get();
-  }
-}
-
-Status<FileReference> SendPayload::PushFileHandle(const RemoteHandle& handle) {
-  return handle.Get();
-}
-
-Status<ChannelReference> SendPayload::PushChannelHandle(
-    const LocalChannelHandle& /*handle*/) {
-  return ErrorStatus{EOPNOTSUPP};
-}
-Status<ChannelReference> SendPayload::PushChannelHandle(
-    const BorrowedChannelHandle& /*handle*/) {
-  return ErrorStatus{EOPNOTSUPP};
-}
-Status<ChannelReference> SendPayload::PushChannelHandle(
-    const RemoteChannelHandle& /*handle*/) {
-  return ErrorStatus{EOPNOTSUPP};
-}
-
-Status<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd) {
-  return Receive(socket_fd, nullptr);
-}
-
-Status<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd,
-                                     ucred* cred) {
-  RecvInterface* receiver = receiver_ ? receiver_ : &g_socket_receiver;
-  MessagePreamble preamble;
-  msghdr msg = {};
-  iovec recv_vect = {&preamble, sizeof(preamble)};
-  msg.msg_iov = &recv_vect;
-  msg.msg_iovlen = 1;
-  const size_t receive_fd_bytes = kMaxFdCount * sizeof(int);
-  msg.msg_controllen = CMSG_SPACE(sizeof(ucred)) + CMSG_SPACE(receive_fd_bytes);
-  msg.msg_control = alloca(msg.msg_controllen);
-
-  Status<void> ret = RecvMsgAll(receiver, socket_fd, &msg);
-  if (!ret)
-    return ret;
-
-  if (preamble.magic != kMagicPreamble) {
-    ALOGE("ReceivePayload::Receive: Message header is invalid");
-    ret.SetError(EIO);
-    return ret;
-  }
-
-  buffer_.resize(preamble.data_size);
-  file_handles_.clear();
-  read_pos_ = 0;
-
-  bool cred_available = false;
-  file_handles_.reserve(preamble.fd_count);
-  cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
-  while (cmsg) {
-    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS &&
-        cred && cmsg->cmsg_len == CMSG_LEN(sizeof(ucred))) {
-      cred_available = true;
-      memcpy(cred, CMSG_DATA(cmsg), sizeof(ucred));
-    } else if (cmsg->cmsg_level == SOL_SOCKET &&
-               cmsg->cmsg_type == SCM_RIGHTS) {
-      socklen_t payload_len = cmsg->cmsg_len - CMSG_LEN(0);
-      const int* fds = reinterpret_cast<const int*>(CMSG_DATA(cmsg));
-      size_t fd_count = payload_len / sizeof(int);
-      std::transform(fds, fds + fd_count, std::back_inserter(file_handles_),
-                     [](int fd) { return LocalHandle{fd}; });
-    }
-    cmsg = CMSG_NXTHDR(&msg, cmsg);
-  }
-
-  ret = RecvAll(receiver, socket_fd, buffer_.data(), buffer_.size());
-  if (!ret)
-    return ret;
-
-  if (cred && !cred_available) {
-    ALOGE("ReceivePayload::Receive: Failed to obtain message credentials");
-    ret.SetError(EIO);
-  }
-
-  return ret;
-}
-
-// MessageReader
-MessageReader::BufferSection ReceivePayload::GetNextReadBufferSection() {
-  return {buffer_.data() + read_pos_, &*buffer_.end()};
-}
-
-void ReceivePayload::ConsumeReadBufferSectionData(const void* new_start) {
-  read_pos_ = PointerDistance(new_start, buffer_.data());
-}
-
-InputResourceMapper* ReceivePayload::GetInputResourceMapper() { return this; }
-
-// InputResourceMapper
-bool ReceivePayload::GetFileHandle(FileReference ref, LocalHandle* handle) {
-  if (ref < 0) {
-    *handle = LocalHandle{ref};
-    return true;
-  }
-  if (static_cast<size_t>(ref) > file_handles_.size())
-    return false;
-  *handle = std::move(file_handles_[ref]);
-  return true;
-}
-
-bool ReceivePayload::GetChannelHandle(ChannelReference /*ref*/,
-                                      LocalChannelHandle* /*handle*/) {
-  return false;
-}
-
-Status<void> SendData(const BorrowedHandle& socket_fd, const void* data,
-                      size_t size) {
-  return SendAll(&g_socket_sender, socket_fd, data, size);
-}
-
-Status<void> SendDataVector(const BorrowedHandle& socket_fd, const iovec* data,
-                            size_t count) {
-  msghdr msg = {};
-  msg.msg_iov = const_cast<iovec*>(data);
-  msg.msg_iovlen = count;
-  return SendMsgAll(&g_socket_sender, socket_fd, &msg);
-}
-
-Status<void> ReceiveData(const BorrowedHandle& socket_fd, void* data,
-                         size_t size) {
-  return RecvAll(&g_socket_receiver, socket_fd, data, size);
-}
-
-Status<void> ReceiveDataVector(const BorrowedHandle& socket_fd,
-                               const iovec* data, size_t count) {
-  msghdr msg = {};
-  msg.msg_iov = const_cast<iovec*>(data);
-  msg.msg_iovlen = count;
-  return RecvMsgAll(&g_socket_receiver, socket_fd, &msg);
-}
-
-size_t CountVectorSize(const iovec* vector, size_t count) {
-  return std::accumulate(
-      vector, vector + count, size_t{0},
-      [](size_t size, const iovec& vec) { return size + vec.iov_len; });
-}
-
-void InitRequest(android::pdx::uds::RequestHeader<BorrowedHandle>* request,
-                 int opcode, uint32_t send_len, uint32_t max_recv_len,
-                 bool is_impulse) {
-  request->op = opcode;
-  request->cred.pid = getpid();
-  request->cred.uid = geteuid();
-  request->cred.gid = getegid();
-  request->send_len = send_len;
-  request->max_recv_len = max_recv_len;
-  request->is_impulse = is_impulse;
-}
-
-Status<void> WaitForEndpoint(const std::string& endpoint_path,
-                             int64_t timeout_ms) {
-  // Endpoint path must be absolute.
-  if (endpoint_path.empty() || endpoint_path.front() != '/')
-    return ErrorStatus(EINVAL);
-
-  // Create inotify fd.
-  LocalHandle fd{inotify_init()};
-  if (!fd)
-    return ErrorStatus(errno);
-
-  // Set the inotify fd to non-blocking.
-  int ret = fcntl(fd.Get(), F_GETFL);
-  fcntl(fd.Get(), F_SETFL, ret | O_NONBLOCK);
-
-  // Setup the pollfd.
-  pollfd pfd = {fd.Get(), POLLIN, 0};
-
-  // Find locations of each path separator.
-  std::vector<size_t> separators{0};  // The path is absolute, so '/' is at #0.
-  size_t pos = endpoint_path.find('/', 1);
-  while (pos != std::string::npos) {
-    separators.push_back(pos);
-    pos = endpoint_path.find('/', pos + 1);
-  }
-  separators.push_back(endpoint_path.size());
-
-  // Walk down the path, checking for existence and waiting if needed.
-  pos = 1;
-  size_t links = 0;
-  std::string current;
-  while (pos < separators.size() && links <= MAXSYMLINKS) {
-    std::string previous = current;
-    current = endpoint_path.substr(0, separators[pos]);
-
-    // Check for existence; proceed to setup a watch if not.
-    if (access(current.c_str(), F_OK) < 0) {
-      if (errno != ENOENT)
-        return ErrorStatus(errno);
-
-      // Extract the name of the path component to wait for.
-      std::string next = current.substr(
-          separators[pos - 1] + 1, separators[pos] - separators[pos - 1] - 1);
-
-      // Add a watch on the last existing directory we reach.
-      int wd = inotify_add_watch(
-          fd.Get(), previous.c_str(),
-          IN_CREATE | IN_DELETE_SELF | IN_MOVE_SELF | IN_MOVED_TO);
-      if (wd < 0) {
-        if (errno != ENOENT)
-          return ErrorStatus(errno);
-        // Restart at the beginning if previous was deleted.
-        links = 0;
-        current.clear();
-        pos = 1;
-        continue;
-      }
-
-      // Make sure current didn't get created before the watch was added.
-      ret = access(current.c_str(), F_OK);
-      if (ret < 0) {
-        if (errno != ENOENT)
-          return ErrorStatus(errno);
-
-        bool exit_poll = false;
-        while (!exit_poll) {
-          // Wait for an event or timeout.
-          ret = poll(&pfd, 1, timeout_ms);
-          if (ret <= 0)
-            return ErrorStatus(ret == 0 ? ETIMEDOUT : errno);
-
-          // Read events.
-          char buffer[sizeof(inotify_event) + NAME_MAX + 1];
-
-          ret = read(fd.Get(), buffer, sizeof(buffer));
-          if (ret < 0) {
-            if (errno == EAGAIN || errno == EWOULDBLOCK)
-              continue;
-            else
-              return ErrorStatus(errno);
-          } else if (static_cast<size_t>(ret) < sizeof(struct inotify_event)) {
-            return ErrorStatus(EIO);
-          }
-
-          auto* event = reinterpret_cast<const inotify_event*>(buffer);
-          auto* end = reinterpret_cast<const inotify_event*>(buffer + ret);
-          while (event < end) {
-            std::string event_for;
-            if (event->len > 0)
-              event_for = event->name;
-
-            if (event->mask & (IN_CREATE | IN_MOVED_TO)) {
-              // See if this is the droid we're looking for.
-              if (next == event_for) {
-                exit_poll = true;
-                break;
-              }
-            } else if (event->mask & (IN_DELETE_SELF | IN_MOVE_SELF)) {
-              // Restart at the beginning if our watch dir is deleted.
-              links = 0;
-              current.clear();
-              pos = 0;
-              exit_poll = true;
-              break;
-            }
-
-            event = reinterpret_cast<const inotify_event*>(AdvancePointer(
-                event, sizeof(struct inotify_event) + event->len));
-          }  // while (event < end)
-        }    // while (!exit_poll)
-      }      // Current dir doesn't exist.
-      ret = inotify_rm_watch(fd.Get(), wd);
-      if (ret < 0 && errno != EINVAL)
-        return ErrorStatus(errno);
-    }  // if (access(current.c_str(), F_OK) < 0)
-
-    // Check for symbolic link and update link count.
-    struct stat stat_buf;
-    ret = lstat(current.c_str(), &stat_buf);
-    if (ret < 0 && errno != ENOENT)
-      return ErrorStatus(errno);
-    else if (ret == 0 && S_ISLNK(stat_buf.st_mode))
-      links++;
-    pos++;
-  }  // while (pos < separators.size() && links <= MAXSYMLINKS)
-
-  return {};
-}
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
diff --git a/libs/vr/libpdx_uds/ipc_helper_tests.cpp b/libs/vr/libpdx_uds/ipc_helper_tests.cpp
deleted file mode 100644
index bfa827e..0000000
--- a/libs/vr/libpdx_uds/ipc_helper_tests.cpp
+++ /dev/null
@@ -1,365 +0,0 @@
-#include "uds/ipc_helper.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-using testing::Return;
-using testing::SetErrnoAndReturn;
-using testing::_;
-
-using android::pdx::BorrowedHandle;
-using android::pdx::uds::SendInterface;
-using android::pdx::uds::RecvInterface;
-using android::pdx::uds::SendAll;
-using android::pdx::uds::SendMsgAll;
-using android::pdx::uds::RecvAll;
-using android::pdx::uds::RecvMsgAll;
-
-namespace {
-
-// Useful constants for tests.
-static constexpr intptr_t kPtr = 1234;
-static constexpr int kSocketFd = 5678;
-static const BorrowedHandle kSocket{kSocketFd};
-
-// Helper functions to construct test data pointer values.
-void* IntToPtr(intptr_t value) { return reinterpret_cast<void*>(value); }
-const void* IntToConstPtr(intptr_t value) {
-  return reinterpret_cast<const void*>(value);
-}
-
-// Mock classes for SendInterface/RecvInterface.
-class MockSender : public SendInterface {
- public:
-  MOCK_METHOD4(Send, ssize_t(int socket_fd, const void* data, size_t size,
-                             int flags));
-  MOCK_METHOD3(SendMessage,
-               ssize_t(int socket_fd, const msghdr* msg, int flags));
-};
-
-class MockReceiver : public RecvInterface {
- public:
-  MOCK_METHOD4(Receive,
-               ssize_t(int socket_fd, void* data, size_t size, int flags));
-  MOCK_METHOD3(ReceiveMessage, ssize_t(int socket_fd, msghdr* msg, int flags));
-};
-
-// Test case classes.
-class SendTest : public testing::Test {
- public:
-  SendTest() {
-    ON_CALL(sender_, Send(_, _, _, _))
-        .WillByDefault(SetErrnoAndReturn(EIO, -1));
-    ON_CALL(sender_, SendMessage(_, _, _))
-        .WillByDefault(SetErrnoAndReturn(EIO, -1));
-  }
-
- protected:
-  MockSender sender_;
-};
-
-class RecvTest : public testing::Test {
- public:
-  RecvTest() {
-    ON_CALL(receiver_, Receive(_, _, _, _))
-        .WillByDefault(SetErrnoAndReturn(EIO, -1));
-    ON_CALL(receiver_, ReceiveMessage(_, _, _))
-        .WillByDefault(SetErrnoAndReturn(EIO, -1));
-  }
-
- protected:
-  MockReceiver receiver_;
-};
-
-class MessageTestBase : public testing::Test {
- public:
-  MessageTestBase() {
-    memset(&msg_, 0, sizeof(msg_));
-    msg_.msg_iovlen = data_.size();
-    msg_.msg_iov = data_.data();
-  }
-
- protected:
-  static constexpr intptr_t kPtr1 = kPtr;
-  static constexpr intptr_t kPtr2 = kPtr + 200;
-  static constexpr intptr_t kPtr3 = kPtr + 1000;
-
-  MockSender sender_;
-  msghdr msg_;
-  std::vector<iovec> data_{
-      {IntToPtr(kPtr1), 100}, {IntToPtr(kPtr2), 200}, {IntToPtr(kPtr3), 300}};
-};
-
-class SendMessageTest : public MessageTestBase {
- public:
-  SendMessageTest() {
-    ON_CALL(sender_, Send(_, _, _, _))
-        .WillByDefault(SetErrnoAndReturn(EIO, -1));
-    ON_CALL(sender_, SendMessage(_, _, _))
-        .WillByDefault(SetErrnoAndReturn(EIO, -1));
-  }
-
- protected:
-  MockSender sender_;
-};
-
-class RecvMessageTest : public MessageTestBase {
- public:
-  RecvMessageTest() {
-    ON_CALL(receiver_, Receive(_, _, _, _))
-        .WillByDefault(SetErrnoAndReturn(EIO, -1));
-    ON_CALL(receiver_, ReceiveMessage(_, _, _))
-        .WillByDefault(SetErrnoAndReturn(EIO, -1));
-  }
-
- protected:
-  MockReceiver receiver_;
-};
-
-// Actual tests.
-
-// SendAll
-TEST_F(SendTest, Complete) {
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr), 100, MSG_NOSIGNAL))
-      .WillOnce(Return(100));
-
-  auto status = SendAll(&sender_, kSocket, IntToConstPtr(kPtr), 100);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(SendTest, Signal) {
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr), 100, MSG_NOSIGNAL))
-      .WillOnce(Return(20));
-  EXPECT_CALL(sender_,
-              Send(kSocketFd, IntToConstPtr(kPtr + 20), 80, MSG_NOSIGNAL))
-      .WillOnce(Return(40));
-  EXPECT_CALL(sender_,
-              Send(kSocketFd, IntToConstPtr(kPtr + 60), 40, MSG_NOSIGNAL))
-      .WillOnce(Return(40));
-
-  auto status = SendAll(&sender_, kSocket, IntToConstPtr(kPtr), 100);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(SendTest, Eintr) {
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr), 100, MSG_NOSIGNAL))
-      .WillOnce(SetErrnoAndReturn(EINTR, -1))
-      .WillOnce(Return(100));
-
-  auto status = SendAll(&sender_, kSocket, IntToConstPtr(kPtr), 100);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(SendTest, Error) {
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr), 100, MSG_NOSIGNAL))
-      .WillOnce(SetErrnoAndReturn(EIO, -1));
-
-  auto status = SendAll(&sender_, kSocket, IntToConstPtr(kPtr), 100);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EIO, status.error());
-}
-
-TEST_F(SendTest, Error2) {
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr), 100, MSG_NOSIGNAL))
-      .WillOnce(Return(50));
-  EXPECT_CALL(sender_,
-              Send(kSocketFd, IntToConstPtr(kPtr + 50), 50, MSG_NOSIGNAL))
-      .WillOnce(SetErrnoAndReturn(EIO, -1));
-
-  auto status = SendAll(&sender_, kSocket, IntToConstPtr(kPtr), 100);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EIO, status.error());
-}
-
-// RecvAll
-TEST_F(RecvTest, Complete) {
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr), 100,
-                                 MSG_WAITALL | MSG_CMSG_CLOEXEC))
-      .WillOnce(Return(100));
-
-  auto status = RecvAll(&receiver_, kSocket, IntToPtr(kPtr), 100);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(RecvTest, Signal) {
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr), 100, _))
-      .WillOnce(Return(20));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr + 20), 80, _))
-      .WillOnce(Return(40));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr + 60), 40, _))
-      .WillOnce(Return(40));
-
-  auto status = RecvAll(&receiver_, kSocket, IntToPtr(kPtr), 100);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(RecvTest, Eintr) {
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr), 100, _))
-      .WillOnce(SetErrnoAndReturn(EINTR, -1))
-      .WillOnce(Return(100));
-
-  auto status = RecvAll(&receiver_, kSocket, IntToPtr(kPtr), 100);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(RecvTest, Error) {
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr), 100, _))
-      .WillOnce(SetErrnoAndReturn(EIO, -1));
-
-  auto status = RecvAll(&receiver_, kSocket, IntToPtr(kPtr), 100);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EIO, status.error());
-}
-
-TEST_F(RecvTest, Error2) {
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr), 100, _))
-      .WillOnce(Return(30));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr + 30), 70, _))
-      .WillOnce(SetErrnoAndReturn(EIO, -1));
-
-  auto status = RecvAll(&receiver_, kSocket, IntToPtr(kPtr), 100);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EIO, status.error());
-}
-
-// SendMsgAll
-TEST_F(SendMessageTest, Complete) {
-  EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, MSG_NOSIGNAL))
-      .WillOnce(Return(600));
-
-  auto status = SendMsgAll(&sender_, kSocket, &msg_);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(SendMessageTest, Partial) {
-  EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, _)).WillOnce(Return(70));
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr1 + 70), 30, _))
-      .WillOnce(Return(30));
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr2), 200, _))
-      .WillOnce(Return(190));
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr2 + 190), 10, _))
-      .WillOnce(Return(10));
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr3), 300, _))
-      .WillOnce(Return(300));
-
-  auto status = SendMsgAll(&sender_, kSocket, &msg_);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(SendMessageTest, Partial2) {
-  EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, _)).WillOnce(Return(310));
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr3 + 10), 290, _))
-      .WillOnce(Return(290));
-
-  auto status = SendMsgAll(&sender_, kSocket, &msg_);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(SendMessageTest, Eintr) {
-  EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, _))
-      .WillOnce(SetErrnoAndReturn(EINTR, -1))
-      .WillOnce(Return(70));
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr1 + 70), 30, _))
-      .WillOnce(SetErrnoAndReturn(EINTR, -1))
-      .WillOnce(Return(30));
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr2), 200, _))
-      .WillOnce(Return(200));
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr3), 300, _))
-      .WillOnce(Return(300));
-
-  auto status = SendMsgAll(&sender_, kSocket, &msg_);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(SendMessageTest, Error) {
-  EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, _))
-      .WillOnce(SetErrnoAndReturn(EBADF, -1));
-
-  auto status = SendMsgAll(&sender_, kSocket, &msg_);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EBADF, status.error());
-}
-
-TEST_F(SendMessageTest, Error2) {
-  EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, _)).WillOnce(Return(20));
-  EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr1 + 20), 80, _))
-      .WillOnce(SetErrnoAndReturn(EBADF, -1));
-
-  auto status = SendMsgAll(&sender_, kSocket, &msg_);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EBADF, status.error());
-}
-
-// RecvMsgAll
-TEST_F(RecvMessageTest, Complete) {
-  EXPECT_CALL(receiver_,
-              ReceiveMessage(kSocketFd, &msg_, MSG_WAITALL | MSG_CMSG_CLOEXEC))
-      .WillOnce(Return(600));
-
-  auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(RecvMessageTest, Partial) {
-  EXPECT_CALL(receiver_, ReceiveMessage(kSocketFd, &msg_, _))
-      .WillOnce(Return(70));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr1 + 70), 30, _))
-      .WillOnce(Return(30));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr2), 200, _))
-      .WillOnce(Return(190));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr2 + 190), 10, _))
-      .WillOnce(Return(10));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr3), 300, _))
-      .WillOnce(Return(300));
-
-  auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(RecvMessageTest, Partial2) {
-  EXPECT_CALL(receiver_, ReceiveMessage(kSocketFd, &msg_, _))
-      .WillOnce(Return(310));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr3 + 10), 290, _))
-      .WillOnce(Return(290));
-
-  auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(RecvMessageTest, Eintr) {
-  EXPECT_CALL(receiver_, ReceiveMessage(kSocketFd, &msg_, _))
-      .WillOnce(SetErrnoAndReturn(EINTR, -1))
-      .WillOnce(Return(70));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr1 + 70), 30, _))
-      .WillOnce(SetErrnoAndReturn(EINTR, -1))
-      .WillOnce(Return(30));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr2), 200, _))
-      .WillOnce(Return(200));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr3), 300, _))
-      .WillOnce(Return(300));
-
-  auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
-  EXPECT_TRUE(status);
-}
-
-TEST_F(RecvMessageTest, Error) {
-  EXPECT_CALL(receiver_, ReceiveMessage(kSocketFd, &msg_, _))
-      .WillOnce(SetErrnoAndReturn(EBADF, -1));
-
-  auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EBADF, status.error());
-}
-
-TEST_F(RecvMessageTest, Error2) {
-  EXPECT_CALL(receiver_, ReceiveMessage(kSocketFd, &msg_, _))
-      .WillOnce(Return(20));
-  EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr1 + 20), 80, _))
-      .WillOnce(SetErrnoAndReturn(EBADF, -1));
-
-  auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
-  ASSERT_FALSE(status);
-  EXPECT_EQ(EBADF, status.error());
-}
-
-}  // namespace
diff --git a/libs/vr/libpdx_uds/private/uds/channel_event_set.h b/libs/vr/libpdx_uds/private/uds/channel_event_set.h
deleted file mode 100644
index e960740..0000000
--- a/libs/vr/libpdx_uds/private/uds/channel_event_set.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef ANDROID_PDX_UDS_CHANNEL_EVENT_SET_H_
-#define ANDROID_PDX_UDS_CHANNEL_EVENT_SET_H_
-
-#include <vector>
-
-#include <pdx/client_channel.h>
-#include <pdx/file_handle.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class ChannelEventSet {
- public:
-  ChannelEventSet();
-  ChannelEventSet(ChannelEventSet&&) = default;
-  ChannelEventSet& operator=(ChannelEventSet&&) = default;
-
-  BorrowedHandle pollin_event_fd() const { return pollin_event_fd_.Borrow(); }
-  BorrowedHandle pollhup_event_fd() const { return pollhup_event_fd_.Borrow(); }
-
-  explicit operator bool() const {
-    return !!pollin_event_fd_ && !!pollhup_event_fd_;
-  }
-
-  int ModifyEvents(int clear_mask, int set_mask);
-
- private:
-  LocalHandle pollin_event_fd_;
-  LocalHandle pollhup_event_fd_;
-  uint32_t event_bits_ = 0;
-
-  ChannelEventSet(const ChannelEventSet&) = delete;
-  void operator=(const ChannelEventSet&) = delete;
-};
-
-class ChannelEventReceiver {
- public:
-  ChannelEventReceiver() = default;
-  ChannelEventReceiver(LocalHandle data_fd, LocalHandle pollin_event_fd,
-                       LocalHandle pollhup_event_fd);
-  ChannelEventReceiver(ChannelEventReceiver&&) = default;
-  ChannelEventReceiver& operator=(ChannelEventReceiver&&) = default;
-
-  explicit operator bool() const {
-    return !!pollin_event_fd_ && !!pollhup_event_fd_ && !!data_fd_ &&
-           !!epoll_fd_;
-  }
-
-  BorrowedHandle event_fd() const { return epoll_fd_.Borrow(); }
-
-  BorrowedHandle pollin_event_fd() const { return pollin_event_fd_.Borrow(); }
-  BorrowedHandle pollhup_event_fd() const { return pollhup_event_fd_.Borrow(); }
-  BorrowedHandle data_fd() const { return data_fd_.Borrow(); }
-
-  // Moves file descriptors out of ChannelEventReceiver. Note these operations
-  // immediately invalidates the receiver.
-  std::tuple<LocalHandle, LocalHandle, LocalHandle> TakeFds() {
-    epoll_fd_.Close();
-    return {std::move(data_fd_), std::move(pollin_event_fd_),
-            std::move(pollhup_event_fd_)};
-  }
-
-  Status<int> GetPendingEvents() const;
-  Status<int> PollPendingEvents(int timeout_ms) const;
-
-  std::vector<ClientChannel::EventSource> GetEventSources() const;
-
- private:
-  LocalHandle data_fd_;
-  LocalHandle pollin_event_fd_;
-  LocalHandle pollhup_event_fd_;
-  LocalHandle epoll_fd_;
-
-  ChannelEventReceiver(const ChannelEventReceiver&) = delete;
-  void operator=(const ChannelEventReceiver&) = delete;
-};
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_UDS_CHANNEL_EVENT_SET_H_
diff --git a/libs/vr/libpdx_uds/private/uds/channel_manager.h b/libs/vr/libpdx_uds/private/uds/channel_manager.h
deleted file mode 100644
index 5f6a514..0000000
--- a/libs/vr/libpdx_uds/private/uds/channel_manager.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef ANDROID_PDX_UDS_CHANNEL_MANAGER_H_
-#define ANDROID_PDX_UDS_CHANNEL_MANAGER_H_
-
-#include <mutex>
-#include <unordered_map>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <uds/channel_event_set.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class ChannelManager : public ChannelManagerInterface {
- public:
-  static ChannelManager& Get();
-
-  LocalChannelHandle CreateHandle(LocalHandle data_fd,
-                                  LocalHandle pollin_event_fd,
-                                  LocalHandle pollhup_event_fd);
-
-  ChannelEventReceiver* GetChannelData(int32_t handle);
-
- private:
-  ChannelManager() = default;
-
-  void CloseHandle(int32_t handle) override;
-
-  std::mutex mutex_;
-  std::unordered_map<int32_t, ChannelEventReceiver> channels_;
-};
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_UDS_CHANNEL_MANAGER_H_
diff --git a/libs/vr/libpdx_uds/private/uds/channel_parcelable.h b/libs/vr/libpdx_uds/private/uds/channel_parcelable.h
deleted file mode 100644
index 1c3fae9..0000000
--- a/libs/vr/libpdx_uds/private/uds/channel_parcelable.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef ANDROID_PDX_UDS_CHANNEL_PARCELABLE_H_
-#define ANDROID_PDX_UDS_CHANNEL_PARCELABLE_H_
-
-#include <pdx/channel_parcelable.h>
-#include <pdx/file_handle.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class ChannelParcelable : public pdx::ChannelParcelable {
- public:
-  ChannelParcelable() = default;
-  ChannelParcelable(LocalHandle data_fd, LocalHandle pollin_event_fd,
-                    LocalHandle pollhup_event_fd);
-
-  // Implements pdx::ChannelParcelable interface.
-  bool IsValid() const override;
-  LocalChannelHandle TakeChannelHandle() override;
-
-  // Implements android::Parcelable interface.
-  status_t writeToParcel(Parcel* parcel) const override;
-  status_t readFromParcel(const Parcel* parcel) override;
-
- private:
-  LocalHandle data_fd_;
-  LocalHandle pollin_event_fd_;
-  LocalHandle pollhup_event_fd_;
-};
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_UDS_CHANNEL_PARCELABLE_H_
diff --git a/libs/vr/libpdx_uds/private/uds/client_channel.h b/libs/vr/libpdx_uds/private/uds/client_channel.h
deleted file mode 100644
index 3561c6f..0000000
--- a/libs/vr/libpdx_uds/private/uds/client_channel.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef ANDROID_PDX_UDS_CLIENT_CHANNEL_H_
-#define ANDROID_PDX_UDS_CLIENT_CHANNEL_H_
-
-#include <pdx/client_channel.h>
-
-#include <mutex>
-
-#include <uds/channel_event_set.h>
-#include <uds/channel_manager.h>
-#include <uds/service_endpoint.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class ClientChannel : public pdx::ClientChannel {
- public:
-  ~ClientChannel() override;
-
-  static std::unique_ptr<pdx::ClientChannel> Create(
-      LocalChannelHandle channel_handle);
-
-  uint32_t GetIpcTag() const override { return Endpoint::kIpcTag; }
-
-  int event_fd() const override {
-    return channel_data_ ? channel_data_->event_fd().Get() : -1;
-  }
-
-  std::vector<EventSource> GetEventSources() const override {
-    if (channel_data_)
-      return channel_data_->GetEventSources();
-    else
-      return {};
-  }
-
-  Status<int> GetEventMask(int /*events*/) override {
-    if (channel_data_)
-      return channel_data_->GetPendingEvents();
-    else
-      return ErrorStatus(EINVAL);
-  }
-
-  LocalChannelHandle& GetChannelHandle() override { return channel_handle_; }
-  const LocalChannelHandle& GetChannelHandle() const override {
-    return channel_handle_;
-  }
-  void* AllocateTransactionState() override;
-  void FreeTransactionState(void* state) override;
-
-  Status<void> SendImpulse(int opcode, const void* buffer,
-                           size_t length) override;
-
-  Status<int> SendWithInt(void* transaction_state, int opcode,
-                          const iovec* send_vector, size_t send_count,
-                          const iovec* receive_vector,
-                          size_t receive_count) override;
-  Status<LocalHandle> SendWithFileHandle(void* transaction_state, int opcode,
-                                         const iovec* send_vector,
-                                         size_t send_count,
-                                         const iovec* receive_vector,
-                                         size_t receive_count) override;
-  Status<LocalChannelHandle> SendWithChannelHandle(
-      void* transaction_state, int opcode, const iovec* send_vector,
-      size_t send_count, const iovec* receive_vector,
-      size_t receive_count) override;
-
-  FileReference PushFileHandle(void* transaction_state,
-                               const LocalHandle& handle) override;
-  FileReference PushFileHandle(void* transaction_state,
-                               const BorrowedHandle& handle) override;
-  ChannelReference PushChannelHandle(void* transaction_state,
-                                     const LocalChannelHandle& handle) override;
-  ChannelReference PushChannelHandle(
-      void* transaction_state, const BorrowedChannelHandle& handle) override;
-  bool GetFileHandle(void* transaction_state, FileReference ref,
-                     LocalHandle* handle) const override;
-  bool GetChannelHandle(void* transaction_state, ChannelReference ref,
-                        LocalChannelHandle* handle) const override;
-
-  std::unique_ptr<pdx::ChannelParcelable> TakeChannelParcelable() override;
-
- private:
-  explicit ClientChannel(LocalChannelHandle channel_handle);
-
-  Status<int> SendAndReceive(void* transaction_state, int opcode,
-                             const iovec* send_vector, size_t send_count,
-                             const iovec* receive_vector, size_t receive_count);
-
-  LocalChannelHandle channel_handle_;
-  ChannelEventReceiver* channel_data_;
-  std::mutex socket_mutex_;
-};
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_UDS_CLIENT_CHANNEL_H_
diff --git a/libs/vr/libpdx_uds/private/uds/client_channel_factory.h b/libs/vr/libpdx_uds/private/uds/client_channel_factory.h
deleted file mode 100644
index c43c5c7..0000000
--- a/libs/vr/libpdx_uds/private/uds/client_channel_factory.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef ANDROID_PDX_UDS_CLIENT_CHANNEL_FACTORY_H_
-#define ANDROID_PDX_UDS_CLIENT_CHANNEL_FACTORY_H_
-
-#include <string>
-
-#include <pdx/client_channel_factory.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class ClientChannelFactory : public pdx::ClientChannelFactory {
- public:
-  static std::unique_ptr<pdx::ClientChannelFactory> Create(
-      const std::string& endpoint_path);
-  static std::unique_ptr<pdx::ClientChannelFactory> Create(LocalHandle socket);
-
-  Status<std::unique_ptr<pdx::ClientChannel>> Connect(
-      int64_t timeout_ms) const override;
-
-  static std::string GetRootEndpointPath();
-  static std::string GetEndpointPath(const std::string& endpoint_path);
-
- private:
-  explicit ClientChannelFactory(const std::string& endpoint_path);
-  explicit ClientChannelFactory(LocalHandle socket);
-
-  mutable LocalHandle socket_;
-  std::string endpoint_path_;
-};
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_UDS_CLIENT_CHANNEL_FACTORY_H_
diff --git a/libs/vr/libpdx_uds/private/uds/ipc_helper.h b/libs/vr/libpdx_uds/private/uds/ipc_helper.h
deleted file mode 100644
index 704a569..0000000
--- a/libs/vr/libpdx_uds/private/uds/ipc_helper.h
+++ /dev/null
@@ -1,222 +0,0 @@
-#ifndef ANDROID_PDX_UDS_IPC_HELPER_H_
-#define ANDROID_PDX_UDS_IPC_HELPER_H_
-
-#include <sys/socket.h>
-#include <utility>
-#include <vector>
-
-#include <pdx/rpc/serializable.h>
-#include <pdx/rpc/serialization.h>
-#include <pdx/status.h>
-#include <pdx/utility.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-// Test interfaces used for unit-testing payload sending/receiving over sockets.
-class SendInterface {
- public:
-  virtual ssize_t Send(int socket_fd, const void* data, size_t size,
-                       int flags) = 0;
-  virtual ssize_t SendMessage(int socket_fd, const msghdr* msg, int flags) = 0;
-
- protected:
-  virtual ~SendInterface() = default;
-};
-
-class RecvInterface {
- public:
-  virtual ssize_t Receive(int socket_fd, void* data, size_t size,
-                          int flags) = 0;
-  virtual ssize_t ReceiveMessage(int socket_fd, msghdr* msg, int flags) = 0;
-
- protected:
-  virtual ~RecvInterface() = default;
-};
-
-// Helper methods that allow to send/receive data through abstract interfaces.
-// Useful for mocking out the underlying socket I/O.
-Status<void> SendAll(SendInterface* sender, const BorrowedHandle& socket_fd,
-                     const void* data, size_t size);
-Status<void> SendMsgAll(SendInterface* sender, const BorrowedHandle& socket_fd,
-                        const msghdr* msg);
-Status<void> RecvAll(RecvInterface* receiver, const BorrowedHandle& socket_fd,
-                     void* data, size_t size);
-Status<void> RecvMsgAll(RecvInterface* receiver,
-                        const BorrowedHandle& socket_fd, msghdr* msg);
-
-#define RETRY_EINTR(fnc_call)                 \
-  ([&]() -> decltype(fnc_call) {              \
-    decltype(fnc_call) result;                \
-    do {                                      \
-      result = (fnc_call);                    \
-    } while (result == -1 && errno == EINTR); \
-    return result;                            \
-  })()
-
-class SendPayload : public MessageWriter, public OutputResourceMapper {
- public:
-  explicit SendPayload(SendInterface* sender = nullptr) : sender_{sender} {}
-  Status<void> Send(const BorrowedHandle& socket_fd);
-  Status<void> Send(const BorrowedHandle& socket_fd, const ucred* cred,
-                    const iovec* data_vec = nullptr, size_t vec_count = 0);
-
-  // MessageWriter
-  void* GetNextWriteBufferSection(size_t size) override;
-  OutputResourceMapper* GetOutputResourceMapper() override;
-
-  // OutputResourceMapper
-  Status<FileReference> PushFileHandle(const LocalHandle& handle) override;
-  Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override;
-  Status<FileReference> PushFileHandle(const RemoteHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      const LocalChannelHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      const BorrowedChannelHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      const RemoteChannelHandle& handle) override;
-
- private:
-  SendInterface* sender_;
-  ByteBuffer buffer_;
-  std::vector<int> file_handles_;
-};
-
-class ReceivePayload : public MessageReader, public InputResourceMapper {
- public:
-  explicit ReceivePayload(RecvInterface* receiver = nullptr)
-      : receiver_{receiver} {}
-  Status<void> Receive(const BorrowedHandle& socket_fd);
-  Status<void> Receive(const BorrowedHandle& socket_fd, ucred* cred);
-
-  // MessageReader
-  BufferSection GetNextReadBufferSection() override;
-  void ConsumeReadBufferSectionData(const void* new_start) override;
-  InputResourceMapper* GetInputResourceMapper() override;
-
-  // InputResourceMapper
-  bool GetFileHandle(FileReference ref, LocalHandle* handle) override;
-  bool GetChannelHandle(ChannelReference ref,
-                        LocalChannelHandle* handle) override;
-
- private:
-  RecvInterface* receiver_;
-  ByteBuffer buffer_;
-  std::vector<LocalHandle> file_handles_;
-  size_t read_pos_{0};
-};
-
-template <typename FileHandleType>
-class ChannelInfo {
- public:
-  FileHandleType data_fd;
-  FileHandleType pollin_event_fd;
-  FileHandleType pollhup_event_fd;
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(ChannelInfo, data_fd, pollin_event_fd,
-                           pollhup_event_fd);
-};
-
-template <typename FileHandleType>
-class ChannelConnectionInfo {
- public:
-  FileHandleType channel_fd;
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(ChannelConnectionInfo, channel_fd);
-};
-
-template <typename FileHandleType>
-class RequestHeader {
- public:
-  int32_t op{0};
-  ucred cred;
-  uint32_t send_len{0};
-  uint32_t max_recv_len{0};
-  std::vector<FileHandleType> file_descriptors;
-  std::vector<ChannelInfo<FileHandleType>> channels;
-  std::array<uint8_t, 32> impulse_payload;
-  bool is_impulse{false};
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(RequestHeader, op, send_len, max_recv_len,
-                           file_descriptors, channels, impulse_payload,
-                           is_impulse);
-};
-
-template <typename FileHandleType>
-class ResponseHeader {
- public:
-  int32_t ret_code{0};
-  uint32_t recv_len{0};
-  std::vector<FileHandleType> file_descriptors;
-  std::vector<ChannelInfo<FileHandleType>> channels;
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(ResponseHeader, ret_code, recv_len, file_descriptors,
-                           channels);
-};
-
-template <typename T>
-inline Status<void> SendData(const BorrowedHandle& socket_fd, const T& data,
-                             const iovec* data_vec = nullptr,
-                             size_t vec_count = 0) {
-  SendPayload payload;
-  rpc::Serialize(data, &payload);
-  return payload.Send(socket_fd, nullptr, data_vec, vec_count);
-}
-
-template <typename FileHandleType>
-inline Status<void> SendData(const BorrowedHandle& socket_fd,
-                             const RequestHeader<FileHandleType>& request,
-                             const iovec* data_vec = nullptr,
-                             size_t vec_count = 0) {
-  SendPayload payload;
-  rpc::Serialize(request, &payload);
-  return payload.Send(socket_fd, &request.cred, data_vec, vec_count);
-}
-
-Status<void> SendData(const BorrowedHandle& socket_fd, const void* data,
-                      size_t size);
-Status<void> SendDataVector(const BorrowedHandle& socket_fd, const iovec* data,
-                            size_t count);
-
-template <typename T>
-inline Status<void> ReceiveData(const BorrowedHandle& socket_fd, T* data) {
-  ReceivePayload payload;
-  Status<void> status = payload.Receive(socket_fd);
-  if (status && rpc::Deserialize(data, &payload) != rpc::ErrorCode::NO_ERROR)
-    status.SetError(EIO);
-  return status;
-}
-
-template <typename FileHandleType>
-inline Status<void> ReceiveData(const BorrowedHandle& socket_fd,
-                                RequestHeader<FileHandleType>* request) {
-  ReceivePayload payload;
-  Status<void> status = payload.Receive(socket_fd, &request->cred);
-  if (status && rpc::Deserialize(request, &payload) != rpc::ErrorCode::NO_ERROR)
-    status.SetError(EIO);
-  return status;
-}
-
-Status<void> ReceiveData(const BorrowedHandle& socket_fd, void* data,
-                         size_t size);
-Status<void> ReceiveDataVector(const BorrowedHandle& socket_fd,
-                               const iovec* data, size_t count);
-
-size_t CountVectorSize(const iovec* data, size_t count);
-void InitRequest(android::pdx::uds::RequestHeader<BorrowedHandle>* request,
-                 int opcode, uint32_t send_len, uint32_t max_recv_len,
-                 bool is_impulse);
-
-Status<void> WaitForEndpoint(const std::string& endpoint_path,
-                             int64_t timeout_ms);
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_UDS_IPC_HELPER_H_
diff --git a/libs/vr/libpdx_uds/private/uds/service_endpoint.h b/libs/vr/libpdx_uds/private/uds/service_endpoint.h
deleted file mode 100644
index 50fc484..0000000
--- a/libs/vr/libpdx_uds/private/uds/service_endpoint.h
+++ /dev/null
@@ -1,168 +0,0 @@
-#ifndef ANDROID_PDX_UDS_SERVICE_ENDPOINT_H_
-#define ANDROID_PDX_UDS_SERVICE_ENDPOINT_H_
-
-#include <sys/stat.h>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include <pdx/service.h>
-#include <pdx/service_endpoint.h>
-#include <uds/channel_event_set.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class Endpoint : public pdx::Endpoint {
- public:
-  enum {
-    kIpcTag = 0x00736674,  // 'uds'
-  };
-
-  // Blocking modes for service endpoint. Controls whether the epoll set is in
-  // blocking mode or not for message receive.
-  enum {
-    kBlocking = true,
-    kNonBlocking = false,
-    kDefaultBlocking = kNonBlocking,
-  };
-
-  enum : mode_t {
-    kDefaultMode = 0,
-  };
-
-  ~Endpoint() override = default;
-
-  uint32_t GetIpcTag() const override { return kIpcTag; }
-  Status<void> SetService(Service* service) override;
-  Status<void> SetChannel(int channel_id, Channel* channel) override;
-  Status<void> CloseChannel(int channel_id) override;
-  Status<void> ModifyChannelEvents(int channel_id, int clear_mask,
-                                   int set_mask) override;
-  Status<RemoteChannelHandle> PushChannel(Message* message, int flags,
-                                          Channel* channel,
-                                          int* channel_id) override;
-  Status<int> CheckChannel(const Message* message, ChannelReference ref,
-                           Channel** channel) override;
-  Status<void> MessageReceive(Message* message) override;
-  Status<void> MessageReply(Message* message, int return_code) override;
-  Status<void> MessageReplyFd(Message* message, unsigned int push_fd) override;
-  Status<void> MessageReplyChannelHandle(
-      Message* message, const LocalChannelHandle& handle) override;
-  Status<void> MessageReplyChannelHandle(
-      Message* message, const BorrowedChannelHandle& handle) override;
-  Status<void> MessageReplyChannelHandle(
-      Message* message, const RemoteChannelHandle& handle) override;
-  Status<size_t> ReadMessageData(Message* message, const iovec* vector,
-                                 size_t vector_length) override;
-  Status<size_t> WriteMessageData(Message* message, const iovec* vector,
-                                  size_t vector_length) override;
-  Status<FileReference> PushFileHandle(Message* message,
-                                       const LocalHandle& handle) override;
-  Status<FileReference> PushFileHandle(Message* message,
-                                       const BorrowedHandle& handle) override;
-  Status<FileReference> PushFileHandle(Message* message,
-                                       const RemoteHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      Message* message, const LocalChannelHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      Message* message, const BorrowedChannelHandle& handle) override;
-  Status<ChannelReference> PushChannelHandle(
-      Message* message, const RemoteChannelHandle& handle) override;
-  LocalHandle GetFileHandle(Message* message, FileReference ref) const override;
-  LocalChannelHandle GetChannelHandle(Message* message,
-                                      ChannelReference ref) const override;
-
-  void* AllocateMessageState() override;
-  void FreeMessageState(void* state) override;
-
-  Status<void> Cancel() override;
-
-  // Open an endpoint at the given path.
-  // Second parameter is unused for UDS, but we have it here for compatibility
-  // in signature with servicefs::Endpoint::Create().
-  // This method uses |endpoint_path| as a relative path to endpoint socket
-  // created by init process.
-  static std::unique_ptr<Endpoint> Create(const std::string& endpoint_path,
-                                          mode_t /*unused_mode*/ = kDefaultMode,
-                                          bool blocking = kDefaultBlocking);
-
-  // Helper method to create an endpoint at the given UDS socket path. This
-  // method physically creates and binds a socket at that path.
-  static std::unique_ptr<Endpoint> CreateAndBindSocket(
-      const std::string& endpoint_path, bool blocking = kDefaultBlocking);
-
-  // Helper method to create an endpoint from an existing socket FD.
-  // Mostly helpful for tests.
-  static std::unique_ptr<Endpoint> CreateFromSocketFd(LocalHandle socket_fd);
-
-  // Test helper method to register a new channel identified by |channel_fd|
-  // socket file descriptor.
-  Status<void> RegisterNewChannelForTests(LocalHandle channel_fd);
-
-  int epoll_fd() const override { return epoll_fd_.Get(); }
-
- private:
-  struct ChannelData {
-    LocalHandle data_fd;
-    ChannelEventSet event_set;
-    Channel* channel_state{nullptr};
-  };
-
-  // This class must be instantiated using Create() static methods above.
-  Endpoint(const std::string& endpoint_path, bool blocking,
-           bool use_init_socket_fd = true);
-  explicit Endpoint(LocalHandle socket_fd);
-
-  void Init(LocalHandle socket_fd);
-
-  Endpoint(const Endpoint&) = delete;
-  void operator=(const Endpoint&) = delete;
-
-  uint32_t GetNextAvailableMessageId() {
-    return next_message_id_.fetch_add(1, std::memory_order_relaxed);
-  }
-
-  void BuildCloseMessage(int32_t channel_id, Message* message);
-
-  Status<void> AcceptConnection(Message* message);
-  Status<void> ReceiveMessageForChannel(const BorrowedHandle& channel_fd,
-                                        Message* message);
-  Status<void> OnNewChannel(LocalHandle channel_fd);
-  Status<std::pair<int32_t, ChannelData*>> OnNewChannelLocked(
-      LocalHandle channel_fd, Channel* channel_state);
-  Status<void> CloseChannelLocked(int32_t channel_id);
-  Status<void> ReenableEpollEvent(const BorrowedHandle& channel_fd);
-  Channel* GetChannelState(int32_t channel_id);
-  BorrowedHandle GetChannelSocketFd(int32_t channel_id);
-  Status<std::pair<BorrowedHandle, BorrowedHandle>> GetChannelEventFd(
-      int32_t channel_id);
-  int32_t GetChannelId(const BorrowedHandle& channel_fd);
-  Status<void> CreateChannelSocketPair(LocalHandle* local_socket,
-                                       LocalHandle* remote_socket);
-
-  std::string endpoint_path_;
-  bool is_blocking_;
-  LocalHandle socket_fd_;
-  LocalHandle cancel_event_fd_;
-  LocalHandle epoll_fd_;
-
-  mutable std::mutex channel_mutex_;
-  std::map<int32_t, ChannelData> channels_;
-  std::map<int, int32_t> channel_fd_to_id_;
-  int32_t last_channel_id_{0};
-
-  Service* service_{nullptr};
-  std::atomic<uint32_t> next_message_id_;
-};
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
-
-#endif  // ANDROID_PDX_UDS_PDX_SERVICE_ENDPOINT_H_
diff --git a/libs/vr/libpdx_uds/remote_method_tests.cpp b/libs/vr/libpdx_uds/remote_method_tests.cpp
deleted file mode 100644
index 4f0670e..0000000
--- a/libs/vr/libpdx_uds/remote_method_tests.cpp
+++ /dev/null
@@ -1,951 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <array>
-#include <cstdint>
-#include <memory>
-#include <numeric>
-#include <string>
-#include <thread>
-
-#include <gtest/gtest.h>
-#include <pdx/channel_handle.h>
-#include <pdx/client.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/rpc/serializable.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-#include <uds/client_channel.h>
-#include <uds/client_channel_factory.h>
-#include <uds/service_endpoint.h>
-
-using android::pdx::BorrowedHandle;
-using android::pdx::Channel;
-using android::pdx::ClientBase;
-using android::pdx::ErrorStatus;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Message;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::RemoteHandle;
-using android::pdx::ServiceBase;
-using android::pdx::ServiceDispatcher;
-using android::pdx::Status;
-using android::pdx::uds::Endpoint;
-using namespace android::pdx::rpc;
-
-namespace {
-
-std::string Rot13(const std::string& s) {
-  std::string text = s;
-  std::transform(std::begin(text), std::end(text), std::begin(text),
-                 [](char c) -> char {
-                   if (!std::isalpha(c)) {
-                     return c;
-                   } else {
-                     const char pivot = std::isupper(c) ? 'A' : 'a';
-                     return (c - pivot + 13) % 26 + pivot;
-                   }
-                 });
-  return text;
-}
-
-// Defines a serializable user type that may be transferred between client and
-// service.
-struct TestType {
-  int a;
-  float b;
-  std::string c;
-
-  TestType() {}
-  TestType(int a, float b, const std::string& c) : a(a), b(b), c(c) {}
-
-  // Make gtest expressions simpler by defining equality operator. This is not
-  // needed for serialization.
-  bool operator==(const TestType& other) const {
-    return a == other.a && b == other.b && c == other.c;
-  }
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(TestType, a, b, c);
-};
-
-struct DerivedTestType : public TestType {
-  DerivedTestType() : TestType() {}
-  DerivedTestType(int a, float b) : TestType(a, b, "constant") {}
-};
-
-// Defines a serializable user type with a LocalHandle member.
-struct TestFdType {
-  int a;
-  LocalHandle fd;
-
-  TestFdType() {}
-  TestFdType(int a, LocalHandle fd) : a(a), fd(std::move(fd)) {}
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(TestFdType, a, fd);
-};
-
-// Defines a serializable user template type with a FileHandle member.
-template <typename FileHandleType>
-struct TestTemplateType {
-  FileHandleType fd;
-
-  TestTemplateType() {}
-  explicit TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(TestTemplateType<FileHandleType>, fd);
-};
-
-struct BasicStruct {
-  int a;
-  int b;
-  std::string c;
-
- private:
-  PDX_SERIALIZABLE_MEMBERS(BasicStruct, a, b, c);
-};
-
-using BasicStructTraits = SerializableTraits<BasicStruct>;
-
-struct NonSerializableType {
-  int a;
-  int b;
-  std::string c;
-};
-
-struct IncorrectlyDefinedSerializableType {
-  int a;
-  int b;
-
- private:
-  using SerializableMembers = std::tuple<int, int>;
-};
-
-// Defines the contract between the client and service, including ServiceFS
-// endpoint path, method opcodes, and remote method signatures.
-struct TestInterface final {
-  // Service path.
-  static constexpr char kClientPath[] = "socket_test";
-
-  // Op codes.
-  enum {
-    kOpAdd = 0,
-    kOpFoo,
-    kOpConcatenate,
-    kOpWriteBuffer,
-    kOpStringLength,
-    kOpSendTestType,
-    kOpSendBasicStruct,
-    kOpSendVector,
-    kOpRot13,
-    kOpNoArgs,
-    kOpSendFile,
-    kOpGetFile,
-    kOpGetTestFdType,
-    kOpOpenFiles,
-    kOpReadFile,
-    kOpPushChannel,
-    kOpPositive,
-  };
-
-  // Methods.
-  PDX_REMOTE_METHOD(Add, kOpAdd, int(int, int));
-  PDX_REMOTE_METHOD(Foo, kOpFoo, int(int, const std::string&));
-  PDX_REMOTE_METHOD(Concatenate, kOpConcatenate,
-                    std::string(const std::string&, const std::string&));
-  PDX_REMOTE_METHOD(SumVector, kOpWriteBuffer, int(const std::vector<int>&));
-  PDX_REMOTE_METHOD(StringLength, kOpStringLength, int(const std::string&));
-  PDX_REMOTE_METHOD(SendTestType, kOpSendTestType, TestType(const TestType&));
-  PDX_REMOTE_METHOD(SendBasicStruct, kOpSendBasicStruct,
-                    BasicStruct(const BasicStruct&));
-  PDX_REMOTE_METHOD(SendVector, kOpSendVector,
-                    std::string(const std::vector<TestType>&));
-  PDX_REMOTE_METHOD(Rot13, kOpRot13, std::string(const std::string&));
-  PDX_REMOTE_METHOD(NoArgs, kOpNoArgs, int(Void));
-  PDX_REMOTE_METHOD(SendFile, kOpSendFile, int(const LocalHandle& fd));
-  PDX_REMOTE_METHOD(GetFile, kOpGetFile, LocalHandle(const std::string&, int));
-  PDX_REMOTE_METHOD(GetTestFdType, kOpGetTestFdType,
-                    TestFdType(int, const std::string&, int));
-  PDX_REMOTE_METHOD(OpenFiles, kOpOpenFiles,
-                    std::vector<LocalHandle>(
-                        const std::vector<std::pair<std::string, int>>&));
-  PDX_REMOTE_METHOD(ReadFile, kOpReadFile,
-                    std::pair<int, BufferWrapper<std::uint8_t*>>(
-                        const std::string&, int, std::size_t));
-  PDX_REMOTE_METHOD(PushChannel, kOpPushChannel, LocalChannelHandle(Void));
-  PDX_REMOTE_METHOD(Positive, kOpPositive, void(int));
-
-  PDX_REMOTE_API(API, Add, Foo, Concatenate, SumVector, StringLength,
-                 SendTestType, SendVector, Rot13, NoArgs, SendFile, GetFile,
-                 GetTestFdType, OpenFiles, PushChannel, Positive);
-};
-
-constexpr char TestInterface::kClientPath[];
-
-// Test client to send messages to the test service.
-class TestClient : public ClientBase<TestClient> {
- public:
-  int Add(int a, int b) {
-    return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::Add>(a, b));
-  }
-
-  int Foo(int a, const std::string& b) {
-    return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::Foo>(a, b));
-  }
-
-  std::string Concatenate(const std::string& a, const std::string& b) {
-    std::string return_value;
-
-    Status<std::string> status =
-        InvokeRemoteMethod<TestInterface::Concatenate>(a, b);
-    if (!status)
-      return std::string("[Error]");
-    else
-      return status.take();
-  }
-
-  int SumVector(const int* buffer, std::size_t size) {
-    return ReturnStatusOrError(
-        InvokeRemoteMethod<TestInterface::SumVector>(WrapArray(buffer, size)));
-  }
-
-  int SumVector(const std::vector<int>& buffer) {
-    return ReturnStatusOrError(
-        InvokeRemoteMethod<TestInterface::SumVector>(buffer));
-  }
-
-  int StringLength(const char* string, std::size_t size) {
-    return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::StringLength>(
-        WrapString(string, size)));
-  }
-
-  int StringLength(const std::string& string) {
-    return ReturnStatusOrError(
-        InvokeRemoteMethod<TestInterface::StringLength>(string));
-  }
-
-  TestType SendTestType(const TestType& tt) {
-    Status<TestType> status =
-        InvokeRemoteMethod<TestInterface::SendTestType>(tt);
-    if (!status)
-      return TestType(0, 0.0, "[Error]");
-    else
-      return status.take();
-  }
-
-  BasicStruct SendBasicStruct(const BasicStruct& bs) {
-    Status<BasicStruct> status =
-        InvokeRemoteMethod<TestInterface::SendBasicStruct>(bs);
-    if (!status)
-      return BasicStruct{0, 0, "[Error]"};
-    else
-      return status.take();
-  }
-
-  std::string SendVector(const std::vector<TestType>& v) {
-    Status<std::string> status =
-        InvokeRemoteMethod<TestInterface::SendVector>(v);
-    if (!status)
-      return "[Error]";
-    else
-      return status.take();
-  }
-
-  std::string Rot13(const std::string& string) {
-    Status<std::string> status =
-        InvokeRemoteMethod<TestInterface::Rot13>(string);
-    return status ? status.get() : string;
-  }
-
-  int NoArgs() {
-    return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::NoArgs>());
-  }
-
-  int SendFile(const LocalHandle& fd) {
-    return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::SendFile>(fd));
-  }
-
-  LocalHandle GetFile(const std::string& path, int mode) {
-    Status<LocalHandle> status =
-        InvokeRemoteMethod<TestInterface::GetFile>(path, mode);
-    if (!status)
-      return LocalHandle(-status.error());
-    else
-      return status.take();
-  }
-
-  int GetFile(const std::string& path, int mode, LocalHandle* fd_out) {
-    Status<void> status =
-        InvokeRemoteMethodInPlace<TestInterface::GetFile>(fd_out, path, mode);
-    return status ? 0 : -status.error();
-  }
-
-  TestFdType GetTestFdType(int a, const std::string& path, int mode) {
-    Status<TestFdType> status =
-        InvokeRemoteMethod<TestInterface::GetTestFdType>(a, path, mode);
-    if (!status)
-      return {};
-    else
-      return status.take();
-  }
-
-  std::vector<LocalHandle> OpenFiles(
-      const std::vector<std::pair<std::string, int>>& file_specs) {
-    Status<std::vector<LocalHandle>> status =
-        InvokeRemoteMethod<TestInterface::OpenFiles>(file_specs);
-    if (!status)
-      return {};
-    else
-      return status.take();
-  }
-
-  int ReadFile(void* buffer, std::size_t size, const std::string& path,
-               int mode) {
-    auto buffer_wrapper = WrapBuffer(buffer, size);
-    auto return_value = std::make_pair(-1, buffer_wrapper);
-
-    Status<void> status = InvokeRemoteMethodInPlace<TestInterface::ReadFile>(
-        &return_value, path, mode, size);
-    return status ? return_value.first : -status.error();
-  }
-
-  int PushChannel(LocalChannelHandle* fd_out) {
-    auto status = InvokeRemoteMethodInPlace<TestInterface::PushChannel>(fd_out);
-    return status ? 0 : -status.error();
-  }
-
-  bool Positive(int test_value) {
-    auto status = InvokeRemoteMethod<TestInterface::Positive>(test_value);
-    return status.ok();
-  }
-
-  int GetFd() const { return event_fd(); }
-
- private:
-  friend BASE;
-
-  explicit TestClient(LocalChannelHandle channel_handle)
-      : BASE{android::pdx::uds::ClientChannel::Create(
-            std::move(channel_handle))} {}
-  TestClient()
-      : BASE{android::pdx::uds::ClientChannelFactory::Create(
-            TestInterface::kClientPath)} {}
-
-  TestClient(const TestClient&) = delete;
-  void operator=(const TestClient&) = delete;
-};
-
-// Test service that encodes/decodes messages from clients.
-class TestService : public ServiceBase<TestService> {
- public:
-  Status<void> HandleMessage(Message& message) override {
-    switch (message.GetOp()) {
-      case TestInterface::Add::Opcode:
-        DispatchRemoteMethod<TestInterface::Add>(*this, &TestService::OnAdd,
-                                                 message);
-        return {};
-
-      case TestInterface::Foo::Opcode:
-        DispatchRemoteMethod<TestInterface::Foo>(*this, &TestService::OnFoo,
-                                                 message);
-        return {};
-
-      case TestInterface::Concatenate::Opcode:
-        DispatchRemoteMethod<TestInterface::Concatenate>(
-            *this, &TestService::OnConcatenate, message);
-        return {};
-
-      case TestInterface::SumVector::Opcode:
-        DispatchRemoteMethod<TestInterface::SumVector>(
-            *this, &TestService::OnSumVector, message);
-        return {};
-
-      case TestInterface::StringLength::Opcode:
-        DispatchRemoteMethod<TestInterface::StringLength>(
-            *this, &TestService::OnStringLength, message);
-        return {};
-
-      case TestInterface::SendTestType::Opcode:
-        DispatchRemoteMethod<TestInterface::SendTestType>(
-            *this, &TestService::OnSendTestType, message);
-        return {};
-
-      case TestInterface::SendVector::Opcode:
-        DispatchRemoteMethod<TestInterface::SendVector>(
-            *this, &TestService::OnSendVector, message);
-        return {};
-
-      case TestInterface::Rot13::Opcode:
-        DispatchRemoteMethod<TestInterface::Rot13>(*this, &TestService::OnRot13,
-                                                   message);
-        return {};
-
-      case TestInterface::NoArgs::Opcode:
-        DispatchRemoteMethod<TestInterface::NoArgs>(
-            *this, &TestService::OnNoArgs, message);
-        return {};
-
-      case TestInterface::SendFile::Opcode:
-        DispatchRemoteMethod<TestInterface::SendFile>(
-            *this, &TestService::OnSendFile, message);
-        return {};
-
-      case TestInterface::GetFile::Opcode:
-        DispatchRemoteMethod<TestInterface::GetFile>(
-            *this, &TestService::OnGetFile, message);
-        return {};
-
-      case TestInterface::GetTestFdType::Opcode:
-        DispatchRemoteMethod<TestInterface::GetTestFdType>(
-            *this, &TestService::OnGetTestFdType, message);
-        return {};
-
-      case TestInterface::OpenFiles::Opcode:
-        DispatchRemoteMethod<TestInterface::OpenFiles>(
-            *this, &TestService::OnOpenFiles, message);
-        return {};
-
-      case TestInterface::ReadFile::Opcode:
-        DispatchRemoteMethod<TestInterface::ReadFile>(
-            *this, &TestService::OnReadFile, message);
-        return {};
-
-      case TestInterface::PushChannel::Opcode:
-        DispatchRemoteMethod<TestInterface::PushChannel>(
-            *this, &TestService::OnPushChannel, message);
-        return {};
-
-      case TestInterface::Positive::Opcode:
-        DispatchRemoteMethod<TestInterface::Positive>(
-            *this, &TestService::OnPositive, message);
-        return {};
-
-      default:
-        return Service::DefaultHandleMessage(message);
-    }
-  }
-
- private:
-  friend BASE;
-
-  TestService()
-      : BASE("TestService",
-             Endpoint::CreateAndBindSocket(TestInterface::kClientPath)) {}
-
-  int OnAdd(Message&, int a, int b) { return a + b; }
-
-  int OnFoo(Message&, int a, const std::string& b) { return a + b.length(); }
-
-  std::string OnConcatenate(Message&, const std::string& a,
-                            const std::string& b) {
-    return a + b;
-  }
-
-  int OnSumVector(Message&, const std::vector<int>& vector) {
-    return std::accumulate(vector.begin(), vector.end(), 0);
-  }
-
-  int OnStringLength(Message&, const std::string& string) {
-    return string.length();
-  }
-
-  TestType OnSendTestType(Message&, const TestType& tt) {
-    return TestType(tt.a + 20, tt.b - 2.0, tt.c + "foo");
-  }
-
-  std::string OnSendVector(Message&, const std::vector<TestType>& v) {
-    std::string return_value = "";
-
-    for (const auto& tt : v)
-      return_value += tt.c;
-
-    return return_value;
-  }
-
-  Status<std::string> OnRot13(Message&, const std::string& s) {
-    return {Rot13(s)};
-  }
-
-  int OnNoArgs(Message&) { return 1; }
-
-  int OnSendFile(Message&, const LocalHandle& fd) { return fd.Get(); }
-
-  LocalHandle OnGetFile(Message& message, const std::string& path, int mode) {
-    LocalHandle fd(path.c_str(), mode);
-    if (!fd)
-      message.ReplyError(errno);
-    return fd;
-  }
-
-  TestFdType OnGetTestFdType(Message& message, int a, const std::string& path,
-                             int mode) {
-    TestFdType return_value(a, LocalHandle(path, mode));
-    if (!return_value.fd)
-      message.ReplyError(errno);
-    return return_value;
-  }
-
-  std::vector<LocalHandle> OnOpenFiles(
-      Message&, const std::vector<std::pair<std::string, int>>& file_specs) {
-    std::vector<LocalHandle> return_value;
-    for (auto& spec : file_specs) {
-      LocalHandle fd(spec.first, spec.second);
-      if (fd)
-        return_value.emplace_back(std::move(fd));
-      else
-        return_value.emplace_back(-errno);
-    }
-    return return_value;
-  }
-
-  std::pair<int, BufferWrapper<std::vector<std::uint8_t>>> OnReadFile(
-      Message& message, const std::string& path, int mode, std::size_t length) {
-    std::pair<int, BufferWrapper<std::vector<std::uint8_t>>> return_value;
-    LocalHandle fd(path, mode);
-    if (!fd) {
-      message.ReplyError(errno);
-      return return_value;
-    }
-
-    return_value.second.reserve(length);
-    const int ret = read(fd.Get(), return_value.second.data(), length);
-    if (ret < 0) {
-      message.ReplyError(errno);
-      return return_value;
-    }
-
-    return_value.second.resize(ret);
-    return_value.first = ret;
-    return return_value;
-  }
-
-  RemoteChannelHandle OnPushChannel(Message& message) {
-    auto status = message.PushChannel(0, nullptr, nullptr);
-    if (!status) {
-      message.ReplyError(status.error());
-      return {};
-    }
-    return status.take();
-  }
-
-  Status<void> OnPositive(Message& /*message*/, int test_value) {
-    if (test_value >= 0)
-      return {};
-    else
-      return ErrorStatus(EINVAL);
-  }
-
-  TestService(const TestService&) = delete;
-  void operator=(const TestService&) = delete;
-};
-
-}  // anonymous namespace
-
-// Use a test fixture to ensure proper order of cleanup between clients,
-// services, and the dispatcher. As these objects are cleaned up in the same
-// thread, either the service or client must be destroyed before stopping the
-// dispatcher. The reason for this is that clients send blocking "close"
-// messages to their respective services on destruction. If this happens after
-// stopping the dispatcher the client destructor will get blocked waiting for a
-// reply that will never come. In normal use of the service framework this is
-// never an issue because clients and the dispatcher for the same service are
-// never destructed in the same thread (they live in different processes).
-class RemoteMethodTest : public ::testing::Test {
- protected:
-  std::unique_ptr<ServiceDispatcher> dispatcher_;
-  std::thread dispatch_thread_;
-
-  void SetUp() override {
-    // Create a dispatcher to handle messages to services.
-    dispatcher_ = android::pdx::ServiceDispatcher::Create();
-    ASSERT_NE(nullptr, dispatcher_);
-
-    // Start the message dispatch loop in a separate thread.
-    dispatch_thread_ = std::thread(
-        std::bind(&ServiceDispatcher::EnterDispatchLoop, dispatcher_.get()));
-  }
-
-  void TearDown() override {
-    if (dispatcher_) {
-      // Cancel the dispatcher and wait for the thread to terminate.
-      // Explicitly
-      // join the thread so that destruction doesn't deallocate the
-      // dispatcher
-      // before the thread finishes.
-      dispatcher_->SetCanceled(true);
-      dispatch_thread_.join();
-    }
-  }
-};
-
-// Test basic operation of TestService/TestClient classes.
-TEST_F(RemoteMethodTest, BasicClientService) {
-  // Create a test service and add it to the dispatcher.
-
-  auto service = TestService::Create();
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create();
-  ASSERT_NE(nullptr, client);
-
-  const int sum = client->Add(10, 25);
-  EXPECT_GE(35, sum);
-
-  const auto cat = client->Concatenate("This is a string", ", that it is.");
-  EXPECT_EQ("This is a string, that it is.", cat);
-
-  std::string alphabet = "abcdefghijklmnopqrstuvwxyz";
-  const auto rot13_alphabet = client->Rot13(alphabet);
-  EXPECT_EQ(Rot13(alphabet), rot13_alphabet);
-
-  const auto length = client->Foo(10, "123");
-  EXPECT_EQ(13, length);
-
-  const std::vector<int> vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-  const int vector_sum = client->SumVector(vector.data(), vector.size());
-  const int vector_sum2 = client->SumVector(vector);
-  EXPECT_EQ(std::accumulate(vector.begin(), vector.end(), 0), vector_sum);
-  EXPECT_EQ(std::accumulate(vector.begin(), vector.end(), 0), vector_sum2);
-
-  const auto string_length1 = client->StringLength("This is a string");
-  EXPECT_EQ(16, string_length1);
-
-  const auto string_length2 = client->StringLength("1234567890");
-  EXPECT_EQ(10, string_length2);
-
-  std::string string = "1234567890";
-  const auto string_length3 =
-      client->StringLength(string.c_str(), string.length());
-  EXPECT_EQ(10, string_length3);
-
-  TestType tt{10, 0.0, "string"};
-  const auto tt_result = client->SendTestType(tt);
-  EXPECT_EQ(TestType(30, -2.0, "stringfoo"), tt_result);
-
-  std::vector<TestType> ttv = {TestType(0, 0.0, "abc"),
-                               TestType(0, 0.0, "123")};
-  const std::string string_result = client->SendVector(ttv);
-  EXPECT_EQ("abc123", string_result);
-
-  const int int_result = client->NoArgs();
-  EXPECT_EQ(1, int_result);
-}
-
-TEST_F(RemoteMethodTest, LocalHandle) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create();
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create();
-  ASSERT_NE(nullptr, client);
-
-  LocalHandle fd("/dev/zero", O_RDONLY);
-  ASSERT_TRUE(fd.IsValid());
-
-  int fd_result = client->SendFile(fd);
-  EXPECT_LE(0, fd_result);
-  EXPECT_NE(fd.Get(), fd_result);
-  fd = LocalHandle(-3);
-  fd_result = client->SendFile(fd);
-  EXPECT_EQ(fd.Get(), fd_result);
-
-  fd = client->GetFile("/dev/zero", O_RDONLY);
-  ASSERT_TRUE(fd.IsValid()) << "Error code: " << fd.Get();
-
-  std::array<uint8_t, 10> buffer;
-  buffer.fill(1);
-  EXPECT_EQ(10, read(fd.Get(), buffer.data(), buffer.size()));
-  EXPECT_EQ(buffer, decltype(buffer){{0}});
-  fd.Close();
-
-  const int error = client->GetFile("/dev/zero", O_RDONLY, &fd);
-  EXPECT_EQ(0, error);
-  EXPECT_TRUE(fd.IsValid());
-
-  buffer.fill(1);
-  EXPECT_EQ(10, read(fd.Get(), buffer.data(), buffer.size()));
-  EXPECT_EQ(buffer, decltype(buffer){{0}});
-
-  /*
-    Seg fault.
-    fd = client->GetFile("/dev/foobar", O_RDONLY);
-    EXPECT_FALSE(fd.IsValid());
-   */
-}
-
-TEST_F(RemoteMethodTest, PushChannel) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create();
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create();
-  ASSERT_NE(nullptr, client);
-
-  // Get a new channel as an fd.
-  LocalChannelHandle channel;
-  const int ret = client->PushChannel(&channel);
-  EXPECT_EQ(0, ret);
-  EXPECT_TRUE(channel.valid());
-
-  // Create a new client from the channel.
-  auto client2 = TestClient::Create(std::move(channel));
-  ASSERT_NE(nullptr, client2);
-
-  // Test that the new channel works.
-  const int sum = client2->Add(10, 25);
-  EXPECT_GE(35, sum);
-}
-
-TEST_F(RemoteMethodTest, Positive) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create();
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create();
-  ASSERT_NE(nullptr, client);
-
-  ASSERT_TRUE(client->Positive(0));
-  ASSERT_TRUE(client->Positive(1));
-  ASSERT_FALSE(client->Positive(-1));
-}
-
-TEST_F(RemoteMethodTest, AggregateLocalHandle) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create();
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create();
-  ASSERT_NE(nullptr, client);
-
-  TestFdType result = client->GetTestFdType(10, "/dev/zero", O_RDONLY);
-  EXPECT_TRUE(result.fd.IsValid());
-  EXPECT_EQ(10, result.a);
-
-  std::vector<LocalHandle> files =
-      client->OpenFiles({{{"/dev/zero", O_RDONLY},
-                          {"/dev/null", O_WRONLY},
-                          {"/dev/zero", O_RDONLY}}});
-  ASSERT_EQ(3u, files.size());
-  EXPECT_TRUE(files[0].IsValid());
-  EXPECT_TRUE(files[1].IsValid());
-  EXPECT_TRUE(files[2].IsValid());
-}
-
-TEST_F(RemoteMethodTest, BufferWrapper) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create();
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create();
-  ASSERT_NE(nullptr, client);
-
-  const int buffer_size = 20;
-  std::vector<std::uint8_t> buffer(buffer_size, 'x');
-  std::vector<std::uint8_t> expected(buffer_size, 0);
-  int ret =
-      client->ReadFile(buffer.data(), buffer.size(), "/dev/zero", O_RDONLY);
-  EXPECT_EQ(buffer_size, ret);
-  EXPECT_EQ(expected, buffer);
-}
-
-//
-// RemoteMethodFramework: Tests the type-based framework that remote method
-// support is built upon.
-//
-
-// Test logical And template.
-TEST(RemoteMethodFramework, And) {
-  EXPECT_TRUE((And<std::true_type, std::true_type>::value));
-  EXPECT_FALSE((And<std::true_type, std::false_type>::value));
-  EXPECT_FALSE((And<std::false_type, std::true_type>::value));
-  EXPECT_FALSE((And<std::false_type, std::false_type>::value));
-
-  EXPECT_TRUE((And<std::true_type, std::true_type, std::true_type>::value));
-  EXPECT_FALSE((And<std::true_type, std::true_type, std::false_type>::value));
-  EXPECT_FALSE((And<std::true_type, std::false_type, std::true_type>::value));
-  EXPECT_FALSE((And<std::true_type, std::false_type, std::false_type>::value));
-  EXPECT_FALSE((And<std::false_type, std::true_type, std::true_type>::value));
-  EXPECT_FALSE((And<std::false_type, std::true_type, std::false_type>::value));
-  EXPECT_FALSE((And<std::false_type, std::false_type, std::true_type>::value));
-  EXPECT_FALSE((And<std::false_type, std::false_type, std::false_type>::value));
-}
-
-// Test convertible type constraints.
-TEST(RemoteMethodFramework, IsConvertible) {
-  // std::pair.
-  EXPECT_TRUE(
-      (IsConvertible<std::pair<int, float>, std::pair<int, float>>::value));
-  EXPECT_FALSE(
-      (IsConvertible<std::pair<int, float>, std::pair<float, float>>::value));
-  EXPECT_FALSE(
-      (IsConvertible<std::pair<int, float>, std::pair<float, int>>::value));
-
-  // Nested std::pair.
-  EXPECT_TRUE((IsConvertible<std::pair<std::pair<int, float>, float>,
-                             std::pair<std::pair<int, float>, float>>::value));
-  EXPECT_FALSE((IsConvertible<std::pair<std::pair<int, float>, float>,
-                              std::pair<std::pair<float, int>, float>>::value));
-
-  // std::tuple and std::pair.
-  EXPECT_TRUE(
-      (IsConvertible<std::pair<int, float>, std::tuple<int, float>>::value));
-  EXPECT_TRUE(
-      (IsConvertible<std::tuple<int, float>, std::pair<int, float>>::value));
-  EXPECT_FALSE(
-      (IsConvertible<std::pair<float, float>, std::tuple<int, float>>::value));
-  EXPECT_FALSE(
-      (IsConvertible<std::tuple<float, float>, std::pair<int, float>>::value));
-  EXPECT_FALSE(
-      (IsConvertible<std::pair<int, int>, std::tuple<int, float>>::value));
-  EXPECT_FALSE(
-      (IsConvertible<std::tuple<int, int>, std::pair<int, float>>::value));
-  EXPECT_FALSE(
-      (IsConvertible<std::pair<int, int>, std::tuple<int, int, int>>::value));
-  EXPECT_FALSE(
-      (IsConvertible<std::tuple<int, int, int>, std::pair<int, int>>::value));
-
-  // std::vector.
-  EXPECT_TRUE((IsConvertible<std::vector<int>, std::vector<int>>::value));
-  EXPECT_FALSE((IsConvertible<std::vector<int>, std::vector<float>>::value));
-
-  // Nested std::vector.
-  EXPECT_TRUE((IsConvertible<std::vector<std::pair<int, int>>,
-                             std::vector<std::pair<int, int>>>::value));
-  EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>,
-                              std::vector<std::pair<int, float>>>::value));
-  EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>,
-                              std::vector<std::pair<float, int>>>::value));
-  EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>,
-                              std::vector<std::pair<float, float>>>::value));
-
-  // std::vector with nested convertible types.
-  EXPECT_TRUE((IsConvertible<std::vector<StringWrapper<char>>,
-                             std::vector<std::string>>::value));
-
-  // std::map and std::unordered_map.
-  EXPECT_TRUE((IsConvertible<std::map<int, float>,
-                             std::unordered_map<int, float>>::value));
-  EXPECT_FALSE((IsConvertible<std::map<float, float>,
-                              std::unordered_map<int, float>>::value));
-  EXPECT_FALSE((IsConvertible<std::map<float, float>,
-                              std::unordered_map<float, int>>::value));
-  EXPECT_FALSE((IsConvertible<std::map<float, float>,
-                              std::unordered_map<int, int>>::value));
-  EXPECT_TRUE((IsConvertible<std::unordered_map<int, float>,
-                             std::map<int, float>>::value));
-  EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>,
-                              std::map<int, float>>::value));
-  EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>,
-                              std::map<float, int>>::value));
-  EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>,
-                              std::map<int, int>>::value));
-
-  // std::map with nested convertible types.
-  EXPECT_TRUE((IsConvertible<std::map<int, std::string>,
-                             std::map<int, StringWrapper<char>>>::value));
-  EXPECT_TRUE(
-      (IsConvertible<std::map<std::tuple<int, int>, std::string>,
-                     std::map<std::pair<int, int>, std::string>>::value));
-
-  // std::unordered_map with nested convertible types.
-  EXPECT_TRUE(
-      (IsConvertible<std::unordered_map<int, std::string>,
-                     std::unordered_map<int, StringWrapper<char>>>::value));
-  EXPECT_TRUE((IsConvertible<
-               std::unordered_map<std::tuple<int, int>, std::string>,
-               std::unordered_map<std::pair<int, int>, std::string>>::value));
-
-  // std::string.
-  EXPECT_TRUE((IsConvertible<std::string, std::string>::value));
-  EXPECT_FALSE((IsConvertible<std::string, int>::value));
-  EXPECT_FALSE((IsConvertible<int, std::string>::value));
-
-  // Nested std::string.
-  EXPECT_TRUE((IsConvertible<std::pair<std::string, std::string>,
-                             std::pair<std::string, std::string>>::value));
-  EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>,
-                              std::pair<std::string, int>>::value));
-  EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>,
-                              std::pair<int, std::string>>::value));
-  EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>,
-                              std::pair<int, int>>::value));
-
-  // StringWrapper.
-  EXPECT_TRUE((IsConvertible<StringWrapper<char>, StringWrapper<char>>::value));
-  EXPECT_TRUE((IsConvertible<StringWrapper<char>, std::string>::value));
-  EXPECT_TRUE((IsConvertible<std::string, StringWrapper<char>>::value));
-  EXPECT_FALSE((IsConvertible<StringWrapper<char>, int>::value));
-  EXPECT_FALSE(
-      (IsConvertible<StringWrapper<char>, BufferWrapper<char*>>::value));
-
-  // BufferWrapper.
-  EXPECT_TRUE(
-      (IsConvertible<BufferWrapper<char*>, BufferWrapper<char*>>::value));
-  EXPECT_TRUE(
-      (IsConvertible<BufferWrapper<char*>, BufferWrapper<const char*>>::value));
-  EXPECT_FALSE(
-      (IsConvertible<BufferWrapper<char*>, BufferWrapper<int*>>::value));
-  EXPECT_TRUE((IsConvertible<BufferWrapper<char*>,
-                             BufferWrapper<std::vector<char>>>::value));
-
-  // RemoteHandle and BorrowedHandle.
-  EXPECT_TRUE((IsConvertible<LocalHandle, RemoteHandle>::value));
-  EXPECT_TRUE((IsConvertible<LocalHandle, BorrowedHandle>::value));
-
-  // Test rewriting user defined types.
-  EXPECT_TRUE((IsConvertible<TestTemplateType<LocalHandle>,
-                             TestTemplateType<RemoteHandle>>::value));
-  EXPECT_TRUE((IsConvertible<TestTemplateType<LocalHandle>,
-                             TestTemplateType<BorrowedHandle>>::value));
-  EXPECT_FALSE((IsConvertible<TestTemplateType<RemoteHandle>,
-                              TestTemplateType<LocalHandle>>::value));
-  EXPECT_FALSE((IsConvertible<TestTemplateType<BorrowedHandle>,
-                              TestTemplateType<LocalHandle>>::value));
-
-  // TODO(eieio): More thorough testing of convertible types.
-}
-
-TEST(RemoteMethodFramework, SerializableMembers) {
-  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<LocalHandle>>::value);
-  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<RemoteHandle>>::value);
-  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<BorrowedHandle>>::value);
-
-  EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers<
-                  TestTemplateType<LocalHandle>>>::value);
-  EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers<
-                  TestTemplateType<RemoteHandle>>>::value);
-  EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers<
-                  TestTemplateType<BorrowedHandle>>>::value);
-
-  EXPECT_TRUE(HasSerializableMembers<DerivedTestType>::value);
-
-  EXPECT_TRUE(HasSerializableMembers<BasicStruct>::value);
-  EXPECT_TRUE(HasSerializableMembers<TestType>::value);
-  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<LocalHandle>>::value);
-  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<RemoteHandle>>::value);
-  EXPECT_TRUE(HasSerializableMembers<TestTemplateType<BorrowedHandle>>::value);
-  EXPECT_TRUE(HasSerializableMembers<DerivedTestType>::value);
-  EXPECT_FALSE(HasSerializableMembers<NonSerializableType>::value);
-  EXPECT_FALSE(
-      HasSerializableMembers<IncorrectlyDefinedSerializableType>::value);
-}
-
-TEST(RemoteMethodFramework, RemoteAPITypes) {
-  EXPECT_EQ(0u, TestInterface::API::MethodIndex<TestInterface::Add>());
-}
diff --git a/libs/vr/libpdx_uds/service_endpoint.cpp b/libs/vr/libpdx_uds/service_endpoint.cpp
deleted file mode 100644
index 810eb19..0000000
--- a/libs/vr/libpdx_uds/service_endpoint.cpp
+++ /dev/null
@@ -1,789 +0,0 @@
-#include "uds/service_endpoint.h"
-
-#include <poll.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <algorithm>  // std::min
-
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <cutils/sockets.h>
-#include <pdx/service.h>
-#include <selinux/selinux.h>
-#include <uds/channel_manager.h>
-#include <uds/client_channel_factory.h>
-#include <uds/ipc_helper.h>
-
-namespace {
-
-constexpr int kMaxBackLogForSocketListen = 1;
-
-using android::pdx::BorrowedChannelHandle;
-using android::pdx::BorrowedHandle;
-using android::pdx::ChannelReference;
-using android::pdx::ErrorStatus;
-using android::pdx::FileReference;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Status;
-using android::pdx::uds::ChannelInfo;
-using android::pdx::uds::ChannelManager;
-
-struct MessageState {
-  bool GetLocalFileHandle(int index, LocalHandle* handle) {
-    if (index < 0) {
-      handle->Reset(index);
-    } else if (static_cast<size_t>(index) < request.file_descriptors.size()) {
-      *handle = std::move(request.file_descriptors[index]);
-    } else {
-      return false;
-    }
-    return true;
-  }
-
-  bool GetLocalChannelHandle(int index, LocalChannelHandle* handle) {
-    if (index < 0) {
-      *handle = LocalChannelHandle{nullptr, index};
-    } else if (static_cast<size_t>(index) < request.channels.size()) {
-      auto& channel_info = request.channels[index];
-      *handle = ChannelManager::Get().CreateHandle(
-          std::move(channel_info.data_fd),
-          std::move(channel_info.pollin_event_fd),
-          std::move(channel_info.pollhup_event_fd));
-    } else {
-      return false;
-    }
-    return true;
-  }
-
-  Status<FileReference> PushFileHandle(BorrowedHandle handle) {
-    if (!handle)
-      return handle.Get();
-    response.file_descriptors.push_back(std::move(handle));
-    return response.file_descriptors.size() - 1;
-  }
-
-  Status<ChannelReference> PushChannelHandle(BorrowedChannelHandle handle) {
-    if (!handle)
-      return handle.value();
-
-    if (auto* channel_data =
-            ChannelManager::Get().GetChannelData(handle.value())) {
-      ChannelInfo<BorrowedHandle> channel_info{
-          channel_data->data_fd(), channel_data->pollin_event_fd(),
-          channel_data->pollhup_event_fd()};
-      response.channels.push_back(std::move(channel_info));
-      return response.channels.size() - 1;
-    } else {
-      return ErrorStatus{EINVAL};
-    }
-  }
-
-  Status<ChannelReference> PushChannelHandle(BorrowedHandle data_fd,
-                                             BorrowedHandle pollin_event_fd,
-                                             BorrowedHandle pollhup_event_fd) {
-    if (!data_fd || !pollin_event_fd || !pollhup_event_fd)
-      return ErrorStatus{EINVAL};
-    ChannelInfo<BorrowedHandle> channel_info{std::move(data_fd),
-                                             std::move(pollin_event_fd),
-                                             std::move(pollhup_event_fd)};
-    response.channels.push_back(std::move(channel_info));
-    return response.channels.size() - 1;
-  }
-
-  Status<size_t> WriteData(const iovec* vector, size_t vector_length) {
-    size_t size = 0;
-    for (size_t i = 0; i < vector_length; i++) {
-      const auto* data = reinterpret_cast<const uint8_t*>(vector[i].iov_base);
-      response_data.insert(response_data.end(), data, data + vector[i].iov_len);
-      size += vector[i].iov_len;
-    }
-    return size;
-  }
-
-  Status<size_t> ReadData(const iovec* vector, size_t vector_length) {
-    size_t size_remaining = request_data.size() - request_data_read_pos;
-    size_t size = 0;
-    for (size_t i = 0; i < vector_length && size_remaining > 0; i++) {
-      size_t size_to_copy = std::min(size_remaining, vector[i].iov_len);
-      memcpy(vector[i].iov_base, request_data.data() + request_data_read_pos,
-             size_to_copy);
-      size += size_to_copy;
-      request_data_read_pos += size_to_copy;
-      size_remaining -= size_to_copy;
-    }
-    return size;
-  }
-
-  android::pdx::uds::RequestHeader<LocalHandle> request;
-  android::pdx::uds::ResponseHeader<BorrowedHandle> response;
-  std::vector<LocalHandle> sockets_to_close;
-  std::vector<uint8_t> request_data;
-  size_t request_data_read_pos{0};
-  std::vector<uint8_t> response_data;
-};
-
-}  // anonymous namespace
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-Endpoint::Endpoint(const std::string& endpoint_path, bool blocking,
-                   bool use_init_socket_fd)
-    : endpoint_path_{ClientChannelFactory::GetEndpointPath(endpoint_path)},
-      is_blocking_{blocking} {
-  LocalHandle fd;
-  if (use_init_socket_fd) {
-    // Cut off the /dev/socket/ prefix from the full socket path and use the
-    // resulting "name" to retrieve the file descriptor for the socket created
-    // by the init process.
-    constexpr char prefix[] = "/dev/socket/";
-    CHECK(android::base::StartsWith(endpoint_path_, prefix))
-        << "Endpoint::Endpoint: Socket name '" << endpoint_path_
-        << "' must begin with '" << prefix << "'";
-    std::string socket_name = endpoint_path_.substr(sizeof(prefix) - 1);
-    fd.Reset(android_get_control_socket(socket_name.c_str()));
-    CHECK(fd.IsValid())
-        << "Endpoint::Endpoint: Unable to obtain the control socket fd for '"
-        << socket_name << "'";
-    fcntl(fd.Get(), F_SETFD, FD_CLOEXEC);
-  } else {
-    fd.Reset(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0));
-    CHECK(fd.IsValid()) << "Endpoint::Endpoint: Failed to create socket: "
-                        << strerror(errno);
-
-    sockaddr_un local;
-    local.sun_family = AF_UNIX;
-    strncpy(local.sun_path, endpoint_path_.c_str(), sizeof(local.sun_path));
-    local.sun_path[sizeof(local.sun_path) - 1] = '\0';
-
-    unlink(local.sun_path);
-    int ret =
-        bind(fd.Get(), reinterpret_cast<sockaddr*>(&local), sizeof(local));
-    CHECK_EQ(ret, 0) << "Endpoint::Endpoint: bind error: " << strerror(errno);
-  }
-  Init(std::move(fd));
-}
-
-Endpoint::Endpoint(LocalHandle socket_fd) { Init(std::move(socket_fd)); }
-
-void Endpoint::Init(LocalHandle socket_fd) {
-  if (socket_fd) {
-    CHECK_EQ(listen(socket_fd.Get(), kMaxBackLogForSocketListen), 0)
-        << "Endpoint::Endpoint: listen error: " << strerror(errno);
-  }
-  cancel_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-  CHECK(cancel_event_fd_.IsValid())
-      << "Endpoint::Endpoint: Failed to create event fd: " << strerror(errno);
-
-  epoll_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
-  CHECK(epoll_fd_.IsValid())
-      << "Endpoint::Endpoint: Failed to create epoll fd: " << strerror(errno);
-
-  if (socket_fd) {
-    epoll_event socket_event;
-    socket_event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
-    socket_event.data.fd = socket_fd.Get();
-    int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, socket_fd.Get(),
-                        &socket_event);
-    CHECK_EQ(ret, 0)
-        << "Endpoint::Endpoint: Failed to add socket fd to epoll fd: "
-        << strerror(errno);
-  }
-
-  epoll_event cancel_event;
-  cancel_event.events = EPOLLIN;
-  cancel_event.data.fd = cancel_event_fd_.Get();
-
-  int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, cancel_event_fd_.Get(),
-                      &cancel_event);
-  CHECK_EQ(ret, 0)
-      << "Endpoint::Endpoint: Failed to add cancel event fd to epoll fd: "
-      << strerror(errno);
-  socket_fd_ = std::move(socket_fd);
-}
-
-void* Endpoint::AllocateMessageState() { return new MessageState; }
-
-void Endpoint::FreeMessageState(void* state) {
-  delete static_cast<MessageState*>(state);
-}
-
-Status<void> Endpoint::AcceptConnection(Message* message) {
-  if (!socket_fd_)
-    return ErrorStatus(EBADF);
-
-  sockaddr_un remote;
-  socklen_t addrlen = sizeof(remote);
-  LocalHandle connection_fd{accept4(socket_fd_.Get(),
-                                    reinterpret_cast<sockaddr*>(&remote),
-                                    &addrlen, SOCK_CLOEXEC)};
-  if (!connection_fd) {
-    ALOGE("Endpoint::AcceptConnection: failed to accept connection: %s",
-          strerror(errno));
-    return ErrorStatus(errno);
-  }
-
-  LocalHandle local_socket;
-  LocalHandle remote_socket;
-  auto status = CreateChannelSocketPair(&local_socket, &remote_socket);
-  if (!status)
-    return status;
-
-  // Borrow the local channel handle before we move it into OnNewChannel().
-  BorrowedHandle channel_handle = local_socket.Borrow();
-  status = OnNewChannel(std::move(local_socket));
-  if (!status)
-    return status;
-
-  // Send the channel socket fd to the client.
-  ChannelConnectionInfo<LocalHandle> connection_info;
-  connection_info.channel_fd = std::move(remote_socket);
-  status = SendData(connection_fd.Borrow(), connection_info);
-
-  if (status) {
-    // Get the CHANNEL_OPEN message from client over the channel socket.
-    status = ReceiveMessageForChannel(channel_handle, message);
-  } else {
-    CloseChannel(GetChannelId(channel_handle));
-  }
-
-  // Don't need the connection socket anymore. Further communication should
-  // happen over the channel socket.
-  shutdown(connection_fd.Get(), SHUT_WR);
-  return status;
-}
-
-Status<void> Endpoint::SetService(Service* service) {
-  service_ = service;
-  return {};
-}
-
-Status<void> Endpoint::SetChannel(int channel_id, Channel* channel) {
-  std::lock_guard<std::mutex> autolock(channel_mutex_);
-  auto channel_data = channels_.find(channel_id);
-  if (channel_data == channels_.end())
-    return ErrorStatus{EINVAL};
-  channel_data->second.channel_state = channel;
-  return {};
-}
-
-Status<void> Endpoint::OnNewChannel(LocalHandle channel_fd) {
-  std::lock_guard<std::mutex> autolock(channel_mutex_);
-  Status<void> status;
-  status.PropagateError(OnNewChannelLocked(std::move(channel_fd), nullptr));
-  return status;
-}
-
-Status<std::pair<int32_t, Endpoint::ChannelData*>> Endpoint::OnNewChannelLocked(
-    LocalHandle channel_fd, Channel* channel_state) {
-  epoll_event event;
-  event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
-  event.data.fd = channel_fd.Get();
-  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, channel_fd.Get(), &event) < 0) {
-    ALOGE(
-        "Endpoint::OnNewChannelLocked: Failed to add channel to endpoint: %s\n",
-        strerror(errno));
-    return ErrorStatus(errno);
-  }
-  ChannelData channel_data;
-  channel_data.data_fd = std::move(channel_fd);
-  channel_data.channel_state = channel_state;
-  for (;;) {
-    // Try new channel IDs until we find one which is not already in the map.
-    if (last_channel_id_++ == std::numeric_limits<int32_t>::max())
-      last_channel_id_ = 1;
-    auto iter = channels_.lower_bound(last_channel_id_);
-    if (iter == channels_.end() || iter->first != last_channel_id_) {
-      channel_fd_to_id_.emplace(channel_data.data_fd.Get(), last_channel_id_);
-      iter = channels_.emplace_hint(iter, last_channel_id_,
-                                    std::move(channel_data));
-      return std::make_pair(last_channel_id_, &iter->second);
-    }
-  }
-}
-
-Status<void> Endpoint::ReenableEpollEvent(const BorrowedHandle& fd) {
-  epoll_event event;
-  event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
-  event.data.fd = fd.Get();
-  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_MOD, fd.Get(), &event) < 0) {
-    ALOGE(
-        "Endpoint::ReenableEpollEvent: Failed to re-enable channel to "
-        "endpoint: %s\n",
-        strerror(errno));
-    return ErrorStatus(errno);
-  }
-  return {};
-}
-
-Status<void> Endpoint::CloseChannel(int channel_id) {
-  std::lock_guard<std::mutex> autolock(channel_mutex_);
-  return CloseChannelLocked(channel_id);
-}
-
-Status<void> Endpoint::CloseChannelLocked(int32_t channel_id) {
-  ALOGD_IF(TRACE, "Endpoint::CloseChannelLocked: channel_id=%d", channel_id);
-
-  auto iter = channels_.find(channel_id);
-  if (iter == channels_.end())
-    return ErrorStatus{EINVAL};
-
-  int channel_fd = iter->second.data_fd.Get();
-  Status<void> status;
-  epoll_event ee;  // See BUGS in man 2 epoll_ctl.
-  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, channel_fd, &ee) < 0) {
-    status.SetError(errno);
-    ALOGE(
-        "Endpoint::CloseChannelLocked: Failed to remove channel from endpoint: "
-        "%s\n",
-        strerror(errno));
-  } else {
-    status.SetValue();
-  }
-
-  channel_fd_to_id_.erase(channel_fd);
-  channels_.erase(iter);
-  return status;
-}
-
-Status<void> Endpoint::ModifyChannelEvents(int channel_id, int clear_mask,
-                                           int set_mask) {
-  std::lock_guard<std::mutex> autolock(channel_mutex_);
-
-  auto search = channels_.find(channel_id);
-  if (search != channels_.end()) {
-    auto& channel_data = search->second;
-    channel_data.event_set.ModifyEvents(clear_mask, set_mask);
-    return {};
-  }
-
-  return ErrorStatus{EINVAL};
-}
-
-Status<void> Endpoint::CreateChannelSocketPair(LocalHandle* local_socket,
-                                               LocalHandle* remote_socket) {
-  Status<void> status;
-  char* endpoint_context = nullptr;
-  // Make sure the channel socket has the correct SELinux label applied.
-  // Here we get the label from the endpoint file descriptor, which should be
-  // something like "u:object_r:pdx_service_endpoint_socket:s0" and replace
-  // "endpoint" with "channel" to produce the channel label such as this:
-  // "u:object_r:pdx_service_channel_socket:s0".
-  if (fgetfilecon_raw(socket_fd_.Get(), &endpoint_context) > 0) {
-    std::string channel_context = endpoint_context;
-    freecon(endpoint_context);
-    const std::string suffix = "_endpoint_socket";
-    auto pos = channel_context.find(suffix);
-    if (pos != std::string::npos) {
-      channel_context.replace(pos, suffix.size(), "_channel_socket");
-    } else {
-      ALOGW(
-          "Endpoint::CreateChannelSocketPair: Endpoint security context '%s' "
-          "does not contain expected substring '%s'",
-          channel_context.c_str(), suffix.c_str());
-    }
-    ALOGE_IF(setsockcreatecon_raw(channel_context.c_str()) == -1,
-             "Endpoint::CreateChannelSocketPair: Failed to set channel socket "
-             "security context: %s",
-             strerror(errno));
-  } else {
-    ALOGE(
-        "Endpoint::CreateChannelSocketPair: Failed to obtain the endpoint "
-        "socket's security context: %s",
-        strerror(errno));
-  }
-
-  int channel_pair[2] = {};
-  if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, channel_pair) == -1) {
-    ALOGE("Endpoint::CreateChannelSocketPair: Failed to create socket pair: %s",
-          strerror(errno));
-    status.SetError(errno);
-    return status;
-  }
-
-  setsockcreatecon_raw(nullptr);
-
-  local_socket->Reset(channel_pair[0]);
-  remote_socket->Reset(channel_pair[1]);
-
-  int optval = 1;
-  if (setsockopt(local_socket->Get(), SOL_SOCKET, SO_PASSCRED, &optval,
-                 sizeof(optval)) == -1) {
-    ALOGE(
-        "Endpoint::CreateChannelSocketPair: Failed to enable the receiving of "
-        "the credentials for channel %d: %s",
-        local_socket->Get(), strerror(errno));
-    status.SetError(errno);
-  }
-  return status;
-}
-
-Status<RemoteChannelHandle> Endpoint::PushChannel(Message* message,
-                                                  int /*flags*/,
-                                                  Channel* channel,
-                                                  int* channel_id) {
-  LocalHandle local_socket;
-  LocalHandle remote_socket;
-  auto status = CreateChannelSocketPair(&local_socket, &remote_socket);
-  if (!status)
-    return status.error_status();
-
-  std::lock_guard<std::mutex> autolock(channel_mutex_);
-  auto channel_data_status =
-      OnNewChannelLocked(std::move(local_socket), channel);
-  if (!channel_data_status)
-    return channel_data_status.error_status();
-
-  ChannelData* channel_data;
-  std::tie(*channel_id, channel_data) = channel_data_status.take();
-
-  // Flags are ignored for now.
-  // TODO(xiaohuit): Implement those.
-
-  auto* state = static_cast<MessageState*>(message->GetState());
-  Status<ChannelReference> ref = state->PushChannelHandle(
-      remote_socket.Borrow(), channel_data->event_set.pollin_event_fd(),
-      channel_data->event_set.pollhup_event_fd());
-  if (!ref)
-    return ref.error_status();
-  state->sockets_to_close.push_back(std::move(remote_socket));
-  return RemoteChannelHandle{ref.get()};
-}
-
-Status<int> Endpoint::CheckChannel(const Message* /*message*/,
-                                   ChannelReference /*ref*/,
-                                   Channel** /*channel*/) {
-  // TODO(xiaohuit): Implement this.
-  return ErrorStatus(EFAULT);
-}
-
-Channel* Endpoint::GetChannelState(int32_t channel_id) {
-  std::lock_guard<std::mutex> autolock(channel_mutex_);
-  auto channel_data = channels_.find(channel_id);
-  return (channel_data != channels_.end()) ? channel_data->second.channel_state
-                                           : nullptr;
-}
-
-BorrowedHandle Endpoint::GetChannelSocketFd(int32_t channel_id) {
-  std::lock_guard<std::mutex> autolock(channel_mutex_);
-  BorrowedHandle handle;
-  auto channel_data = channels_.find(channel_id);
-  if (channel_data != channels_.end())
-    handle = channel_data->second.data_fd.Borrow();
-  return handle;
-}
-
-Status<std::pair<BorrowedHandle, BorrowedHandle>> Endpoint::GetChannelEventFd(
-    int32_t channel_id) {
-  std::lock_guard<std::mutex> autolock(channel_mutex_);
-  auto channel_data = channels_.find(channel_id);
-  if (channel_data != channels_.end()) {
-    return {{channel_data->second.event_set.pollin_event_fd(),
-             channel_data->second.event_set.pollhup_event_fd()}};
-  }
-  return ErrorStatus(ENOENT);
-}
-
-int32_t Endpoint::GetChannelId(const BorrowedHandle& channel_fd) {
-  std::lock_guard<std::mutex> autolock(channel_mutex_);
-  auto iter = channel_fd_to_id_.find(channel_fd.Get());
-  return (iter != channel_fd_to_id_.end()) ? iter->second : -1;
-}
-
-Status<void> Endpoint::ReceiveMessageForChannel(
-    const BorrowedHandle& channel_fd, Message* message) {
-  RequestHeader<LocalHandle> request;
-  int32_t channel_id = GetChannelId(channel_fd);
-  auto status = ReceiveData(channel_fd.Borrow(), &request);
-  if (!status) {
-    if (status.error() == ESHUTDOWN) {
-      BuildCloseMessage(channel_id, message);
-      return {};
-    } else {
-      CloseChannel(channel_id);
-      return status;
-    }
-  }
-
-  MessageInfo info;
-  info.pid = request.cred.pid;
-  info.tid = -1;
-  info.cid = channel_id;
-  info.mid = request.is_impulse ? Message::IMPULSE_MESSAGE_ID
-                                : GetNextAvailableMessageId();
-  info.euid = request.cred.uid;
-  info.egid = request.cred.gid;
-  info.op = request.op;
-  info.flags = 0;
-  info.service = service_;
-  info.channel = GetChannelState(channel_id);
-  if (info.channel != nullptr) {
-    info.channel->SetActiveProcessId(request.cred.pid);
-  }
-  info.send_len = request.send_len;
-  info.recv_len = request.max_recv_len;
-  info.fd_count = request.file_descriptors.size();
-  static_assert(sizeof(info.impulse) == request.impulse_payload.size(),
-                "Impulse payload sizes must be the same in RequestHeader and "
-                "MessageInfo");
-  memcpy(info.impulse, request.impulse_payload.data(),
-         request.impulse_payload.size());
-  *message = Message{info};
-  auto* state = static_cast<MessageState*>(message->GetState());
-  state->request = std::move(request);
-  if (state->request.send_len > 0 && !state->request.is_impulse) {
-    state->request_data.resize(state->request.send_len);
-    status = ReceiveData(channel_fd, state->request_data.data(),
-                         state->request_data.size());
-  }
-
-  if (status && state->request.is_impulse)
-    status = ReenableEpollEvent(channel_fd);
-
-  if (!status) {
-    if (status.error() == ESHUTDOWN) {
-      BuildCloseMessage(channel_id, message);
-      return {};
-    } else {
-      CloseChannel(channel_id);
-      return status;
-    }
-  }
-
-  return status;
-}
-
-void Endpoint::BuildCloseMessage(int32_t channel_id, Message* message) {
-  ALOGD_IF(TRACE, "Endpoint::BuildCloseMessage: channel_id=%d", channel_id);
-  MessageInfo info;
-  info.pid = -1;
-  info.tid = -1;
-  info.cid = channel_id;
-  info.mid = GetNextAvailableMessageId();
-  info.euid = -1;
-  info.egid = -1;
-  info.op = opcodes::CHANNEL_CLOSE;
-  info.flags = 0;
-  info.service = service_;
-  info.channel = GetChannelState(channel_id);
-  info.send_len = 0;
-  info.recv_len = 0;
-  info.fd_count = 0;
-  *message = Message{info};
-}
-
-Status<void> Endpoint::MessageReceive(Message* message) {
-  // Receive at most one event from the epoll set. This should prevent multiple
-  // dispatch threads from attempting to handle messages on the same socket at
-  // the same time.
-  epoll_event event;
-  int count = RETRY_EINTR(
-      epoll_wait(epoll_fd_.Get(), &event, 1, is_blocking_ ? -1 : 0));
-  if (count < 0) {
-    ALOGE("Endpoint::MessageReceive: Failed to wait for epoll events: %s\n",
-          strerror(errno));
-    return ErrorStatus{errno};
-  } else if (count == 0) {
-    return ErrorStatus{ETIMEDOUT};
-  }
-
-  if (event.data.fd == cancel_event_fd_.Get()) {
-    return ErrorStatus{ESHUTDOWN};
-  }
-
-  if (socket_fd_ && event.data.fd == socket_fd_.Get()) {
-    auto status = AcceptConnection(message);
-    auto reenable_status = ReenableEpollEvent(socket_fd_.Borrow());
-    if (!reenable_status)
-      return reenable_status;
-    return status;
-  }
-
-  BorrowedHandle channel_fd{event.data.fd};
-  return ReceiveMessageForChannel(channel_fd, message);
-}
-
-Status<void> Endpoint::MessageReply(Message* message, int return_code) {
-  const int32_t channel_id = message->GetChannelId();
-  auto channel_socket = GetChannelSocketFd(channel_id);
-  if (!channel_socket)
-    return ErrorStatus{EBADF};
-
-  auto* state = static_cast<MessageState*>(message->GetState());
-  switch (message->GetOp()) {
-    case opcodes::CHANNEL_CLOSE:
-      return CloseChannel(channel_id);
-
-    case opcodes::CHANNEL_OPEN:
-      if (return_code < 0) {
-        return CloseChannel(channel_id);
-      } else {
-        // Open messages do not have a payload and may not transfer any channels
-        // or file descriptors on behalf of the service.
-        state->response_data.clear();
-        state->response.file_descriptors.clear();
-        state->response.channels.clear();
-
-        // Return the channel event-related fds in a single ChannelInfo entry
-        // with an empty data_fd member.
-        auto status = GetChannelEventFd(channel_id);
-        if (!status)
-          return status.error_status();
-
-        auto handles = status.take();
-        state->response.channels.push_back({BorrowedHandle(),
-                                            std::move(handles.first),
-                                            std::move(handles.second)});
-        return_code = 0;
-      }
-      break;
-  }
-
-  state->response.ret_code = return_code;
-  state->response.recv_len = state->response_data.size();
-  auto status = SendData(channel_socket, state->response);
-  if (status && !state->response_data.empty()) {
-    status = SendData(channel_socket, state->response_data.data(),
-                      state->response_data.size());
-  }
-
-  if (status)
-    status = ReenableEpollEvent(channel_socket);
-
-  return status;
-}
-
-Status<void> Endpoint::MessageReplyFd(Message* message, unsigned int push_fd) {
-  auto* state = static_cast<MessageState*>(message->GetState());
-  auto ref = state->PushFileHandle(BorrowedHandle{static_cast<int>(push_fd)});
-  if (!ref)
-    return ref.error_status();
-  return MessageReply(message, ref.get());
-}
-
-Status<void> Endpoint::MessageReplyChannelHandle(
-    Message* message, const LocalChannelHandle& handle) {
-  auto* state = static_cast<MessageState*>(message->GetState());
-  auto ref = state->PushChannelHandle(handle.Borrow());
-  if (!ref)
-    return ref.error_status();
-  return MessageReply(message, ref.get());
-}
-
-Status<void> Endpoint::MessageReplyChannelHandle(
-    Message* message, const BorrowedChannelHandle& handle) {
-  auto* state = static_cast<MessageState*>(message->GetState());
-  auto ref = state->PushChannelHandle(handle.Duplicate());
-  if (!ref)
-    return ref.error_status();
-  return MessageReply(message, ref.get());
-}
-
-Status<void> Endpoint::MessageReplyChannelHandle(
-    Message* message, const RemoteChannelHandle& handle) {
-  return MessageReply(message, handle.value());
-}
-
-Status<size_t> Endpoint::ReadMessageData(Message* message, const iovec* vector,
-                                         size_t vector_length) {
-  auto* state = static_cast<MessageState*>(message->GetState());
-  return state->ReadData(vector, vector_length);
-}
-
-Status<size_t> Endpoint::WriteMessageData(Message* message, const iovec* vector,
-                                          size_t vector_length) {
-  auto* state = static_cast<MessageState*>(message->GetState());
-  return state->WriteData(vector, vector_length);
-}
-
-Status<FileReference> Endpoint::PushFileHandle(Message* message,
-                                               const LocalHandle& handle) {
-  auto* state = static_cast<MessageState*>(message->GetState());
-  return state->PushFileHandle(handle.Borrow());
-}
-
-Status<FileReference> Endpoint::PushFileHandle(Message* message,
-                                               const BorrowedHandle& handle) {
-  auto* state = static_cast<MessageState*>(message->GetState());
-  return state->PushFileHandle(handle.Duplicate());
-}
-
-Status<FileReference> Endpoint::PushFileHandle(Message* /*message*/,
-                                               const RemoteHandle& handle) {
-  return handle.Get();
-}
-
-Status<ChannelReference> Endpoint::PushChannelHandle(
-    Message* message, const LocalChannelHandle& handle) {
-  auto* state = static_cast<MessageState*>(message->GetState());
-  return state->PushChannelHandle(handle.Borrow());
-}
-
-Status<ChannelReference> Endpoint::PushChannelHandle(
-    Message* message, const BorrowedChannelHandle& handle) {
-  auto* state = static_cast<MessageState*>(message->GetState());
-  return state->PushChannelHandle(handle.Duplicate());
-}
-
-Status<ChannelReference> Endpoint::PushChannelHandle(
-    Message* /*message*/, const RemoteChannelHandle& handle) {
-  return handle.value();
-}
-
-LocalHandle Endpoint::GetFileHandle(Message* message, FileReference ref) const {
-  LocalHandle handle;
-  auto* state = static_cast<MessageState*>(message->GetState());
-  state->GetLocalFileHandle(ref, &handle);
-  return handle;
-}
-
-LocalChannelHandle Endpoint::GetChannelHandle(Message* message,
-                                              ChannelReference ref) const {
-  LocalChannelHandle handle;
-  auto* state = static_cast<MessageState*>(message->GetState());
-  state->GetLocalChannelHandle(ref, &handle);
-  return handle;
-}
-
-Status<void> Endpoint::Cancel() {
-  if (eventfd_write(cancel_event_fd_.Get(), 1) < 0)
-    return ErrorStatus{errno};
-  return {};
-}
-
-std::unique_ptr<Endpoint> Endpoint::Create(const std::string& endpoint_path,
-                                           mode_t /*unused_mode*/,
-                                           bool blocking) {
-  return std::unique_ptr<Endpoint>(new Endpoint(endpoint_path, blocking));
-}
-
-std::unique_ptr<Endpoint> Endpoint::CreateAndBindSocket(
-    const std::string& endpoint_path, bool blocking) {
-  return std::unique_ptr<Endpoint>(
-      new Endpoint(endpoint_path, blocking, false));
-}
-
-std::unique_ptr<Endpoint> Endpoint::CreateFromSocketFd(LocalHandle socket_fd) {
-  return std::unique_ptr<Endpoint>(new Endpoint(std::move(socket_fd)));
-}
-
-Status<void> Endpoint::RegisterNewChannelForTests(LocalHandle channel_fd) {
-  int optval = 1;
-  if (setsockopt(channel_fd.Get(), SOL_SOCKET, SO_PASSCRED, &optval,
-                 sizeof(optval)) == -1) {
-    ALOGE(
-        "Endpoint::RegisterNewChannelForTests: Failed to enable the receiving"
-        "of the credentials for channel %d: %s",
-        channel_fd.Get(), strerror(errno));
-    return ErrorStatus(errno);
-  }
-  return OnNewChannel(std::move(channel_fd));
-}
-
-}  // namespace uds
-}  // namespace pdx
-}  // namespace android
diff --git a/libs/vr/libpdx_uds/service_framework_tests.cpp b/libs/vr/libpdx_uds/service_framework_tests.cpp
deleted file mode 100644
index 2742716..0000000
--- a/libs/vr/libpdx_uds/service_framework_tests.cpp
+++ /dev/null
@@ -1,718 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-#include <unistd.h>
-
-#include <array>
-#include <atomic>
-#include <memory>
-#include <numeric>
-#include <string>
-#include <thread>
-
-#include <gtest/gtest.h>
-#include <pdx/channel_handle.h>
-#include <pdx/client.h>
-#include <pdx/file_handle.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-#include <private/android_filesystem_config.h>
-#include <uds/client_channel.h>
-#include <uds/client_channel_factory.h>
-#include <uds/service_endpoint.h>
-
-using android::pdx::BorrowedChannelHandle;
-using android::pdx::Channel;
-using android::pdx::ChannelReference;
-using android::pdx::ClientBase;
-using android::pdx::ErrorStatus;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Message;
-using android::pdx::MessageInfo;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::ServiceBase;
-using android::pdx::ServiceDispatcher;
-using android::pdx::Status;
-using android::pdx::Transaction;
-using android::pdx::uds::Endpoint;
-
-namespace {
-
-const size_t kLargeDataSize = 100000;
-
-const char kTestServicePath[] = "socket_test";
-const char kTestService1[] = "1";
-const char kTestService2[] = "2";
-
-enum test_op_codes {
-  TEST_OP_GET_SERVICE_ID,
-  TEST_OP_SET_TEST_CHANNEL,
-  TEST_OP_GET_THIS_CHANNEL_ID,
-  TEST_OP_GET_TEST_CHANNEL_ID,
-  TEST_OP_CHECK_CHANNEL_ID,
-  TEST_OP_CHECK_CHANNEL_OBJECT,
-  TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE,
-  TEST_OP_GET_NEW_CHANNEL,
-  TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE,
-  TEST_OP_GET_THIS_PROCESS_ID,
-  TEST_OP_GET_THIS_THREAD_ID,
-  TEST_OP_GET_THIS_EUID,
-  TEST_OP_GET_THIS_EGID,
-  TEST_OP_IMPULSE,
-  TEST_OP_POLLHUP_FROM_SERVICE,
-  TEST_OP_POLLIN_FROM_SERVICE,
-  TEST_OP_SEND_LARGE_DATA_RETURN_SUM,
-};
-
-using ImpulsePayload = std::array<std::uint8_t, sizeof(MessageInfo::impulse)>;
-
-// The test service creates a TestChannel for every client (channel) that
-// connects. This represents the service-side context for each client.
-class TestChannel : public Channel {
- public:
-  explicit TestChannel(int channel_id) : channel_id_(channel_id) {}
-
-  int channel_id() const { return channel_id_; }
-
- private:
-  friend class TestService;
-
-  int channel_id_;
-
-  TestChannel(const TestChannel&) = delete;
-  void operator=(const TestChannel&) = delete;
-};
-
-// Test service that creates a TestChannel for each channel and responds to test
-// messages.
-class TestService : public ServiceBase<TestService> {
- public:
-  std::shared_ptr<Channel> OnChannelOpen(Message& message) override {
-    return std::make_shared<TestChannel>(message.GetChannelId());
-  }
-
-  void OnChannelClose(Message& /*message*/,
-                      const std::shared_ptr<Channel>& channel) override {
-    if (test_channel_ == channel)
-      test_channel_ = nullptr;
-  }
-
-  void HandleImpulse(Message& message) override {
-    switch (message.GetOp()) {
-      case TEST_OP_SET_TEST_CHANNEL:
-        test_channel_ = message.GetChannel<TestChannel>();
-        break;
-
-      case TEST_OP_IMPULSE: {
-        impulse_payload_.fill(0);
-        std::copy(message.ImpulseBegin(), message.ImpulseEnd(),
-                  impulse_payload_.begin());
-        break;
-      }
-
-      case TEST_OP_POLLHUP_FROM_SERVICE: {
-        message.ModifyChannelEvents(0, EPOLLHUP);
-        break;
-      }
-    }
-  }
-
-  Status<void> HandleMessage(Message& message) override {
-    switch (message.GetOp()) {
-      case TEST_OP_GET_SERVICE_ID:
-        REPLY_MESSAGE_RETURN(message, service_id_, {});
-
-      // Set the test channel to the TestChannel for the current channel. Other
-      // messages can use this to perform tests.
-      case TEST_OP_SET_TEST_CHANNEL:
-        test_channel_ = message.GetChannel<TestChannel>();
-        REPLY_MESSAGE_RETURN(message, 0, {});
-
-      // Return the channel id for the current channel.
-      case TEST_OP_GET_THIS_CHANNEL_ID:
-        REPLY_MESSAGE_RETURN(message, message.GetChannelId(), {});
-
-      // Return the channel id for the test channel.
-      case TEST_OP_GET_TEST_CHANNEL_ID:
-        if (test_channel_)
-          REPLY_MESSAGE_RETURN(message, test_channel_->channel_id(), {});
-        else
-          REPLY_ERROR_RETURN(message, ENOENT, {});
-
-      // Test check channel feature.
-      case TEST_OP_CHECK_CHANNEL_ID: {
-        ChannelReference ref = 0;
-        if (!message.ReadAll(&ref, sizeof(ref)))
-          REPLY_ERROR_RETURN(message, EIO, {});
-
-        const Status<int> ret = message.CheckChannel<TestChannel>(ref, nullptr);
-        REPLY_MESSAGE_RETURN(message, ret, {});
-      }
-
-      case TEST_OP_CHECK_CHANNEL_OBJECT: {
-        std::shared_ptr<TestChannel> channel;
-        ChannelReference ref = 0;
-        if (!message.ReadAll(&ref, sizeof(ref)))
-          REPLY_ERROR_RETURN(message, EIO, {});
-
-        const Status<int> ret =
-            message.CheckChannel<TestChannel>(ref, &channel);
-        if (!ret)
-          REPLY_MESSAGE_RETURN(message, ret, {});
-
-        if (channel != nullptr)
-          REPLY_MESSAGE_RETURN(message, channel->channel_id(), {});
-        else
-          REPLY_ERROR_RETURN(message, ENODATA, {});
-      }
-
-      case TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE: {
-        ChannelReference ref = 0;
-        if (!message.ReadAll(&ref, sizeof(ref)))
-          REPLY_ERROR_RETURN(message, EIO, {});
-
-        const Status<int> ret = message.CheckChannel<TestChannel>(
-            other_service_.get(), ref, nullptr);
-        REPLY_MESSAGE_RETURN(message, ret, {});
-      }
-
-      case TEST_OP_GET_NEW_CHANNEL: {
-        auto channel = std::make_shared<TestChannel>(-1);
-        Status<RemoteChannelHandle> channel_handle =
-            message.PushChannel(0, channel, &channel->channel_id_);
-        REPLY_MESSAGE_RETURN(message, channel_handle, {});
-      }
-
-      case TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE: {
-        if (!other_service_)
-          REPLY_ERROR_RETURN(message, EINVAL, {});
-
-        auto channel = std::make_shared<TestChannel>(-1);
-        Status<RemoteChannelHandle> channel_handle = message.PushChannel(
-            other_service_.get(), 0, channel, &channel->channel_id_);
-        REPLY_MESSAGE_RETURN(message, channel_handle, {});
-      }
-
-      case TEST_OP_GET_THIS_PROCESS_ID:
-        REPLY_MESSAGE_RETURN(message, message.GetProcessId(), {});
-
-      case TEST_OP_GET_THIS_THREAD_ID:
-        REPLY_MESSAGE_RETURN(message, message.GetThreadId(), {});
-
-      case TEST_OP_GET_THIS_EUID:
-        REPLY_MESSAGE_RETURN(message, message.GetEffectiveUserId(), {});
-
-      case TEST_OP_GET_THIS_EGID:
-        REPLY_MESSAGE_RETURN(message, message.GetEffectiveGroupId(), {});
-
-      case TEST_OP_POLLIN_FROM_SERVICE:
-        REPLY_MESSAGE_RETURN(message, message.ModifyChannelEvents(0, EPOLLIN),
-                             {});
-
-      case TEST_OP_SEND_LARGE_DATA_RETURN_SUM: {
-        std::array<int, kLargeDataSize> data_array;
-        size_t size_to_read = data_array.size() * sizeof(int);
-        if (!message.ReadAll(data_array.data(), size_to_read)) {
-          REPLY_ERROR_RETURN(message, EIO, {});
-        }
-        int sum = std::accumulate(data_array.begin(), data_array.end(), 0);
-        REPLY_MESSAGE_RETURN(message, sum, {});
-      }
-
-      default:
-        return Service::DefaultHandleMessage(message);
-    }
-  }
-
-  const ImpulsePayload& GetImpulsePayload() const { return impulse_payload_; }
-
- private:
-  friend BASE;
-
-  std::shared_ptr<TestChannel> test_channel_;
-  std::shared_ptr<TestService> other_service_;
-  int service_id_;
-  ImpulsePayload impulse_payload_;
-
-  static std::atomic<int> service_counter_;
-
-  TestService(const std::string& name,
-              const std::shared_ptr<TestService>& other_service)
-      : TestService(name, other_service, false) {}
-
-  TestService(const std::string& name,
-              const std::shared_ptr<TestService>& other_service, bool blocking)
-      : BASE(std::string("TestService") + name,
-             Endpoint::CreateAndBindSocket(kTestServicePath + name, blocking)),
-        other_service_(other_service),
-        service_id_(service_counter_++) {}
-
-  explicit TestService(const std::string& name) : TestService(name, nullptr) {}
-
-  TestService(const TestService&) = delete;
-  void operator=(const TestService&) = delete;
-};
-
-std::atomic<int> TestService::service_counter_;
-
-// Test client to send messages to the test service.
-class TestClient : public ClientBase<TestClient> {
- public:
-  // Requests the service id of the service this channel is connected to.
-  int GetServiceId() {
-    Transaction trans{*this};
-    return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_SERVICE_ID));
-  }
-
-  // Requests the test channel to be set to this client's channel.
-  int SetTestChannel() {
-    Transaction trans{*this};
-    return ReturnStatusOrError(trans.Send<int>(TEST_OP_SET_TEST_CHANNEL));
-  }
-
-  // Request the test channel to be set to this client's channel using an async
-  // message.
-  int SetTestChannelAsync() {
-    return ReturnStatusOrError(SendImpulse(TEST_OP_SET_TEST_CHANNEL));
-  }
-
-  // Sends a test async message with payload.
-  int SendAsync(const void* buffer, size_t length) {
-    Transaction trans{*this};
-    return ReturnStatusOrError(SendImpulse(TEST_OP_IMPULSE, buffer, length));
-  }
-
-  // Requests the channel id for this client.
-  int GetThisChannelId() {
-    Transaction trans{*this};
-    return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_CHANNEL_ID));
-  }
-
-  // Requests the channel id of the test channel.
-  int GetTestChannelId() {
-    Transaction trans{*this};
-    return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_TEST_CHANNEL_ID));
-  }
-
-  // Checks whether the fd |channel_id| is a channel to the test service.
-  // Returns the channel id of the channel.
-  int CheckChannelIdArgument(BorrowedChannelHandle channel) {
-    Transaction trans{*this};
-    ChannelReference ref = trans.PushChannelHandle(channel).get();
-    return ReturnStatusOrError(trans.Send<int>(TEST_OP_CHECK_CHANNEL_ID, &ref,
-                                               sizeof(ref), nullptr, 0));
-  }
-
-  // Checks whether the fd |channel_id| is a channel to the test service.
-  // Returns the channel id of the channel exercising the context pointer.
-  int CheckChannelObjectArgument(BorrowedChannelHandle channel) {
-    Transaction trans{*this};
-    ChannelReference ref = trans.PushChannelHandle(channel).get();
-    return ReturnStatusOrError(trans.Send<int>(TEST_OP_CHECK_CHANNEL_OBJECT,
-                                               &ref, sizeof(ref), nullptr, 0));
-  }
-
-  // Checks whether the fd |channel_fd| is a channel to the other test service.
-  // Returns 0 on success.
-  int CheckChannelFromOtherService(BorrowedChannelHandle channel) {
-    Transaction trans{*this};
-    ChannelReference ref = trans.PushChannelHandle(channel).get();
-    return ReturnStatusOrError(
-        trans.Send<int>(TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE, &ref,
-                        sizeof(ref), nullptr, 0));
-  }
-
-  // Requests a new channel to the service.
-  std::unique_ptr<TestClient> GetNewChannel() {
-    Transaction trans{*this};
-    auto status = trans.Send<LocalChannelHandle>(TEST_OP_GET_NEW_CHANNEL);
-    if (status)
-      return TestClient::Create(status.take());
-    else
-      return nullptr;
-  }
-
-  // Requests a new channel to the other service.
-  std::unique_ptr<TestClient> GetNewChannelFromOtherService() {
-    Transaction trans{*this};
-    auto status = trans.Send<LocalChannelHandle>(
-        TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE);
-    if (status)
-      return TestClient::Create(status.take());
-    else
-      return nullptr;
-  }
-
-  // Requests an id from the message description.
-  pid_t GetThisProcessId() {
-    Transaction trans{*this};
-    return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_PROCESS_ID));
-  }
-  pid_t GetThisThreadId() {
-    Transaction trans{*this};
-    return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_THREAD_ID));
-  }
-  uid_t GetThisEffectiveUserId() {
-    Transaction trans{*this};
-    return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_EUID));
-  }
-  gid_t GetThisEffectiveGroupId() {
-    Transaction trans{*this};
-    return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_EGID));
-  }
-
-  int SendPollHupEvent() {
-    return ReturnStatusOrError(SendImpulse(TEST_OP_POLLHUP_FROM_SERVICE));
-  }
-
-  int SendPollInEvent() {
-    Transaction trans{*this};
-    return ReturnStatusOrError(trans.Send<int>(TEST_OP_POLLIN_FROM_SERVICE));
-  }
-
-  int SendLargeDataReturnSum(
-      const std::array<int, kLargeDataSize>& data_array) {
-    Transaction trans{*this};
-    return ReturnStatusOrError(
-        trans.Send<int>(TEST_OP_SEND_LARGE_DATA_RETURN_SUM, data_array.data(),
-                        data_array.size() * sizeof(int), nullptr, 0));
-  }
-
-  Status<int> GetEventMask(int events) {
-    if (auto* client_channel = GetChannel()) {
-      return client_channel->GetEventMask(events);
-    } else {
-      return ErrorStatus(EINVAL);
-    }
-  }
-
-  using ClientBase<TestClient>::event_fd;
-
-  enum : size_t { kMaxPayload = MAX_IMPULSE_LENGTH };
-
- private:
-  friend BASE;
-
-  explicit TestClient(const std::string& name)
-      : BASE{android::pdx::uds::ClientChannelFactory::Create(kTestServicePath +
-                                                             name)} {}
-
-  explicit TestClient(LocalChannelHandle channel)
-      : BASE{android::pdx::uds::ClientChannel::Create(std::move(channel))} {}
-
-  TestClient(const TestClient&) = delete;
-  void operator=(const TestClient&) = delete;
-};
-
-}  // anonymous namespace
-
-// Use a test fixture to ensure proper order of cleanup between clients,
-// services, and the dispatcher. These objects are cleaned up in the same
-// thread, order is important; either the service or the client must be
-// destroyed before the dispatcher is stopped. The reason for this is that
-// clients send blocking "close" messages to their respective services on
-// destruction. If this happens after the dispatcher is stopped the client
-// destructor will get blocked waiting for a reply that will never come. In
-// normal use of the service framework this is never an issue because clients
-// and the dispatcher for the same service are never destructed in the same
-// thread (they live in different processes).
-class ServiceFrameworkTest : public ::testing::Test {
- protected:
-  std::unique_ptr<ServiceDispatcher> dispatcher_;
-  std::thread dispatch_thread_;
-
-  void SetUp() override {
-    // Create a dispatcher to handle messages to services.
-    dispatcher_ = android::pdx::ServiceDispatcher::Create();
-    ASSERT_NE(nullptr, dispatcher_);
-
-    // Start the message dispatch loop in a separate thread.
-    dispatch_thread_ = std::thread(
-        std::bind(&ServiceDispatcher::EnterDispatchLoop, dispatcher_.get()));
-  }
-
-  void TearDown() override {
-    if (dispatcher_) {
-      // Cancel the dispatcher and wait for the thread to terminate. Explicitly
-      // join the thread so that destruction doesn't deallocate the dispatcher
-      // before the thread finishes.
-      dispatcher_->SetCanceled(true);
-      dispatch_thread_.join();
-    }
-  }
-};
-
-// Test basic operation of TestService/TestClient classes.
-TEST_F(ServiceFrameworkTest, BasicClientService) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create(kTestService1);
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create(kTestService1);
-  ASSERT_NE(nullptr, client);
-
-  // Get the channel id that will be returned by the next tests.
-  const int channel_id = client->GetThisChannelId();
-  EXPECT_LE(0, channel_id);
-
-  // Check return value before test channel is set.
-  EXPECT_EQ(-ENOENT, client->GetTestChannelId());
-
-  // Set test channel and perform the test again.
-  EXPECT_EQ(0, client->SetTestChannel());
-  EXPECT_EQ(channel_id, client->GetTestChannelId());
-}
-
-// Test impulses.
-TEST_F(ServiceFrameworkTest, Impulse) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create(kTestService1);
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  auto client = TestClient::Create(kTestService1);
-  ASSERT_NE(nullptr, client);
-
-  // Get the channel id that will be returned by the next tests.
-  const int channel_id = client->GetThisChannelId();
-  EXPECT_LE(0, channel_id);
-
-  // Check return value before test channel is set.
-  EXPECT_EQ(-ENOENT, client->GetTestChannelId());
-
-  // Set test channel with an impulse and perform the test again.
-  EXPECT_EQ(0, client->SetTestChannelAsync());
-  EXPECT_EQ(channel_id, client->GetTestChannelId());
-
-  ImpulsePayload expected_payload = {{'a', 'b', 'c'}};
-  EXPECT_EQ(0, client->SendAsync(expected_payload.data(), 3));
-  // Send a synchronous message to make sure the async message is handled before
-  // we check the payload.
-  client->GetThisChannelId();
-  EXPECT_EQ(expected_payload, service->GetImpulsePayload());
-
-  // Impulse payloads are limited to 4 machine words.
-  EXPECT_EQ(
-      0, client->SendAsync(expected_payload.data(), TestClient::kMaxPayload));
-  EXPECT_EQ(-EINVAL, client->SendAsync(expected_payload.data(),
-                                       TestClient::kMaxPayload + 1));
-
-  // Test invalid pointer.
-  const std::uint8_t* invalid_pointer = nullptr;
-  EXPECT_EQ(-EINVAL, client->SendAsync(invalid_pointer, sizeof(int)));
-}
-
-// Test impulses.
-TEST_F(ServiceFrameworkTest, ImpulseHangup) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create(kTestService1);
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  auto client = TestClient::Create(kTestService1);
-  ASSERT_NE(nullptr, client);
-
-  const int kMaxIterations = 1000;
-  for (int i = 0; i < kMaxIterations; i++) {
-    auto impulse_client = TestClient::Create(kTestService1);
-    ASSERT_NE(nullptr, impulse_client);
-
-    const uint8_t a = (i >> 0) & 0xff;
-    const uint8_t b = (i >> 8) & 0xff;
-    const uint8_t c = (i >> 16) & 0xff;
-    const uint8_t d = (i >> 24) & 0xff;
-    ImpulsePayload expected_payload = {{a, b, c, d}};
-    EXPECT_EQ(0, impulse_client->SendAsync(expected_payload.data(), 4));
-
-    // Hangup the impulse test client, then send a sync message over client to
-    // make sure the hangup message is handled before checking the impulse
-    // payload.
-    impulse_client = nullptr;
-    client->GetThisChannelId();
-    EXPECT_EQ(expected_payload, service->GetImpulsePayload());
-  }
-}
-
-// Test Message::PushChannel/Service::PushChannel API.
-TEST_F(ServiceFrameworkTest, PushChannel) {
-  // Create a test service and add it to the dispatcher.
-  auto other_service = TestService::Create(kTestService1);
-  ASSERT_NE(nullptr, other_service);
-  ASSERT_EQ(0, dispatcher_->AddService(other_service));
-
-  // Create a second test service and add it to the dispatcher.
-  auto service = TestService::Create(kTestService2, other_service);
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to the second test service.
-  auto client1 = TestClient::Create(kTestService2);
-  ASSERT_NE(nullptr, client1);
-
-  // Test the creation of new channels using the push APIs.
-  const int channel_id1 = client1->GetThisChannelId();
-  EXPECT_LE(0, channel_id1);
-
-  auto client2 = client1->GetNewChannel();
-  EXPECT_NE(nullptr, client2);
-  EXPECT_NE(client1->event_fd(), client2->event_fd());
-
-  const int channel_id2 = client2->GetThisChannelId();
-  EXPECT_LE(0, channel_id2);
-  EXPECT_NE(channel_id1, channel_id2);
-
-  auto client3 = client1->GetNewChannelFromOtherService();
-  EXPECT_NE(nullptr, client3);
-  EXPECT_NE(client1->event_fd(), client3->event_fd());
-
-  const int channel_id3 = client3->GetThisChannelId();
-  EXPECT_LE(0, channel_id3);
-
-  // Test which services the channels are connected to.
-  const int service_id1 = client1->GetServiceId();
-  EXPECT_LE(0, service_id1);
-
-  const int service_id2 = client2->GetServiceId();
-  EXPECT_LE(0, service_id2);
-
-  const int service_id3 = client3->GetServiceId();
-  EXPECT_LE(0, service_id3);
-
-  EXPECT_EQ(service_id1, service_id2);
-  EXPECT_NE(service_id1, service_id3);
-}
-
-// Tests process id, thread id, effective user id, and effective group id
-// returned in the message description.
-TEST_F(ServiceFrameworkTest, Ids) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create(kTestService1);
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create(kTestService1);
-  ASSERT_NE(nullptr, client);
-
-  // Pids 0-2 are defined, no user task should have them.
-
-  const pid_t process_id1 = client->GetThisProcessId();
-  EXPECT_LT(2, process_id1);
-
-  pid_t process_id2;
-
-  std::thread thread([&]() { process_id2 = client->GetThisProcessId(); });
-  thread.join();
-
-  EXPECT_LT(2, process_id2);
-  EXPECT_EQ(process_id1, process_id2);
-
-  // This test must run as root for the rest of these tests to work.
-  const int euid1 = client->GetThisEffectiveUserId();
-  ASSERT_EQ(0, euid1);
-
-  const int egid1 = client->GetThisEffectiveGroupId();
-  EXPECT_EQ(0, egid1);
-
-  // Set effective uid/gid to system.
-  ASSERT_EQ(0, setegid(AID_SYSTEM));
-  ASSERT_EQ(0, seteuid(AID_SYSTEM));
-
-  const int euid2 = client->GetThisEffectiveUserId();
-  EXPECT_EQ(AID_SYSTEM, euid2);
-
-  const int egid2 = client->GetThisEffectiveGroupId();
-  EXPECT_EQ(AID_SYSTEM, egid2);
-
-  // Set the euid/egid back to root.
-  ASSERT_EQ(0, setegid(0));
-  ASSERT_EQ(0, seteuid(0));
-}
-
-TEST_F(ServiceFrameworkTest, PollIn) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create(kTestService1);
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create(kTestService1);
-  ASSERT_NE(nullptr, client);
-
-  pollfd pfd{client->event_fd(), POLLIN, 0};
-  int count = poll(&pfd, 1, 0);
-  ASSERT_EQ(0, count);
-
-  client->SendPollInEvent();
-
-  count = poll(&pfd, 1, 10000 /*10s*/);
-  ASSERT_EQ(1, count);
-  ASSERT_TRUE((POLLIN & pfd.revents) != 0);
-}
-
-TEST_F(ServiceFrameworkTest, PollHup) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create(kTestService1);
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create(kTestService1);
-  ASSERT_NE(nullptr, client);
-
-  pollfd pfd{client->event_fd(), POLLIN, 0};
-  int count = poll(&pfd, 1, 0);
-  ASSERT_EQ(0, count);
-
-  client->SendPollHupEvent();
-
-  count = poll(&pfd, 1, 10000 /*10s*/);
-  ASSERT_EQ(1, count);
-  auto event_status = client->GetEventMask(pfd.revents);
-  ASSERT_TRUE(event_status.ok());
-  ASSERT_TRUE((EPOLLHUP & event_status.get()) != 0);
-}
-
-TEST_F(ServiceFrameworkTest, LargeDataSum) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create(kTestService1);
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create(kTestService1);
-  ASSERT_NE(nullptr, client);
-
-  std::array<int, kLargeDataSize> data_array;
-  std::iota(data_array.begin(), data_array.end(), 0);
-  int expected_sum = std::accumulate(data_array.begin(), data_array.end(), 0);
-  int sum = client->SendLargeDataReturnSum(data_array);
-  ASSERT_EQ(expected_sum, sum);
-}
-
-TEST_F(ServiceFrameworkTest, Cancel) {
-  // Create a test service and add it to the dispatcher.
-  auto service = TestService::Create(kTestService1, nullptr, true);
-  ASSERT_NE(nullptr, service);
-  ASSERT_EQ(0, dispatcher_->AddService(service));
-
-  // Create a client to service.
-  auto client = TestClient::Create(kTestService1);
-  ASSERT_NE(nullptr, client);
-
-  auto previous_time = std::chrono::system_clock::now();
-  dispatcher_->ReceiveAndDispatch(100);  // 0.1 seconds should block.
-  auto time = std::chrono::system_clock::now();
-  ASSERT_LE(100, std::chrono::duration_cast<std::chrono::milliseconds>(
-                     time - previous_time)
-                     .count());
-  service->Cancel();
-  // Non-blocking. Return immediately.
-  dispatcher_->ReceiveAndDispatch(-1);
-  dispatcher_->ReceiveAndDispatch(-1);
-}
diff --git a/libs/vr/libperformance/Android.bp b/libs/vr/libperformance/Android.bp
deleted file mode 100644
index 38bf4ea..0000000
--- a/libs/vr/libperformance/Android.bp
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (C) 2016 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"],
-}
-
-sourceFiles = [
-    "performance_client.cpp",
-    "performance_rpc.cpp",
-]
-
-includeFiles = [ "include" ]
-
-sharedLibraries = [
-    "libbase",
-    "libbinder",
-    "libcutils",
-    "liblog",
-    "libutils",
-    "libpdx_default_transport",
-]
-
-cc_library {
-    srcs: sourceFiles,
-    cflags: [
-        "-DLOG_TAG=\"libperformance\"",
-        "-DTRACE=0",
-        "-Wall",
-        "-Werror",
-    ],
-    export_include_dirs: includeFiles,
-    shared_libs: sharedLibraries,
-    name: "libperformance",
-}
diff --git a/libs/vr/libperformance/include/CPPLINT.cfg b/libs/vr/libperformance/include/CPPLINT.cfg
deleted file mode 100644
index 2f8a3c0..0000000
--- a/libs/vr/libperformance/include/CPPLINT.cfg
+++ /dev/null
@@ -1 +0,0 @@
-filter=-build/header_guard
diff --git a/libs/vr/libperformance/include/dvr/performance_client_api.h b/libs/vr/libperformance/include/dvr/performance_client_api.h
deleted file mode 100644
index 9d617cb..0000000
--- a/libs/vr/libperformance/include/dvr/performance_client_api.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCE_CLIENT_API_H_
-#define ANDROID_DVR_PERFORMANCE_CLIENT_API_H_
-
-#include <stddef.h>
-#include <unistd.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/// Sets the scheduler policy for a task.
-///
-/// Sets the scheduler policy for a task to the class described by a semantic
-/// string.
-///
-/// Supported policies are device-specific.
-///
-/// @param task_id The task id of task to set the policy for. When task_id is 0
-/// the current task id is substituted.
-/// @param scheduler_policy NULL-terminated ASCII string containing the desired
-/// scheduler policy.
-/// @returns Returns 0 on success or a negative errno error code on error.
-int dvrSetSchedulerPolicy(pid_t task_id, const char* scheduler_policy);
-
-/// Sets the CPU partition for a task.
-///
-/// Sets the CPU partition for a task to the partition described by a CPU
-/// partition path.
-///
-/// TODO(eieio): Describe supported partitions and rules governing assignment.
-///
-/// @param task_id The task id of task to attach to a partition. When task_id is
-/// 0 the current task id is substituted.
-/// @param partition NULL-terminated ASCII string describing the CPU partition
-/// to attach the task to.
-/// @returns Returns 0 on success or a negative errno error code on error.
-int dvrSetCpuPartition(pid_t task_id, const char* partition);
-
-/// Sets the scheduler class for a task.
-///
-/// Sets the scheduler class for a task to the class described by a semantic
-/// string.
-///
-/// Supported classes for applications are: audio, graphics, normal, and
-/// background. Additional options following a ':' to be supported in the
-/// future.
-///
-/// @param task_id The task id of task to attach to a partition. When task_id is
-/// 0 the current task id is substituted.
-/// @param scheduler_class NULL-terminated ASCII string containing the desired
-/// scheduler class.
-/// @returns Returns 0 on success or a negative errno error code on error.
-int dvrSetSchedulerClass(pid_t task_id, const char* scheduler_class);
-
-/// Gets the CPU partition for a task.
-///
-/// Gets the CPU partition path for a task as a NULL-terminated ASCII string. If
-/// the path is too large to fit in the supplied buffer, -ENOBUFS is returned.
-///
-/// @param task_id The task id of the task to retrieve the partition for. When
-/// task_id is 0 the current task id is substituted.
-/// @param partition Pointer to an ASCII string buffer to store the partition
-/// path.
-/// @param size Size of the string buffer in bytes, including space for the NULL
-/// terminator.
-/// @returns Returns 0 on success or a negative errno error code on error.
-int dvrGetCpuPartition(pid_t task_id, char* partition, size_t size);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  // ANDROID_DVR_PERFORMANCE_CLIENT_API_H_
diff --git a/libs/vr/libperformance/include/private/dvr/performance_client.h b/libs/vr/libperformance/include/private/dvr/performance_client.h
deleted file mode 100644
index 3bd90dc..0000000
--- a/libs/vr/libperformance/include/private/dvr/performance_client.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCE_CLIENT_H_
-#define ANDROID_DVR_PERFORMANCE_CLIENT_H_
-
-#include <sys/types.h>
-
-#include <cstddef>
-#include <string>
-#include <tuple>
-
-#include <pdx/client.h>
-
-namespace android {
-namespace dvr {
-
-class PerformanceClient : public pdx::ClientBase<PerformanceClient> {
- public:
-  int SetSchedulerPolicy(pid_t task_id, const std::string& scheduler_policy);
-  int SetSchedulerPolicy(pid_t task_id, const char* scheduler_policy);
-
-  // TODO(eieio): Consider deprecating this API.
-  int SetCpuPartition(pid_t task_id, const std::string& partition);
-  int SetCpuPartition(pid_t task_id, const char* partition);
-  int SetSchedulerClass(pid_t task_id, const std::string& scheduler_class);
-  int SetSchedulerClass(pid_t task_id, const char* scheduler_class);
-  int GetCpuPartition(pid_t task_id, std::string* partition_out);
-  int GetCpuPartition(pid_t task_id, char* partition_out, std::size_t size);
-
- private:
-  friend BASE;
-
-  explicit PerformanceClient(int* error);
-
-  PerformanceClient(const PerformanceClient&) = delete;
-  void operator=(const PerformanceClient&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_PERFORMANCE_CLIENT_H_
diff --git a/libs/vr/libperformance/include/private/dvr/performance_rpc.h b/libs/vr/libperformance/include/private/dvr/performance_rpc.h
deleted file mode 100644
index d57bbe8..0000000
--- a/libs/vr/libperformance/include/private/dvr/performance_rpc.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCE_RPC_H_
-#define ANDROID_DVR_PERFORMANCE_RPC_H_
-
-#include <sys/types.h>
-
-#include <string>
-
-#include <pdx/rpc/remote_method_type.h>
-
-namespace android {
-namespace dvr {
-
-// Performance Service RPC interface. Defines the endpoint paths, op codes, and
-// method type signatures supported by performanced.
-struct PerformanceRPC {
-  // Service path.
-  static constexpr char kClientPath[] = "system/performance/client";
-
-  // Op codes.
-  enum {
-    kOpSetCpuPartition = 0,
-    kOpSetSchedulerClass,
-    kOpGetCpuPartition,
-    kOpSetSchedulerPolicy,
-  };
-
-  // Methods.
-  PDX_REMOTE_METHOD(SetCpuPartition, kOpSetCpuPartition,
-                    void(pid_t, const std::string&));
-  PDX_REMOTE_METHOD(SetSchedulerClass, kOpSetSchedulerClass,
-                    void(pid_t, const std::string&));
-  PDX_REMOTE_METHOD(GetCpuPartition, kOpGetCpuPartition, std::string(pid_t));
-  PDX_REMOTE_METHOD(SetSchedulerPolicy, kOpSetSchedulerPolicy,
-                    void(pid_t, const std::string&));
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_PERFORMANCE_RPC_H_
diff --git a/libs/vr/libperformance/performance_client.cpp b/libs/vr/libperformance/performance_client.cpp
deleted file mode 100644
index bf3726e..0000000
--- a/libs/vr/libperformance/performance_client.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-#include "include/private/dvr/performance_client.h"
-
-#include <sys/types.h>
-
-#include <pdx/default_transport/client_channel_factory.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/rpc/string_wrapper.h>
-#include <private/dvr/performance_rpc.h>
-
-using android::pdx::rpc::WrapString;
-
-namespace android {
-namespace dvr {
-
-PerformanceClient::PerformanceClient(int* error)
-    : BASE(pdx::default_transport::ClientChannelFactory::Create(
-          PerformanceRPC::kClientPath)) {
-  if (error)
-    *error = Client::error();
-}
-
-int PerformanceClient::SetCpuPartition(pid_t task_id,
-                                       const std::string& partition) {
-  if (task_id == 0)
-    task_id = gettid();
-
-  return ReturnStatusOrError(
-      InvokeRemoteMethod<PerformanceRPC::SetCpuPartition>(task_id, partition));
-}
-
-int PerformanceClient::SetCpuPartition(pid_t task_id, const char* partition) {
-  if (task_id == 0)
-    task_id = gettid();
-
-  return ReturnStatusOrError(
-      InvokeRemoteMethod<PerformanceRPC::SetCpuPartition>(
-          task_id, WrapString(partition)));
-}
-
-int PerformanceClient::SetSchedulerPolicy(pid_t task_id,
-                                          const std::string& scheduler_policy) {
-  if (task_id == 0)
-    task_id = gettid();
-
-  return ReturnStatusOrError(
-      InvokeRemoteMethod<PerformanceRPC::SetSchedulerPolicy>(task_id,
-                                                             scheduler_policy));
-}
-
-int PerformanceClient::SetSchedulerPolicy(pid_t task_id,
-                                          const char* scheduler_policy) {
-  if (task_id == 0)
-    task_id = gettid();
-
-  return ReturnStatusOrError(
-      InvokeRemoteMethod<PerformanceRPC::SetSchedulerPolicy>(
-          task_id, WrapString(scheduler_policy)));
-}
-
-int PerformanceClient::SetSchedulerClass(pid_t task_id,
-                                         const std::string& scheduler_class) {
-  if (task_id == 0)
-    task_id = gettid();
-
-  return ReturnStatusOrError(
-      InvokeRemoteMethod<PerformanceRPC::SetSchedulerClass>(task_id,
-                                                            scheduler_class));
-}
-
-int PerformanceClient::SetSchedulerClass(pid_t task_id,
-                                         const char* scheduler_class) {
-  if (task_id == 0)
-    task_id = gettid();
-
-  return ReturnStatusOrError(
-      InvokeRemoteMethod<PerformanceRPC::SetSchedulerClass>(
-          task_id, WrapString(scheduler_class)));
-}
-
-int PerformanceClient::GetCpuPartition(pid_t task_id,
-                                       std::string* partition_out) {
-  if (partition_out == nullptr)
-    return -EINVAL;
-
-  if (task_id == 0)
-    task_id = gettid();
-
-  auto status = InvokeRemoteMethodInPlace<PerformanceRPC::GetCpuPartition>(
-      partition_out, task_id);
-  return status ? 0 : -status.error();
-}
-
-int PerformanceClient::GetCpuPartition(pid_t task_id, char* partition_out,
-                                       std::size_t size) {
-  if (partition_out == nullptr)
-    return -EINVAL;
-
-  if (task_id == 0)
-    task_id = gettid();
-
-  auto wrapper = WrapString(partition_out, size);
-  auto status = InvokeRemoteMethodInPlace<PerformanceRPC::GetCpuPartition>(
-      &wrapper, task_id);
-  if (!status)
-    return -status.error();
-
-  if (wrapper.size() < size)
-    partition_out[wrapper.size()] = '\0';
-
-  return 0;
-}
-
-}  // namespace dvr
-}  // namespace android
-
-extern "C" int dvrSetCpuPartition(pid_t task_id, const char* partition) {
-  int error;
-  if (auto client = android::dvr::PerformanceClient::Create(&error))
-    return client->SetCpuPartition(task_id, partition);
-  else
-    return error;
-}
-
-extern "C" int dvrSetSchedulerPolicy(pid_t task_id,
-                                     const char* scheduler_policy) {
-  int error;
-  if (auto client = android::dvr::PerformanceClient::Create(&error))
-    return client->SetSchedulerPolicy(task_id, scheduler_policy);
-  else
-    return error;
-}
-
-extern "C" int dvrSetSchedulerClass(pid_t task_id,
-                                    const char* scheduler_class) {
-  int error;
-  if (auto client = android::dvr::PerformanceClient::Create(&error))
-    return client->SetSchedulerClass(task_id, scheduler_class);
-  else
-    return error;
-}
-
-extern "C" int dvrGetCpuPartition(pid_t task_id, char* partition, size_t size) {
-  int error;
-  if (auto client = android::dvr::PerformanceClient::Create(&error))
-    return client->GetCpuPartition(task_id, partition, size);
-  else
-    return error;
-}
diff --git a/libs/vr/libperformance/performance_rpc.cpp b/libs/vr/libperformance/performance_rpc.cpp
deleted file mode 100644
index 9135349..0000000
--- a/libs/vr/libperformance/performance_rpc.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "include/private/dvr/performance_rpc.h"
-
-namespace android {
-namespace dvr {
-
-constexpr char PerformanceRPC::kClientPath[];
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libvr_manager/Android.bp b/libs/vr/libvr_manager/Android.bp
deleted file mode 100644
index 6f2ada4..0000000
--- a/libs/vr/libvr_manager/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2017 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_library_static {
-    name: "libvr_manager",
-    srcs: [
-        "vr_manager.cpp",
-        "trusted_uids.cpp",
-    ],
-    include_dirs: ["frameworks/native/include/vr/vr_manager"],
-    export_include_dirs: [ "include" ],
-    cflags: ["-Wall", "-Werror", "-Wunused", "-Wunreachable-code"],
-    shared_libs: [
-        "libutils",
-        "libbinder",
-    ],
-}
diff --git a/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h b/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h
deleted file mode 100644
index 4496fbf..0000000
--- a/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef ANDROID_DVR_TRUSTED_UIDS_H_
-#define ANDROID_DVR_TRUSTED_UIDS_H_
-
-#include <sys/types.h>
-
-namespace android {
-namespace dvr {
-
-/**
- * Tells if a provided UID can be trusted to access restricted VR APIs.
- *
- * UID trust is based on the android.permission.RESTRICTED_VR_ACCESS permission.
- * AID_SYSTEM and AID_ROOT are automatically trusted by Android.
- *
- * UIDs are guaranteed not to be reused until the next reboot even in case
- * of package reinstall. For performance reasons this method caches results by
- * default, as otherwise every check would trigger a Java call.
- *
- * This function is thread-safe.
- *
- * @param uid The uid to check.
- * @param use_cache If true any cached result for the provided uid will be
- *     reused. If false this call will reach the Application Manager Service
- *     in Java to get updated values. Any updates will be stored in the cache.
- * @return true if the uid is trusted, false if not or if the VR Manager Service
- *         could not be reached to verify the uid.
- */
-bool IsTrustedUid(uid_t uid, bool use_cache = true);
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_TRUSTED_UIDS_H_
diff --git a/libs/vr/libvr_manager/trusted_uids.cpp b/libs/vr/libvr_manager/trusted_uids.cpp
deleted file mode 100644
index 4228a05..0000000
--- a/libs/vr/libvr_manager/trusted_uids.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "private/dvr/trusted_uids.h"
-
-#include <mutex>
-#include <unordered_map>
-
-#include <binder/IPermissionController.h>
-#include <binder/IServiceManager.h>
-#include <private/android_filesystem_config.h>
-#include <utils/String16.h>
-#include <vr/vr_manager/vr_manager.h>
-
-namespace android {
-namespace dvr {
-
-bool IsTrustedUid(uid_t uid, bool use_cache) {
-  static std::unordered_map<uid_t, bool> uid_cache;
-  static std::mutex uid_cache_mutex;
-
-  // Whitelist requests from the system UID.
-  // These are already whitelisted by the permission service, but it might not
-  // be available if the ActivityManagerService is up during boot.
-  // This ensures the correct result for system services while booting up.
-  if (uid == AID_SYSTEM)
-    return true;
-
-  std::lock_guard<std::mutex> lock(uid_cache_mutex);
-
-  if (use_cache) {
-    auto it = uid_cache.find(uid);
-    if (it != uid_cache.end())
-      return it->second;
-  }
-
-  sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
-  if (binder == 0) {
-    ALOGW("Could not access permission service");
-    return false;
-  }
-
-  // Note: we ignore the pid because it's only used to automatically reply
-  // true if the caller is the Activity Manager Service.
-  bool trusted = interface_cast<IPermissionController>(binder)->checkPermission(
-      String16("android.permission.RESTRICTED_VR_ACCESS"), -1, uid);
-
-  // Cache the information for this uid to avoid future Java calls.
-  uid_cache[uid] = trusted;
-  return trusted;
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libvr_manager/vr_manager.cpp b/libs/vr/libvr_manager/vr_manager.cpp
deleted file mode 100644
index 5cfc22e..0000000
--- a/libs/vr/libvr_manager/vr_manager.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2017 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 "VrManager"
-#include <utils/Log.h>
-
-#include <vr/vr_manager/vr_manager.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <binder/Parcel.h>
-
-namespace android {
-
-// Must be kept in sync with interface defined in IVrStateCallbacks.aidl.
-
-class BpVrStateCallbacks : public BpInterface<IVrStateCallbacks> {
- public:
-  explicit BpVrStateCallbacks(const sp<IBinder>& impl)
-      : BpInterface<IVrStateCallbacks>(impl) {}
-
-  void onVrStateChanged(bool enabled) {
-    Parcel data, reply;
-    data.writeInterfaceToken(IVrStateCallbacks::getInterfaceDescriptor());
-    data.writeBool(enabled);
-    remote()->transact(ON_VR_STATE_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
-  }
-};
-
-IMPLEMENT_META_INTERFACE(VrStateCallbacks, "android.service.vr.IVrStateCallbacks");
-
-status_t BnVrStateCallbacks::onTransact(uint32_t code, const Parcel& data,
-                                        Parcel* reply, uint32_t flags) {
-  switch(code) {
-    case ON_VR_STATE_CHANGED: {
-      CHECK_INTERFACE(IVrStateCallbacks, data, reply);
-      onVrStateChanged(data.readBool());
-      return OK;
-    }
-  }
-  return BBinder::onTransact(code, data, reply, flags);
-}
-
-// Must be kept in sync with interface defined in
-// IPersistentVrStateCallbacks.aidl.
-
-class BpPersistentVrStateCallbacks
-    : public BpInterface<IPersistentVrStateCallbacks> {
- public:
-  explicit BpPersistentVrStateCallbacks(const sp<IBinder>& impl)
-      : BpInterface<IPersistentVrStateCallbacks>(impl) {}
-
-  void onPersistentVrStateChanged(bool enabled) {
-    Parcel data, reply;
-    data.writeInterfaceToken(
-        IPersistentVrStateCallbacks::getInterfaceDescriptor());
-    data.writeBool(enabled);
-    remote()->transact(ON_PERSISTENT_VR_STATE_CHANGED,
-                       data, &reply, IBinder::FLAG_ONEWAY);
-  }
-};
-
-IMPLEMENT_META_INTERFACE(PersistentVrStateCallbacks,
-                         "android.service.vr.IPersistentVrStateCallbacks");
-
-status_t BnPersistentVrStateCallbacks::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
-  switch(code) {
-    case ON_PERSISTENT_VR_STATE_CHANGED: {
-      CHECK_INTERFACE(IPersistentVrStateCallbacks, data, reply);
-      onPersistentVrStateChanged(data.readBool());
-      return OK;
-    }
-  }
-  return BBinder::onTransact(code, data, reply, flags);
-}
-
-// Must be kept in sync with interface defined in IVrManager.aidl.
-
-class BpVrManager : public BpInterface<IVrManager> {
- public:
-  explicit BpVrManager(const sp<IBinder>& impl)
-      : BpInterface<IVrManager>(impl) {}
-
-  void registerListener(const sp<IVrStateCallbacks>& cb) override {
-    Parcel data;
-    data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
-    data.writeStrongBinder(IInterface::asBinder(cb));
-    remote()->transact(REGISTER_LISTENER, data, NULL);
-  }
-
-  void unregisterListener(const sp<IVrStateCallbacks>& cb) override {
-    Parcel data;
-    data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
-    data.writeStrongBinder(IInterface::asBinder(cb));
-    remote()->transact(UNREGISTER_LISTENER, data, NULL);
-  }
-
-  void registerPersistentVrStateListener(
-      const sp<IPersistentVrStateCallbacks>& cb) override {
-    Parcel data;
-    data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
-    data.writeStrongBinder(IInterface::asBinder(cb));
-    remote()->transact(REGISTER_PERSISTENT_VR_STATE_LISTENER, data, NULL);
-  }
-
-  void unregisterPersistentVrStateListener(
-      const sp<IPersistentVrStateCallbacks>& cb) override {
-    Parcel data;
-    data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
-    data.writeStrongBinder(IInterface::asBinder(cb));
-    remote()->transact(UNREGISTER_PERSISTENT_VR_STATE_LISTENER, data, NULL);
-  }
-
-  bool getVrModeState() override {
-    Parcel data, reply;
-    data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
-    remote()->transact(GET_VR_MODE_STATE, data, &reply);
-    int32_t ret = reply.readExceptionCode();
-    if (ret != 0) {
-      return false;
-    }
-    return reply.readBool();
-  }
-};
-
-IMPLEMENT_META_INTERFACE(VrManager, "android.service.vr.IVrManager");
-
-}  // namespace android
diff --git a/libs/vr/public.libraries-google.txt b/libs/vr/public.libraries-google.txt
deleted file mode 100644
index 8271b94..0000000
--- a/libs/vr/public.libraries-google.txt
+++ /dev/null
@@ -1 +0,0 @@
-libdvr.google.so
\ No newline at end of file
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 5b5afd3..b1a287f 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -383,6 +383,14 @@
         // before using cnx->major & cnx->minor
         if (major != nullptr) *major = cnx->major;
         if (minor != nullptr) *minor = cnx->minor;
+        auto mergeExtensionStrings = [](const std::vector<std::string>& strings) {
+            std::ostringstream combinedStringStream;
+            std::copy(strings.begin(), strings.end(),
+                      std::ostream_iterator<std::string>(combinedStringStream, " "));
+            // gBuiltinExtensionString already has a trailing space so is added here
+            return gBuiltinExtensionString + combinedStringStream.str();
+        };
+        mExtensionString = mergeExtensionStrings(extensionStrings);
     }
 
     { // scope for refLock
@@ -391,14 +399,6 @@
         refCond.notify_all();
     }
 
-    auto mergeExtensionStrings = [](const std::vector<std::string>& strings) {
-        std::ostringstream combinedStringStream;
-        std::copy(strings.begin(), strings.end(),
-                  std::ostream_iterator<std::string>(combinedStringStream, " "));
-        // gBuiltinExtensionString already has a trailing space so is added here
-        return gBuiltinExtensionString + combinedStringStream.str();
-    };
-    mExtensionString = mergeExtensionStrings(extensionStrings);
     return EGL_TRUE;
 }
 
diff --git a/services/inputflinger/InputDeviceMetricsCollector.cpp b/services/inputflinger/InputDeviceMetricsCollector.cpp
index b5cb3cb..4621144 100644
--- a/services/inputflinger/InputDeviceMetricsCollector.cpp
+++ b/services/inputflinger/InputDeviceMetricsCollector.cpp
@@ -133,15 +133,6 @@
     mNextListener.notify(args);
 }
 
-void InputDeviceMetricsCollector::notifyConfigurationChanged(
-        const NotifyConfigurationChangedArgs& args) {
-    {
-        std::scoped_lock lock(mLock);
-        reportCompletedSessions();
-    }
-    mNextListener.notify(args);
-}
-
 void InputDeviceMetricsCollector::notifyKey(const NotifyKeyArgs& args) {
     {
         std::scoped_lock lock(mLock);
diff --git a/services/inputflinger/InputDeviceMetricsCollector.h b/services/inputflinger/InputDeviceMetricsCollector.h
index 1bcd527..0a520e6 100644
--- a/services/inputflinger/InputDeviceMetricsCollector.h
+++ b/services/inputflinger/InputDeviceMetricsCollector.h
@@ -107,7 +107,6 @@
                                 std::chrono::nanoseconds usageSessionTimeout);
 
     void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
-    void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
     void notifyKey(const NotifyKeyArgs& args) override;
     void notifyMotion(const NotifyMotionArgs& args) override;
     void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/InputFilter.cpp b/services/inputflinger/InputFilter.cpp
index 8e73ce5..e4d73fc 100644
--- a/services/inputflinger/InputFilter.cpp
+++ b/services/inputflinger/InputFilter.cpp
@@ -67,10 +67,6 @@
     mNextListener.notify(args);
 }
 
-void InputFilter::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
-    mNextListener.notify(args);
-}
-
 void InputFilter::notifyKey(const NotifyKeyArgs& args) {
     if (isFilterEnabled()) {
         LOG_ALWAYS_FATAL_IF(!mInputFilterRust->notifyKey(notifyKeyArgsToKeyEvent(args)).isOk());
diff --git a/services/inputflinger/InputFilter.h b/services/inputflinger/InputFilter.h
index 4ddc9f4..f626703 100644
--- a/services/inputflinger/InputFilter.h
+++ b/services/inputflinger/InputFilter.h
@@ -53,7 +53,6 @@
                          InputFilterPolicyInterface& policy);
     ~InputFilter() override = default;
     void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
-    void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
     void notifyKey(const NotifyKeyArgs& args) override;
     void notifyMotion(const NotifyMotionArgs& args) override;
     void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index 016ae04..8b6accf 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -47,7 +47,6 @@
 void InputListenerInterface::notify(const NotifyArgs& generalArgs) {
     Visitor v{
             [&](const NotifyInputDevicesChangedArgs& args) { notifyInputDevicesChanged(args); },
-            [&](const NotifyConfigurationChangedArgs& args) { notifyConfigurationChanged(args); },
             [&](const NotifyKeyArgs& args) { notifyKey(args); },
             [&](const NotifyMotionArgs& args) { notifyMotion(args); },
             [&](const NotifySwitchArgs& args) { notifySwitch(args); },
@@ -68,10 +67,6 @@
     mArgsQueue.emplace_back(args);
 }
 
-void QueuedInputListener::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
-    mArgsQueue.emplace_back(args);
-}
-
 void QueuedInputListener::notifyKey(const NotifyKeyArgs& args) {
     mArgsQueue.emplace_back(args);
 }
@@ -119,13 +114,6 @@
     mInnerListener.notify(args);
 }
 
-void TracedInputListener::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
-    constexpr static auto& fnName = __func__;
-    ATRACE_NAME_IF(ATRACE_ENABLED(),
-                   StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id));
-    mInnerListener.notify(args);
-}
-
 void TracedInputListener::notifyKey(const NotifyKeyArgs& args) {
     constexpr static auto& fnName = __func__;
     ATRACE_NAME_IF(ATRACE_ENABLED(),
diff --git a/services/inputflinger/InputProcessor.cpp b/services/inputflinger/InputProcessor.cpp
index 6dd267c..8b8b1ad 100644
--- a/services/inputflinger/InputProcessor.cpp
+++ b/services/inputflinger/InputProcessor.cpp
@@ -419,12 +419,6 @@
     mQueuedListener.flush();
 }
 
-void InputProcessor::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
-    // pass through
-    mQueuedListener.notifyConfigurationChanged(args);
-    mQueuedListener.flush();
-}
-
 void InputProcessor::notifyKey(const NotifyKeyArgs& args) {
     // pass through
     mQueuedListener.notifyKey(args);
diff --git a/services/inputflinger/InputProcessor.h b/services/inputflinger/InputProcessor.h
index 7a00a2d..2945dd2 100644
--- a/services/inputflinger/InputProcessor.h
+++ b/services/inputflinger/InputProcessor.h
@@ -246,7 +246,6 @@
     explicit InputProcessor(InputListenerInterface& listener);
 
     void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
-    void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
     void notifyKey(const NotifyKeyArgs& args) override;
     void notifyMotion(const NotifyMotionArgs& args) override;
     void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/NotifyArgs.cpp b/services/inputflinger/NotifyArgs.cpp
index 19a4f26..b2680a2 100644
--- a/services/inputflinger/NotifyArgs.cpp
+++ b/services/inputflinger/NotifyArgs.cpp
@@ -35,11 +35,6 @@
                                                              std::vector<InputDeviceInfo> infos)
       : id(id), inputDeviceInfos(std::move(infos)) {}
 
-// --- NotifyConfigurationChangedArgs ---
-
-NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(int32_t id, nsecs_t eventTime)
-      : id(id), eventTime(eventTime) {}
-
 // --- NotifyKeyArgs ---
 
 NotifyKeyArgs::NotifyKeyArgs(int32_t id, nsecs_t eventTime, nsecs_t readTime, int32_t deviceId,
@@ -198,7 +193,6 @@
 const char* toString(const NotifyArgs& args) {
     Visitor toStringVisitor{
             [&](const NotifyInputDevicesChangedArgs&) { return "NotifyInputDevicesChangedArgs"; },
-            [&](const NotifyConfigurationChangedArgs&) { return "NotifyConfigurationChangedArgs"; },
             [&](const NotifyKeyArgs&) { return "NotifyKeyArgs"; },
             [&](const NotifyMotionArgs&) { return "NotifyMotionArgs"; },
             [&](const NotifySensorArgs&) { return "NotifySensorArgs"; },
diff --git a/services/inputflinger/PointerChoreographer.cpp b/services/inputflinger/PointerChoreographer.cpp
index 00dd6ba..625599a 100644
--- a/services/inputflinger/PointerChoreographer.cpp
+++ b/services/inputflinger/PointerChoreographer.cpp
@@ -165,10 +165,6 @@
     mNextListener.notify(args);
 }
 
-void PointerChoreographer::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
-    mNextListener.notify(args);
-}
-
 void PointerChoreographer::notifyKey(const NotifyKeyArgs& args) {
     fadeMouseCursorOnKeyPress(args);
     mNextListener.notify(args);
@@ -202,6 +198,7 @@
     }
     auto it = mMousePointersByDisplay.find(targetDisplay);
     if (it != mMousePointersByDisplay.end()) {
+        mPolicy.notifyMouseCursorFadedOnTyping();
         it->second->fade(PointerControllerInterface::Transition::GRADUAL);
     }
 }
@@ -367,7 +364,8 @@
     const uint8_t actionIndex = MotionEvent::getActionIndex(args.action);
     std::array<uint32_t, MAX_POINTER_ID + 1> idToIndex;
     BitSet32 idBits;
-    if (maskedAction != AMOTION_EVENT_ACTION_UP && maskedAction != AMOTION_EVENT_ACTION_CANCEL) {
+    if (maskedAction != AMOTION_EVENT_ACTION_UP && maskedAction != AMOTION_EVENT_ACTION_CANCEL &&
+        maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
         for (size_t i = 0; i < args.getPointerCount(); i++) {
             if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP && actionIndex == i) {
                 continue;
diff --git a/services/inputflinger/PointerChoreographer.h b/services/inputflinger/PointerChoreographer.h
index aaf1e3e..635487b 100644
--- a/services/inputflinger/PointerChoreographer.h
+++ b/services/inputflinger/PointerChoreographer.h
@@ -105,7 +105,6 @@
     void setFocusedDisplay(ui::LogicalDisplayId displayId) override;
 
     void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
-    void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
     void notifyKey(const NotifyKeyArgs& args) override;
     void notifyMotion(const NotifyMotionArgs& args) override;
     void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/UnwantedInteractionBlocker.cpp b/services/inputflinger/UnwantedInteractionBlocker.cpp
index 1e2b9b3a..0e9ec91 100644
--- a/services/inputflinger/UnwantedInteractionBlocker.cpp
+++ b/services/inputflinger/UnwantedInteractionBlocker.cpp
@@ -342,12 +342,6 @@
                                                        bool enablePalmRejection)
       : mQueuedListener(listener), mEnablePalmRejection(enablePalmRejection) {}
 
-void UnwantedInteractionBlocker::notifyConfigurationChanged(
-        const NotifyConfigurationChangedArgs& args) {
-    mQueuedListener.notifyConfigurationChanged(args);
-    mQueuedListener.flush();
-}
-
 void UnwantedInteractionBlocker::notifyKey(const NotifyKeyArgs& args) {
     mQueuedListener.notifyKey(args);
     mQueuedListener.flush();
diff --git a/services/inputflinger/UnwantedInteractionBlocker.h b/services/inputflinger/UnwantedInteractionBlocker.h
index 419da83..8a66e25 100644
--- a/services/inputflinger/UnwantedInteractionBlocker.h
+++ b/services/inputflinger/UnwantedInteractionBlocker.h
@@ -91,7 +91,6 @@
     explicit UnwantedInteractionBlocker(InputListenerInterface& listener, bool enablePalmRejection);
 
     void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
-    void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
     void notifyKey(const NotifyKeyArgs& args) override;
     void notifyMotion(const NotifyMotionArgs& args) override;
     void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index ad9cec1..ff407af 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -68,15 +68,6 @@
         injectionState(nullptr),
         dispatchInProgress(false) {}
 
-// --- ConfigurationChangedEntry ---
-
-ConfigurationChangedEntry::ConfigurationChangedEntry(int32_t id, nsecs_t eventTime)
-      : EventEntry(id, Type::CONFIGURATION_CHANGED, eventTime, 0) {}
-
-std::string ConfigurationChangedEntry::getDescription() const {
-    return StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
-}
-
 // --- DeviceResetEntry ---
 
 DeviceResetEntry::DeviceResetEntry(int32_t id, nsecs_t eventTime, int32_t deviceId)
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index f2f31d8..becfb05 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -32,7 +32,6 @@
 
 struct EventEntry {
     enum class Type {
-        CONFIGURATION_CHANGED,
         DEVICE_RESET,
         FOCUS,
         KEY,
@@ -78,11 +77,6 @@
     virtual ~EventEntry() = default;
 };
 
-struct ConfigurationChangedEntry : EventEntry {
-    explicit ConfigurationChangedEntry(int32_t id, nsecs_t eventTime);
-    std::string getDescription() const override;
-};
-
 struct DeviceResetEntry : EventEntry {
     int32_t deviceId;
 
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 47c2889..4076817 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -558,7 +558,6 @@
 // Returns true if the event type passed as argument represents a user activity.
 bool isUserActivityEvent(const EventEntry& eventEntry) {
     switch (eventEntry.type) {
-        case EventEntry::Type::CONFIGURATION_CHANGED:
         case EventEntry::Type::DEVICE_RESET:
         case EventEntry::Type::DRAG:
         case EventEntry::Type::FOCUS:
@@ -879,7 +878,7 @@
 class ScopedSyntheticEventTracer {
 public:
     ScopedSyntheticEventTracer(std::unique_ptr<trace::InputTracerInterface>& tracer)
-          : mTracer(tracer) {
+          : mTracer(tracer), mProcessingTimestamp(now()) {
         if (mTracer) {
             mEventTracker = mTracer->createTrackerForSyntheticEvent();
         }
@@ -887,7 +886,7 @@
 
     ~ScopedSyntheticEventTracer() {
         if (mTracer) {
-            mTracer->eventProcessingComplete(*mEventTracker);
+            mTracer->eventProcessingComplete(*mEventTracker, mProcessingTimestamp);
         }
     }
 
@@ -896,10 +895,29 @@
     }
 
 private:
-    std::unique_ptr<trace::InputTracerInterface>& mTracer;
+    const std::unique_ptr<trace::InputTracerInterface>& mTracer;
     std::unique_ptr<trace::EventTrackerInterface> mEventTracker;
+    const nsecs_t mProcessingTimestamp;
 };
 
+/**
+ * This is needed to help use "InputEventInjectionResult" with base::Result.
+ */
+template <typename T>
+struct EnumErrorWrapper {
+    T mVal;
+    EnumErrorWrapper(T&& e) : mVal(std::forward<T>(e)) {}
+    operator const T&() const { return mVal; }
+    T value() const { return mVal; }
+    std::string print() const { return ftl::enum_string(mVal); }
+};
+
+Error<EnumErrorWrapper<InputEventInjectionResult>> injectionError(InputEventInjectionResult&& e) {
+    LOG_ALWAYS_FATAL_IF(e == InputEventInjectionResult::SUCCEEDED);
+    return Error<EnumErrorWrapper<InputEventInjectionResult>>(
+            std::forward<InputEventInjectionResult>(e));
+}
+
 } // namespace
 
 // --- InputDispatcher ---
@@ -1152,14 +1170,6 @@
     }
 
     switch (mPendingEvent->type) {
-        case EventEntry::Type::CONFIGURATION_CHANGED: {
-            const ConfigurationChangedEntry& typedEntry =
-                    static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
-            done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
-            dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
-            break;
-        }
-
         case EventEntry::Type::DEVICE_RESET: {
             const DeviceResetEntry& typedEntry =
                     static_cast<const DeviceResetEntry&>(*mPendingEvent);
@@ -1263,7 +1273,7 @@
 
         if (mTracer) {
             if (auto& traceTracker = getTraceTracker(*mPendingEvent); traceTracker != nullptr) {
-                mTracer->eventProcessingComplete(*traceTracker);
+                mTracer->eventProcessingComplete(*traceTracker, currentTime);
             }
         }
 
@@ -1307,7 +1317,7 @@
 
         // Alternatively, maybe there's a spy window that could handle this event.
         const std::vector<sp<WindowInfoHandle>> touchedSpies =
-                findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
+                findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus, motionEntry.deviceId);
         for (const auto& windowHandle : touchedSpies) {
             const std::shared_ptr<Connection> connection =
                     getConnectionLocked(windowHandle->getToken());
@@ -1391,7 +1401,6 @@
             break;
         }
         case EventEntry::Type::TOUCH_MODE_CHANGED:
-        case EventEntry::Type::CONFIGURATION_CHANGED:
         case EventEntry::Type::DEVICE_RESET:
         case EventEntry::Type::SENSOR:
         case EventEntry::Type::POINTER_CAPTURE_CHANGED:
@@ -1462,15 +1471,27 @@
 }
 
 std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
-        ui::LogicalDisplayId displayId, float x, float y, bool isStylus) const {
+        ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId) const {
     // Traverse windows from front to back and gather the touched spy windows.
     std::vector<sp<WindowInfoHandle>> spyWindows;
     const auto& windowHandles = getWindowHandlesLocked(displayId);
     for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
         const WindowInfo& info = *windowHandle->getInfo();
-
         if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
-            continue;
+            // Generally, we would skip any pointer that's outside of the window. However, if the
+            // spy prevents splitting, and already has some of the pointers from this device, then
+            // it should get more pointers from the same device, even if they are outside of that
+            // window
+            if (info.supportsSplitTouch()) {
+                continue;
+            }
+
+            // We know that split touch is not supported. Skip this window only if it doesn't have
+            // any touching pointers for this device already.
+            if (!windowHasTouchingPointersLocked(windowHandle, deviceId)) {
+                continue;
+            }
+            // If it already has pointers down for this device, then give it this pointer, too.
         }
         if (!info.isSpy()) {
             // The first touched non-spy window was found, so return the spy windows touched so far.
@@ -1553,7 +1574,6 @@
         }
         case EventEntry::Type::FOCUS:
         case EventEntry::Type::TOUCH_MODE_CHANGED:
-        case EventEntry::Type::CONFIGURATION_CHANGED:
         case EventEntry::Type::DEVICE_RESET: {
             LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
             break;
@@ -1642,24 +1662,6 @@
     return newEntry;
 }
 
-bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
-                                                         const ConfigurationChangedEntry& entry) {
-    if (DEBUG_OUTBOUND_EVENT_DETAILS) {
-        ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
-    }
-
-    // Reset key repeating in case a keyboard device was added or removed or something.
-    resetKeyRepeatLocked();
-
-    // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
-    auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
-        scoped_unlock unlock(mLock);
-        mPolicy.notifyConfigurationChanged(eventTime);
-    };
-    postCommandLocked(std::move(command));
-    return true;
-}
-
 bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
                                                 const DeviceResetEntry& entry) {
     if (DEBUG_OUTBOUND_EVENT_DETAILS) {
@@ -1922,20 +1924,21 @@
     }
 
     // Identify targets.
-    InputEventInjectionResult injectionResult;
-    sp<WindowInfoHandle> focusedWindow =
-            findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime,
-                                          /*byref*/ injectionResult);
-    if (injectionResult == InputEventInjectionResult::PENDING) {
-        return false;
-    }
+    Result<sp<WindowInfoHandle>, InputEventInjectionResult> result =
+            findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime);
 
-    setInjectionResult(*entry, injectionResult);
-    if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
+    if (!result.ok()) {
+        if (result.error().code() == InputEventInjectionResult::PENDING) {
+            return false;
+        }
+        setInjectionResult(*entry, result.error().code());
         return true;
     }
+    sp<WindowInfoHandle>& focusedWindow = *result;
     LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
 
+    setInjectionResult(*entry, InputEventInjectionResult::SUCCEEDED);
+
     std::vector<InputTarget> inputTargets;
     addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
                           InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets);
@@ -2040,19 +2043,28 @@
             pilferPointersLocked(mDragState->dragWindow->getToken());
         }
 
-        inputTargets =
-                findTouchedWindowTargetsLocked(currentTime, *entry, /*byref*/ injectionResult);
-        LOG_ALWAYS_FATAL_IF(injectionResult != InputEventInjectionResult::SUCCEEDED &&
-                            !inputTargets.empty());
+        Result<std::vector<InputTarget>, InputEventInjectionResult> result =
+                findTouchedWindowTargetsLocked(currentTime, *entry);
+
+        if (result.ok()) {
+            inputTargets = std::move(*result);
+            injectionResult = InputEventInjectionResult::SUCCEEDED;
+        } else {
+            injectionResult = result.error().code();
+        }
     } else {
         // Non touch event.  (eg. trackball)
-        sp<WindowInfoHandle> focusedWindow =
-                findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime, injectionResult);
-        if (injectionResult == InputEventInjectionResult::SUCCEEDED) {
+        Result<sp<WindowInfoHandle>, InputEventInjectionResult> result =
+                findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime);
+        if (result.ok()) {
+            sp<WindowInfoHandle>& focusedWindow = *result;
             LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
             addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
                                   InputTarget::Flags::FOREGROUND, getDownTime(*entry),
                                   inputTargets);
+            injectionResult = InputEventInjectionResult::SUCCEEDED;
+        } else {
+            injectionResult = result.error().code();
         }
     }
     if (injectionResult == InputEventInjectionResult::PENDING) {
@@ -2113,19 +2125,16 @@
     if (DEBUG_OUTBOUND_EVENT_DETAILS) {
         ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=%s, displayId=%s, policyFlags=0x%x, "
               "action=%s, actionButton=0x%x, flags=0x%x, "
-              "metaState=0x%x, buttonState=0x%x,"
-              "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%" PRId64,
+              "metaState=0x%x, buttonState=0x%x, downTime=%" PRId64,
               prefix, entry.eventTime, entry.deviceId,
               inputEventSourceToString(entry.source).c_str(), entry.displayId.toString().c_str(),
               entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
-              entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.edgeFlags,
-              entry.xPrecision, entry.yPrecision, entry.downTime);
+              entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.downTime);
 
         for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
             ALOGD("  Pointer %d: id=%d, toolType=%s, "
                   "x=%f, y=%f, pressure=%f, size=%f, "
-                  "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
-                  "orientation=%f",
+                  "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
                   i, entry.pointerProperties[i].id,
                   ftl::enum_string(entry.pointerProperties[i].toolType).c_str(),
                   entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
@@ -2220,7 +2229,6 @@
         case EventEntry::Type::TOUCH_MODE_CHANGED:
         case EventEntry::Type::POINTER_CAPTURE_CHANGED:
         case EventEntry::Type::FOCUS:
-        case EventEntry::Type::CONFIGURATION_CHANGED:
         case EventEntry::Type::DEVICE_RESET:
         case EventEntry::Type::SENSOR:
         case EventEntry::Type::DRAG: {
@@ -2262,11 +2270,9 @@
     return false;
 }
 
-sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked(
-        nsecs_t currentTime, const EventEntry& entry, nsecs_t& nextWakeupTime,
-        InputEventInjectionResult& outInjectionResult) {
-    outInjectionResult = InputEventInjectionResult::FAILED; // Default result
-
+Result<sp<WindowInfoHandle>, InputEventInjectionResult>
+InputDispatcher::findFocusedWindowTargetLocked(nsecs_t currentTime, const EventEntry& entry,
+                                               nsecs_t& nextWakeupTime) {
     ui::LogicalDisplayId displayId = getTargetDisplayId(entry);
     sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
     std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
@@ -2278,12 +2284,12 @@
         ALOGI("Dropping %s event because there is no focused window or focused application in "
               "display %s.",
               ftl::enum_string(entry.type).c_str(), displayId.toString().c_str());
-        return nullptr;
+        return injectionError(InputEventInjectionResult::FAILED);
     }
 
     // Drop key events if requested by input feature
     if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
-        return nullptr;
+        return injectionError(InputEventInjectionResult::FAILED);
     }
 
     // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
@@ -2303,17 +2309,15 @@
                   "window when it finishes starting up. Will wait for %" PRId64 "ms",
                   mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
             nextWakeupTime = std::min(nextWakeupTime, *mNoFocusedWindowTimeoutTime);
-            outInjectionResult = InputEventInjectionResult::PENDING;
-            return nullptr;
+            return injectionError(InputEventInjectionResult::PENDING);
         } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
             // Already raised ANR. Drop the event
             ALOGE("Dropping %s event because there is no focused window",
                   ftl::enum_string(entry.type).c_str());
-            return nullptr;
+            return injectionError(InputEventInjectionResult::FAILED);
         } else {
             // Still waiting for the focused window
-            outInjectionResult = InputEventInjectionResult::PENDING;
-            return nullptr;
+            return injectionError(InputEventInjectionResult::PENDING);
         }
     }
 
@@ -2323,15 +2327,13 @@
     // Verify targeted injection.
     if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
         ALOGW("Dropping injected event: %s", (*err).c_str());
-        outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
-        return nullptr;
+        return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
     }
 
     if (focusedWindowHandle->getInfo()->inputConfig.test(
                 WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
         ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
-        outInjectionResult = InputEventInjectionResult::PENDING;
-        return nullptr;
+        return injectionError(InputEventInjectionResult::PENDING);
     }
 
     // If the event is a key event, then we must wait for all previous events to
@@ -2348,12 +2350,10 @@
     if (entry.type == EventEntry::Type::KEY) {
         if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
             nextWakeupTime = std::min(nextWakeupTime, *mKeyIsWaitingForEventsTimeout);
-            outInjectionResult = InputEventInjectionResult::PENDING;
-            return nullptr;
+            return injectionError(InputEventInjectionResult::PENDING);
         }
     }
-
-    outInjectionResult = InputEventInjectionResult::SUCCEEDED;
+    // Success!
     return focusedWindowHandle;
 }
 
@@ -2377,9 +2377,8 @@
     return responsiveMonitors;
 }
 
-std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
-        nsecs_t currentTime, const MotionEntry& entry,
-        InputEventInjectionResult& outInjectionResult) {
+base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
+InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) {
     ATRACE_CALL();
 
     std::vector<InputTarget> targets;
@@ -2389,9 +2388,6 @@
     const int32_t action = entry.action;
     const int32_t maskedAction = MotionEvent::getActionMasked(action);
 
-    // Update the touch state as needed based on the properties of the touch event.
-    outInjectionResult = InputEventInjectionResult::PENDING;
-
     // Copy current touch state into tempTouchState.
     // This state will be used to update mTouchStatesByDisplay at the end of this function.
     // If no state for the specified display exists, then our initial state will be empty.
@@ -2431,8 +2427,7 @@
             // Started hovering, but the device is already down: reject the hover event
             LOG(ERROR) << "Got hover event " << entry.getDescription()
                        << " but the device is already down " << oldState->dump();
-            outInjectionResult = InputEventInjectionResult::FAILED;
-            return {};
+            return injectionError(InputEventInjectionResult::FAILED);
         }
         // For hover actions, we will treat 'tempTouchState' as a new state, so let's erase
         // all of the existing hovering pointers and recompute.
@@ -2464,9 +2459,7 @@
         // Verify targeted injection.
         if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
             ALOGW("Dropping injected touch event: %s", (*err).c_str());
-            outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
-            newTouchedWindowHandle = nullptr;
-            return {};
+            return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
         }
 
         // Figure out whether splitting will be allowed for this window.
@@ -2489,18 +2482,16 @@
         }
 
         std::vector<sp<WindowInfoHandle>> newTouchedWindows =
-                findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
+                findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus, entry.deviceId);
         if (newTouchedWindowHandle != nullptr) {
             // Process the foreground window first so that it is the first to receive the event.
             newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
         }
 
         if (newTouchedWindows.empty()) {
-            ALOGI("Dropping event because there is no touchable window at (%.1f, %.1f) on display "
-                  "%s.",
-                  x, y, displayId.toString().c_str());
-            outInjectionResult = InputEventInjectionResult::FAILED;
-            return {};
+            LOG(INFO) << "Dropping event because there is no touchable window at (" << x << ", "
+                      << y << ") on display " << displayId << ": " << entry;
+            return injectionError(InputEventInjectionResult::FAILED);
         }
 
         for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
@@ -2600,8 +2591,7 @@
                           << " is not down or we previously dropped the pointer down event in "
                           << "display " << displayId << ": " << entry.getDescription();
             }
-            outInjectionResult = InputEventInjectionResult::FAILED;
-            return {};
+            return injectionError(InputEventInjectionResult::FAILED);
         }
 
         // If the pointer is not currently hovering, then ignore the event.
@@ -2612,8 +2602,7 @@
                 LOG(INFO) << "Dropping event because the hovering pointer is not in any windows in "
                              "display "
                           << displayId << ": " << entry.getDescription();
-                outInjectionResult = InputEventInjectionResult::FAILED;
-                return {};
+                return injectionError(InputEventInjectionResult::FAILED);
             }
             tempTouchState.removeHoveringPointer(entry.deviceId, pointerId);
         }
@@ -2634,8 +2623,7 @@
             // Verify targeted injection.
             if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
                 ALOGW("Dropping injected event: %s", (*err).c_str());
-                outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
-                return {};
+                return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
             }
 
             // Do not slide events to the window which can not receive motion event
@@ -2704,6 +2692,9 @@
                 if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
                     continue;
                 }
+                if (!touchedWindow.hasTouchingPointers(entry.deviceId)) {
+                    continue;
+                }
                 touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
             }
         }
@@ -2735,8 +2726,7 @@
             ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
                   "%s:%s",
                   entry.injectionState->targetUid->toString().c_str(), errs.c_str());
-            outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
-            return {};
+            return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
         }
     }
 
@@ -2793,8 +2783,7 @@
 
     if (targets.empty()) {
         LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription();
-        outInjectionResult = InputEventInjectionResult::FAILED;
-        return {};
+        return injectionError(InputEventInjectionResult::FAILED);
     }
 
     // If we only have windows getting ACTION_OUTSIDE, then drop the event, because there is no
@@ -2804,12 +2793,9 @@
         })) {
         LOG(INFO) << "Dropping event because all windows would just receive ACTION_OUTSIDE: "
                   << entry.getDescription();
-        outInjectionResult = InputEventInjectionResult::FAILED;
-        return {};
+        return injectionError(InputEventInjectionResult::FAILED);
     }
 
-    outInjectionResult = InputEventInjectionResult::SUCCEEDED;
-
     // Now that we have generated all of the input targets for this event, reset the dispatch
     // mode for all touched window to AS_IS.
     for (TouchedWindow& touchedWindow : tempTouchState.windows) {
@@ -3617,7 +3603,6 @@
             LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
             break;
         }
-        case EventEntry::Type::CONFIGURATION_CHANGED:
         case EventEntry::Type::DEVICE_RESET: {
             LOG_ALWAYS_FATAL("%s events should not go to apps",
                              ftl::enum_string(eventEntry->type).c_str());
@@ -3830,6 +3815,10 @@
                 }
                 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
                 status = publishMotionEvent(*connection, *dispatchEntry);
+                if (status == BAD_VALUE) {
+                    logDispatchStateLocked();
+                    LOG(FATAL) << "Publisher failed for " << motionEntry;
+                }
                 if (mTracer) {
                     ensureEventTraced(motionEntry);
                     mTracer->traceEventDispatch(*dispatchEntry, *motionEntry.traceTracker);
@@ -3874,7 +3863,6 @@
                 break;
             }
 
-            case EventEntry::Type::CONFIGURATION_CHANGED:
             case EventEntry::Type::DEVICE_RESET:
             case EventEntry::Type::SENSOR: {
                 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
@@ -4270,7 +4258,6 @@
                                  ftl::enum_string(cancelationEventEntry->type).c_str());
                 break;
             }
-            case EventEntry::Type::CONFIGURATION_CHANGED:
             case EventEntry::Type::DEVICE_RESET:
             case EventEntry::Type::SENSOR: {
                 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
@@ -4353,7 +4340,6 @@
             case EventEntry::Type::KEY:
             case EventEntry::Type::FOCUS:
             case EventEntry::Type::TOUCH_MODE_CHANGED:
-            case EventEntry::Type::CONFIGURATION_CHANGED:
             case EventEntry::Type::DEVICE_RESET:
             case EventEntry::Type::POINTER_CAPTURE_CHANGED:
             case EventEntry::Type::SENSOR:
@@ -4439,28 +4425,11 @@
 
 void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
     std::scoped_lock _l(mLock);
+    // Reset key repeating in case a keyboard device was added or removed or something.
+    resetKeyRepeatLocked();
     mLatencyTracker.setInputDevices(args.inputDeviceInfos);
 }
 
-void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
-    if (debugInboundEventDetails()) {
-        ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args.eventTime);
-    }
-
-    bool needWake = false;
-    { // acquire lock
-        std::scoped_lock _l(mLock);
-
-        std::unique_ptr<ConfigurationChangedEntry> newEntry =
-                std::make_unique<ConfigurationChangedEntry>(args.id, args.eventTime);
-        needWake = enqueueInboundEventLocked(std::move(newEntry));
-    } // release lock
-
-    if (needWake) {
-        mLooper->wake();
-    }
-}
-
 void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
     ALOGD_IF(debugInboundEventDetails(),
              "notifyKey - id=%" PRIx32 ", eventTime=%" PRId64
@@ -4548,13 +4517,12 @@
         ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=%s, "
               "displayId=%s, policyFlags=0x%x, "
               "action=%s, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
-              "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, xCursorPosition=%f, "
-              "yCursorPosition=%f, downTime=%" PRId64,
+              "xCursorPosition=%f, yCursorPosition=%f, downTime=%" PRId64,
               args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
               args.displayId.toString().c_str(), args.policyFlags,
               MotionEvent::actionToString(args.action).c_str(), args.actionButton, args.flags,
-              args.metaState, args.buttonState, args.edgeFlags, args.xPrecision, args.yPrecision,
-              args.xCursorPosition, args.yCursorPosition, args.downTime);
+              args.metaState, args.buttonState, args.xCursorPosition, args.yCursorPosition,
+              args.downTime);
         for (uint32_t i = 0; i < args.getPointerCount(); i++) {
             ALOGD("  Pointer %d: id=%d, toolType=%s, x=%f, y=%f, pressure=%f, size=%f, "
                   "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
@@ -5676,7 +5644,7 @@
     mMaximumObscuringOpacityForTouch = opacity;
 }
 
-std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId /*displayId*/>
+std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId>
 InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) {
     for (auto& [displayId, state] : mTouchStatesByDisplay) {
         for (TouchedWindow& w : state.windows) {
@@ -5688,6 +5656,22 @@
     return std::make_tuple(nullptr, nullptr, ui::LogicalDisplayId::DEFAULT);
 }
 
+std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId>
+InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) const {
+    return const_cast<InputDispatcher*>(this)->findTouchStateWindowAndDisplayLocked(token);
+}
+
+bool InputDispatcher::windowHasTouchingPointersLocked(const sp<WindowInfoHandle>& windowHandle,
+                                                      DeviceId deviceId) const {
+    const auto& [touchState, touchedWindow, _] =
+            findTouchStateWindowAndDisplayLocked(windowHandle->getToken());
+    if (touchState == nullptr) {
+        // No touching pointers at all
+        return false;
+    }
+    return touchState->hasTouchingPointers(deviceId);
+}
+
 bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
                                            bool isDragDrop) {
     if (fromToken == toToken) {
@@ -6024,17 +6008,12 @@
                 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
                                      connection->outboundQueue.size());
                 dump += dumpQueue(connection->outboundQueue, currentTime);
-
-            } else {
-                dump += INDENT3 "OutboundQueue: <empty>\n";
             }
 
             if (!connection->waitQueue.empty()) {
                 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
                                      connection->waitQueue.size());
                 dump += dumpQueue(connection->waitQueue, currentTime);
-            } else {
-                dump += INDENT3 "WaitQueue: <empty>\n";
             }
             std::string inputStateDump = streamableToString(connection->inputState);
             if (!inputStateDump.empty()) {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index e2fc7a0..698bdba 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -97,7 +97,6 @@
     status_t stop() override;
 
     void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
-    void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
     void notifyKey(const NotifyKeyArgs& args) override;
     void notifyMotion(const NotifyMotionArgs& args) override;
     void notifySwitch(const NotifySwitchArgs& args) override;
@@ -258,7 +257,8 @@
             int32_t pointerId) const REQUIRES(mLock);
 
     std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAtLocked(
-            ui::LogicalDisplayId displayId, float x, float y, bool isStylus) const REQUIRES(mLock);
+            ui::LogicalDisplayId displayId, float x, float y, bool isStylus,
+            DeviceId deviceId) const REQUIRES(mLock);
 
     sp<android::gui::WindowInfoHandle> findTouchedForegroundWindowLocked(
             ui::LogicalDisplayId displayId) const REQUIRES(mLock);
@@ -446,8 +446,6 @@
             REQUIRES(mLock);
 
     // Dispatch inbound events.
-    bool dispatchConfigurationChangedLocked(nsecs_t currentTime,
-                                            const ConfigurationChangedEntry& entry) REQUIRES(mLock);
     bool dispatchDeviceResetLocked(nsecs_t currentTime, const DeviceResetEntry& entry)
             REQUIRES(mLock);
     bool dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry,
@@ -536,12 +534,11 @@
     void resetNoFocusedWindowTimeoutLocked() REQUIRES(mLock);
 
     ui::LogicalDisplayId getTargetDisplayId(const EventEntry& entry);
-    sp<android::gui::WindowInfoHandle> findFocusedWindowTargetLocked(
-            nsecs_t currentTime, const EventEntry& entry, nsecs_t& nextWakeupTime,
-            android::os::InputEventInjectionResult& outInjectionResult) REQUIRES(mLock);
-    std::vector<InputTarget> findTouchedWindowTargetsLocked(
-            nsecs_t currentTime, const MotionEntry& entry,
-            android::os::InputEventInjectionResult& outInjectionResult) REQUIRES(mLock);
+    base::Result<sp<android::gui::WindowInfoHandle>, android::os::InputEventInjectionResult>
+    findFocusedWindowTargetLocked(nsecs_t currentTime, const EventEntry& entry,
+                                  nsecs_t& nextWakeupTime) REQUIRES(mLock);
+    base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
+    findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) REQUIRES(mLock);
     std::vector<Monitor> selectResponsiveMonitorsLocked(
             const std::vector<Monitor>& gestureMonitors) const REQUIRES(mLock);
 
@@ -684,16 +681,21 @@
                                   const std::string& reason) REQUIRES(mLock);
     void updateLastAnrStateLocked(const std::string& windowLabel, const std::string& reason)
             REQUIRES(mLock);
-    std::map<ui::LogicalDisplayId /*displayId*/, InputVerifier> mVerifiersByDisplay;
+    std::map<ui::LogicalDisplayId, InputVerifier> mVerifiersByDisplay;
     // Returns a fallback KeyEntry that should be sent to the connection, if required.
     std::unique_ptr<const KeyEntry> afterKeyEventLockedInterruptable(
             const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry,
             bool handled) REQUIRES(mLock);
 
     // Find touched state and touched window by token.
-    std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId /*displayId*/>
+    std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId>
     findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) REQUIRES(mLock);
 
+    std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId>
+    findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) const REQUIRES(mLock);
+    bool windowHasTouchingPointersLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
+                                         DeviceId deviceId) const REQUIRES(mLock);
+
     // Statistics gathering.
     LatencyAggregator mLatencyAggregator GUARDED_BY(mLock);
     LatencyTracker mLatencyTracker GUARDED_BY(mLock);
diff --git a/services/inputflinger/dispatcher/InputEventTimeline.cpp b/services/inputflinger/dispatcher/InputEventTimeline.cpp
index a7c6d16..a365003 100644
--- a/services/inputflinger/dispatcher/InputEventTimeline.cpp
+++ b/services/inputflinger/dispatcher/InputEventTimeline.cpp
@@ -68,7 +68,7 @@
 
 InputEventTimeline::InputEventTimeline(bool isDown, nsecs_t eventTime, nsecs_t readTime,
                                        uint16_t vendorId, uint16_t productId,
-                                       std::set<InputDeviceUsageSource> sources)
+                                       const std::set<InputDeviceUsageSource>& sources)
       : isDown(isDown),
         eventTime(eventTime),
         readTime(readTime),
diff --git a/services/inputflinger/dispatcher/InputEventTimeline.h b/services/inputflinger/dispatcher/InputEventTimeline.h
index e9deb2d..1756944 100644
--- a/services/inputflinger/dispatcher/InputEventTimeline.h
+++ b/services/inputflinger/dispatcher/InputEventTimeline.h
@@ -76,7 +76,7 @@
 
 struct InputEventTimeline {
     InputEventTimeline(bool isDown, nsecs_t eventTime, nsecs_t readTime, uint16_t vendorId,
-                       uint16_t productId, std::set<InputDeviceUsageSource> sources);
+                       uint16_t productId, const std::set<InputDeviceUsageSource>& sources);
     const bool isDown; // True if this is an ACTION_DOWN event
     const nsecs_t eventTime;
     const nsecs_t readTime;
diff --git a/services/inputflinger/dispatcher/InputState.cpp b/services/inputflinger/dispatcher/InputState.cpp
index 46e7e8b..4df23c5 100644
--- a/services/inputflinger/dispatcher/InputState.cpp
+++ b/services/inputflinger/dispatcher/InputState.cpp
@@ -499,67 +499,53 @@
         nsecs_t currentTime) {
     std::vector<std::unique_ptr<MotionEntry>> events;
     std::vector<uint32_t> canceledPointerIndices;
-    std::vector<PointerProperties> pointerProperties(MAX_POINTERS);
-    std::vector<PointerCoords> pointerCoords(MAX_POINTERS);
+
     for (uint32_t pointerIdx = 0; pointerIdx < memento.getPointerCount(); pointerIdx++) {
         uint32_t pointerId = uint32_t(memento.pointerProperties[pointerIdx].id);
-        pointerProperties[pointerIdx] = memento.pointerProperties[pointerIdx];
-        pointerCoords[pointerIdx] = memento.pointerCoords[pointerIdx];
         if (pointerIds.test(pointerId)) {
             canceledPointerIndices.push_back(pointerIdx);
         }
     }
 
     if (canceledPointerIndices.size() == memento.getPointerCount()) {
-        const int32_t action =
-                memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL;
-        int32_t flags = memento.flags;
-        if (action == AMOTION_EVENT_ACTION_CANCEL) {
-            flags |= AMOTION_EVENT_FLAG_CANCELED;
+        // We are cancelling all pointers.
+        events.emplace_back(createCancelEntryForMemento(memento, currentTime));
+        return events;
+    }
+
+    // If we aren't canceling all pointers, we need to generate ACTION_POINTER_UP with
+    // FLAG_CANCELED for each of the canceled pointers. For each event, we must remove the
+    // previously canceled pointers from PointerProperties and PointerCoords, and update
+    // pointerCount appropriately. For convenience, sort the canceled pointer indices in
+    // descending order so that we can just slide the remaining pointers to the beginning of
+    // the array when a pointer is canceled.
+    std::sort(canceledPointerIndices.begin(), canceledPointerIndices.end(),
+              std::greater<uint32_t>());
+
+    std::vector<PointerProperties> pointerProperties = memento.pointerProperties;
+    std::vector<PointerCoords> pointerCoords = memento.pointerCoords;
+    for (const uint32_t pointerIdx : canceledPointerIndices) {
+        if (pointerProperties.size() <= 1) {
+            LOG(FATAL) << "Unexpected code path for canceling all pointers!";
         }
+        const int32_t action = AMOTION_EVENT_ACTION_POINTER_UP |
+                (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
         events.push_back(
                 std::make_unique<MotionEntry>(mIdGenerator.nextId(), /*injectionState=*/nullptr,
                                               currentTime, memento.deviceId, memento.source,
                                               memento.displayId, memento.policyFlags, action,
-                                              /*actionButton=*/0, flags, AMETA_NONE,
-                                              /*buttonState=*/0, MotionClassification::NONE,
+                                              /*actionButton=*/0,
+                                              memento.flags | AMOTION_EVENT_FLAG_CANCELED,
+                                              AMETA_NONE, /*buttonState=*/0,
+                                              MotionClassification::NONE,
                                               AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
                                               memento.yPrecision, memento.xCursorPosition,
                                               memento.yCursorPosition, memento.downTime,
-                                              memento.pointerProperties, memento.pointerCoords));
-    } else {
-        // If we aren't canceling all pointers, we need to generate ACTION_POINTER_UP with
-        // FLAG_CANCELED for each of the canceled pointers. For each event, we must remove the
-        // previously canceled pointers from PointerProperties and PointerCoords, and update
-        // pointerCount appropriately. For convenience, sort the canceled pointer indices so that we
-        // can just slide the remaining pointers to the beginning of the array when a pointer is
-        // canceled.
-        std::sort(canceledPointerIndices.begin(), canceledPointerIndices.end(),
-                  std::greater<uint32_t>());
+                                              pointerProperties, pointerCoords));
 
-        uint32_t pointerCount = memento.getPointerCount();
-        for (const uint32_t pointerIdx : canceledPointerIndices) {
-            const int32_t action = pointerCount == 1 ? AMOTION_EVENT_ACTION_CANCEL
-                                                     : AMOTION_EVENT_ACTION_POINTER_UP |
-                            (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
-            events.push_back(
-                    std::make_unique<MotionEntry>(mIdGenerator.nextId(), /*injectionState=*/nullptr,
-                                                  currentTime, memento.deviceId, memento.source,
-                                                  memento.displayId, memento.policyFlags, action,
-                                                  /*actionButton=*/0,
-                                                  memento.flags | AMOTION_EVENT_FLAG_CANCELED,
-                                                  AMETA_NONE, /*buttonState=*/0,
-                                                  MotionClassification::NONE,
-                                                  AMOTION_EVENT_EDGE_FLAG_NONE, memento.xPrecision,
-                                                  memento.yPrecision, memento.xCursorPosition,
-                                                  memento.yCursorPosition, memento.downTime,
-                                                  pointerProperties, pointerCoords));
-
-            // Cleanup pointer information
-            pointerProperties.erase(pointerProperties.begin() + pointerIdx);
-            pointerCoords.erase(pointerCoords.begin() + pointerIdx);
-            pointerCount--;
-        }
+        // Cleanup pointer information
+        pointerProperties.erase(pointerProperties.begin() + pointerIdx);
+        pointerCoords.erase(pointerCoords.begin() + pointerIdx);
     }
     return events;
 }
@@ -661,7 +647,9 @@
     if (!state.mMotionMementos.empty()) {
         out << "mMotionMementos: ";
         for (const InputState::MotionMemento& memento : state.mMotionMementos) {
-            out << "{deviceId= " << memento.deviceId << ", hovering=" << memento.hovering << "}, ";
+            out << "{deviceId=" << memento.deviceId
+                << ", hovering=" << std::to_string(memento.hovering)
+                << ", downTime=" << memento.downTime << "}, ";
         }
     }
     return out;
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
index 65fb76d..b885ba1 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
@@ -43,9 +43,6 @@
     InputDispatcherPolicyInterface() = default;
     virtual ~InputDispatcherPolicyInterface() = default;
 
-    /* Notifies the system that a configuration change has occurred. */
-    virtual void notifyConfigurationChanged(nsecs_t when) = 0;
-
     /* Notifies the system that an application does not have a focused window.
      */
     virtual void notifyNoFocusedWindowAnr(
diff --git a/services/inputflinger/dispatcher/trace/InputTracer.cpp b/services/inputflinger/dispatcher/trace/InputTracer.cpp
index a1a87af..5d2b854 100644
--- a/services/inputflinger/dispatcher/trace/InputTracer.cpp
+++ b/services/inputflinger/dispatcher/trace/InputTracer.cpp
@@ -145,7 +145,8 @@
     eventState->metadata.isSecure |= targetInfo.isSecureWindow;
 }
 
-void InputTracer::eventProcessingComplete(const EventTrackerInterface& cookie) {
+void InputTracer::eventProcessingComplete(const EventTrackerInterface& cookie,
+                                          nsecs_t processingTimestamp) {
     if (isDerivedCookie(cookie)) {
         LOG(FATAL) << "Event processing cannot be set from a derived cookie.";
     }
@@ -154,7 +155,7 @@
         LOG(FATAL) << "Traced event was already logged. "
                       "eventProcessingComplete() was likely called more than once.";
     }
-    eventState->onEventProcessingComplete();
+    eventState->onEventProcessingComplete(processingTimestamp);
 }
 
 std::unique_ptr<EventTrackerInterface> InputTracer::traceDerivedEvent(
@@ -242,7 +243,8 @@
 
 // --- InputTracer::EventState ---
 
-void InputTracer::EventState::onEventProcessingComplete() {
+void InputTracer::EventState::onEventProcessingComplete(nsecs_t processingTimestamp) {
+    metadata.processingTimestamp = processingTimestamp;
     metadata.isImeConnectionActive = tracer.mIsImeConnectionActive;
 
     // Write all of the events known so far to the trace.
@@ -277,7 +279,7 @@
     // We should never end up here in normal operation. However, in tests, it's possible that we
     // stop and destroy InputDispatcher without waiting for it to finish processing events, at
     // which point an event (and thus its EventState) may be destroyed before processing finishes.
-    onEventProcessingComplete();
+    onEventProcessingComplete(systemTime(CLOCK_MONOTONIC));
 }
 
 } // namespace android::inputdispatcher::trace::impl
diff --git a/services/inputflinger/dispatcher/trace/InputTracer.h b/services/inputflinger/dispatcher/trace/InputTracer.h
index ab175be..cb525a4 100644
--- a/services/inputflinger/dispatcher/trace/InputTracer.h
+++ b/services/inputflinger/dispatcher/trace/InputTracer.h
@@ -44,7 +44,8 @@
     std::unique_ptr<EventTrackerInterface> traceInboundEvent(const EventEntry&) override;
     std::unique_ptr<EventTrackerInterface> createTrackerForSyntheticEvent() override;
     void dispatchToTargetHint(const EventTrackerInterface&, const InputTarget&) override;
-    void eventProcessingComplete(const EventTrackerInterface&) override;
+    void eventProcessingComplete(const EventTrackerInterface&,
+                                 nsecs_t processingTimestamp) override;
     std::unique_ptr<EventTrackerInterface> traceDerivedEvent(const EventEntry&,
                                                              const EventTrackerInterface&) override;
     void traceEventDispatch(const DispatchEntry&, const EventTrackerInterface&) override;
@@ -61,7 +62,7 @@
         explicit inline EventState(InputTracer& tracer) : tracer(tracer){};
         ~EventState();
 
-        void onEventProcessingComplete();
+        void onEventProcessingComplete(nsecs_t processingTimestamp);
 
         InputTracer& tracer;
         std::vector<const TracedEvent> events;
diff --git a/services/inputflinger/dispatcher/trace/InputTracerInterface.h b/services/inputflinger/dispatcher/trace/InputTracerInterface.h
index af6eefb..f5e4e59 100644
--- a/services/inputflinger/dispatcher/trace/InputTracerInterface.h
+++ b/services/inputflinger/dispatcher/trace/InputTracerInterface.h
@@ -81,7 +81,8 @@
      * outside of our control, such as how long apps take to respond, so we don't want to depend on
      * that.
      */
-    virtual void eventProcessingComplete(const EventTrackerInterface&) = 0;
+    virtual void eventProcessingComplete(const EventTrackerInterface&,
+                                         nsecs_t processingTimestamp) = 0;
 
     /**
      * Trace an input event that is derived from another event. This is used in cases where an event
diff --git a/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h b/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h
index 25099c3..761d619 100644
--- a/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h
+++ b/services/inputflinger/dispatcher/trace/InputTracingBackendInterface.h
@@ -99,6 +99,8 @@
     std::set<gui::Uid> targets;
     // True if the there was an active input method connection while this event was processed.
     bool isImeConnectionActive;
+    // The timestamp for when the dispatching decisions were made for the event by the system.
+    nsecs_t processingTimestamp;
 };
 
 /** Additional information about an input event being dispatched to a window. */
diff --git a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
index 3d30ad6..77b5c2e 100644
--- a/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
+++ b/services/inputflinger/dispatcher/trace/InputTracingPerfettoBackend.cpp
@@ -231,6 +231,8 @@
         }
         const bool isRedacted = traceLevel == TraceLevel::TRACE_LEVEL_REDACTED;
         auto tracePacket = ctx.NewTracePacket();
+        tracePacket->set_timestamp(metadata.processingTimestamp);
+        tracePacket->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
         auto* winscopeExtensions = static_cast<perfetto::protos::pbzero::WinscopeExtensionsImpl*>(
                 tracePacket->set_winscope_extensions());
         auto* inputEvent = winscopeExtensions->set_android_input_event();
@@ -257,6 +259,8 @@
         }
         const bool isRedacted = traceLevel == TraceLevel::TRACE_LEVEL_REDACTED;
         auto tracePacket = ctx.NewTracePacket();
+        tracePacket->set_timestamp(metadata.processingTimestamp);
+        tracePacket->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
         auto* winscopeExtensions = static_cast<perfetto::protos::pbzero::WinscopeExtensionsImpl*>(
                 tracePacket->set_winscope_extensions());
         auto* inputEvent = winscopeExtensions->set_android_input_event();
@@ -283,6 +287,8 @@
         }
         const bool isRedacted = traceLevel == TraceLevel::TRACE_LEVEL_REDACTED;
         auto tracePacket = ctx.NewTracePacket();
+        tracePacket->set_timestamp(dispatchArgs.deliveryTime);
+        tracePacket->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
         auto* winscopeExtensions = static_cast<perfetto::protos::pbzero::WinscopeExtensionsImpl*>(
                 tracePacket->set_winscope_extensions());
         auto* inputEvent = winscopeExtensions->set_android_input_event();
diff --git a/services/inputflinger/include/InputListener.h b/services/inputflinger/include/InputListener.h
index 0b7f7c2..d8a9afa 100644
--- a/services/inputflinger/include/InputListener.h
+++ b/services/inputflinger/include/InputListener.h
@@ -38,7 +38,6 @@
     virtual ~InputListenerInterface() { }
 
     virtual void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) = 0;
-    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) = 0;
     virtual void notifyKey(const NotifyKeyArgs& args) = 0;
     virtual void notifyMotion(const NotifyMotionArgs& args) = 0;
     virtual void notifySwitch(const NotifySwitchArgs& args) = 0;
@@ -60,7 +59,6 @@
     explicit QueuedInputListener(InputListenerInterface& innerListener);
 
     virtual void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
-    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
     virtual void notifyKey(const NotifyKeyArgs& args) override;
     virtual void notifyMotion(const NotifyMotionArgs& args) override;
     virtual void notifySwitch(const NotifySwitchArgs& args) override;
@@ -84,7 +82,6 @@
     explicit TracedInputListener(const char* name, InputListenerInterface& innerListener);
 
     virtual void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
-    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
     virtual void notifyKey(const NotifyKeyArgs& args) override;
     virtual void notifyMotion(const NotifyMotionArgs& args) override;
     virtual void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index 889ee09..42a03c1 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -397,6 +397,9 @@
      * Returns ReservedInputDeviceId::INVALID_INPUT_DEVICE_ID if no device has been used since boot.
      */
     virtual DeviceId getLastUsedInputDeviceId() = 0;
+
+    /* Notifies that mouse cursor faded due to typing. */
+    virtual void notifyMouseCursorFadedOnTyping() = 0;
 };
 
 // --- TouchAffineTransformation ---
diff --git a/services/inputflinger/include/NotifyArgs.h b/services/inputflinger/include/NotifyArgs.h
index db417cf..14487fe 100644
--- a/services/inputflinger/include/NotifyArgs.h
+++ b/services/inputflinger/include/NotifyArgs.h
@@ -39,21 +39,6 @@
     NotifyInputDevicesChangedArgs& operator=(const NotifyInputDevicesChangedArgs&) = default;
 };
 
-/* Describes a configuration change event. */
-struct NotifyConfigurationChangedArgs {
-    int32_t id;
-    nsecs_t eventTime;
-
-    inline NotifyConfigurationChangedArgs() {}
-
-    NotifyConfigurationChangedArgs(int32_t id, nsecs_t eventTime);
-
-    bool operator==(const NotifyConfigurationChangedArgs& rhs) const = default;
-
-    NotifyConfigurationChangedArgs(const NotifyConfigurationChangedArgs& other) = default;
-    NotifyConfigurationChangedArgs& operator=(const NotifyConfigurationChangedArgs&) = default;
-};
-
 /* Describes a key event. */
 struct NotifyKeyArgs {
     int32_t id;
@@ -234,8 +219,8 @@
 };
 
 using NotifyArgs =
-        std::variant<NotifyInputDevicesChangedArgs, NotifyConfigurationChangedArgs, NotifyKeyArgs,
-                     NotifyMotionArgs, NotifySensorArgs, NotifySwitchArgs, NotifyDeviceResetArgs,
+        std::variant<NotifyInputDevicesChangedArgs, NotifyKeyArgs, NotifyMotionArgs,
+                     NotifySensorArgs, NotifySwitchArgs, NotifyDeviceResetArgs,
                      NotifyPointerCaptureChangedArgs, NotifyVibratorStateArgs>;
 
 const char* toString(const NotifyArgs& args);
diff --git a/services/inputflinger/include/PointerChoreographerPolicyInterface.h b/services/inputflinger/include/PointerChoreographerPolicyInterface.h
index 7a85c12..e1f8fda 100644
--- a/services/inputflinger/include/PointerChoreographerPolicyInterface.h
+++ b/services/inputflinger/include/PointerChoreographerPolicyInterface.h
@@ -58,6 +58,9 @@
 
     /* Returns true if any InputConnection is currently active. */
     virtual bool isInputMethodConnectionActive() = 0;
+
+    /* Notifies that mouse cursor faded due to typing. */
+    virtual void notifyMouseCursorFadedOnTyping() = 0;
 };
 
 } // namespace android
diff --git a/services/inputflinger/reader/Android.bp b/services/inputflinger/reader/Android.bp
index e76b648..b76e8c5 100644
--- a/services/inputflinger/reader/Android.bp
+++ b/services/inputflinger/reader/Android.bp
@@ -78,6 +78,7 @@
     name: "libinputreader_defaults",
     srcs: [":libinputreader_sources"],
     shared_libs: [
+        "android.companion.virtualdevice.flags-aconfig-cc",
         "libbase",
         "libcap",
         "libcrypto",
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index fe70a51..e48e94f 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -33,6 +33,8 @@
 #include <sys/sysmacros.h>
 #include <unistd.h>
 
+#include <android_companion_virtualdevice_flags.h>
+
 #define LOG_TAG "EventHub"
 
 // #define LOG_NDEBUG 0
@@ -68,6 +70,8 @@
 
 namespace android {
 
+namespace vd_flags = android::companion::virtualdevice::flags;
+
 using namespace ftl::flag_operators;
 
 static const char* DEVICE_INPUT_PATH = "/dev/input";
@@ -885,7 +889,6 @@
       : mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD),
         mNextDeviceId(1),
         mControllerNumbers(),
-        mNeedToSendFinishedDeviceScan(false),
         mNeedToReopenDevices(false),
         mNeedToScanDevices(true),
         mPendingEventCount(0),
@@ -998,26 +1001,23 @@
     return *device->configuration;
 }
 
-status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
-                                       RawAbsoluteAxisInfo* outAxisInfo) const {
-    outAxisInfo->clear();
+std::optional<RawAbsoluteAxisInfo> EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis) const {
     if (axis < 0 || axis > ABS_MAX) {
-        return NAME_NOT_FOUND;
+        return std::nullopt;
     }
     std::scoped_lock _l(mLock);
     const Device* device = getDeviceLocked(deviceId);
     if (device == nullptr) {
-        return NAME_NOT_FOUND;
+        return std::nullopt;
     }
     // We can read the RawAbsoluteAxisInfo even if the device is disabled and doesn't have a valid
     // fd, because the info is populated once when the device is first opened, and it doesn't change
     // throughout the device lifecycle.
     auto it = device->absState.find(axis);
     if (it == device->absState.end()) {
-        return NAME_NOT_FOUND;
+        return std::nullopt;
     }
-    *outAxisInfo = it->second.info;
-    return OK;
+    return it->second.info;
 }
 
 bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const {
@@ -1130,22 +1130,20 @@
     return device->swState.test(sw) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
 }
 
-status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const {
-    *outValue = 0;
+std::optional<int32_t> EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis) const {
     if (axis < 0 || axis > ABS_MAX) {
-        return NAME_NOT_FOUND;
+        return std::nullopt;
     }
     std::scoped_lock _l(mLock);
     const Device* device = getDeviceLocked(deviceId);
     if (device == nullptr || !device->hasValidFd()) {
-        return NAME_NOT_FOUND;
+        return std::nullopt;
     }
     const auto it = device->absState.find(axis);
     if (it == device->absState.end()) {
-        return NAME_NOT_FOUND;
+        return std::nullopt;
     }
-    *outValue = it->second.value;
-    return OK;
+    return it->second.value;
 }
 
 base::Result<std::vector<int32_t>> EventHub::getMtSlotValues(int32_t deviceId, int32_t axis,
@@ -1879,7 +1877,6 @@
                     .type = DEVICE_REMOVED,
             });
             it = mClosingDevices.erase(it);
-            mNeedToSendFinishedDeviceScan = true;
             if (events.size() == EVENT_BUFFER_SIZE) {
                 break;
             }
@@ -1888,7 +1885,6 @@
         if (mNeedToScanDevices) {
             mNeedToScanDevices = false;
             scanDevicesLocked();
-            mNeedToSendFinishedDeviceScan = true;
         }
 
         while (!mOpeningDevices.empty()) {
@@ -1917,18 +1913,6 @@
             if (!inserted) {
                 ALOGW("Device id %d exists, replaced.", device->id);
             }
-            mNeedToSendFinishedDeviceScan = true;
-            if (events.size() == EVENT_BUFFER_SIZE) {
-                break;
-            }
-        }
-
-        if (mNeedToSendFinishedDeviceScan) {
-            mNeedToSendFinishedDeviceScan = false;
-            events.push_back({
-                    .when = now,
-                    .type = FINISHED_DEVICE_SCAN,
-            });
             if (events.size() == EVENT_BUFFER_SIZE) {
                 break;
             }
@@ -2503,6 +2487,12 @@
         }
     }
 
+    // See if the device is a rotary encoder with a single scroll axis and nothing else.
+    if (vd_flags::virtual_rotary() && device->classes == ftl::Flags<InputDeviceClass>(0) &&
+        device->relBitmask.test(REL_WHEEL) && !device->relBitmask.test(REL_HWHEEL)) {
+        device->classes |= InputDeviceClass::ROTARY_ENCODER;
+    }
+
     // If the device isn't recognized as something we handle, don't monitor it.
     if (device->classes == ftl::Flags<InputDeviceClass>(0)) {
         ALOGV("Dropping device: id=%d, path='%s', name='%s'", deviceId, devicePath.c_str(),
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index ab13ad4..f0e53b5 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -180,6 +180,9 @@
         }
 
         if (oldGeneration != mGeneration) {
+            // Reset global meta state because it depends on connected input devices.
+            updateGlobalMetaStateLocked();
+
             inputDevicesChanged = true;
             inputDevices = getInputDevicesLocked();
             mPendingArgs.emplace_back(
@@ -247,9 +250,6 @@
                 case EventHubInterface::DEVICE_REMOVED:
                     removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
                     break;
-                case EventHubInterface::FINISHED_DEVICE_SCAN:
-                    handleConfigurationChangedLocked(rawEvent->when);
-                    break;
                 default:
                     ALOG_ASSERT(false); // can't happen
                     break;
@@ -414,14 +414,6 @@
     return ++mNextInputDeviceId;
 }
 
-void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
-    // Reset global meta state because it depends on the list of all configured devices.
-    updateGlobalMetaStateLocked();
-
-    // Enqueue configuration changed.
-    mPendingArgs.emplace_back(NotifyConfigurationChangedArgs{mContext.getNextId(), when});
-}
-
 void InputReader::refreshConfigurationLocked(ConfigurationChanges changes) {
     mPolicy->getReaderConfiguration(&mConfig);
     mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
@@ -907,6 +899,12 @@
     return mLastUsedDeviceId;
 }
 
+void InputReader::notifyMouseCursorFadedOnTyping() {
+    std::scoped_lock _l(mLock);
+    // disable touchpad taps when cursor has faded due to typing
+    mPreventingTouchpadTaps = true;
+}
+
 void InputReader::dump(std::string& dump) {
     std::scoped_lock _l(mLock);
 
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 7cf584d..feae6b6 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -21,6 +21,7 @@
 #include <filesystem>
 #include <functional>
 #include <map>
+#include <optional>
 #include <ostream>
 #include <string>
 #include <unordered_map>
@@ -257,9 +258,6 @@
         DEVICE_ADDED = 0x10000000,
         // Sent when a device is removed.
         DEVICE_REMOVED = 0x20000000,
-        // Sent when all added/removed devices from the most recent scan have been reported.
-        // This event is always sent at least once.
-        FINISHED_DEVICE_SCAN = 0x30000000,
 
         FIRST_SYNTHETIC_EVENT = DEVICE_ADDED,
     };
@@ -278,8 +276,8 @@
      */
     virtual std::optional<PropertyMap> getConfiguration(int32_t deviceId) const = 0;
 
-    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
-                                         RawAbsoluteAxisInfo* outAxisInfo) const = 0;
+    virtual std::optional<RawAbsoluteAxisInfo> getAbsoluteAxisInfo(int32_t deviceId,
+                                                                   int axis) const = 0;
 
     virtual bool hasRelativeAxis(int32_t deviceId, int axis) const = 0;
 
@@ -339,8 +337,7 @@
     virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0;
     virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0;
     virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;
-    virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
-                                          int32_t* outValue) const = 0;
+    virtual std::optional<int32_t> getAbsoluteAxisValue(int32_t deviceId, int32_t axis) const = 0;
     /* Query Multi-Touch slot values for an axis. Returns error or an 1 indexed array of size
      * (slotCount + 1). The value at the 0 index is set to queried axis. */
     virtual base::Result<std::vector<int32_t>> getMtSlotValues(int32_t deviceId, int32_t axis,
@@ -511,8 +508,8 @@
 
     std::optional<PropertyMap> getConfiguration(int32_t deviceId) const override final;
 
-    status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
-                                 RawAbsoluteAxisInfo* outAxisInfo) const override final;
+    std::optional<RawAbsoluteAxisInfo> getAbsoluteAxisInfo(int32_t deviceId,
+                                                           int axis) const override final;
 
     bool hasRelativeAxis(int32_t deviceId, int axis) const override final;
 
@@ -559,8 +556,8 @@
     int32_t getSwitchState(int32_t deviceId, int32_t sw) const override final;
     int32_t getKeyCodeForKeyLocation(int32_t deviceId,
                                      int32_t locationKeyCode) const override final;
-    status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
-                                  int32_t* outValue) const override final;
+    std::optional<int32_t> getAbsoluteAxisValue(int32_t deviceId,
+                                                int32_t axis) const override final;
     base::Result<std::vector<int32_t>> getMtSlotValues(int32_t deviceId, int32_t axis,
                                                        size_t slotCount) const override final;
 
@@ -793,7 +790,6 @@
     std::vector<std::unique_ptr<Device>> mOpeningDevices;
     std::vector<std::unique_ptr<Device>> mClosingDevices;
 
-    bool mNeedToSendFinishedDeviceScan;
     bool mNeedToReopenDevices;
     bool mNeedToScanDevices;
     std::vector<std::string> mExcludedDevices;
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index 2a7e262..086c26f 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -306,9 +306,12 @@
         return mEventHub->getDeviceControllerNumber(mId);
     }
     inline status_t getAbsoluteAxisInfo(int32_t code, RawAbsoluteAxisInfo* axisInfo) const {
-        if (const auto status = mEventHub->getAbsoluteAxisInfo(mId, code, axisInfo); status != OK) {
-            return status;
+        std::optional<RawAbsoluteAxisInfo> info = mEventHub->getAbsoluteAxisInfo(mId, code);
+        if (!info.has_value()) {
+            axisInfo->clear();
+            return NAME_NOT_FOUND;
         }
+        *axisInfo = *info;
 
         // Validate axis info for InputDevice.
         if (axisInfo->valid && axisInfo->minValue == axisInfo->maxValue) {
@@ -379,8 +382,8 @@
         return mEventHub->getKeyCodeForKeyLocation(mId, locationKeyCode);
     }
     inline int32_t getSwitchState(int32_t sw) const { return mEventHub->getSwitchState(mId, sw); }
-    inline status_t getAbsoluteAxisValue(int32_t code, int32_t* outValue) const {
-        return mEventHub->getAbsoluteAxisValue(mId, code, outValue);
+    inline std::optional<int32_t> getAbsoluteAxisValue(int32_t code) const {
+        return mEventHub->getAbsoluteAxisValue(mId, code);
     }
     inline base::Result<std::vector<int32_t>> getMtSlotValues(int32_t axis,
                                                               size_t slotCount) const {
@@ -432,9 +435,8 @@
     }
 
     inline bool hasAbsoluteAxis(int32_t code) const {
-        RawAbsoluteAxisInfo info;
-        mEventHub->getAbsoluteAxisInfo(mId, code, &info);
-        return info.valid;
+        std::optional<RawAbsoluteAxisInfo> info = mEventHub->getAbsoluteAxisInfo(mId, code);
+        return info.has_value() && info->valid;
     }
     inline bool isKeyPressed(int32_t scanCode) const {
         return mEventHub->getScanCodeState(mId, scanCode) == AKEY_STATE_DOWN;
@@ -442,11 +444,6 @@
     inline bool isKeyCodePressed(int32_t keyCode) const {
         return mEventHub->getKeyCodeState(mId, keyCode) == AKEY_STATE_DOWN;
     }
-    inline int32_t getAbsoluteAxisValue(int32_t code) const {
-        int32_t value;
-        mEventHub->getAbsoluteAxisValue(mId, code, &value);
-        return value;
-    }
     inline bool isDeviceEnabled() { return mEventHub->isDeviceEnabled(mId); }
     inline status_t enableDevice() { return mEventHub->enableDevice(mId); }
     inline status_t disableDevice() { return mEventHub->disableDevice(mId); }
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index 6f8c289..4f60a8a 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -118,6 +118,8 @@
 
     DeviceId getLastUsedInputDeviceId() override;
 
+    void notifyMouseCursorFadedOnTyping() override;
+
 protected:
     // These members are protected so they can be instrumented by test cases.
     virtual std::shared_ptr<InputDevice> createDeviceLocked(nsecs_t when, int32_t deviceId,
@@ -199,7 +201,7 @@
     std::unordered_map<std::shared_ptr<InputDevice>, std::vector<int32_t> /*eventHubId*/>
             mDeviceToEventHubIdsMap GUARDED_BY(mLock);
 
-    // true if tap-to-click on touchpad currently disabled
+    // true if tap-to-click on touchpad is currently disabled
     bool mPreventingTouchpadTaps GUARDED_BY(mLock){false};
 
     // records timestamp of the last key press on the physical keyboard
@@ -219,8 +221,6 @@
                                                                      size_t count) REQUIRES(mLock);
     [[nodiscard]] std::list<NotifyArgs> timeoutExpiredLocked(nsecs_t when) REQUIRES(mLock);
 
-    void handleConfigurationChangedLocked(nsecs_t when) REQUIRES(mLock);
-
     int32_t mGlobalMetaState GUARDED_BY(mLock);
     void updateGlobalMetaStateLocked() REQUIRES(mLock);
     int32_t getGlobalMetaStateLocked() REQUIRES(mLock);
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index 25f4893..4a21e48 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -493,12 +493,6 @@
 void KeyboardInputMapper::onKeyDownProcessed(nsecs_t downTime) {
     InputReaderContext& context = *getContext();
     context.setLastKeyDownTimestamp(downTime);
-    // Ignore meta keys or multiple simultaneous down keys as they are likely to be keyboard
-    // shortcuts
-    bool shouldHideCursor = mKeyDowns.size() == 1 && !isMetaKey(mKeyDowns[0].keyCode);
-    if (shouldHideCursor && context.getPolicy()->isInputMethodConnectionActive()) {
-        context.setPreventingTouchpadTaps(true);
-    }
 }
 
 } // namespace android
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
index 27ff52f..b72cc6e 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.cpp
@@ -27,11 +27,14 @@
 
 namespace android {
 
+constexpr float kDefaultScaleFactor = 1.0f;
+
 RotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDeviceContext& deviceContext,
                                                    const InputReaderConfiguration& readerConfig)
-      : InputMapper(deviceContext, readerConfig), mOrientation(ui::ROTATION_0) {
-    mSource = AINPUT_SOURCE_ROTARY_ENCODER;
-}
+      : InputMapper(deviceContext, readerConfig),
+        mSource(AINPUT_SOURCE_ROTARY_ENCODER),
+        mScalingFactor(kDefaultScaleFactor),
+        mOrientation(ui::ROTATION_0) {}
 
 RotaryEncoderInputMapper::~RotaryEncoderInputMapper() {}
 
@@ -51,9 +54,10 @@
         std::optional<float> scalingFactor = config.getFloat("device.scalingFactor");
         if (!scalingFactor.has_value()) {
             ALOGW("Rotary Encoder device configuration file didn't specify scaling factor,"
-                  "default to 1.0!\n");
+                  "default to %f!\n",
+                  kDefaultScaleFactor);
         }
-        mScalingFactor = scalingFactor.value_or(1.0f);
+        mScalingFactor = scalingFactor.value_or(kDefaultScaleFactor);
         info.addMotionRange(AMOTION_EVENT_AXIS_SCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
                             res.value_or(0.0f) * mScalingFactor);
     }
@@ -84,12 +88,18 @@
         }
     }
     if (!changes.any() || changes.test(InputReaderConfiguration::Change::DISPLAY_INFO)) {
-        std::optional<DisplayViewport> internalViewport =
-                config.getDisplayViewportByType(ViewportType::INTERNAL);
-        if (internalViewport) {
-            mOrientation = internalViewport->orientation;
+        if (getDeviceContext().getAssociatedViewport()) {
+            mDisplayId = getDeviceContext().getAssociatedViewport()->displayId;
+            mOrientation = getDeviceContext().getAssociatedViewport()->orientation;
         } else {
-            mOrientation = ui::ROTATION_0;
+            mDisplayId = ui::LogicalDisplayId::INVALID;
+            std::optional<DisplayViewport> internalViewport =
+                    config.getDisplayViewportByType(ViewportType::INTERNAL);
+            if (internalViewport) {
+                mOrientation = internalViewport->orientation;
+            } else {
+                mOrientation = ui::ROTATION_0;
+            }
         }
     }
     return out;
@@ -124,8 +134,6 @@
     // Send motion event.
     if (scrolled) {
         int32_t metaState = getContext()->getGlobalMetaState();
-        // This is not a pointer, so it's not associated with a display.
-        ui::LogicalDisplayId displayId = ui::LogicalDisplayId::INVALID;
 
         if (mOrientation == ui::ROTATION_180) {
             scroll = -scroll;
@@ -147,7 +155,7 @@
 
         out.push_back(
                 NotifyMotionArgs(getContext()->getNextId(), when, readTime, getDeviceId(), mSource,
-                                 displayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0,
+                                 mDisplayId, policyFlags, AMOTION_EVENT_ACTION_SCROLL, 0, 0,
                                  metaState, /*buttonState=*/0, MotionClassification::NONE,
                                  AMOTION_EVENT_EDGE_FLAG_NONE, 1, &pointerProperties,
                                  &pointerCoords, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
diff --git a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
index 14c540b..7e80415 100644
--- a/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
+++ b/services/inputflinger/reader/mapper/RotaryEncoderInputMapper.h
@@ -47,6 +47,7 @@
     int32_t mSource;
     float mScalingFactor;
     ui::Rotation mOrientation;
+    ui::LogicalDisplayId mDisplayId = ui::LogicalDisplayId::INVALID;
     std::unique_ptr<SlopController> mSlopController;
 
     explicit RotaryEncoderInputMapper(InputDeviceContext& deviceContext,
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index a383490..2d89208 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -931,7 +931,7 @@
             mSource |= AINPUT_SOURCE_STYLUS;
         }
     } else if (mParameters.deviceType == Parameters::DeviceType::TOUCH_NAVIGATION) {
-        mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
+        mSource = AINPUT_SOURCE_TOUCH_NAVIGATION | AINPUT_SOURCE_TOUCHPAD;
         mDeviceMode = DeviceMode::NAVIGATION;
     } else {
         ALOGW("Touch device '%s' has invalid parameters or configuration.  The device will be "
@@ -981,8 +981,9 @@
         viewportChanged = mViewport != newViewport;
     }
 
+    const bool deviceModeChanged = mDeviceMode != oldDeviceMode;
     bool skipViewportUpdate = false;
-    if (viewportChanged) {
+    if (viewportChanged || deviceModeChanged) {
         const bool viewportOrientationChanged = mViewport.orientation != newViewport.orientation;
         const bool viewportDisplayIdChanged = mViewport.displayId != newViewport.displayId;
         mViewport = newViewport;
@@ -1024,7 +1025,6 @@
     }
 
     // If moving between pointer modes, need to reset some state.
-    bool deviceModeChanged = mDeviceMode != oldDeviceMode;
     if (deviceModeChanged) {
         mOrientedRanges.clear();
     }
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index 30c58a5..a9a0190 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -339,8 +339,8 @@
         int32_t buttonState{};
 
         // Scroll state.
-        int32_t rawVScroll{};
-        int32_t rawHScroll{};
+        float rawVScroll{};
+        float rawHScroll{};
 
         inline void clear() { *this = RawState(); }
     };
diff --git a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
index 24efae8..128f515 100644
--- a/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchpadInputMapper.cpp
@@ -257,11 +257,9 @@
     // 2) TouchpadInputMapper is stored as a unique_ptr and not moved.
     mGestureInterpreter->SetPropProvider(const_cast<GesturesPropProvider*>(&gesturePropProvider),
                                          &mPropertyProvider);
-    if (input_flags::enable_gestures_library_timer_provider()) {
-        mGestureInterpreter->SetTimerProvider(const_cast<GesturesTimerProvider*>(
-                                                      &kGestureTimerProvider),
-                                              &mTimerProvider);
-    }
+    mGestureInterpreter->SetTimerProvider(const_cast<GesturesTimerProvider*>(
+                                                  &kGestureTimerProvider),
+                                          &mTimerProvider);
     mGestureInterpreter->SetCallback(gestureInterpreterCallback, this);
 }
 
@@ -299,12 +297,8 @@
     dump += addLinePrefix(mGestureConverter.dump(), INDENT4);
     dump += INDENT3 "Gesture properties:\n";
     dump += addLinePrefix(mPropertyProvider.dump(), INDENT4);
-    if (input_flags::enable_gestures_library_timer_provider()) {
-        dump += INDENT3 "Timer provider:\n";
-        dump += addLinePrefix(mTimerProvider.dump(), INDENT4);
-    } else {
-        dump += INDENT3 "Timer provider: disabled by flag\n";
-    }
+    dump += INDENT3 "Timer provider:\n";
+    dump += addLinePrefix(mTimerProvider.dump(), INDENT4);
     dump += INDENT3 "Captured event converter:\n";
     dump += addLinePrefix(mCapturedEventConverter.dump(), INDENT4);
     dump += StringPrintf(INDENT3 "DisplayId: %s\n",
@@ -467,9 +461,6 @@
 }
 
 std::list<NotifyArgs> TouchpadInputMapper::timeoutExpired(nsecs_t when) {
-    if (!input_flags::enable_gestures_library_timer_provider()) {
-        return {};
-    }
     mTimerProvider.triggerCallbacks(when);
     return processGestures(when, when);
 }
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
index f85cab2..5373440 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.cpp
@@ -16,18 +16,29 @@
 
 #include "CursorScrollAccumulator.h"
 
+#include <android_companion_virtualdevice_flags.h>
 #include "EventHub.h"
 #include "InputDevice.h"
 
 namespace android {
 
-CursorScrollAccumulator::CursorScrollAccumulator() : mHaveRelWheel(false), mHaveRelHWheel(false) {
+namespace vd_flags = android::companion::virtualdevice::flags;
+
+CursorScrollAccumulator::CursorScrollAccumulator()
+      : mHaveRelWheel(false),
+        mHaveRelHWheel(false),
+        mHaveRelWheelHighRes(false),
+        mHaveRelHWheelHighRes(false) {
     clearRelativeAxes();
 }
 
 void CursorScrollAccumulator::configure(InputDeviceContext& deviceContext) {
     mHaveRelWheel = deviceContext.hasRelativeAxis(REL_WHEEL);
     mHaveRelHWheel = deviceContext.hasRelativeAxis(REL_HWHEEL);
+    if (vd_flags::high_resolution_scroll()) {
+        mHaveRelWheelHighRes = deviceContext.hasRelativeAxis(REL_WHEEL_HI_RES);
+        mHaveRelHWheelHighRes = deviceContext.hasRelativeAxis(REL_HWHEEL_HI_RES);
+    }
 }
 
 void CursorScrollAccumulator::reset(InputDeviceContext& deviceContext) {
@@ -42,11 +53,31 @@
 void CursorScrollAccumulator::process(const RawEvent& rawEvent) {
     if (rawEvent.type == EV_REL) {
         switch (rawEvent.code) {
+            case REL_WHEEL_HI_RES:
+                if (mHaveRelWheelHighRes) {
+                    mRelWheel =
+                            rawEvent.value / static_cast<float>(kEvdevHighResScrollUnitsPerDetent);
+                }
+                break;
+            case REL_HWHEEL_HI_RES:
+                if (mHaveRelHWheelHighRes) {
+                    mRelHWheel =
+                            rawEvent.value / static_cast<float>(kEvdevHighResScrollUnitsPerDetent);
+                }
+                break;
             case REL_WHEEL:
-                mRelWheel = rawEvent.value;
+                // We should ignore regular scroll events, if we have already have high-res scroll
+                // enabled.
+                if (!mHaveRelWheelHighRes) {
+                    mRelWheel = rawEvent.value;
+                }
                 break;
             case REL_HWHEEL:
-                mRelHWheel = rawEvent.value;
+                // We should ignore regular scroll events, if we have already have high-res scroll
+                // enabled.
+                if (!mHaveRelHWheelHighRes) {
+                    mRelHWheel = rawEvent.value;
+                }
                 break;
         }
     }
diff --git a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
index e563620..d3373cc 100644
--- a/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/CursorScrollAccumulator.h
@@ -16,15 +16,12 @@
 
 #pragma once
 
-#include <stdint.h>
-
 namespace android {
 
 class InputDeviceContext;
 struct RawEvent;
 
 /* Keeps track of cursor scrolling motions. */
-
 class CursorScrollAccumulator {
 public:
     CursorScrollAccumulator();
@@ -37,19 +34,17 @@
     inline bool haveRelativeVWheel() const { return mHaveRelWheel; }
     inline bool haveRelativeHWheel() const { return mHaveRelHWheel; }
 
-    inline int32_t getRelativeX() const { return mRelX; }
-    inline int32_t getRelativeY() const { return mRelY; }
-    inline int32_t getRelativeVWheel() const { return mRelWheel; }
-    inline int32_t getRelativeHWheel() const { return mRelHWheel; }
+    inline float getRelativeVWheel() const { return mRelWheel; }
+    inline float getRelativeHWheel() const { return mRelHWheel; }
 
 private:
     bool mHaveRelWheel;
     bool mHaveRelHWheel;
+    bool mHaveRelWheelHighRes;
+    bool mHaveRelHWheelHighRes;
 
-    int32_t mRelX;
-    int32_t mRelY;
-    int32_t mRelWheel;
-    int32_t mRelHWheel;
+    float mRelWheel;
+    float mRelHWheel;
 
     void clearRelativeAxes();
 };
diff --git a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
index 4919068..8dc6e4d 100644
--- a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
@@ -139,13 +139,11 @@
     if (!mUsingSlotsProtocol) {
         return;
     }
-    int32_t initialSlot;
-    if (const auto status = deviceContext.getAbsoluteAxisValue(ABS_MT_SLOT, &initialSlot);
-        status == OK) {
-        mCurrentSlot = initialSlot;
+    if (const std::optional<int32_t> initialSlot = deviceContext.getAbsoluteAxisValue(ABS_MT_SLOT);
+        initialSlot.has_value()) {
+        mCurrentSlot = initialSlot.value();
     } else {
-        ALOGE("Could not retrieve current multi-touch slot index. status=%s",
-              statusToString(status).c_str());
+        ALOGE("Could not retrieve current multi-touch slot index");
     }
 }
 
diff --git a/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp
index 2b82ddf..4cf9243 100644
--- a/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/SingleTouchMotionAccumulator.cpp
@@ -26,13 +26,13 @@
 }
 
 void SingleTouchMotionAccumulator::reset(InputDeviceContext& deviceContext) {
-    mAbsX = deviceContext.getAbsoluteAxisValue(ABS_X);
-    mAbsY = deviceContext.getAbsoluteAxisValue(ABS_Y);
-    mAbsPressure = deviceContext.getAbsoluteAxisValue(ABS_PRESSURE);
-    mAbsToolWidth = deviceContext.getAbsoluteAxisValue(ABS_TOOL_WIDTH);
-    mAbsDistance = deviceContext.getAbsoluteAxisValue(ABS_DISTANCE);
-    mAbsTiltX = deviceContext.getAbsoluteAxisValue(ABS_TILT_X);
-    mAbsTiltY = deviceContext.getAbsoluteAxisValue(ABS_TILT_Y);
+    mAbsX = deviceContext.getAbsoluteAxisValue(ABS_X).value_or(0);
+    mAbsY = deviceContext.getAbsoluteAxisValue(ABS_Y).value_or(0);
+    mAbsPressure = deviceContext.getAbsoluteAxisValue(ABS_PRESSURE).value_or(0);
+    mAbsToolWidth = deviceContext.getAbsoluteAxisValue(ABS_TOOL_WIDTH).value_or(0);
+    mAbsDistance = deviceContext.getAbsoluteAxisValue(ABS_DISTANCE).value_or(0);
+    mAbsTiltX = deviceContext.getAbsoluteAxisValue(ABS_TILT_X).value_or(0);
+    mAbsTiltY = deviceContext.getAbsoluteAxisValue(ABS_TILT_Y).value_or(0);
 }
 
 void SingleTouchMotionAccumulator::clearAbsoluteAxes() {
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index cf0d46a..95283ba 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -70,17 +70,21 @@
         "InputTraceSession.cpp",
         "InputTracingTest.cpp",
         "InstrumentedInputReader.cpp",
+        "JoystickInputMapper_test.cpp",
         "LatencyTracker_test.cpp",
         "MultiTouchMotionAccumulator_test.cpp",
         "NotifyArgs_test.cpp",
         "PointerChoreographer_test.cpp",
         "PreferStylusOverTouch_test.cpp",
         "PropertyProvider_test.cpp",
+        "RotaryEncoderInputMapper_test.cpp",
         "SlopController_test.cpp",
+        "SwitchInputMapper_test.cpp",
         "SyncQueue_test.cpp",
         "TimerProvider_test.cpp",
         "TestInputListener.cpp",
         "TouchpadInputMapper_test.cpp",
+        "VibratorInputMapper_test.cpp",
         "MultiTouchInputMapper_test.cpp",
         "KeyboardInputMapper_test.cpp",
         "UinputDevice.cpp",
@@ -115,5 +119,8 @@
     test_options: {
         unit_test: true,
     },
-    test_suites: ["device-tests"],
+    test_suites: [
+        "device-tests",
+        "device-platinum-tests",
+    ],
 }
diff --git a/services/inputflinger/tests/CursorInputMapper_test.cpp b/services/inputflinger/tests/CursorInputMapper_test.cpp
index 83074ff..727237f 100644
--- a/services/inputflinger/tests/CursorInputMapper_test.cpp
+++ b/services/inputflinger/tests/CursorInputMapper_test.cpp
@@ -22,6 +22,7 @@
 #include <variant>
 
 #include <android-base/logging.h>
+#include <android_companion_virtualdevice_flags.h>
 #include <com_android_input_flags.h>
 #include <gtest/gtest.h>
 #include <input/DisplayViewport.h>
@@ -127,6 +128,7 @@
 } // namespace
 
 namespace input_flags = com::android::input::flags;
+namespace vd_flags = android::companion::virtualdevice::flags;
 
 /**
  * Unit tests for CursorInputMapper.
@@ -151,6 +153,10 @@
                 .WillRepeatedly(Return(false));
         EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_HWHEEL))
                 .WillRepeatedly(Return(false));
+        EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
+                .WillRepeatedly(Return(false));
+        EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_HWHEEL_HI_RES))
+                .WillRepeatedly(Return(false));
 
         mFakePolicy->setDefaultPointerDisplayId(DISPLAY_ID);
         mFakePolicy->addDisplayViewport(createPrimaryViewport(ui::Rotation::Rotation0));
@@ -194,6 +200,7 @@
 protected:
     void SetUp() override {
         input_flags::enable_new_mouse_pointer_ballistics(false);
+        vd_flags::high_resolution_scroll(false);
         CursorInputMapperUnitTestBase::SetUp();
     }
 };
@@ -840,6 +847,72 @@
                               WithOrientation(0.0f), WithDistance(0.0f)))));
 }
 
+TEST_F(CursorInputMapperUnitTest, ProcessRegularScroll) {
+    createMapper();
+
+    std::list<NotifyArgs> args;
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_REL, REL_HWHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+
+    EXPECT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))),
+                            VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_SCROLL),
+                                          WithScroll(1.0f, 1.0f)))));
+}
+
+TEST_F(CursorInputMapperUnitTest, ProcessHighResScroll) {
+    vd_flags::high_resolution_scroll(true);
+    EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
+            .WillRepeatedly(Return(true));
+    EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_HWHEEL_HI_RES))
+            .WillRepeatedly(Return(true));
+    createMapper();
+
+    std::list<NotifyArgs> args;
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL_HI_RES, 60);
+    args += process(ARBITRARY_TIME, EV_REL, REL_HWHEEL_HI_RES, 60);
+    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+
+    EXPECT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))),
+                            VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_SCROLL),
+                                          WithScroll(0.5f, 0.5f)))));
+}
+
+TEST_F(CursorInputMapperUnitTest, HighResScrollIgnoresRegularScroll) {
+    vd_flags::high_resolution_scroll(true);
+    EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
+            .WillRepeatedly(Return(true));
+    EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_HWHEEL_HI_RES))
+            .WillRepeatedly(Return(true));
+    createMapper();
+
+    std::list<NotifyArgs> args;
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL_HI_RES, 60);
+    args += process(ARBITRARY_TIME, EV_REL, REL_HWHEEL_HI_RES, 60);
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_REL, REL_HWHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+
+    EXPECT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))),
+                            VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_SCROLL),
+                                          WithScroll(0.5f, 0.5f)))));
+}
+
 /**
  * When Pointer Capture is enabled, we expect to report unprocessed relative movements, so any
  * pointer acceleration or speed processing should not be applied.
@@ -1030,6 +1103,72 @@
                               WithRelativeMotion(10, 20)))));
 }
 
+TEST_F(CursorInputMapperUnitTestWithNewBallistics, ProcessRegularScroll) {
+    createMapper();
+
+    std::list<NotifyArgs> args;
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_REL, REL_HWHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+
+    EXPECT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))),
+                            VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_SCROLL),
+                                          WithScroll(1.0f, 1.0f)))));
+}
+
+TEST_F(CursorInputMapperUnitTestWithNewBallistics, ProcessHighResScroll) {
+    vd_flags::high_resolution_scroll(true);
+    EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
+            .WillRepeatedly(Return(true));
+    EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_HWHEEL_HI_RES))
+            .WillRepeatedly(Return(true));
+    createMapper();
+
+    std::list<NotifyArgs> args;
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL_HI_RES, 60);
+    args += process(ARBITRARY_TIME, EV_REL, REL_HWHEEL_HI_RES, 60);
+    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+
+    EXPECT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))),
+                            VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_SCROLL),
+                                          WithScroll(0.5f, 0.5f)))));
+}
+
+TEST_F(CursorInputMapperUnitTestWithNewBallistics, HighResScrollIgnoresRegularScroll) {
+    vd_flags::high_resolution_scroll(true);
+    EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
+            .WillRepeatedly(Return(true));
+    EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_HWHEEL_HI_RES))
+            .WillRepeatedly(Return(true));
+    createMapper();
+
+    std::list<NotifyArgs> args;
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL_HI_RES, 60);
+    args += process(ARBITRARY_TIME, EV_REL, REL_HWHEEL_HI_RES, 60);
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_REL, REL_HWHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+
+    EXPECT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_HOVER_MOVE))),
+                            VariantWith<NotifyMotionArgs>(
+                                    AllOf(WithSource(AINPUT_SOURCE_MOUSE),
+                                          WithMotionAction(AMOTION_EVENT_ACTION_SCROLL),
+                                          WithScroll(0.5f, 0.5f)))));
+}
+
 namespace {
 
 // Minimum timestamp separation between subsequent input events from a Bluetooth device.
diff --git a/services/inputflinger/tests/EventHub_test.cpp b/services/inputflinger/tests/EventHub_test.cpp
index 2e296da..0e3d15a 100644
--- a/services/inputflinger/tests/EventHub_test.cpp
+++ b/services/inputflinger/tests/EventHub_test.cpp
@@ -48,9 +48,6 @@
                 case EventHubInterface::DEVICE_REMOVED:
                     ALOGI("Device removed: %i", event.deviceId);
                     break;
-                case EventHubInterface::FINISHED_DEVICE_SCAN:
-                    ALOGI("Finished device scan.");
-                    break;
             }
         } else {
             ALOGI("Device %" PRId32 " : time = %" PRId64 ", type %i, code %i, value %i",
@@ -145,15 +142,13 @@
     // None of the existing system devices should be changing while this test is run.
     // Check that the returned device ids are unique for all of the existing devices.
     EXPECT_EQ(existingDevices.size(), events.size() - 1);
-    // The last event should be "finished device scan"
-    EXPECT_EQ(EventHubInterface::FINISHED_DEVICE_SCAN, events[events.size() - 1].type);
 }
 
 int32_t EventHubTest::waitForDeviceCreation() {
     // Wait a little longer than usual, to ensure input device has time to be created
     std::vector<RawEvent> events = getEvents(2);
-    if (events.size() != 2) {
-        ADD_FAILURE() << "Instead of 2 events, received " << events.size();
+    if (events.size() != 1) {
+        ADD_FAILURE() << "Instead of 1 event, received " << events.size();
         return 0; // this value is unused
     }
     const RawEvent& deviceAddedEvent = events[0];
@@ -161,21 +156,15 @@
     InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceAddedEvent.deviceId);
     const int32_t deviceId = deviceAddedEvent.deviceId;
     EXPECT_EQ(identifier.name, mKeyboard->getName());
-    const RawEvent& finishedDeviceScanEvent = events[1];
-    EXPECT_EQ(static_cast<int32_t>(EventHubInterface::FINISHED_DEVICE_SCAN),
-              finishedDeviceScanEvent.type);
     return deviceId;
 }
 
 void EventHubTest::waitForDeviceClose(int32_t deviceId) {
     std::vector<RawEvent> events = getEvents(2);
-    ASSERT_EQ(2U, events.size());
+    ASSERT_EQ(1U, events.size());
     const RawEvent& deviceRemovedEvent = events[0];
     EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_REMOVED), deviceRemovedEvent.type);
     EXPECT_EQ(deviceId, deviceRemovedEvent.deviceId);
-    const RawEvent& finishedDeviceScanEvent = events[1];
-    EXPECT_EQ(static_cast<int32_t>(EventHubInterface::FINISHED_DEVICE_SCAN),
-              finishedDeviceScanEvent.type);
 }
 
 void EventHubTest::assertNoMoreEvents() {
diff --git a/services/inputflinger/tests/FakeEventHub.cpp b/services/inputflinger/tests/FakeEventHub.cpp
index daa000f..99db999 100644
--- a/services/inputflinger/tests/FakeEventHub.cpp
+++ b/services/inputflinger/tests/FakeEventHub.cpp
@@ -16,6 +16,8 @@
 
 #include "FakeEventHub.h"
 
+#include <optional>
+
 #include <android-base/thread_annotations.h>
 #include <gtest/gtest.h>
 #include <linux/input-event-codes.h>
@@ -86,10 +88,6 @@
     return device->disable();
 }
 
-void FakeEventHub::finishDeviceScan() {
-    enqueueEvent(ARBITRARY_TIME, READ_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0);
-}
-
 void FakeEventHub::addConfigurationProperty(int32_t deviceId, const char* key, const char* value) {
     getDevice(deviceId)->configuration.addProperty(key, value);
 }
@@ -263,18 +261,16 @@
     return device->configuration;
 }
 
-status_t FakeEventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
-                                           RawAbsoluteAxisInfo* outAxisInfo) const {
+std::optional<RawAbsoluteAxisInfo> FakeEventHub::getAbsoluteAxisInfo(int32_t deviceId,
+                                                                     int axis) const {
     Device* device = getDevice(deviceId);
     if (device) {
         ssize_t index = device->absoluteAxes.indexOfKey(axis);
         if (index >= 0) {
-            *outAxisInfo = device->absoluteAxes.valueAt(index);
-            return OK;
+            return device->absoluteAxes.valueAt(index);
         }
     }
-    outAxisInfo->clear();
-    return -1;
+    return std::nullopt;
 }
 
 bool FakeEventHub::hasRelativeAxis(int32_t deviceId, int axis) const {
@@ -417,18 +413,15 @@
     return AKEY_STATE_UNKNOWN;
 }
 
-status_t FakeEventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
-                                            int32_t* outValue) const {
+std::optional<int32_t> FakeEventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis) const {
     Device* device = getDevice(deviceId);
     if (device) {
         ssize_t index = device->absoluteAxisValue.indexOfKey(axis);
         if (index >= 0) {
-            *outValue = device->absoluteAxisValue.valueAt(index);
-            return OK;
+            return device->absoluteAxisValue.valueAt(index);
         }
     }
-    *outValue = 0;
-    return -1;
+    return std::nullopt;
 }
 
 void FakeEventHub::setMtSlotValues(int32_t deviceId, int32_t axis,
diff --git a/services/inputflinger/tests/FakeEventHub.h b/services/inputflinger/tests/FakeEventHub.h
index f07b344..3d8dddd 100644
--- a/services/inputflinger/tests/FakeEventHub.h
+++ b/services/inputflinger/tests/FakeEventHub.h
@@ -112,8 +112,6 @@
     status_t enableDevice(int32_t deviceId) override;
     status_t disableDevice(int32_t deviceId) override;
 
-    void finishDeviceScan();
-
     void addConfigurationProperty(int32_t deviceId, const char* key, const char* value);
     void addConfigurationMap(int32_t deviceId, const PropertyMap* configuration);
 
@@ -168,8 +166,8 @@
     InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const override;
     int32_t getDeviceControllerNumber(int32_t) const override;
     std::optional<PropertyMap> getConfiguration(int32_t deviceId) const override;
-    status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
-                                 RawAbsoluteAxisInfo* outAxisInfo) const override;
+    std::optional<RawAbsoluteAxisInfo> getAbsoluteAxisInfo(int32_t deviceId,
+                                                           int axis) const override;
     bool hasRelativeAxis(int32_t deviceId, int axis) const override;
     bool hasInputProperty(int32_t, int) const override;
     bool hasMscEvent(int32_t deviceId, int mscEvent) const override final;
@@ -187,7 +185,7 @@
     std::optional<RawLayoutInfo> getRawLayoutInfo(int32_t deviceId) const override;
     int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override;
     int32_t getSwitchState(int32_t deviceId, int32_t sw) const override;
-    status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const override;
+    std::optional<int32_t> getAbsoluteAxisValue(int32_t deviceId, int32_t axis) const override;
     int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const override;
 
     // Return true if the device has non-empty key layout.
diff --git a/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp b/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp
index 3df05f4..db68d8a 100644
--- a/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp
+++ b/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp
@@ -54,13 +54,6 @@
     ASSERT_EQ(nullptr, mFilteredEvent);
 }
 
-void FakeInputDispatcherPolicy::assertNotifyConfigurationChangedWasCalled(nsecs_t when) {
-    std::scoped_lock lock(mLock);
-    ASSERT_TRUE(mConfigurationChangedTime) << "Timed out waiting for configuration changed call";
-    ASSERT_EQ(*mConfigurationChangedTime, when);
-    mConfigurationChangedTime = std::nullopt;
-}
-
 void FakeInputDispatcherPolicy::assertNotifySwitchWasCalled(const NotifySwitchArgs& args) {
     std::scoped_lock lock(mLock);
     ASSERT_TRUE(mLastNotifySwitch);
@@ -342,11 +335,6 @@
     return std::make_optional(item);
 }
 
-void FakeInputDispatcherPolicy::notifyConfigurationChanged(nsecs_t when) {
-    std::scoped_lock lock(mLock);
-    mConfigurationChangedTime = when;
-}
-
 void FakeInputDispatcherPolicy::notifyWindowUnresponsive(const sp<IBinder>& connectionToken,
                                                          std::optional<gui::Pid> pid,
                                                          const std::string&) {
diff --git a/services/inputflinger/tests/FakeInputDispatcherPolicy.h b/services/inputflinger/tests/FakeInputDispatcherPolicy.h
index a0f3ea9..a9e39d1 100644
--- a/services/inputflinger/tests/FakeInputDispatcherPolicy.h
+++ b/services/inputflinger/tests/FakeInputDispatcherPolicy.h
@@ -66,7 +66,6 @@
     void assertFilterInputEventWasCalled(const NotifyKeyArgs& args);
     void assertFilterInputEventWasCalled(const NotifyMotionArgs& args, vec2 point);
     void assertFilterInputEventWasNotCalled();
-    void assertNotifyConfigurationChangedWasCalled(nsecs_t when);
     void assertNotifySwitchWasCalled(const NotifySwitchArgs& args);
     void assertOnPointerDownEquals(const sp<IBinder>& touchedToken);
     void assertOnPointerDownWasNotCalled();
@@ -121,7 +120,6 @@
 private:
     std::mutex mLock;
     std::unique_ptr<InputEvent> mFilteredEvent GUARDED_BY(mLock);
-    std::optional<nsecs_t> mConfigurationChangedTime GUARDED_BY(mLock);
     sp<IBinder> mOnPointerDownToken GUARDED_BY(mLock);
     std::optional<NotifySwitchArgs> mLastNotifySwitch GUARDED_BY(mLock);
 
@@ -173,7 +171,6 @@
                                                            std::condition_variable& condition)
             REQUIRES(mLock);
 
-    void notifyConfigurationChanged(nsecs_t when) override;
     void notifyWindowUnresponsive(const sp<IBinder>& connectionToken, std::optional<gui::Pid> pid,
                                   const std::string&) override;
     void notifyWindowResponsive(const sp<IBinder>& connectionToken,
diff --git a/services/inputflinger/tests/FakeInputReaderPolicy.cpp b/services/inputflinger/tests/FakeInputReaderPolicy.cpp
index d2cb0ac..6099c91 100644
--- a/services/inputflinger/tests/FakeInputReaderPolicy.cpp
+++ b/services/inputflinger/tests/FakeInputReaderPolicy.cpp
@@ -16,6 +16,7 @@
 
 #include "FakeInputReaderPolicy.h"
 
+#include <android-base/properties.h>
 #include <android-base/thread_annotations.h>
 #include <gtest/gtest.h>
 
@@ -24,6 +25,12 @@
 
 namespace android {
 
+namespace {
+
+static const int HW_TIMEOUT_MULTIPLIER = base::GetIntProperty("ro.hw_timeout_multiplier", 1);
+
+} // namespace
+
 void FakeInputReaderPolicy::assertInputDevicesChanged() {
     waitForInputDevices([](bool devicesChanged) {
         if (!devicesChanged) {
@@ -241,9 +248,11 @@
     base::ScopedLockAssertion assumeLocked(mLock);
 
     const bool devicesChanged =
-            mDevicesChangedCondition.wait_for(lock, WAIT_TIMEOUT, [this]() REQUIRES(mLock) {
-                return mInputDevicesChanged;
-            });
+            mDevicesChangedCondition.wait_for(lock,
+                                              ADD_INPUT_DEVICE_TIMEOUT * HW_TIMEOUT_MULTIPLIER,
+                                              [this]() REQUIRES(mLock) {
+                                                  return mInputDevicesChanged;
+                                              });
     ASSERT_NO_FATAL_FAILURE(processDevicesChanged(devicesChanged));
     mInputDevicesChanged = false;
 }
diff --git a/services/inputflinger/tests/FakeWindows.h b/services/inputflinger/tests/FakeWindows.h
index 36a8f00..3a3238a 100644
--- a/services/inputflinger/tests/FakeWindows.h
+++ b/services/inputflinger/tests/FakeWindows.h
@@ -304,15 +304,18 @@
                                           WithFlags(expectedFlags)));
     }
 
-    inline void consumeMotionPointerUp(
-            int32_t pointerIdx,
-            ui::LogicalDisplayId expectedDisplayId = ui::LogicalDisplayId::DEFAULT,
-            int32_t expectedFlags = 0) {
+    inline void consumeMotionPointerDown(int32_t pointerIdx,
+                                         const ::testing::Matcher<MotionEvent>& matcher) {
+        const int32_t action = AMOTION_EVENT_ACTION_POINTER_DOWN |
+                (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+        consumeMotionEvent(testing::AllOf(WithMotionAction(action), matcher));
+    }
+
+    inline void consumeMotionPointerUp(int32_t pointerIdx,
+                                       const ::testing::Matcher<MotionEvent>& matcher) {
         const int32_t action = AMOTION_EVENT_ACTION_POINTER_UP |
                 (pointerIdx << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
-        consumeMotionEvent(testing::AllOf(WithMotionAction(action),
-                                          WithDisplayId(expectedDisplayId),
-                                          WithFlags(expectedFlags)));
+        consumeMotionEvent(testing::AllOf(WithMotionAction(action), matcher));
     }
 
     inline void consumeMotionUp(
diff --git a/services/inputflinger/tests/HardwareProperties_test.cpp b/services/inputflinger/tests/HardwareProperties_test.cpp
index 8dfa8c8..643fab6 100644
--- a/services/inputflinger/tests/HardwareProperties_test.cpp
+++ b/services/inputflinger/tests/HardwareProperties_test.cpp
@@ -48,24 +48,20 @@
     static constexpr int32_t EVENTHUB_ID = 1;
 
     void setupValidAxis(int axis, int32_t min, int32_t max, int32_t resolution) {
-        EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis, testing::_))
-                .WillRepeatedly([=](int32_t, int32_t, RawAbsoluteAxisInfo* outAxisInfo) {
-                    outAxisInfo->valid = true;
-                    outAxisInfo->minValue = min;
-                    outAxisInfo->maxValue = max;
-                    outAxisInfo->flat = 0;
-                    outAxisInfo->fuzz = 0;
-                    outAxisInfo->resolution = resolution;
-                    return OK;
-                });
+        EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis))
+                .WillRepeatedly(Return(std::optional<RawAbsoluteAxisInfo>{{
+                        .valid = true,
+                        .minValue = min,
+                        .maxValue = max,
+                        .flat = 0,
+                        .fuzz = 0,
+                        .resolution = resolution,
+                }}));
     }
 
     void setupInvalidAxis(int axis) {
-        EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis, testing::_))
-                .WillRepeatedly([=](int32_t, int32_t, RawAbsoluteAxisInfo* outAxisInfo) {
-                    outAxisInfo->valid = false;
-                    return -1;
-                });
+        EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis))
+                .WillRepeatedly(Return(std::nullopt));
     }
 
     void setProperty(int property, bool value) {
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index aa1462a..c70afd6 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -411,16 +411,6 @@
             << "Should reject motion events with duplicate pointer ids.";
 }
 
-/* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */
-
-TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) {
-    constexpr nsecs_t eventTime = 20;
-    mDispatcher->notifyConfigurationChanged({/*id=*/10, eventTime});
-    ASSERT_TRUE(mDispatcher->waitForIdle());
-
-    mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime);
-}
-
 TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
     NotifySwitchArgs args(InputEvent::nextId(), /*eventTime=*/20, /*policyFlags=*/0,
                           /*switchValues=*/1,
@@ -1282,9 +1272,11 @@
               injectMotionEvent(*mDispatcher, secondFingerUpEvent, INJECT_EVENT_TIMEOUT,
                                 InputEventInjectionSync::WAIT_FOR_RESULT))
             << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
-    foregroundWindow->consumeMotionPointerUp(0);
-    wallpaperWindow->consumeMotionPointerUp(0, ui::LogicalDisplayId::DEFAULT,
-                                            EXPECTED_WALLPAPER_FLAGS);
+    foregroundWindow->consumeMotionPointerUp(/*pointerIdx=*/0,
+                                             WithDisplayId(ui::LogicalDisplayId::DEFAULT));
+    wallpaperWindow->consumeMotionPointerUp(/*pointerIdx=*/0,
+                                            AllOf(WithDisplayId(ui::LogicalDisplayId::DEFAULT),
+                                                  WithFlags(EXPECTED_WALLPAPER_FLAGS)));
 
     ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
               injectMotionEvent(*mDispatcher,
@@ -4170,6 +4162,121 @@
     window2->consumeMotionEvent(WithDownTime(secondDown->getDownTime()));
 }
 
+/**
+ * When events are not split, the downTime should be adjusted such that the downTime corresponds
+ * to the event time of the first ACTION_DOWN. If a new window appears, it should not affect
+ * the event routing because the first window prevents splitting.
+ */
+TEST_F(InputDispatcherTest, SplitTouchesSendCorrectActionDownTimeForNewWindow) {
+    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+    sp<FakeWindowHandle> window1 =
+            sp<FakeWindowHandle>::make(application, mDispatcher, "Window1", DISPLAY_ID);
+    window1->setTouchableRegion(Region{{0, 0, 100, 100}});
+    window1->setPreventSplitting(true);
+
+    sp<FakeWindowHandle> window2 =
+            sp<FakeWindowHandle>::make(application, mDispatcher, "Window2", DISPLAY_ID);
+    window2->setTouchableRegion(Region{{100, 0, 200, 100}});
+
+    mDispatcher->onWindowInfosChanged({{*window1->getInfo()}, {}, 0, 0});
+
+    // Touch down on the first window
+    NotifyMotionArgs downArgs = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                                        .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                        .build();
+    mDispatcher->notifyMotion(downArgs);
+
+    window1->consumeMotionEvent(
+            AllOf(WithMotionAction(ACTION_DOWN), WithDownTime(downArgs.downTime)));
+
+    // Second window is added
+    mDispatcher->onWindowInfosChanged({{*window1->getInfo(), *window2->getInfo()}, {}, 0, 0});
+
+    // Now touch down on the window with another pointer
+    mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                      .pointer(PointerBuilder(1, ToolType::FINGER).x(150).y(50))
+                                      .downTime(downArgs.downTime)
+                                      .build());
+    window1->consumeMotionPointerDown(1, AllOf(WithDownTime(downArgs.downTime)));
+
+    // Finish the gesture
+    mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                      .pointer(PointerBuilder(1, ToolType::FINGER).x(150).y(50))
+                                      .downTime(downArgs.downTime)
+                                      .build());
+    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                      .downTime(downArgs.downTime)
+                                      .build());
+    window1->consumeMotionPointerUp(1, AllOf(WithDownTime(downArgs.downTime)));
+    window1->consumeMotionEvent(
+            AllOf(WithMotionAction(ACTION_UP), WithDownTime(downArgs.downTime)));
+    window2->assertNoEvents();
+}
+
+/**
+ * When splitting touch events, the downTime should be adjusted such that the downTime corresponds
+ * to the event time of the first ACTION_DOWN sent to the new window.
+ * If a new window that does not support split appears on the screen and gets touched with the
+ * second finger, it should not get any events because it doesn't want split touches. At the same
+ * time, the first window should not get the pointer_down event because it supports split touches
+ * (and the touch occurred outside of the bounds of window1).
+ */
+TEST_F(InputDispatcherTest, SplitTouchesDropsEventForNonSplittableSecondWindow) {
+    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+    sp<FakeWindowHandle> window1 =
+            sp<FakeWindowHandle>::make(application, mDispatcher, "Window1", DISPLAY_ID);
+    window1->setTouchableRegion(Region{{0, 0, 100, 100}});
+
+    sp<FakeWindowHandle> window2 =
+            sp<FakeWindowHandle>::make(application, mDispatcher, "Window2", DISPLAY_ID);
+    window2->setTouchableRegion(Region{{100, 0, 200, 100}});
+
+    mDispatcher->onWindowInfosChanged({{*window1->getInfo()}, {}, 0, 0});
+
+    // Touch down on the first window
+    NotifyMotionArgs downArgs = MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                                        .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                        .build();
+    mDispatcher->notifyMotion(downArgs);
+
+    window1->consumeMotionEvent(
+            AllOf(WithMotionAction(ACTION_DOWN), WithDownTime(downArgs.downTime)));
+
+    // Second window is added
+    window2->setPreventSplitting(true);
+    mDispatcher->onWindowInfosChanged({{*window1->getInfo(), *window2->getInfo()}, {}, 0, 0});
+
+    // Now touch down on the window with another pointer
+    mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                      .pointer(PointerBuilder(1, ToolType::FINGER).x(150).y(50))
+                                      .downTime(downArgs.downTime)
+                                      .build());
+    // Event is dropped because window2 doesn't support split touch, and window1 does.
+
+    // Complete the gesture
+    mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                      .pointer(PointerBuilder(1, ToolType::FINGER).x(150).y(50))
+                                      .downTime(downArgs.downTime)
+                                      .build());
+    // A redundant MOVE event is generated that doesn't carry any new information
+    window1->consumeMotionEvent(
+            AllOf(WithMotionAction(ACTION_MOVE), WithDownTime(downArgs.downTime)));
+    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                      .downTime(downArgs.downTime)
+                                      .build());
+
+    window1->consumeMotionEvent(
+            AllOf(WithMotionAction(ACTION_UP), WithDownTime(downArgs.downTime)));
+    window1->assertNoEvents();
+    window2->assertNoEvents();
+}
+
 TEST_F(InputDispatcherTest, HoverMoveEnterMouseClickAndHoverMoveExit) {
     std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
     sp<FakeWindowHandle> windowLeft = sp<FakeWindowHandle>::make(application, mDispatcher, "Left",
@@ -4374,6 +4481,201 @@
     window->assertNoEvents();
 }
 
+/**
+ * A spy window sits above a window with NO_INPUT_CHANNEL. Ensure that the spy receives events even
+ * though the window underneath should not get any events.
+ */
+TEST_F(InputDispatcherTest, NonSplittableSpyAboveNoInputChannelWindowSinglePointer) {
+    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+
+    sp<FakeWindowHandle> spyWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Spy",
+                                                                ui::LogicalDisplayId::DEFAULT);
+    spyWindow->setFrame(Rect(0, 0, 100, 100));
+    spyWindow->setTrustedOverlay(true);
+    spyWindow->setPreventSplitting(true);
+    spyWindow->setSpy(true);
+    // Another window below spy that has both NO_INPUT_CHANNEL and PREVENT_SPLITTING
+    sp<FakeWindowHandle> inputSinkWindow =
+            sp<FakeWindowHandle>::make(application, mDispatcher, "Input sink below spy",
+                                       ui::LogicalDisplayId::DEFAULT);
+    inputSinkWindow->setFrame(Rect(0, 0, 100, 100));
+    inputSinkWindow->setTrustedOverlay(true);
+    inputSinkWindow->setPreventSplitting(true);
+    inputSinkWindow->setNoInputChannel(true);
+
+    mDispatcher->onWindowInfosChanged(
+            {{*spyWindow->getInfo(), *inputSinkWindow->getInfo()}, {}, 0, 0});
+
+    // Tap the spy window
+    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(51))
+                                      .build());
+    mDispatcher->notifyMotion(
+            MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                    .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(51))
+                    .build());
+
+    spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN)));
+    spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP)));
+    inputSinkWindow->assertNoEvents();
+}
+
+/**
+ * A spy window sits above a window with NO_INPUT_CHANNEL. Ensure that the spy receives events even
+ * though the window underneath should not get any events.
+ * Same test as above, but with two pointers touching instead of one.
+ */
+TEST_F(InputDispatcherTest, NonSplittableSpyAboveNoInputChannelWindowTwoPointers) {
+    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+
+    sp<FakeWindowHandle> spyWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Spy",
+                                                                ui::LogicalDisplayId::DEFAULT);
+    spyWindow->setFrame(Rect(0, 0, 100, 100));
+    spyWindow->setTrustedOverlay(true);
+    spyWindow->setPreventSplitting(true);
+    spyWindow->setSpy(true);
+    // Another window below spy that would have both NO_INPUT_CHANNEL and PREVENT_SPLITTING
+    sp<FakeWindowHandle> inputSinkWindow =
+            sp<FakeWindowHandle>::make(application, mDispatcher, "Input sink below spy",
+                                       ui::LogicalDisplayId::DEFAULT);
+    inputSinkWindow->setFrame(Rect(0, 0, 100, 100));
+    inputSinkWindow->setTrustedOverlay(true);
+    inputSinkWindow->setPreventSplitting(true);
+    inputSinkWindow->setNoInputChannel(true);
+
+    mDispatcher->onWindowInfosChanged(
+            {{*spyWindow->getInfo(), *inputSinkWindow->getInfo()}, {}, 0, 0});
+
+    // Both fingers land into the spy window
+    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(51))
+                                      .build());
+    mDispatcher->notifyMotion(
+            MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                    .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(51))
+                    .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(10).y(11))
+                    .build());
+    mDispatcher->notifyMotion(
+            MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                    .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(51))
+                    .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(10).y(11))
+                    .build());
+    mDispatcher->notifyMotion(
+            MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                    .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(51))
+                    .build());
+
+    spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN)));
+    spyWindow->consumeMotionPointerDown(1, WithPointerCount(2));
+    spyWindow->consumeMotionPointerUp(1, WithPointerCount(2));
+    spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP)));
+    inputSinkWindow->assertNoEvents();
+}
+
+/** Check the behaviour for cases where input sink prevents or doesn't prevent splitting. */
+class SpyThatPreventsSplittingWithApplicationFixture : public InputDispatcherTest,
+                                                       public ::testing::WithParamInterface<bool> {
+};
+
+/**
+ * Three windows:
+ * - An application window (app window)
+ * - A spy window that does not overlap the app window. Has PREVENT_SPLITTING flag
+ * - A window below the spy that has NO_INPUT_CHANNEL (call it 'inputSink')
+ *
+ * The spy window is side-by-side with the app window. The inputSink is below the spy.
+ * We first touch the area outside of the appWindow, but inside spyWindow.
+ * Only the SPY window should get the DOWN event.
+ * The spy pilfers after receiving the first DOWN event.
+ * Next, we touch the app window.
+ * The spy should receive POINTER_DOWN(1) (since spy is preventing splits).
+ * Also, since the spy is already pilfering the first pointer, it will be sent the remaining new
+ * pointers automatically, as well.
+ * Next, the first pointer (from the spy) is lifted.
+ * Spy should get POINTER_UP(0).
+ * This event should not go to the app because the app never received this pointer to begin with.
+ * Now, lift the remaining pointer and check that the spy receives UP event.
+ *
+ * Finally, send a new ACTION_DOWN event to the spy and check that it's received.
+ * This test attempts to reproduce a crash in the dispatcher.
+ */
+TEST_P(SpyThatPreventsSplittingWithApplicationFixture, SpyThatPreventsSplittingWithApplication) {
+    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+
+    sp<FakeWindowHandle> spyWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Spy",
+                                                                ui::LogicalDisplayId::DEFAULT);
+    spyWindow->setFrame(Rect(100, 100, 200, 200));
+    spyWindow->setTrustedOverlay(true);
+    spyWindow->setPreventSplitting(true);
+    spyWindow->setSpy(true);
+    // Another window below spy that has both NO_INPUT_CHANNEL and PREVENT_SPLITTING
+    sp<FakeWindowHandle> inputSinkWindow =
+            sp<FakeWindowHandle>::make(application, mDispatcher, "Input sink below spy",
+                                       ui::LogicalDisplayId::DEFAULT);
+    inputSinkWindow->setFrame(Rect(100, 100, 200, 200)); // directly below the spy
+    inputSinkWindow->setTrustedOverlay(true);
+    inputSinkWindow->setPreventSplitting(GetParam());
+    inputSinkWindow->setNoInputChannel(true);
+
+    sp<FakeWindowHandle> appWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "App",
+                                                                ui::LogicalDisplayId::DEFAULT);
+    appWindow->setFrame(Rect(0, 0, 100, 100));
+
+    mDispatcher->setFocusedApplication(ui::LogicalDisplayId::DEFAULT, application);
+    mDispatcher->onWindowInfosChanged(
+            {{*spyWindow->getInfo(), *inputSinkWindow->getInfo(), *appWindow->getInfo()},
+             {},
+             0,
+             0});
+
+    // First finger lands outside of the appWindow, but inside of the spy window
+    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(150))
+                                      .build());
+    spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN)));
+
+    mDispatcher->pilferPointers(spyWindow->getToken());
+
+    // Second finger lands in the app, and goes to the spy window. It doesn't go to the app because
+    // the spy is already pilfering the first pointer, and this automatically grants the remaining
+    // new pointers to the spy, as well.
+    mDispatcher->notifyMotion(
+            MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                    .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(150).y(150))
+                    .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
+                    .build());
+
+    spyWindow->consumeMotionPointerDown(1, WithPointerCount(2));
+
+    // Now lift up the first pointer
+    mDispatcher->notifyMotion(
+            MotionArgsBuilder(POINTER_0_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                    .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(150).y(150))
+                    .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
+                    .build());
+    spyWindow->consumeMotionPointerUp(0, WithPointerCount(2));
+
+    // And lift the remaining pointer!
+    mDispatcher->notifyMotion(
+            MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                    .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
+                    .build());
+    spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithPointerCount(1)));
+
+    // Now send a new DOWN, which should again go to spy.
+    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(150))
+                                      .build());
+    spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN)));
+    // The app window doesn't get any events this entire time because the spy received the events
+    // first and pilfered, which makes all new pointers go to it as well.
+    appWindow->assertNoEvents();
+}
+
+// Behaviour should be the same regardless of whether inputSink supports splitting.
+INSTANTIATE_TEST_SUITE_P(SpyThatPreventsSplittingWithApplication,
+                         SpyThatPreventsSplittingWithApplicationFixture, testing::Bool());
+
 TEST_F(InputDispatcherTest, HoverWithSpyWindows) {
     std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
 
@@ -5355,6 +5657,72 @@
     rightWindow->assertNoEvents();
 }
 
+/**
+ * Two windows: left and right. The left window has PREVENT_SPLITTING input config. Device A sends a
+ * down event to the right window. Device B sends a down event to the left window, and then a
+ * POINTER_DOWN event to the right window. However, since the left window prevents splitting, the
+ * POINTER_DOWN event should only go to the left window, and not to the right window.
+ * This test attempts to reproduce a crash.
+ */
+TEST_F(InputDispatcherTest, MultiDeviceTwoWindowsPreventSplitting) {
+    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+    sp<FakeWindowHandle> leftWindow =
+            sp<FakeWindowHandle>::make(application, mDispatcher, "Left window (prevent splitting)",
+                                       ui::LogicalDisplayId::DEFAULT);
+    leftWindow->setFrame(Rect(0, 0, 100, 100));
+    leftWindow->setPreventSplitting(true);
+
+    sp<FakeWindowHandle> rightWindow =
+            sp<FakeWindowHandle>::make(application, mDispatcher, "Right window",
+                                       ui::LogicalDisplayId::DEFAULT);
+    rightWindow->setFrame(Rect(100, 0, 200, 100));
+
+    mDispatcher->onWindowInfosChanged(
+            {{*leftWindow->getInfo(), *rightWindow->getInfo()}, {}, 0, 0});
+
+    const DeviceId deviceA = 9;
+    const DeviceId deviceB = 3;
+    // Touch the right window with device A
+    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50))
+                                      .deviceId(deviceA)
+                                      .build());
+    rightWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceA)));
+    // Touch the left window with device B
+    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                      .deviceId(deviceB)
+                                      .build());
+    leftWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceB)));
+    // Send a second pointer from device B to the right window. It shouldn't go to the right window
+    // because the left window prevents splitting.
+    mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .deviceId(deviceB)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                      .pointer(PointerBuilder(1, ToolType::FINGER).x(120).y(120))
+                                      .build());
+    leftWindow->consumeMotionPointerDown(1, WithDeviceId(deviceB));
+
+    // Finish the gesture for both devices
+    mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .deviceId(deviceB)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                      .pointer(PointerBuilder(1, ToolType::FINGER).x(120).y(120))
+                                      .build());
+    leftWindow->consumeMotionPointerUp(1, WithDeviceId(deviceB));
+    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+                                      .deviceId(deviceB)
+                                      .build());
+    leftWindow->consumeMotionEvent(
+            AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceB), WithPointerId(0, 0)));
+    mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+                                      .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50))
+                                      .deviceId(deviceA)
+                                      .build());
+    rightWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceA)));
+}
+
 TEST_F(InputDispatcherTest, TouchpadThreeFingerSwipeOnlySentToTrustedOverlays) {
     std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
     sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window",
@@ -6220,8 +6588,10 @@
                                                  {touchPoint, touchPoint}));
     // The first window gets nothing and the second gets pointer up
     firstWindow->assertNoEvents();
-    secondWindow->consumeMotionPointerUp(1, ui::LogicalDisplayId::DEFAULT,
-                                         AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE);
+    secondWindow->consumeMotionPointerUp(/*pointerIdx=*/1,
+                                         AllOf(WithDisplayId(ui::LogicalDisplayId::DEFAULT),
+                                               WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE),
+                                               WithPointerCount(2)));
 
     // Send up event to the second window
     mDispatcher->notifyMotion(generateMotionArgs(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
@@ -6363,8 +6733,10 @@
                                                  {pointInFirst, pointInSecond}));
     // The first window gets nothing and the second gets pointer up
     firstWindow->assertNoEvents();
-    secondWindow->consumeMotionPointerUp(1, ui::LogicalDisplayId::DEFAULT,
-                                         AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE);
+    secondWindow->consumeMotionPointerUp(/*pointerIdx=*/1,
+                                         AllOf(WithDisplayId(ui::LogicalDisplayId::DEFAULT),
+                                               WithFlags(AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE),
+                                               WithPointerCount(2)));
 
     // Send up event to the second window
     mDispatcher->notifyMotion(generateMotionArgs(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
@@ -12881,10 +13253,14 @@
 
     // Spy window pilfers the pointers.
     EXPECT_EQ(OK, mDispatcher->pilferPointers(spy->getToken()));
-    window->consumeMotionPointerUp(/*idx=*/2, ui::LogicalDisplayId::DEFAULT,
-                                   AMOTION_EVENT_FLAG_CANCELED);
-    window->consumeMotionPointerUp(/*idx=*/1, ui::LogicalDisplayId::DEFAULT,
-                                   AMOTION_EVENT_FLAG_CANCELED);
+    window->consumeMotionPointerUp(/*pointerIdx=*/2,
+                                   AllOf(WithDisplayId(ui::LogicalDisplayId::DEFAULT),
+                                         WithFlags(AMOTION_EVENT_FLAG_CANCELED),
+                                         WithPointerCount(3)));
+    window->consumeMotionPointerUp(/*pointerIdx=*/1,
+                                   AllOf(WithDisplayId(ui::LogicalDisplayId::DEFAULT),
+                                         WithFlags(AMOTION_EVENT_FLAG_CANCELED),
+                                         WithPointerCount(2)));
 
     spy->assertNoEvents();
     window->assertNoEvents();
diff --git a/services/inputflinger/tests/InputMapperTest.cpp b/services/inputflinger/tests/InputMapperTest.cpp
index b5c9232..7e96d5f 100644
--- a/services/inputflinger/tests/InputMapperTest.cpp
+++ b/services/inputflinger/tests/InputMapperTest.cpp
@@ -57,16 +57,16 @@
 
 void InputMapperUnitTest::setupAxis(int axis, bool valid, int32_t min, int32_t max,
                                     int32_t resolution) {
-    EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis, _))
-            .WillRepeatedly([=](int32_t, int32_t, RawAbsoluteAxisInfo* outAxisInfo) {
-                outAxisInfo->valid = valid;
-                outAxisInfo->minValue = min;
-                outAxisInfo->maxValue = max;
-                outAxisInfo->flat = 0;
-                outAxisInfo->fuzz = 0;
-                outAxisInfo->resolution = resolution;
-                return valid ? OK : -1;
-            });
+    EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, axis))
+            .WillRepeatedly(Return(valid ? std::optional<RawAbsoluteAxisInfo>{{
+                                                   .valid = true,
+                                                   .minValue = min,
+                                                   .maxValue = max,
+                                                   .flat = 0,
+                                                   .fuzz = 0,
+                                                   .resolution = resolution,
+                                           }}
+                                         : std::nullopt));
 }
 
 void InputMapperUnitTest::expectScanCodes(bool present, std::set<int> scanCodes) {
@@ -90,6 +90,13 @@
     }
 }
 
+void InputMapperUnitTest::setSwitchState(int32_t state, std::set<int32_t> switchCodes) {
+    for (const auto& switchCode : switchCodes) {
+        EXPECT_CALL(mMockEventHub, getSwitchState(EVENTHUB_ID, switchCode))
+                .WillRepeatedly(testing::Return(static_cast<int>(state)));
+    }
+}
+
 std::list<NotifyArgs> InputMapperUnitTest::process(int32_t type, int32_t code, int32_t value) {
     nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
     return process(when, type, code, value);
diff --git a/services/inputflinger/tests/InputMapperTest.h b/services/inputflinger/tests/InputMapperTest.h
index 5bd8cda..88057dc 100644
--- a/services/inputflinger/tests/InputMapperTest.h
+++ b/services/inputflinger/tests/InputMapperTest.h
@@ -58,6 +58,8 @@
 
     void setKeyCodeState(KeyState state, std::set<int> keyCodes);
 
+    void setSwitchState(int32_t state, std::set<int32_t> switchCodes);
+
     std::list<NotifyArgs> process(int32_t type, int32_t code, int32_t value);
     std::list<NotifyArgs> process(nsecs_t when, int32_t type, int32_t code, int32_t value);
 
diff --git a/services/inputflinger/tests/InputProcessor_test.cpp b/services/inputflinger/tests/InputProcessor_test.cpp
index f7e5e67..d4c5a00 100644
--- a/services/inputflinger/tests/InputProcessor_test.cpp
+++ b/services/inputflinger/tests/InputProcessor_test.cpp
@@ -63,20 +63,6 @@
     void SetUp() override { mProcessor = std::make_unique<InputProcessor>(mTestListener); }
 };
 
-/**
- * Create a basic configuration change and send it to input processor.
- * Expect that the event is received by the next input stage, unmodified.
- */
-TEST_F(InputProcessorTest, SendToNextStage_NotifyConfigurationChangedArgs) {
-    // Create a basic configuration change and send to processor
-    NotifyConfigurationChangedArgs args(/*sequenceNum=*/1, /*eventTime=*/2);
-
-    mProcessor->notifyConfigurationChanged(args);
-    NotifyConfigurationChangedArgs outArgs;
-    ASSERT_NO_FATAL_FAILURE(mTestListener.assertNotifyConfigurationChangedWasCalled(&outArgs));
-    ASSERT_EQ(args, outArgs);
-}
-
 TEST_F(InputProcessorTest, SendToNextStage_NotifyKeyArgs) {
     // Create a basic key event and send to processor
     NotifyKeyArgs args(/*sequenceNum=*/1, /*eventTime=*/2, /*readTime=*/21, /*deviceId=*/3,
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index fe238f3..8bb22d0 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -24,19 +24,16 @@
 #include <InputReader.h>
 #include <InputReaderBase.h>
 #include <InputReaderFactory.h>
-#include <JoystickInputMapper.h>
 #include <KeyboardInputMapper.h>
 #include <MultiTouchInputMapper.h>
 #include <NotifyArgsBuilders.h>
 #include <PeripheralController.h>
 #include <SensorInputMapper.h>
 #include <SingleTouchInputMapper.h>
-#include <SwitchInputMapper.h>
 #include <TestEventMatchers.h>
 #include <TestInputListener.h>
 #include <TouchInputMapper.h>
 #include <UinputDevice.h>
-#include <VibratorInputMapper.h>
 #include <android-base/thread_annotations.h>
 #include <com_android_input_flags.h>
 #include <ftl/enum.h>
@@ -56,6 +53,7 @@
 
 using namespace ftl::flag_operators;
 using testing::AllOf;
+using testing::VariantWith;
 using std::chrono_literals::operator""ms;
 using std::chrono_literals::operator""s;
 
@@ -623,7 +621,6 @@
         if (configuration) {
             mFakeEventHub->addConfigurationMap(eventHubId, configuration);
         }
-        mFakeEventHub->finishDeviceScan();
         mReader->loopOnce();
         mReader->loopOnce();
         ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
@@ -757,8 +754,6 @@
     mReader->pushNextDevice(device);
     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
 
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
-
     NotifyDeviceResetArgs resetArgs;
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
     ASSERT_EQ(deviceId, resetArgs.deviceId);
@@ -774,7 +769,6 @@
     disableDevice(deviceId);
     mReader->loopOnce();
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasNotCalled());
     ASSERT_EQ(device->isEnabled(), false);
 
     enableDevice(deviceId);
@@ -959,16 +953,6 @@
     ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
 }
 
-TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
-    constexpr int32_t eventHubId = 1;
-    addDevice(eventHubId, "ignored", InputDeviceClass::KEYBOARD, nullptr);
-
-    NotifyConfigurationChangedArgs args;
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-}
-
 TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
     constexpr int32_t deviceId = END_RESERVED_ID + 1000;
     constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
@@ -1073,7 +1057,6 @@
     // The device is added after the input port associations are processed since
     // we do not yet support dynamic device-to-display associations.
     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled());
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
     ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
 
@@ -1103,8 +1086,6 @@
     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
     ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
 
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
-
     NotifyDeviceResetArgs resetArgs;
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
     ASSERT_EQ(deviceId, resetArgs.deviceId);
@@ -1476,9 +1457,8 @@
         // Since this test is run on a real device, all the input devices connected
         // to the test device will show up in mReader. We wait for those input devices to
         // show up before beginning the tests.
-        ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
         ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyInputDevicesChangedWasCalled());
-        ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
+        ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
     }
 };
 
@@ -1498,12 +1478,10 @@
     // consider it as a valid device.
     std::unique_ptr<UinputDevice> invalidDevice = createUinputDevice<InvalidUinputDevice>();
     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
-    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
     ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
 
     invalidDevice.reset();
     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
-    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
     ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
 }
 
@@ -1512,7 +1490,6 @@
 
     std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
-    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
     ASSERT_EQ(initialNumDevices + 1, mFakePolicy->getInputDevices().size());
 
     const auto device = waitForDevice(keyboard->getName());
@@ -1523,7 +1500,6 @@
 
     keyboard.reset();
     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
-    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
     ASSERT_EQ(initialNumDevices, mFakePolicy->getInputDevices().size());
 }
 
@@ -1531,21 +1507,14 @@
     std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
 
-    NotifyConfigurationChangedArgs configChangedArgs;
-    ASSERT_NO_FATAL_FAILURE(
-            mTestListener->assertNotifyConfigurationChangedWasCalled(&configChangedArgs));
-    int32_t prevId = configChangedArgs.id;
-    nsecs_t prevTimestamp = configChangedArgs.eventTime;
-
     NotifyKeyArgs keyArgs;
     keyboard->pressAndReleaseHomeKey();
     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
     ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_NE(prevId, keyArgs.id);
-    prevId = keyArgs.id;
-    ASSERT_LE(prevTimestamp, keyArgs.eventTime);
     ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
-    prevTimestamp = keyArgs.eventTime;
+
+    int32_t prevId = keyArgs.id;
+    nsecs_t prevTimestamp = keyArgs.eventTime;
 
     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
     ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
@@ -1668,7 +1637,6 @@
 
         mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
         ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
-        ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
         const auto info = waitForDevice(mDevice->getName());
         ASSERT_TRUE(info);
         mDeviceInfo = *info;
@@ -1737,7 +1705,6 @@
                                      UNIQUE_ID, isInputPortAssociation ? DISPLAY_PORT : NO_PORT,
                                      ViewportType::INTERNAL);
         ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
-        ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
         const auto info = waitForDevice(mDevice->getName());
         ASSERT_TRUE(info);
         mDeviceInfo = *info;
@@ -2070,7 +2037,6 @@
     // Connecting an external stylus mid-gesture should not interrupt the ongoing gesture stream.
     auto externalStylus = createUinputDevice<UinputExternalStylus>();
     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
-    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
     const auto stylusInfo = waitForDevice(externalStylus->getName());
     ASSERT_TRUE(stylusInfo);
 
@@ -2083,7 +2049,6 @@
     // Disconnecting an external stylus mid-gesture should not interrupt the ongoing gesture stream.
     externalStylus.reset();
     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
-    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
     ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
 
     // Up
@@ -2141,7 +2106,6 @@
         mStylusDeviceLifecycleTracker = createUinputDevice<T>();
         mStylus = mStylusDeviceLifecycleTracker.get();
         ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
-        ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
         const auto info = waitForDevice(mStylus->getName());
         ASSERT_TRUE(info);
         mStylusInfo = *info;
@@ -2411,7 +2375,6 @@
     std::unique_ptr<UinputExternalStylusWithPressure> stylus =
             createUinputDevice<UinputExternalStylusWithPressure>();
     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
-    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
     const auto stylusInfo = waitForDevice(stylus->getName());
     ASSERT_TRUE(stylusInfo);
 
@@ -2429,7 +2392,6 @@
     std::unique_ptr<UinputExternalStylusWithPressure> stylus =
             createUinputDevice<UinputExternalStylusWithPressure>();
     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
-    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
     const auto stylusInfo = waitForDevice(stylus->getName());
     ASSERT_TRUE(stylusInfo);
 
@@ -2475,7 +2437,6 @@
     std::unique_ptr<UinputExternalStylusWithPressure> stylus =
             createUinputDevice<UinputExternalStylusWithPressure>();
     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
-    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
     const auto stylusInfo = waitForDevice(stylus->getName());
     ASSERT_TRUE(stylusInfo);
 
@@ -2555,7 +2516,6 @@
     // touch pointers.
     std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
     ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
-    ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
     const auto stylusInfo = waitForDevice(stylus->getName());
     ASSERT_TRUE(stylusInfo);
 
@@ -3057,106 +3017,6 @@
     mapper.assertProcessWasCalled();
 }
 
-// --- SwitchInputMapperTest ---
-
-class SwitchInputMapperTest : public InputMapperTest {
-protected:
-};
-
-TEST_F(SwitchInputMapperTest, GetSources) {
-    SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
-
-    ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper.getSources());
-}
-
-TEST_F(SwitchInputMapperTest, GetSwitchState) {
-    SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
-
-    mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 1);
-    ASSERT_EQ(1, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
-
-    mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 0);
-    ASSERT_EQ(0, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
-}
-
-TEST_F(SwitchInputMapperTest, Process) {
-    SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
-    std::list<NotifyArgs> out;
-    out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_LID, 1);
-    ASSERT_TRUE(out.empty());
-    out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
-    ASSERT_TRUE(out.empty());
-    out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_HEADPHONE_INSERT, 0);
-    ASSERT_TRUE(out.empty());
-    out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
-
-    ASSERT_EQ(1u, out.size());
-    const NotifySwitchArgs& args = std::get<NotifySwitchArgs>(*out.begin());
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT), args.switchValues);
-    ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
-            args.switchMask);
-    ASSERT_EQ(uint32_t(0), args.policyFlags);
-}
-
-// --- VibratorInputMapperTest ---
-class VibratorInputMapperTest : public InputMapperTest {
-protected:
-    void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::VIBRATOR); }
-};
-
-TEST_F(VibratorInputMapperTest, GetSources) {
-    VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
-
-    ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mapper.getSources());
-}
-
-TEST_F(VibratorInputMapperTest, GetVibratorIds) {
-    VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
-
-    ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
-}
-
-TEST_F(VibratorInputMapperTest, Vibrate) {
-    constexpr uint8_t DEFAULT_AMPLITUDE = 192;
-    constexpr int32_t VIBRATION_TOKEN = 100;
-    VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
-
-    VibrationElement pattern(2);
-    VibrationSequence sequence(2);
-    pattern.duration = std::chrono::milliseconds(200);
-    pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 2},
-                        {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
-    sequence.addElement(pattern);
-    pattern.duration = std::chrono::milliseconds(500);
-    pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 4},
-                        {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
-    sequence.addElement(pattern);
-
-    std::vector<int64_t> timings = {0, 1};
-    std::vector<uint8_t> amplitudes = {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE / 2};
-
-    ASSERT_FALSE(mapper.isVibrating());
-    // Start vibrating
-    std::list<NotifyArgs> out = mapper.vibrate(sequence, /*repeat=*/-1, VIBRATION_TOKEN);
-    ASSERT_TRUE(mapper.isVibrating());
-    // Verify vibrator state listener was notified.
-    mReader->loopOnce();
-    ASSERT_EQ(1u, out.size());
-    const NotifyVibratorStateArgs& vibrateArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
-    ASSERT_EQ(DEVICE_ID, vibrateArgs.deviceId);
-    ASSERT_TRUE(vibrateArgs.isOn);
-    // Stop vibrating
-    out = mapper.cancelVibrate(VIBRATION_TOKEN);
-    ASSERT_FALSE(mapper.isVibrating());
-    // Verify vibrator state listener was notified.
-    mReader->loopOnce();
-    ASSERT_EQ(1u, out.size());
-    const NotifyVibratorStateArgs& cancelArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
-    ASSERT_EQ(DEVICE_ID, cancelArgs.deviceId);
-    ASSERT_FALSE(cancelArgs.isOn);
-}
-
 // --- SensorInputMapperTest ---
 
 class SensorInputMapperTest : public InputMapperTest {
@@ -4487,15 +4347,15 @@
     void prepareButtons();
     void prepareAxes(int axes);
 
-    void processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
-    void processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
-    void processUp(SingleTouchInputMapper& mappery);
-    void processPressure(SingleTouchInputMapper& mapper, int32_t pressure);
-    void processToolMajor(SingleTouchInputMapper& mapper, int32_t toolMajor);
-    void processDistance(SingleTouchInputMapper& mapper, int32_t distance);
-    void processTilt(SingleTouchInputMapper& mapper, int32_t tiltX, int32_t tiltY);
-    void processKey(SingleTouchInputMapper& mapper, int32_t code, int32_t value);
-    void processSync(SingleTouchInputMapper& mapper);
+    std::list<NotifyArgs> processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
+    std::list<NotifyArgs> processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y);
+    std::list<NotifyArgs> processUp(SingleTouchInputMapper& mappery);
+    std::list<NotifyArgs> processPressure(SingleTouchInputMapper& mapper, int32_t pressure);
+    std::list<NotifyArgs> processToolMajor(SingleTouchInputMapper& mapper, int32_t toolMajor);
+    std::list<NotifyArgs> processDistance(SingleTouchInputMapper& mapper, int32_t distance);
+    std::list<NotifyArgs> processTilt(SingleTouchInputMapper& mapper, int32_t tiltX, int32_t tiltY);
+    std::list<NotifyArgs> processKey(SingleTouchInputMapper& mapper, int32_t code, int32_t value);
+    std::list<NotifyArgs> processSync(SingleTouchInputMapper& mapper);
 };
 
 void SingleTouchInputMapperTest::prepareButtons() {
@@ -4525,47 +4385,57 @@
     }
 }
 
-void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
+std::list<NotifyArgs> SingleTouchInputMapperTest::processDown(SingleTouchInputMapper& mapper,
+                                                              int32_t x, int32_t y) {
+    std::list<NotifyArgs> args;
+    args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 1);
+    args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
+    args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
+    return args;
 }
 
-void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper& mapper, int32_t x, int32_t y) {
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
+std::list<NotifyArgs> SingleTouchInputMapperTest::processMove(SingleTouchInputMapper& mapper,
+                                                              int32_t x, int32_t y) {
+    std::list<NotifyArgs> args;
+    args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_X, x);
+    args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_Y, y);
+    return args;
 }
 
-void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper& mapper) {
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 0);
+std::list<NotifyArgs> SingleTouchInputMapperTest::processUp(SingleTouchInputMapper& mapper) {
+    return process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, BTN_TOUCH, 0);
 }
 
-void SingleTouchInputMapperTest::processPressure(SingleTouchInputMapper& mapper, int32_t pressure) {
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_PRESSURE, pressure);
+std::list<NotifyArgs> SingleTouchInputMapperTest::processPressure(SingleTouchInputMapper& mapper,
+                                                                  int32_t pressure) {
+    return process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_PRESSURE, pressure);
 }
 
-void SingleTouchInputMapperTest::processToolMajor(SingleTouchInputMapper& mapper,
-                                                  int32_t toolMajor) {
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
+std::list<NotifyArgs> SingleTouchInputMapperTest::processToolMajor(SingleTouchInputMapper& mapper,
+                                                                   int32_t toolMajor) {
+    return process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
 }
 
-void SingleTouchInputMapperTest::processDistance(SingleTouchInputMapper& mapper, int32_t distance) {
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_DISTANCE, distance);
+std::list<NotifyArgs> SingleTouchInputMapperTest::processDistance(SingleTouchInputMapper& mapper,
+                                                                  int32_t distance) {
+    return process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_DISTANCE, distance);
 }
 
-void SingleTouchInputMapperTest::processTilt(SingleTouchInputMapper& mapper, int32_t tiltX,
-                                             int32_t tiltY) {
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_X, tiltX);
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_Y, tiltY);
+std::list<NotifyArgs> SingleTouchInputMapperTest::processTilt(SingleTouchInputMapper& mapper,
+                                                              int32_t tiltX, int32_t tiltY) {
+    std::list<NotifyArgs> args;
+    args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_X, tiltX);
+    args += process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, ABS_TILT_Y, tiltY);
+    return args;
 }
 
-void SingleTouchInputMapperTest::processKey(SingleTouchInputMapper& mapper, int32_t code,
-                                            int32_t value) {
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
+std::list<NotifyArgs> SingleTouchInputMapperTest::processKey(SingleTouchInputMapper& mapper,
+                                                             int32_t code, int32_t value) {
+    return process(mapper, ARBITRARY_TIME, READ_TIME, EV_KEY, code, value);
 }
 
-void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper& mapper) {
-    process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+std::list<NotifyArgs> SingleTouchInputMapperTest::processSync(SingleTouchInputMapper& mapper) {
+    return process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
 }
 
 TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) {
@@ -4656,6 +4526,42 @@
     ASSERT_FALSE(flags[1]);
 }
 
+TEST_F(SingleTouchInputMapperTest, DeviceTypeChange_RecalculatesRawToDisplayTransform) {
+    prepareDisplay(ui::ROTATION_0);
+    prepareAxes(POSITION);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
+
+    const int32_t x = 900;
+    const int32_t y = 75;
+    std::list<NotifyArgs> args;
+    args += processDown(mapper, x, y);
+    args += processSync(mapper);
+
+    // Assert that motion event is received in display coordinate space for deviceType touchScreen.
+    ASSERT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                        AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+                              WithCoords(toDisplayX(x), toDisplayY(y))))));
+
+    // Add device type association after the device was created.
+    mFakePolicy->addDeviceTypeAssociation(DEVICE_LOCATION, "touchNavigation");
+    // Send update to the mapper.
+    std::list<NotifyArgs> unused =
+            mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
+                               InputReaderConfiguration::Change::DEVICE_TYPE /*changes*/);
+
+    args.clear();
+    args += processDown(mapper, x, y);
+    args += processSync(mapper);
+
+    // Assert that motion event is received in raw coordinate space for deviceType touchNavigation.
+    ASSERT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                        AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN),
+                              WithCoords(x - RAW_X_MIN, y - RAW_Y_MIN)))));
+}
+
 TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
     addConfigurationProperty("touch.deviceType", "touchScreen");
     prepareDisplay(ui::ROTATION_0);
@@ -6245,7 +6151,7 @@
     SingleTouchInputMapper& mapper = constructAndAddMapper<SingleTouchInputMapper>();
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
 
-    ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION, mapper.getSources());
+    ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION | AINPUT_SOURCE_TOUCHPAD, mapper.getSources());
 }
 
 TEST_F(SingleTouchInputMapperTest, WhenDeviceTypeIsChangedToTouchNavigation_updatesDeviceType) {
@@ -6268,7 +6174,7 @@
                                InputReaderConfiguration::Change::DEVICE_TYPE /*changes*/);
 
     // Check whether device type update was successful.
-    ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION, mDevice->getSources());
+    ASSERT_EQ(AINPUT_SOURCE_TOUCH_NAVIGATION | AINPUT_SOURCE_TOUCHPAD, mDevice->getSources());
 }
 
 TEST_F(SingleTouchInputMapperTest, HoverEventsOutsidePhysicalFrameAreIgnored) {
@@ -10111,67 +10017,6 @@
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
 }
 
-// --- JoystickInputMapperTest ---
-
-class JoystickInputMapperTest : public InputMapperTest {
-protected:
-    static const int32_t RAW_X_MIN;
-    static const int32_t RAW_X_MAX;
-    static const int32_t RAW_Y_MIN;
-    static const int32_t RAW_Y_MAX;
-
-    void SetUp() override {
-        InputMapperTest::SetUp(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL);
-    }
-    void prepareAxes() {
-        mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
-        mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
-    }
-
-    void processAxis(JoystickInputMapper& mapper, int32_t axis, int32_t value) {
-        process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, axis, value);
-    }
-
-    void processSync(JoystickInputMapper& mapper) {
-        process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
-    }
-
-    void prepareVirtualDisplay(ui::Rotation orientation) {
-        setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH,
-                                     VIRTUAL_DISPLAY_HEIGHT, orientation, VIRTUAL_DISPLAY_UNIQUE_ID,
-                                     NO_PORT, ViewportType::VIRTUAL);
-    }
-};
-
-const int32_t JoystickInputMapperTest::RAW_X_MIN = -32767;
-const int32_t JoystickInputMapperTest::RAW_X_MAX = 32767;
-const int32_t JoystickInputMapperTest::RAW_Y_MIN = -32767;
-const int32_t JoystickInputMapperTest::RAW_Y_MAX = 32767;
-
-TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) {
-    prepareAxes();
-    JoystickInputMapper& mapper = constructAndAddMapper<JoystickInputMapper>();
-
-    mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
-
-    prepareVirtualDisplay(ui::ROTATION_0);
-
-    // Send an axis event
-    processAxis(mapper, ABS_X, 100);
-    processSync(mapper);
-
-    NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
-
-    // Send another axis event
-    processAxis(mapper, ABS_Y, 100);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
-}
-
 // --- PeripheralControllerTest ---
 
 class PeripheralControllerTest : public testing::Test {
diff --git a/services/inputflinger/tests/InputTraceSession.cpp b/services/inputflinger/tests/InputTraceSession.cpp
index a9d370a..db4e761 100644
--- a/services/inputflinger/tests/InputTraceSession.cpp
+++ b/services/inputflinger/tests/InputTraceSession.cpp
@@ -103,6 +103,11 @@
                 continue;
             }
 
+            EXPECT_TRUE(packet.has_timestamp());
+            EXPECT_TRUE(packet.has_timestamp_clock_id());
+            EXPECT_EQ(packet.timestamp_clock_id(),
+                      static_cast<uint32_t>(perfetto::protos::pbzero::BUILTIN_CLOCK_MONOTONIC));
+
             AndroidInputEvent::Decoder event{field.as_bytes()};
             if (event.has_dispatcher_motion_event()) {
                 tracedMotions.emplace_back(event.dispatcher_motion_event(),
diff --git a/services/inputflinger/tests/InterfaceMocks.h b/services/inputflinger/tests/InterfaceMocks.h
index 16d3193..48e0b4f 100644
--- a/services/inputflinger/tests/InterfaceMocks.h
+++ b/services/inputflinger/tests/InterfaceMocks.h
@@ -91,8 +91,8 @@
     MOCK_METHOD(InputDeviceIdentifier, getDeviceIdentifier, (int32_t deviceId), (const));
     MOCK_METHOD(int32_t, getDeviceControllerNumber, (int32_t deviceId), (const));
     MOCK_METHOD(std::optional<PropertyMap>, getConfiguration, (int32_t deviceId), (const));
-    MOCK_METHOD(status_t, getAbsoluteAxisInfo,
-                (int32_t deviceId, int axis, RawAbsoluteAxisInfo* outAxisInfo), (const));
+    MOCK_METHOD(std::optional<RawAbsoluteAxisInfo>, getAbsoluteAxisInfo,
+                (int32_t deviceId, int axis), (const));
     MOCK_METHOD(bool, hasRelativeAxis, (int32_t deviceId, int axis), (const));
     MOCK_METHOD(bool, hasInputProperty, (int32_t deviceId, int property), (const));
     MOCK_METHOD(bool, hasMscEvent, (int32_t deviceId, int mscEvent), (const));
@@ -131,7 +131,7 @@
     MOCK_METHOD(int32_t, getKeyCodeState, (int32_t deviceId, int32_t keyCode), (const, override));
     MOCK_METHOD(int32_t, getSwitchState, (int32_t deviceId, int32_t sw), (const, override));
 
-    MOCK_METHOD(status_t, getAbsoluteAxisValue, (int32_t deviceId, int32_t axis, int32_t* outValue),
+    MOCK_METHOD(std::optional<int32_t>, getAbsoluteAxisValue, (int32_t deviceId, int32_t axis),
                 (const, override));
     MOCK_METHOD(base::Result<std::vector<int32_t>>, getMtSlotValues,
                 (int32_t deviceId, int32_t axis, size_t slotCount), (const, override));
@@ -187,6 +187,7 @@
     MOCK_METHOD(void, notifyPointerDisplayIdChanged,
                 (ui::LogicalDisplayId displayId, const FloatPoint& position), (override));
     MOCK_METHOD(bool, isInputMethodConnectionActive, (), (override));
+    MOCK_METHOD(void, notifyMouseCursorFadedOnTyping, (), (override));
 };
 
 } // namespace android
diff --git a/services/inputflinger/tests/JoystickInputMapper_test.cpp b/services/inputflinger/tests/JoystickInputMapper_test.cpp
new file mode 100644
index 0000000..ec70192
--- /dev/null
+++ b/services/inputflinger/tests/JoystickInputMapper_test.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2024 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 "JoystickInputMapper.h"
+
+#include <optional>
+
+#include <EventHub.h>
+#include <NotifyArgs.h>
+#include <ftl/flags.h>
+#include <gtest/gtest.h>
+#include <input/DisplayViewport.h>
+#include <linux/input-event-codes.h>
+#include <ui/LogicalDisplayId.h>
+
+#include "InputMapperTest.h"
+#include "TestConstants.h"
+
+namespace android {
+
+namespace {
+
+using namespace ftl::flag_operators;
+
+} // namespace
+
+class JoystickInputMapperTest : public InputMapperTest {
+protected:
+    static const int32_t RAW_X_MIN;
+    static const int32_t RAW_X_MAX;
+    static const int32_t RAW_Y_MIN;
+    static const int32_t RAW_Y_MAX;
+
+    static constexpr ui::LogicalDisplayId VIRTUAL_DISPLAY_ID = ui::LogicalDisplayId{1};
+    static const char* const VIRTUAL_DISPLAY_UNIQUE_ID;
+
+    void SetUp() override {
+        InputMapperTest::SetUp(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL);
+    }
+    void prepareAxes() {
+        mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
+        mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
+    }
+
+    void processAxis(JoystickInputMapper& mapper, int32_t axis, int32_t value) {
+        process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, axis, value);
+    }
+
+    void processSync(JoystickInputMapper& mapper) {
+        process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+    }
+
+    void prepareVirtualDisplay(ui::Rotation orientation) {
+        setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, /*width=*/400, /*height=*/500, orientation,
+                                     VIRTUAL_DISPLAY_UNIQUE_ID, /*physicalPort=*/std::nullopt,
+                                     ViewportType::VIRTUAL);
+    }
+};
+
+const int32_t JoystickInputMapperTest::RAW_X_MIN = -32767;
+const int32_t JoystickInputMapperTest::RAW_X_MAX = 32767;
+const int32_t JoystickInputMapperTest::RAW_Y_MIN = -32767;
+const int32_t JoystickInputMapperTest::RAW_Y_MAX = 32767;
+const char* const JoystickInputMapperTest::VIRTUAL_DISPLAY_UNIQUE_ID = "virtual:1";
+
+TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) {
+    prepareAxes();
+    JoystickInputMapper& mapper = constructAndAddMapper<JoystickInputMapper>();
+
+    mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
+
+    prepareVirtualDisplay(ui::ROTATION_0);
+
+    // Send an axis event
+    processAxis(mapper, ABS_X, 100);
+    processSync(mapper);
+
+    NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
+
+    // Send another axis event
+    processAxis(mapper, ABS_Y, 100);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/KeyboardInputMapper_test.cpp b/services/inputflinger/tests/KeyboardInputMapper_test.cpp
index ab47cc6..d3e8dee 100644
--- a/services/inputflinger/tests/KeyboardInputMapper_test.cpp
+++ b/services/inputflinger/tests/KeyboardInputMapper_test.cpp
@@ -69,48 +69,8 @@
         mMapper = createInputMapper<KeyboardInputMapper>(*mDeviceContext, mReaderConfiguration,
                                                          AINPUT_SOURCE_KEYBOARD);
     }
-
-    void testTouchpadTapStateForKeys(const std::vector<int32_t>& keyCodes,
-                                     const bool expectPrevent) {
-        if (expectPrevent) {
-            EXPECT_CALL(mMockInputReaderContext, setPreventingTouchpadTaps(true))
-                    .Times(keyCodes.size());
-        }
-        for (int32_t keyCode : keyCodes) {
-            process(EV_KEY, keyCode, 1);
-            process(EV_SYN, SYN_REPORT, 0);
-            process(EV_KEY, keyCode, 0);
-            process(EV_SYN, SYN_REPORT, 0);
-        }
-    }
 };
 
-/**
- * Touchpad tap should not be disabled if there is no active Input Method Connection
- */
-TEST_F(KeyboardInputMapperUnitTest, KeystrokesWithoutIMeConnectionDontDisableTouchpadTap) {
-    testTouchpadTapStateForKeys({KEY_0, KEY_A, KEY_LEFTCTRL}, /* expectPrevent= */ false);
-}
-
-/**
- * Touchpad tap should be disabled if there is a active Input Method Connection
- */
-TEST_F(KeyboardInputMapperUnitTest, AlphanumericKeystrokesWithIMeConnectionDisableTouchpadTap) {
-    mFakePolicy->setIsInputMethodConnectionActive(true);
-    testTouchpadTapStateForKeys({KEY_0, KEY_A}, /* expectPrevent= */ true);
-}
-
-/**
- * Touchpad tap should not be disabled by meta keys even if Input Method Connection is active
- */
-TEST_F(KeyboardInputMapperUnitTest, MetaKeystrokesWithIMeConnectionDontDisableTouchpadTap) {
-    mFakePolicy->setIsInputMethodConnectionActive(true);
-    std::vector<int32_t> metaKeys{KEY_LEFTALT,   KEY_RIGHTALT, KEY_LEFTSHIFT, KEY_RIGHTSHIFT,
-                                  KEY_FN,        KEY_LEFTCTRL, KEY_RIGHTCTRL, KEY_LEFTMETA,
-                                  KEY_RIGHTMETA, KEY_CAPSLOCK, KEY_NUMLOCK,   KEY_SCROLLLOCK};
-    testTouchpadTapStateForKeys(metaKeys, /* expectPrevent= */ false);
-}
-
 TEST_F(KeyboardInputMapperUnitTest, KeyPressTimestampRecorded) {
     nsecs_t when = ARBITRARY_TIME;
     std::vector<int32_t> keyCodes{KEY_0, KEY_A, KEY_LEFTCTRL, KEY_RIGHTALT, KEY_LEFTSHIFT};
diff --git a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
index b5f8971..d4d3c38 100644
--- a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
+++ b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
@@ -99,11 +99,8 @@
         setupAxis(ABS_MT_TOOL_TYPE, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
 
         // reset current slot at the beginning
-        EXPECT_CALL(mMockEventHub, getAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, _))
-                .WillRepeatedly([](int32_t, int32_t, int32_t* outValue) {
-                    *outValue = 0;
-                    return OK;
-                });
+        EXPECT_CALL(mMockEventHub, getAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT))
+                .WillRepeatedly(Return(0));
 
         // mark all slots not in use
         mockSlotValues({});
@@ -211,11 +208,8 @@
     const auto pointerCoordsBeforeReset = std::get<NotifyMotionArgs>(args.back()).pointerCoords;
 
     // On buffer overflow mapper will be reset and MT slots data will be repopulated
-    EXPECT_CALL(mMockEventHub, getAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, _))
-            .WillRepeatedly([=](int32_t, int32_t, int32_t* outValue) {
-                *outValue = 1;
-                return OK;
-            });
+    EXPECT_CALL(mMockEventHub, getAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT))
+            .WillRepeatedly(Return(1));
 
     mockSlotValues(
             {{1, {Point{x1, y1}, FIRST_TRACKING_ID}}, {2, {Point{x2, y2}, SECOND_TRACKING_ID}}});
diff --git a/services/inputflinger/tests/PointerChoreographer_test.cpp b/services/inputflinger/tests/PointerChoreographer_test.cpp
index 9a5b6a7..18222dd 100644
--- a/services/inputflinger/tests/PointerChoreographer_test.cpp
+++ b/services/inputflinger/tests/PointerChoreographer_test.cpp
@@ -196,7 +196,6 @@
 TEST_F(PointerChoreographerTest, ForwardsArgsToInnerListener) {
     const std::vector<NotifyArgs>
             allArgs{NotifyInputDevicesChangedArgs{},
-                    NotifyConfigurationChangedArgs{},
                     KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, AINPUT_SOURCE_KEYBOARD).build(),
                     MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
                             .pointer(FIRST_TOUCH_POINTER)
@@ -214,9 +213,6 @@
                                    [&](const NotifyInputDevicesChangedArgs& args) {
                                        mTestListener.assertNotifyInputDevicesChangedWasCalled();
                                    },
-                                   [&](const NotifyConfigurationChangedArgs& args) {
-                                       mTestListener.assertNotifyConfigurationChangedWasCalled();
-                                   },
                                    [&](const NotifyKeyArgs& args) {
                                        mTestListener.assertNotifyKeyWasCalled();
                                    },
@@ -830,15 +826,20 @@
     pc->assertSpotCount(DISPLAY_ID, 0);
 }
 
+/**
+ * In this test, we simulate the complete event of the stylus approaching and clicking on the
+ * screen, and then leaving the screen. We should ensure that spots are displayed correctly.
+ */
 TEST_F(PointerChoreographerTest, TouchSetsSpotsForStylusEvent) {
     mChoreographer.setShowTouchesEnabled(true);
+    mChoreographer.setStylusPointerIconEnabled(false);
     mChoreographer.notifyInputDevicesChanged(
             {/*id=*/0,
              {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS,
                                      DISPLAY_ID)}});
 
-    // Emit down event with stylus properties.
-    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN,
+    // First, the stylus begin to approach the screen.
+    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
                                                   AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
                                         .pointer(STYLUS_POINTER)
                                         .deviceId(DEVICE_ID)
@@ -846,6 +847,72 @@
                                         .build());
     auto pc = assertPointerControllerCreated(ControllerType::TOUCH);
     pc->assertSpotCount(DISPLAY_ID, 1);
+
+    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
+                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+                                        .pointer(STYLUS_POINTER)
+                                        .deviceId(DEVICE_ID)
+                                        .displayId(DISPLAY_ID)
+                                        .build());
+    pc->assertSpotCount(DISPLAY_ID, 1);
+
+    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
+                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+                                        .pointer(STYLUS_POINTER)
+                                        .deviceId(DEVICE_ID)
+                                        .displayId(DISPLAY_ID)
+                                        .build());
+    pc->assertSpotCount(DISPLAY_ID, 0);
+
+    // Now, use stylus touch the screen.
+    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN,
+                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+                                        .pointer(STYLUS_POINTER)
+                                        .deviceId(DEVICE_ID)
+                                        .displayId(DISPLAY_ID)
+                                        .build());
+    pc->assertSpotCount(DISPLAY_ID, 1);
+
+    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE,
+                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+                                        .pointer(STYLUS_POINTER)
+                                        .deviceId(DEVICE_ID)
+                                        .displayId(DISPLAY_ID)
+                                        .build());
+    pc->assertSpotCount(DISPLAY_ID, 1);
+
+    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_UP,
+                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+                                        .pointer(STYLUS_POINTER)
+                                        .deviceId(DEVICE_ID)
+                                        .displayId(DISPLAY_ID)
+                                        .build());
+    pc->assertSpotCount(DISPLAY_ID, 0);
+
+    // Then, the stylus start leave from the screen.
+    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
+                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+                                        .pointer(STYLUS_POINTER)
+                                        .deviceId(DEVICE_ID)
+                                        .displayId(DISPLAY_ID)
+                                        .build());
+    pc->assertSpotCount(DISPLAY_ID, 1);
+
+    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
+                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+                                        .pointer(STYLUS_POINTER)
+                                        .deviceId(DEVICE_ID)
+                                        .displayId(DISPLAY_ID)
+                                        .build());
+    pc->assertSpotCount(DISPLAY_ID, 1);
+
+    mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
+                                                  AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+                                        .pointer(STYLUS_POINTER)
+                                        .deviceId(DEVICE_ID)
+                                        .displayId(DISPLAY_ID)
+                                        .build());
+    pc->assertSpotCount(DISPLAY_ID, 0);
 }
 
 TEST_F(PointerChoreographerTest, TouchSetsSpotsForTwoDisplays) {
@@ -2294,7 +2361,13 @@
     assertPointerControllerRemoved(pc);
 }
 
-class PointerVisibilityOnKeyPressTest : public PointerChoreographerTest {
+using PointerVisibilityAndTouchpadTapStateOnKeyPressTestFixtureParam =
+        std::tuple<std::string_view /*name*/, uint32_t /*source*/>;
+
+class PointerVisibilityAndTouchpadTapStateOnKeyPressTestFixture
+      : public PointerChoreographerTest,
+        public testing::WithParamInterface<
+                PointerVisibilityAndTouchpadTapStateOnKeyPressTestFixtureParam> {
 protected:
     const std::unordered_map<int32_t, int32_t>
             mMetaKeyStates{{AKEYCODE_ALT_LEFT, AMETA_ALT_LEFT_ON},
@@ -2358,15 +2431,28 @@
     }
 };
 
-TEST_F(PointerVisibilityOnKeyPressTest, KeystrokesWithoutImeConnectionDoesNotHidePointer) {
+INSTANTIATE_TEST_SUITE_P(
+        PointerChoreographerTest, PointerVisibilityAndTouchpadTapStateOnKeyPressTestFixture,
+        testing::Values(std::make_tuple("Mouse", AINPUT_SOURCE_MOUSE),
+                        std::make_tuple("Touchpad", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD)),
+        [](const testing::TestParamInfo<
+                PointerVisibilityAndTouchpadTapStateOnKeyPressTestFixtureParam>& p) {
+            return std::string{std::get<0>(p.param)};
+        });
+
+TEST_P(PointerVisibilityAndTouchpadTapStateOnKeyPressTestFixture,
+       KeystrokesWithoutImeConnectionDoesNotHidePointerOrDisablesTouchpadTap) {
+    const auto& [_, source] = GetParam();
     mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID}));
 
     // Mouse connected
     mChoreographer.notifyInputDevicesChanged(
-            {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, DISPLAY_ID)}});
+            {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, source, DISPLAY_ID)}});
     auto pc = assertPointerControllerCreated(ControllerType::MOUSE);
     ASSERT_TRUE(pc->isPointerShown());
 
+    EXPECT_CALL(mMockPolicy, notifyMouseCursorFadedOnTyping).Times(0);
+
     notifyKey(ui::LogicalDisplayId::INVALID, AKEYCODE_0);
     notifyKey(ui::LogicalDisplayId::INVALID, AKEYCODE_A);
     notifyKey(ui::LogicalDisplayId::INVALID, AKEYCODE_CTRL_LEFT);
@@ -2374,16 +2460,19 @@
     ASSERT_TRUE(pc->isPointerShown());
 }
 
-TEST_F(PointerVisibilityOnKeyPressTest, AlphanumericKeystrokesWithImeConnectionHidePointer) {
+TEST_P(PointerVisibilityAndTouchpadTapStateOnKeyPressTestFixture,
+       AlphanumericKeystrokesWithImeConnectionHidePointerAndDisablesTouchpadTap) {
+    const auto& [_, source] = GetParam();
     mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID}));
 
     // Mouse connected
     mChoreographer.notifyInputDevicesChanged(
-            {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, DISPLAY_ID)}});
+            {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, source, DISPLAY_ID)}});
     auto pc = assertPointerControllerCreated(ControllerType::MOUSE);
     ASSERT_TRUE(pc->isPointerShown());
 
     EXPECT_CALL(mMockPolicy, isInputMethodConnectionActive).WillRepeatedly(testing::Return(true));
+    EXPECT_CALL(mMockPolicy, notifyMouseCursorFadedOnTyping).Times(2);
 
     notifyKey(DISPLAY_ID, AKEYCODE_0);
     ASSERT_FALSE(pc->isPointerShown());
@@ -2394,17 +2483,19 @@
     ASSERT_FALSE(pc->isPointerShown());
 }
 
-TEST_F(PointerVisibilityOnKeyPressTest, MetaKeystrokesDoNotHidePointer) {
+TEST_P(PointerVisibilityAndTouchpadTapStateOnKeyPressTestFixture,
+       MetaKeystrokesDoNotHidePointerOrDisablesTouchpadTap) {
+    const auto& [_, source] = GetParam();
     mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID}));
 
     // Mouse connected
     mChoreographer.notifyInputDevicesChanged(
-            {/*id=*/0,
-             {generateTestDeviceInfo(SECOND_DEVICE_ID, AINPUT_SOURCE_MOUSE, DISPLAY_ID)}});
+            {/*id=*/0, {generateTestDeviceInfo(SECOND_DEVICE_ID, source, DISPLAY_ID)}});
     auto pc = assertPointerControllerCreated(ControllerType::MOUSE);
     ASSERT_TRUE(pc->isPointerShown());
 
     EXPECT_CALL(mMockPolicy, isInputMethodConnectionActive).WillRepeatedly(testing::Return(true));
+    EXPECT_CALL(mMockPolicy, notifyMouseCursorFadedOnTyping).Times(0);
 
     const std::vector<int32_t> metaKeyCodes{AKEYCODE_ALT_LEFT,   AKEYCODE_ALT_RIGHT,
                                             AKEYCODE_SHIFT_LEFT, AKEYCODE_SHIFT_RIGHT,
@@ -2420,14 +2511,16 @@
     ASSERT_TRUE(pc->isPointerShown());
 }
 
-TEST_F(PointerVisibilityOnKeyPressTest, KeystrokesWithoutTargetHidePointerOnlyOnFocusedDisplay) {
+TEST_P(PointerVisibilityAndTouchpadTapStateOnKeyPressTestFixture,
+       KeystrokesWithoutTargetHidePointerOnlyOnFocusedDisplayAndDisablesTouchpadTap) {
+    const auto& [_, source] = GetParam();
     mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID, ANOTHER_DISPLAY_ID}));
     mChoreographer.setFocusedDisplay(DISPLAY_ID);
 
     // Mouse connected
     mChoreographer.notifyInputDevicesChanged(
             {/*id=*/0,
-             {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, DISPLAY_ID),
+             {generateTestDeviceInfo(DEVICE_ID, source, DISPLAY_ID),
               generateTestDeviceInfo(SECOND_DEVICE_ID, AINPUT_SOURCE_MOUSE, ANOTHER_DISPLAY_ID)}});
     auto pc1 = assertPointerControllerCreated(ControllerType::MOUSE);
     auto pc2 = assertPointerControllerCreated(ControllerType::MOUSE);
@@ -2435,6 +2528,7 @@
     ASSERT_TRUE(pc2->isPointerShown());
 
     EXPECT_CALL(mMockPolicy, isInputMethodConnectionActive).WillRepeatedly(testing::Return(true));
+    EXPECT_CALL(mMockPolicy, notifyMouseCursorFadedOnTyping).Times(2);
 
     notifyKey(ui::LogicalDisplayId::INVALID, AKEYCODE_0);
     ASSERT_FALSE(pc1->isPointerShown());
@@ -2446,16 +2540,19 @@
     ASSERT_TRUE(pc2->isPointerShown());
 }
 
-TEST_F(PointerVisibilityOnKeyPressTest, TestMetaKeyCombinations) {
+TEST_P(PointerVisibilityAndTouchpadTapStateOnKeyPressTestFixture, TestMetaKeyCombinations) {
+    const auto& [_, source] = GetParam();
     mChoreographer.setDisplayViewports(createViewports({DISPLAY_ID}));
 
     // Mouse connected
     mChoreographer.notifyInputDevicesChanged(
-            {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_MOUSE, DISPLAY_ID)}});
+            {/*id=*/0, {generateTestDeviceInfo(DEVICE_ID, source, DISPLAY_ID)}});
     auto pc = assertPointerControllerCreated(ControllerType::MOUSE);
+
     EXPECT_CALL(mMockPolicy, isInputMethodConnectionActive).WillRepeatedly(testing::Return(true));
 
-    // meta key combinations that should hide pointer
+    // meta key combinations that should hide pointer and disable touchpad taps
+    EXPECT_CALL(mMockPolicy, notifyMouseCursorFadedOnTyping).Times(5);
     metaKeyCombinationHidesPointer(*pc, AKEYCODE_A, AKEYCODE_SHIFT_LEFT);
     metaKeyCombinationHidesPointer(*pc, AKEYCODE_A, AKEYCODE_SHIFT_RIGHT);
     metaKeyCombinationHidesPointer(*pc, AKEYCODE_A, AKEYCODE_CAPS_LOCK);
@@ -2463,6 +2560,7 @@
     metaKeyCombinationHidesPointer(*pc, AKEYCODE_A, AKEYCODE_SCROLL_LOCK);
 
     // meta key combinations that should not hide pointer
+    EXPECT_CALL(mMockPolicy, notifyMouseCursorFadedOnTyping).Times(0);
     metaKeyCombinationDoesNotHidePointer(*pc, AKEYCODE_A, AKEYCODE_ALT_LEFT);
     metaKeyCombinationDoesNotHidePointer(*pc, AKEYCODE_A, AKEYCODE_ALT_RIGHT);
     metaKeyCombinationDoesNotHidePointer(*pc, AKEYCODE_A, AKEYCODE_CTRL_LEFT);
diff --git a/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp b/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp
new file mode 100644
index 0000000..366b3dc
--- /dev/null
+++ b/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2024 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 "RotaryEncoderInputMapper.h"
+
+#include <list>
+#include <string>
+#include <tuple>
+#include <variant>
+
+#include <android-base/logging.h>
+#include <android_companion_virtualdevice_flags.h>
+#include <gtest/gtest.h>
+#include <input/DisplayViewport.h>
+#include <linux/input-event-codes.h>
+#include <linux/input.h>
+#include <utils/Timers.h>
+
+#include "InputMapperTest.h"
+#include "InputReaderBase.h"
+#include "InterfaceMocks.h"
+#include "NotifyArgs.h"
+#include "TestEventMatchers.h"
+#include "ui/Rotation.h"
+
+#define TAG "RotaryEncoderInputMapper_test"
+
+namespace android {
+
+using testing::AllOf;
+using testing::Return;
+using testing::VariantWith;
+constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;
+constexpr ui::LogicalDisplayId SECONDARY_DISPLAY_ID = ui::LogicalDisplayId{DISPLAY_ID.val() + 1};
+constexpr int32_t DISPLAY_WIDTH = 480;
+constexpr int32_t DISPLAY_HEIGHT = 800;
+
+namespace {
+
+DisplayViewport createViewport() {
+    DisplayViewport v;
+    v.orientation = ui::Rotation::Rotation0;
+    v.logicalRight = DISPLAY_HEIGHT;
+    v.logicalBottom = DISPLAY_WIDTH;
+    v.physicalRight = DISPLAY_HEIGHT;
+    v.physicalBottom = DISPLAY_WIDTH;
+    v.deviceWidth = DISPLAY_HEIGHT;
+    v.deviceHeight = DISPLAY_WIDTH;
+    v.isActive = true;
+    return v;
+}
+
+DisplayViewport createPrimaryViewport() {
+    DisplayViewport v = createViewport();
+    v.displayId = DISPLAY_ID;
+    v.uniqueId = "local:1";
+    return v;
+}
+
+DisplayViewport createSecondaryViewport() {
+    DisplayViewport v = createViewport();
+    v.displayId = SECONDARY_DISPLAY_ID;
+    v.uniqueId = "local:2";
+    v.type = ViewportType::EXTERNAL;
+    return v;
+}
+
+/**
+ * A fake InputDeviceContext that allows the associated viewport to be specified for the mapper.
+ *
+ * This is currently necessary because InputMapperUnitTest doesn't register the mappers it creates
+ * with the InputDevice object, meaning that InputDevice::isIgnored becomes true, and the input
+ * device doesn't set its associated viewport when it's configured.
+ *
+ * TODO(b/319217713): work out a way to avoid this fake.
+ */
+class ViewportFakingInputDeviceContext : public InputDeviceContext {
+public:
+    ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId,
+                                     std::optional<DisplayViewport> viewport)
+          : InputDeviceContext(device, eventHubId), mAssociatedViewport(viewport) {}
+
+    ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId)
+          : ViewportFakingInputDeviceContext(device, eventHubId, createPrimaryViewport()) {}
+
+    std::optional<DisplayViewport> getAssociatedViewport() const override {
+        return mAssociatedViewport;
+    }
+
+    void setViewport(const std::optional<DisplayViewport>& viewport) {
+        mAssociatedViewport = viewport;
+    }
+
+private:
+    std::optional<DisplayViewport> mAssociatedViewport;
+};
+
+} // namespace
+
+namespace vd_flags = android::companion::virtualdevice::flags;
+
+/**
+ * Unit tests for RotaryEncoderInputMapper.
+ */
+class RotaryEncoderInputMapperTest : public InputMapperUnitTest {
+protected:
+    void SetUp() override { SetUpWithBus(BUS_USB); }
+    void SetUpWithBus(int bus) override {
+        InputMapperUnitTest::SetUpWithBus(bus);
+
+        EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL))
+                .WillRepeatedly(Return(true));
+        EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_HWHEEL))
+                .WillRepeatedly(Return(false));
+        EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
+                .WillRepeatedly(Return(false));
+        EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_HWHEEL_HI_RES))
+                .WillRepeatedly(Return(false));
+    }
+};
+
+TEST_F(RotaryEncoderInputMapperTest, ConfigureDisplayIdWithAssociatedViewport) {
+    DisplayViewport primaryViewport = createPrimaryViewport();
+    DisplayViewport secondaryViewport = createSecondaryViewport();
+    mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport});
+
+    // Set up the secondary display as the associated viewport of the mapper.
+    createDevice();
+    ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
+    mMapper = createInputMapper<RotaryEncoderInputMapper>(deviceContext, mReaderConfiguration);
+
+    std::list<NotifyArgs> args;
+    // Ensure input events are generated for the secondary display.
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+    EXPECT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                        AllOf(WithMotionAction(AMOTION_EVENT_ACTION_SCROLL),
+                              WithSource(AINPUT_SOURCE_ROTARY_ENCODER),
+                              WithDisplayId(SECONDARY_DISPLAY_ID)))));
+}
+
+TEST_F(RotaryEncoderInputMapperTest, ConfigureDisplayIdNoAssociatedViewport) {
+    // Set up the default display.
+    mFakePolicy->clearViewports();
+    mFakePolicy->addDisplayViewport(createPrimaryViewport());
+
+    // Set up the mapper with no associated viewport.
+    createDevice();
+    mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
+
+    // Ensure input events are generated without display ID
+    std::list<NotifyArgs> args;
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+    EXPECT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                        AllOf(WithMotionAction(AMOTION_EVENT_ACTION_SCROLL),
+                              WithSource(AINPUT_SOURCE_ROTARY_ENCODER),
+                              WithDisplayId(ui::LogicalDisplayId::INVALID)))));
+}
+
+TEST_F(RotaryEncoderInputMapperTest, ProcessRegularScroll) {
+    createDevice();
+    mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
+
+    std::list<NotifyArgs> args;
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+
+    EXPECT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                        AllOf(WithSource(AINPUT_SOURCE_ROTARY_ENCODER),
+                              WithMotionAction(AMOTION_EVENT_ACTION_SCROLL), WithScroll(1.0f)))));
+}
+
+TEST_F(RotaryEncoderInputMapperTest, ProcessHighResScroll) {
+    vd_flags::high_resolution_scroll(true);
+    EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
+            .WillRepeatedly(Return(true));
+    createDevice();
+    mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
+
+    std::list<NotifyArgs> args;
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL_HI_RES, 60);
+    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+
+    EXPECT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                        AllOf(WithSource(AINPUT_SOURCE_ROTARY_ENCODER),
+                              WithMotionAction(AMOTION_EVENT_ACTION_SCROLL), WithScroll(0.5f)))));
+}
+
+TEST_F(RotaryEncoderInputMapperTest, HighResScrollIgnoresRegularScroll) {
+    vd_flags::high_resolution_scroll(true);
+    EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
+            .WillRepeatedly(Return(true));
+    createDevice();
+    mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
+
+    std::list<NotifyArgs> args;
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL_HI_RES, 60);
+    args += process(ARBITRARY_TIME, EV_REL, REL_WHEEL, 1);
+    args += process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+
+    EXPECT_THAT(args,
+                ElementsAre(VariantWith<NotifyMotionArgs>(
+                        AllOf(WithSource(AINPUT_SOURCE_ROTARY_ENCODER),
+                              WithMotionAction(AMOTION_EVENT_ACTION_SCROLL), WithScroll(0.5f)))));
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/inputflinger/tests/SwitchInputMapper_test.cpp b/services/inputflinger/tests/SwitchInputMapper_test.cpp
new file mode 100644
index 0000000..4020e78
--- /dev/null
+++ b/services/inputflinger/tests/SwitchInputMapper_test.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2024 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 "SwitchInputMapper.h"
+
+#include <list>
+#include <variant>
+
+#include <NotifyArgs.h>
+#include <gtest/gtest.h>
+#include <input/Input.h>
+#include <linux/input-event-codes.h>
+
+#include "InputMapperTest.h"
+#include "TestConstants.h"
+
+namespace android {
+
+class SwitchInputMapperTest : public InputMapperUnitTest {
+protected:
+    void SetUp() override {
+        InputMapperUnitTest::SetUp();
+        createDevice();
+        mMapper = createInputMapper<SwitchInputMapper>(*mDeviceContext,
+                                                       mFakePolicy->getReaderConfiguration());
+    }
+};
+
+TEST_F(SwitchInputMapperTest, GetSources) {
+    ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mMapper->getSources());
+}
+
+TEST_F(SwitchInputMapperTest, GetSwitchState) {
+    setSwitchState(1, {SW_LID});
+    ASSERT_EQ(1, mMapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
+
+    setSwitchState(0, {SW_LID});
+    ASSERT_EQ(0, mMapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
+}
+
+TEST_F(SwitchInputMapperTest, Process) {
+    std::list<NotifyArgs> out;
+    out = process(ARBITRARY_TIME, EV_SW, SW_LID, 1);
+    ASSERT_TRUE(out.empty());
+    out = process(ARBITRARY_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
+    ASSERT_TRUE(out.empty());
+    out = process(ARBITRARY_TIME, EV_SW, SW_HEADPHONE_INSERT, 0);
+    ASSERT_TRUE(out.empty());
+    out = process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+
+    ASSERT_EQ(1u, out.size());
+    const NotifySwitchArgs& args = std::get<NotifySwitchArgs>(*out.begin());
+    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
+    ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT), args.switchValues);
+    ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
+              args.switchMask);
+    ASSERT_EQ(uint32_t(0), args.policyFlags);
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/inputflinger/tests/TestConstants.h b/services/inputflinger/tests/TestConstants.h
index ad48b0f..082bbb8 100644
--- a/services/inputflinger/tests/TestConstants.h
+++ b/services/inputflinger/tests/TestConstants.h
@@ -24,6 +24,9 @@
 
 using std::chrono_literals::operator""ms;
 
+// Timeout for waiting for an input device to be added and processed
+static constexpr std::chrono::duration ADD_INPUT_DEVICE_TIMEOUT = 500ms;
+
 // Timeout for waiting for an expected event
 static constexpr std::chrono::duration WAIT_TIMEOUT = 100ms;
 
diff --git a/services/inputflinger/tests/TestEventMatchers.h b/services/inputflinger/tests/TestEventMatchers.h
index 65fb9c6..cfedc6e 100644
--- a/services/inputflinger/tests/TestEventMatchers.h
+++ b/services/inputflinger/tests/TestEventMatchers.h
@@ -609,10 +609,33 @@
     return arg.getRepeatCount() == repeatCount;
 }
 
-MATCHER_P2(WithPointerId, index, id, "MotionEvent with specified pointer ID for pointer index") {
-    const auto argPointerId = arg.pointerProperties[index].id;
-    *result_listener << "expected pointer with index " << index << " to have ID " << argPointerId;
-    return argPointerId == id;
+class WithPointerIdMatcher {
+public:
+    using is_gtest_matcher = void;
+    explicit WithPointerIdMatcher(size_t index, int32_t pointerId)
+          : mIndex(index), mPointerId(pointerId) {}
+
+    bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
+        return args.pointerProperties[mIndex].id == mPointerId;
+    }
+
+    bool MatchAndExplain(const MotionEvent& event, std::ostream*) const {
+        return event.getPointerId(mIndex) == mPointerId;
+    }
+
+    void DescribeTo(std::ostream* os) const {
+        *os << "with pointer[" << mIndex << "] id = " << mPointerId;
+    }
+
+    void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointerId"; }
+
+private:
+    const size_t mIndex;
+    const int32_t mPointerId;
+};
+
+inline WithPointerIdMatcher WithPointerId(size_t index, int32_t pointerId) {
+    return WithPointerIdMatcher(index, pointerId);
 }
 
 MATCHER_P2(WithCursorPosition, x, y, "InputEvent with specified cursor position") {
@@ -697,6 +720,21 @@
     return argDistance == distance;
 }
 
+MATCHER_P(WithScroll, scroll, "InputEvent with specified scroll value") {
+    const auto argScroll = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_SCROLL);
+    *result_listener << "expected scroll value " << scroll << ", but got " << argScroll;
+    return argScroll == scroll;
+}
+
+MATCHER_P2(WithScroll, scrollX, scrollY, "InputEvent with specified scroll values") {
+    const auto argScrollX = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_HSCROLL);
+    const auto argScrollY = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_VSCROLL);
+    *result_listener << "expected scroll values " << scrollX << " scroll x " << scrollY
+                     << " scroll y, but got " << argScrollX << " scroll x " << argScrollY
+                     << " scroll y";
+    return argScrollX == scrollX && argScrollY == scrollY;
+}
+
 MATCHER_P2(WithTouchDimensions, maj, min, "InputEvent with specified touch dimensions") {
     const auto argMajor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR);
     const auto argMinor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR);
diff --git a/services/inputflinger/tests/TestInputListener.cpp b/services/inputflinger/tests/TestInputListener.cpp
index 41e250f..369f9cc 100644
--- a/services/inputflinger/tests/TestInputListener.cpp
+++ b/services/inputflinger/tests/TestInputListener.cpp
@@ -37,19 +37,6 @@
                                                         "to have been called."));
 }
 
-void TestInputListener::assertNotifyConfigurationChangedWasCalled(
-        NotifyConfigurationChangedArgs* outEventArgs) {
-    ASSERT_NO_FATAL_FAILURE(
-            assertCalled<NotifyConfigurationChangedArgs>(outEventArgs,
-                                                         "Expected notifyConfigurationChanged() "
-                                                         "to have been called."));
-}
-
-void TestInputListener::assertNotifyConfigurationChangedWasNotCalled() {
-    ASSERT_NO_FATAL_FAILURE(assertNotCalled<NotifyConfigurationChangedArgs>(
-            "notifyConfigurationChanged() should not be called."));
-}
-
 void TestInputListener::assertNotifyDeviceResetWasCalled(NotifyDeviceResetArgs* outEventArgs) {
     ASSERT_NO_FATAL_FAILURE(
             assertCalled<
@@ -192,10 +179,6 @@
     addToQueue<NotifyInputDevicesChangedArgs>(args);
 }
 
-void TestInputListener::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
-    addToQueue<NotifyConfigurationChangedArgs>(args);
-}
-
 void TestInputListener::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
     addToQueue<NotifyDeviceResetArgs>(args);
 }
diff --git a/services/inputflinger/tests/TestInputListener.h b/services/inputflinger/tests/TestInputListener.h
index 3c5e014..47eae4d 100644
--- a/services/inputflinger/tests/TestInputListener.h
+++ b/services/inputflinger/tests/TestInputListener.h
@@ -38,11 +38,6 @@
     void assertNotifyInputDevicesChangedWasCalled(
             NotifyInputDevicesChangedArgs* outEventArgs = nullptr);
 
-    void assertNotifyConfigurationChangedWasCalled(
-            NotifyConfigurationChangedArgs* outEventArgs = nullptr);
-
-    void assertNotifyConfigurationChangedWasNotCalled();
-
     void clearNotifyDeviceResetCalls();
 
     void assertNotifyDeviceResetWasCalled(const ::testing::Matcher<NotifyDeviceResetArgs>& matcher);
@@ -85,8 +80,6 @@
 
     virtual void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
 
-    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
-
     virtual void notifyDeviceReset(const NotifyDeviceResetArgs& args) override;
 
     virtual void notifyKey(const NotifyKeyArgs& args) override;
@@ -107,7 +100,6 @@
     const std::chrono::milliseconds mEventDidNotHappenTimeout;
 
     std::tuple<std::vector<NotifyInputDevicesChangedArgs>,   //
-               std::vector<NotifyConfigurationChangedArgs>,  //
                std::vector<NotifyDeviceResetArgs>,           //
                std::vector<NotifyKeyArgs>,                   //
                std::vector<NotifyMotionArgs>,                //
diff --git a/services/inputflinger/tests/TouchpadInputMapper_test.cpp b/services/inputflinger/tests/TouchpadInputMapper_test.cpp
index 2b62dd1..1afb4f0 100644
--- a/services/inputflinger/tests/TouchpadInputMapper_test.cpp
+++ b/services/inputflinger/tests/TouchpadInputMapper_test.cpp
@@ -103,11 +103,8 @@
         setupAxis(ABS_MT_DISTANCE, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
         setupAxis(ABS_MT_TOOL_TYPE, /*valid=*/false, /*min=*/0, /*max=*/0, /*resolution=*/0);
 
-        EXPECT_CALL(mMockEventHub, getAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT, testing::_))
-                .WillRepeatedly([](int32_t eventHubId, int32_t, int32_t* outValue) {
-                    *outValue = 0;
-                    return OK;
-                });
+        EXPECT_CALL(mMockEventHub, getAbsoluteAxisValue(EVENTHUB_ID, ABS_MT_SLOT))
+                .WillRepeatedly(Return(0));
         EXPECT_CALL(mMockEventHub, getMtSlotValues(EVENTHUB_ID, testing::_, testing::_))
                 .WillRepeatedly([]() -> base::Result<std::vector<int32_t>> {
                     return base::ResultError("Axis not supported", NAME_NOT_FOUND);
diff --git a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
index 853f628..bbb2fc8 100644
--- a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
+++ b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
@@ -414,20 +414,6 @@
 };
 
 /**
- * Create a basic configuration change and send it to input processor.
- * Expect that the event is received by the next input stage, unmodified.
- */
-TEST_F(UnwantedInteractionBlockerTest, ConfigurationChangedIsPassedToNextListener) {
-    // Create a basic configuration change and send to blocker
-    NotifyConfigurationChangedArgs args(/*sequenceNum=*/1, /*eventTime=*/2);
-
-    mBlocker->notifyConfigurationChanged(args);
-    NotifyConfigurationChangedArgs outArgs;
-    ASSERT_NO_FATAL_FAILURE(mTestListener.assertNotifyConfigurationChangedWasCalled(&outArgs));
-    ASSERT_EQ(args, outArgs);
-}
-
-/**
  * Keys are not handled in 'UnwantedInteractionBlocker' and should be passed
  * to next stage unmodified.
  */
diff --git a/services/inputflinger/tests/VibratorInputMapper_test.cpp b/services/inputflinger/tests/VibratorInputMapper_test.cpp
new file mode 100644
index 0000000..aa4a6bb
--- /dev/null
+++ b/services/inputflinger/tests/VibratorInputMapper_test.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2024 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 "VibratorInputMapper.h"
+
+#include <chrono>
+#include <list>
+#include <variant>
+#include <vector>
+
+#include <EventHub.h>
+#include <NotifyArgs.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <input/Input.h>
+
+#include "InputMapperTest.h"
+#include "VibrationElement.h"
+
+namespace android {
+
+class VibratorInputMapperTest : public InputMapperUnitTest {
+protected:
+    void SetUp() override {
+        InputMapperUnitTest::SetUp();
+        createDevice();
+        EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID))
+                .WillRepeatedly(testing::Return(InputDeviceClass::VIBRATOR));
+        EXPECT_CALL(mMockEventHub, getVibratorIds(EVENTHUB_ID))
+                .WillRepeatedly(testing::Return<std::vector<int32_t>>({0, 1}));
+        mMapper = createInputMapper<VibratorInputMapper>(*mDeviceContext,
+                                                         mFakePolicy->getReaderConfiguration());
+    }
+};
+
+TEST_F(VibratorInputMapperTest, GetSources) {
+    ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mMapper->getSources());
+}
+
+TEST_F(VibratorInputMapperTest, GetVibratorIds) {
+    ASSERT_EQ(mMapper->getVibratorIds().size(), 2U);
+}
+
+TEST_F(VibratorInputMapperTest, Vibrate) {
+    constexpr uint8_t DEFAULT_AMPLITUDE = 192;
+    constexpr int32_t VIBRATION_TOKEN = 100;
+
+    VibrationElement pattern(2);
+    VibrationSequence sequence(2);
+    pattern.duration = std::chrono::milliseconds(200);
+    pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 2},
+                        {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
+    sequence.addElement(pattern);
+    pattern.duration = std::chrono::milliseconds(500);
+    pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 4},
+                        {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
+    sequence.addElement(pattern);
+
+    std::vector<int64_t> timings = {0, 1};
+    std::vector<uint8_t> amplitudes = {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE / 2};
+
+    ASSERT_FALSE(mMapper->isVibrating());
+    // Start vibrating
+    std::list<NotifyArgs> out = mMapper->vibrate(sequence, /*repeat=*/-1, VIBRATION_TOKEN);
+    ASSERT_TRUE(mMapper->isVibrating());
+    // Verify vibrator state listener was notified.
+    ASSERT_EQ(1u, out.size());
+    const NotifyVibratorStateArgs& vibrateArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
+    ASSERT_EQ(DEVICE_ID, vibrateArgs.deviceId);
+    ASSERT_TRUE(vibrateArgs.isOn);
+    // Stop vibrating
+    out = mMapper->cancelVibrate(VIBRATION_TOKEN);
+    ASSERT_FALSE(mMapper->isVibrating());
+    // Verify vibrator state listener was notified.
+    ASSERT_EQ(1u, out.size());
+    const NotifyVibratorStateArgs& cancelArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
+    ASSERT_EQ(DEVICE_ID, cancelArgs.deviceId);
+    ASSERT_FALSE(cancelArgs.isOn);
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
index 0b4ac1f..46a6189 100644
--- a/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
@@ -39,12 +39,6 @@
     while (fdp.remaining_bytes() > 0) {
         fdp.PickValueInArray<std::function<void()>>({
                 [&]() -> void {
-                    // SendToNextStage_NotifyConfigurationChangedArgs
-                    mClassifier->notifyConfigurationChanged(
-                            {/*sequenceNum=*/fdp.ConsumeIntegral<int32_t>(),
-                             /*eventTime=*/fdp.ConsumeIntegral<nsecs_t>()});
-                },
-                [&]() -> void {
                     // SendToNextStage_NotifyKeyArgs
                     const nsecs_t eventTime =
                             fdp.ConsumeIntegralInRange<nsecs_t>(0,
diff --git a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
index 7d26a43..d552c19 100644
--- a/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/InputReaderFuzzer.cpp
@@ -169,6 +169,8 @@
 
     DeviceId getLastUsedInputDeviceId() override { return reader->getLastUsedInputDeviceId(); }
 
+    void notifyMouseCursorFadedOnTyping() override { reader->notifyMouseCursorFadedOnTyping(); }
+
 private:
     std::unique_ptr<InputReaderInterface> reader;
 };
diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h
index ff425dd..bf56d3a 100644
--- a/services/inputflinger/tests/fuzzers/MapperHelpers.h
+++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h
@@ -17,6 +17,7 @@
 
 #include <map>
 #include <memory>
+#include <optional>
 
 #include <EventHub.h>
 #include <InputDevice.h>
@@ -31,8 +32,7 @@
                                   EV_MSC,
                                   EV_REL,
                                   android::EventHubInterface::DEVICE_ADDED,
-                                  android::EventHubInterface::DEVICE_REMOVED,
-                                  android::EventHubInterface::FINISHED_DEVICE_SCAN};
+                                  android::EventHubInterface::DEVICE_REMOVED};
 
 constexpr size_t kValidCodes[] = {
         SYN_REPORT,
@@ -119,16 +119,26 @@
     void setAbsoluteAxisInfo(int32_t deviceId, int axis, const RawAbsoluteAxisInfo& axisInfo) {
         mAxes[deviceId][axis] = axisInfo;
     }
-    status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
-                                 RawAbsoluteAxisInfo* outAxisInfo) const override {
+    std::optional<RawAbsoluteAxisInfo> getAbsoluteAxisInfo(int32_t deviceId,
+                                                           int axis) const override {
         if (auto deviceAxesIt = mAxes.find(deviceId); deviceAxesIt != mAxes.end()) {
             const std::map<int, RawAbsoluteAxisInfo>& deviceAxes = deviceAxesIt->second;
             if (auto axisInfoIt = deviceAxes.find(axis); axisInfoIt != deviceAxes.end()) {
-                *outAxisInfo = axisInfoIt->second;
-                return OK;
+                return axisInfoIt->second;
             }
         }
-        return mFdp->ConsumeIntegral<status_t>();
+        if (mFdp->ConsumeBool()) {
+            return std::optional<RawAbsoluteAxisInfo>({
+                    .valid = mFdp->ConsumeBool(),
+                    .minValue = mFdp->ConsumeIntegral<int32_t>(),
+                    .maxValue = mFdp->ConsumeIntegral<int32_t>(),
+                    .flat = mFdp->ConsumeIntegral<int32_t>(),
+                    .fuzz = mFdp->ConsumeIntegral<int32_t>(),
+                    .resolution = mFdp->ConsumeIntegral<int32_t>(),
+            });
+        } else {
+            return std::nullopt;
+        }
     }
     bool hasRelativeAxis(int32_t deviceId, int axis) const override { return mFdp->ConsumeBool(); }
     bool hasInputProperty(int32_t deviceId, int property) const override {
@@ -197,9 +207,12 @@
     int32_t getKeyCodeForKeyLocation(int32_t deviceId, int32_t locationKeyCode) const override {
         return mFdp->ConsumeIntegral<int32_t>();
     }
-    status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
-                                  int32_t* outValue) const override {
-        return mFdp->ConsumeIntegral<status_t>();
+    std::optional<int32_t> getAbsoluteAxisValue(int32_t deviceId, int32_t axis) const override {
+        if (mFdp->ConsumeBool()) {
+            return mFdp->ConsumeIntegral<int32_t>();
+        } else {
+            return std::nullopt;
+        }
     }
     base::Result<std::vector<int32_t>> getMtSlotValues(int32_t deviceId, int32_t axis,
                                                        size_t slotCount) const override {
@@ -293,7 +306,6 @@
 class FuzzInputListener : public virtual InputListenerInterface {
 public:
     void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override {}
-    void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override {}
     void notifyKey(const NotifyKeyArgs& args) override {}
     void notifyMotion(const NotifyMotionArgs& args) override {}
     void notifySwitch(const NotifySwitchArgs& args) override {}
@@ -333,8 +345,8 @@
     int32_t getLedMetaState() override { return mFdp->ConsumeIntegral<int32_t>(); };
     void notifyStylusGestureStarted(int32_t, nsecs_t) {}
 
-    void setPreventingTouchpadTaps(bool prevent) {}
-    bool isPreventingTouchpadTaps() { return mFdp->ConsumeBool(); };
+    void setPreventingTouchpadTaps(bool prevent) override {}
+    bool isPreventingTouchpadTaps() override { return mFdp->ConsumeBool(); };
 
     void setLastKeyDownTimestamp(nsecs_t when) { mLastKeyDownTimestamp = when; };
     nsecs_t getLastKeyDownTimestamp() { return mLastKeyDownTimestamp; };
diff --git a/services/sensorservice/aidl/fuzzer/Android.bp b/services/sensorservice/aidl/fuzzer/Android.bp
index f6f104e..b2dc89b 100644
--- a/services/sensorservice/aidl/fuzzer/Android.bp
+++ b/services/sensorservice/aidl/fuzzer/Android.bp
@@ -26,6 +26,11 @@
         "libfakeservicemanager",
         "libcutils",
         "liblog",
+        "libsensor_flags_c_lib",
+    ],
+    shared_libs: [
+        "libaconfig_storage_read_api_cc",
+        "server_configurable_flags",
     ],
     srcs: [
         "fuzzer.cpp",
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 1b6c598..a37433c 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -85,7 +85,7 @@
         "libui",
         "libutils",
         "libSurfaceFlingerProp",
-        "libaconfig_storage_read_api_cc"
+        "libaconfig_storage_read_api_cc",
     ],
     static_libs: [
         "iinputflinger_aidl_lib_static",
@@ -187,6 +187,7 @@
         "FrameTracker.cpp",
         "HdrLayerInfoReporter.cpp",
         "HdrSdrRatioOverlay.cpp",
+        "Jank/JankTracker.cpp",
         "WindowInfosListenerInvoker.cpp",
         "Layer.cpp",
         "LayerFE.cpp",
diff --git a/services/surfaceflinger/ClientCache.cpp b/services/surfaceflinger/ClientCache.cpp
index 09e41ff..40ea8d3 100644
--- a/services/surfaceflinger/ClientCache.cpp
+++ b/services/surfaceflinger/ClientCache.cpp
@@ -22,7 +22,7 @@
 #include <cinttypes>
 
 #include <android-base/stringprintf.h>
-#include <gui/TraceUtils.h>
+#include <common/trace.h>
 #include <renderengine/impl/ExternalTexture.h>
 
 #include "ClientCache.h"
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
index 11759b8..d1429a2 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
@@ -35,6 +35,7 @@
 #pragma clang diagnostic ignored "-Wextra"
 
 #include <gui/BufferQueue.h>
+#include <ui/EdgeExtensionEffect.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/GraphicTypes.h>
 #include <ui/StretchEffect.h>
@@ -133,12 +134,16 @@
     // The bounds of the layer in layer local coordinates
     FloatRect geomLayerBounds;
 
+    // The crop to apply to the layer in layer local coordinates
+    FloatRect geomLayerCrop;
+
     ShadowSettings shadowSettings;
 
     // List of regions that require blur
     std::vector<BlurRegion> blurRegions;
 
     StretchEffect stretchEffect;
+    EdgeExtensionEffect edgeExtensionEffect;
 
     /*
      * Geometry state
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h
index 6be6735..9c0e072 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h
@@ -92,15 +92,15 @@
     }
 
 private:
-    std::vector<const LayerState> copyLayers(const std::vector<const LayerState*>& layers) {
-        std::vector<const LayerState> copiedLayers;
+    std::vector<LayerState> copyLayers(const std::vector<const LayerState*>& layers) {
+        std::vector<LayerState> copiedLayers;
         copiedLayers.reserve(layers.size());
         std::transform(layers.cbegin(), layers.cend(), std::back_inserter(copiedLayers),
                        [](const LayerState* layerState) { return *layerState; });
         return copiedLayers;
     }
 
-    std::vector<const LayerState> mLayers;
+    std::vector<LayerState> mLayers;
 
     // TODO(b/180976743): Tune kMaxDifferingFields
     constexpr static int kMaxDifferingFields = 6;
diff --git a/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp b/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp
index bdaa1d0..d9018bc 100644
--- a/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp
@@ -37,7 +37,8 @@
             lhs.colorTransform == rhs.colorTransform &&
             lhs.disableBlending == rhs.disableBlending && lhs.shadow == rhs.shadow &&
             lhs.backgroundBlurRadius == rhs.backgroundBlurRadius &&
-            lhs.stretchEffect == rhs.stretchEffect;
+            lhs.stretchEffect == rhs.stretchEffect &&
+            lhs.edgeExtensionEffect == rhs.edgeExtensionEffect;
 }
 
 inline bool equalIgnoringBuffer(const renderengine::Buffer& lhs, const renderengine::Buffer& rhs) {
diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
index 4c77687..5c5d0cd 100644
--- a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <common/trace.h>
 #include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/LayerFE.h>
 #include <compositionengine/LayerFECompositionState.h>
@@ -23,7 +24,6 @@
 #include <ui/DisplayMap.h>
 
 #include <renderengine/RenderEngine.h>
-#include <utils/Trace.h>
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
 #pragma clang diagnostic push
@@ -128,7 +128,7 @@
 } // namespace
 
 void CompositionEngine::present(CompositionRefreshArgs& args) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV(__FUNCTION__);
 
     preComposition(args);
@@ -155,7 +155,7 @@
     }
 
     {
-        ATRACE_NAME("Waiting on HWC");
+        SFTRACE_NAME("Waiting on HWC");
         for (auto& future : presentFutures) {
             // TODO(b/185536303): Call ftl::Future::wait() once it exists, since
             // we do not need the return value of get().
@@ -177,7 +177,7 @@
 }
 
 void CompositionEngine::preComposition(CompositionRefreshArgs& args) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV(__FUNCTION__);
 
     bool needsAnotherUpdate = false;
@@ -199,7 +199,7 @@
 // promises for buffer releases are fulfilled at the end of composition.
 void CompositionEngine::postComposition(CompositionRefreshArgs& args) {
     if (FlagManager::getInstance().ce_fence_promise()) {
-        ATRACE_CALL();
+        SFTRACE_CALL();
         ALOGV(__FUNCTION__);
 
         for (auto& layerFE : args.layers) {
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index c1617d7..77b1940 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <android-base/stringprintf.h>
+#include <common/trace.h>
 #include <compositionengine/CompositionEngine.h>
 #include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/DisplayCreationArgs.h>
@@ -25,9 +26,6 @@
 #include <compositionengine/impl/DumpHelpers.h>
 #include <compositionengine/impl/OutputLayer.h>
 #include <compositionengine/impl/RenderSurface.h>
-#include <gui/TraceUtils.h>
-
-#include <utils/Trace.h>
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
 #pragma clang diagnostic push
@@ -235,7 +233,7 @@
 
 bool Display::chooseCompositionStrategy(
         std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
-    ATRACE_FORMAT("%s for %s", __func__, getNamePlusId().c_str());
+    SFTRACE_FORMAT("%s for %s", __func__, getNamePlusId().c_str());
     ALOGV(__FUNCTION__);
 
     if (mIsDisconnected) {
diff --git a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
index f339d41..4424a04 100644
--- a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
@@ -260,10 +260,6 @@
 
 void DisplayColorProfile::populateColorModes(
         const DisplayColorProfileCreationArgs::HwcColorModes& hwcColorModes) {
-    if (!hasWideColorGamut()) {
-        return;
-    }
-
     // collect all known SDR render intents
     std::unordered_set<RenderIntent> sdrRenderIntents(sSdrRenderIntents.begin(),
                                                       sSdrRenderIntents.end());
@@ -352,13 +348,9 @@
         *outMode = iter->second.colorMode;
         *outIntent = iter->second.renderIntent;
     } else {
-        // this is unexpected on a WCG display
-        if (hasWideColorGamut()) {
-            ALOGE("map unknown (%s)/(%s) to default color mode",
-                  dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(),
-                  decodeRenderIntent(intent).c_str());
-        }
-
+        ALOGI("map unknown (%s)/(%s) to default color mode",
+              dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(),
+              decodeRenderIntent(intent).c_str());
         *outDataspace = Dataspace::UNKNOWN;
         *outMode = ColorMode::NATIVE;
         *outIntent = RenderIntent::COLORIMETRIC;
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 5b9a102..64cded8 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -17,6 +17,7 @@
 #include <SurfaceFlingerProperties.sysprop.h>
 #include <android-base/stringprintf.h>
 #include <common/FlagManager.h>
+#include <common/trace.h>
 #include <compositionengine/CompositionEngine.h>
 #include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/DisplayColorProfile.h>
@@ -31,7 +32,6 @@
 #include <compositionengine/impl/planner/Planner.h>
 #include <ftl/algorithm.h>
 #include <ftl/future.h>
-#include <gui/TraceUtils.h>
 #include <scheduler/FrameTargeter.h>
 #include <scheduler/Time.h>
 
@@ -53,7 +53,6 @@
 #include <android-base/properties.h>
 #include <ui/DebugUtils.h>
 #include <ui/HdrCapabilities.h>
-#include <utils/Trace.h>
 
 #include "TracedOrdinal.h"
 
@@ -424,7 +423,7 @@
 
 void Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArgs,
                      LayerFESet& geomSnapshots) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV(__FUNCTION__);
 
     rebuildLayerStacks(refreshArgs, geomSnapshots);
@@ -453,8 +452,8 @@
                 })
                 .value();
     };
-    ATRACE_FORMAT("%s for %s%s", __func__, mNamePlusId.c_str(),
-                  stringifyExpectedPresentTime().c_str());
+    SFTRACE_FORMAT("%s for %s%s", __func__, mNamePlusId.c_str(),
+                   stringifyExpectedPresentTime().c_str());
     ALOGV(__FUNCTION__);
 
     updateColorProfile(refreshArgs);
@@ -518,7 +517,7 @@
     if (!outputState.isEnabled || CC_LIKELY(!refreshArgs.updatingOutputGeometryThisFrame)) {
         return;
     }
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV(__FUNCTION__);
 
     // Process the layers to determine visibility and coverage
@@ -804,7 +803,7 @@
 }
 
 void Output::updateCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV(__FUNCTION__);
 
     if (!getState().isEnabled) {
@@ -831,14 +830,14 @@
         return;
     }
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV(__FUNCTION__);
 
     mPlanner->plan(getOutputLayersOrderedByZ());
 }
 
 void Output::writeCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV(__FUNCTION__);
 
     if (!getState().isEnabled) {
@@ -1081,7 +1080,7 @@
 }
 
 void Output::prepareFrame() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV(__FUNCTION__);
 
     auto& outputState = editState();
@@ -1102,7 +1101,7 @@
 }
 
 ftl::Future<std::monostate> Output::presentFrameAndReleaseLayersAsync(bool flushEvenWhenDisabled) {
-    return ftl::Future<bool>(std::move(mHwComposerAsyncWorker->send([&]() {
+    return ftl::Future<bool>(std::move(mHwComposerAsyncWorker->send([this, flushEvenWhenDisabled]() {
                presentFrameAndReleaseLayers(flushEvenWhenDisabled);
                return true;
            })))
@@ -1116,7 +1115,7 @@
 }
 
 GpuCompositionResult Output::prepareFrameAsync() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV(__FUNCTION__);
     auto& state = editState();
     const auto& previousChanges = state.previousDeviceRequestedChanges;
@@ -1146,7 +1145,7 @@
     state.strategyPrediction = predictionSucceeded ? CompositionStrategyPredictionState::SUCCESS
                                                    : CompositionStrategyPredictionState::FAIL;
     if (!predictionSucceeded) {
-        ATRACE_NAME("CompositionStrategyPredictionMiss");
+        SFTRACE_NAME("CompositionStrategyPredictionMiss");
         resetCompositionStrategy();
         if (chooseCompositionSuccess) {
             applyCompositionStrategy(changes);
@@ -1155,7 +1154,7 @@
         // Track the dequeued buffer to reuse so we don't need to dequeue another one.
         compositionResult.buffer = buffer;
     } else {
-        ATRACE_NAME("CompositionStrategyPredictionHit");
+        SFTRACE_NAME("CompositionStrategyPredictionHit");
     }
     state.previousDeviceRequestedChanges = std::move(changes);
     state.previousDeviceRequestedSuccess = chooseCompositionSuccess;
@@ -1187,7 +1186,7 @@
 }
 
 void Output::finishFrame(GpuCompositionResult&& result) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV(__FUNCTION__);
     const auto& outputState = getState();
     if (!outputState.isEnabled) {
@@ -1276,7 +1275,7 @@
 std::optional<base::unique_fd> Output::composeSurfaces(
         const Region& debugRegion, std::shared_ptr<renderengine::ExternalTexture> tex,
         base::unique_fd& fd) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV(__FUNCTION__);
 
     const auto& outputState = getState();
@@ -1317,13 +1316,13 @@
         if (mClientCompositionRequestCache->exists(tex->getBuffer()->getId(),
                                                    clientCompositionDisplay,
                                                    clientCompositionLayers)) {
-            ATRACE_NAME("ClientCompositionCacheHit");
+            SFTRACE_NAME("ClientCompositionCacheHit");
             outputCompositionState.reusedClientComposition = true;
             setExpensiveRenderingExpected(false);
             // b/239944175 pass the fence associated with the buffer.
             return base::unique_fd(std::move(fd));
         }
-        ATRACE_NAME("ClientCompositionCacheMiss");
+        SFTRACE_NAME("ClientCompositionCacheMiss");
         mClientCompositionRequestCache->add(tex->getBuffer()->getId(), clientCompositionDisplay,
                                             clientCompositionLayers);
     }
@@ -1570,7 +1569,7 @@
 }
 
 void Output::presentFrameAndReleaseLayers(bool flushEvenWhenDisabled) {
-    ATRACE_FORMAT("%s for %s", __func__, mNamePlusId.c_str());
+    SFTRACE_FORMAT("%s for %s", __func__, mNamePlusId.c_str());
     ALOGV(__FUNCTION__);
 
     if (!getState().isEnabled) {
diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
index c0b23d9..d6028bf 100644
--- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
@@ -18,6 +18,7 @@
 
 #include <android-base/stringprintf.h>
 #include <android/native_window.h>
+#include <common/trace.h>
 #include <compositionengine/CompositionEngine.h>
 #include <compositionengine/Display.h>
 #include <compositionengine/DisplaySurface.h>
@@ -32,7 +33,6 @@
 #include <system/window.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/Rect.h>
-#include <utils/Trace.h>
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
 #pragma clang diagnostic push
@@ -149,7 +149,7 @@
 
 std::shared_ptr<renderengine::ExternalTexture> RenderSurface::dequeueBuffer(
         base::unique_fd* bufferFence) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     int fd = -1;
     ANativeWindowBuffer* buffer = nullptr;
 
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
index ea9442d..409a206 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp
@@ -21,6 +21,7 @@
 
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
+#include <common/trace.h>
 #include <compositionengine/impl/OutputCompositionState.h>
 #include <compositionengine/impl/planner/CachedSet.h>
 #include <math/HashCombine.h>
@@ -28,7 +29,6 @@
 #include <renderengine/RenderEngine.h>
 #include <ui/DebugUtils.h>
 #include <ui/HdrRenderTypeUtils.h>
-#include <utils/Trace.h>
 
 namespace android::compositionengine::impl::planner {
 
@@ -160,7 +160,7 @@
 void CachedSet::render(renderengine::RenderEngine& renderEngine, TexturePool& texturePool,
                        const OutputCompositionState& outputState,
                        bool deviceHandlesColorTransform) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     if (outputState.powerCallback) {
         outputState.powerCallback->notifyCpuLoadUp();
     }
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
index 4bafed2..783209c 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Flattener.cpp
@@ -21,11 +21,10 @@
 
 #include <android-base/properties.h>
 #include <common/FlagManager.h>
+#include <common/trace.h>
 #include <compositionengine/impl/planner/Flattener.h>
 #include <compositionengine/impl/planner/LayerState.h>
 
-#include <gui/TraceUtils.h>
-
 using time_point = std::chrono::steady_clock::time_point;
 using namespace std::chrono_literals;
 
@@ -77,7 +76,7 @@
 
 NonBufferHash Flattener::flattenLayers(const std::vector<const LayerState*>& layers,
                                        NonBufferHash hash, time_point now) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     const size_t unflattenedDisplayCost = calculateDisplayCost(layers);
     mUnflattenedDisplayCost += unflattenedDisplayCost;
 
@@ -113,7 +112,7 @@
         const OutputCompositionState& outputState,
         std::optional<std::chrono::steady_clock::time_point> renderDeadline,
         bool deviceHandlesColorTransform) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (!mNewCachedSet) {
         return;
@@ -121,7 +120,7 @@
 
     // Ensure that a cached set has a valid buffer first
     if (mNewCachedSet->hasRenderedBuffer()) {
-        ATRACE_NAME("mNewCachedSet->hasRenderedBuffer()");
+        SFTRACE_NAME("mNewCachedSet->hasRenderedBuffer()");
         return;
     }
 
@@ -138,13 +137,13 @@
 
             if (mNewCachedSet->getSkipCount() <=
                 mTunables.mRenderScheduling->maxDeferRenderAttempts) {
-                ATRACE_FORMAT("DeadlinePassed: exceeded deadline by: %d us",
-                              std::chrono::duration_cast<std::chrono::microseconds>(
-                                      estimatedRenderFinish - *renderDeadline)
-                                      .count());
+                SFTRACE_FORMAT("DeadlinePassed: exceeded deadline by: %d us",
+                               std::chrono::duration_cast<std::chrono::microseconds>(
+                                       estimatedRenderFinish - *renderDeadline)
+                                       .count());
                 return;
             } else {
-                ATRACE_NAME("DeadlinePassed: exceeded max skips");
+                SFTRACE_NAME("DeadlinePassed: exceeded max skips");
             }
         }
     }
@@ -271,7 +270,7 @@
 // was already populated with these layers, i.e. on the second and following
 // calls with the same geometry.
 bool Flattener::mergeWithCachedSets(const std::vector<const LayerState*>& layers, time_point now) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::vector<CachedSet> merged;
 
     if (mLayers.empty()) {
@@ -415,7 +414,7 @@
 }
 
 std::vector<Flattener::Run> Flattener::findCandidateRuns(time_point now) const {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::vector<Run> runs;
     bool isPartOfRun = false;
     Run::Builder builder;
@@ -431,8 +430,8 @@
         if (!layerIsInactive && currentSet->getLayerCount() == kNumLayersFpsConsideration) {
             auto layerFps = currentSet->getFirstLayer().getState()->getFps();
             if (layerFps > 0 && layerFps <= kFpsActiveThreshold) {
-                ATRACE_FORMAT("layer is considered inactive due to low FPS [%s] %f",
-                              currentSet->getFirstLayer().getName().c_str(), layerFps);
+                SFTRACE_FORMAT("layer is considered inactive due to low FPS [%s] %f",
+                               currentSet->getFirstLayer().getName().c_str(), layerFps);
                 layerIsInactive = true;
             }
         }
@@ -494,7 +493,7 @@
 }
 
 void Flattener::buildCachedSets(time_point now) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     if (mLayers.empty()) {
         ALOGV("[%s] No layers found, returning", __func__);
         return;
@@ -508,7 +507,7 @@
     for (const CachedSet& layer : mLayers) {
         // TODO (b/191997217): make it less aggressive, and sync with findCandidateRuns
         if (layer.hasProtectedLayers()) {
-            ATRACE_NAME("layer->hasProtectedLayers()");
+            SFTRACE_NAME("layer->hasProtectedLayers()");
             return;
         }
     }
diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
index 5e6cade..d114ff7 100644
--- a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp
@@ -21,11 +21,11 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #include <android-base/properties.h>
+#include <common/trace.h>
 #include <compositionengine/LayerFECompositionState.h>
 #include <compositionengine/impl/OutputLayerCompositionState.h>
 #include <compositionengine/impl/planner/Planner.h>
 
-#include <utils/Trace.h>
 #include <chrono>
 
 namespace android::compositionengine::impl::planner {
@@ -83,7 +83,7 @@
 
 void Planner::plan(
         compositionengine::Output::OutputLayersEnumerator<compositionengine::Output>&& layers) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::unordered_set<LayerId> removedLayers;
     removedLayers.reserve(mPreviousLayers.size());
 
@@ -165,7 +165,7 @@
 
 void Planner::reportFinalPlan(
         compositionengine::Output::OutputLayersEnumerator<compositionengine::Output>&& layers) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     if (!mPredictorEnabled) {
         return;
     }
@@ -204,7 +204,7 @@
 void Planner::renderCachedSets(const OutputCompositionState& outputState,
                                std::optional<std::chrono::steady_clock::time_point> renderDeadline,
                                bool deviceHandlesColorTransform) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     mFlattener.renderCachedSets(outputState, renderDeadline, deviceHandlesColorTransform);
 }
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
index 03a97dc..c354e4a 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
@@ -123,10 +123,10 @@
                 .build();
     }
 
-    static impl::DisplayColorProfile createProfileWithSRGBColorModeSupport() {
+    static impl::DisplayColorProfile createProfileWithSRGBColorModeSupport(bool wcg = true) {
         return ProfileFactory()
-                .setHasWideColorGamut(true)
                 .addHdrType(Hdr::HDR10)
+                .setHasWideColorGamut(wcg)
                 .addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::COLORIMETRIC)
                 .addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::ENHANCE)
                 .addColorModeRenderIntent(ColorMode::SRGB, VendorRenderIntent)
@@ -289,7 +289,7 @@
 TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasNoSupport) {
     auto profile = ProfileFactory::createProfileWithNoColorModeSupport();
 
-    EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
+    EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
     EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
     EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
     EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
@@ -306,6 +306,16 @@
     EXPECT_FALSE(profile.hasRenderIntent(VendorRenderIntent));
 }
 
+TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasSRGBSupport_NoWCG) {
+    auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport(false);
+
+    EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
+    EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
+    EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
+    EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
+    EXPECT_TRUE(profile.hasRenderIntent(VendorRenderIntent));
+}
+
 TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasSRGBSupport) {
     auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
 
@@ -476,6 +486,40 @@
     checkGetBestColorMode(profile, expectedResults);
 }
 
+TEST_F(DisplayColorProfileTest,
+       getBestColorModeReturnsExpectedModesWhenOutputHasSRGBSupport_NoWCG) {
+    auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport(false);
+
+    // Note: This table of expected values goes with the table of arguments
+    // used in checkGetBestColorMode.
+    using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
+    std::array<Result, 15> expectedResults = {
+            /* clang-format off */
+            /*  0 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+            /*  1 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+            /*  2 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+
+            /*  3 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+            /*  4 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+            /*  5 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+
+            /*  6 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+            /*  7 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+            /*  8 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+
+            /*  9 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+            /* 10 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+            /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+            /* 12 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+            /* 13 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+            /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+            /* clang-format on */
+    };
+
+    checkGetBestColorMode(profile, expectedResults);
+}
+
 TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasSRGBSupport) {
     auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
 
diff --git a/services/surfaceflinger/Display/DisplayModeController.cpp b/services/surfaceflinger/Display/DisplayModeController.cpp
index a6a9bec..c43d585 100644
--- a/services/surfaceflinger/Display/DisplayModeController.cpp
+++ b/services/surfaceflinger/Display/DisplayModeController.cpp
@@ -83,7 +83,7 @@
             FTL_EXPECT(mDisplays.get(displayId).ok_or(DesiredModeAction::None)).get();
 
     {
-        ATRACE_NAME(displayPtr->concatId(__func__).c_str());
+        SFTRACE_NAME(displayPtr->concatId(__func__).c_str());
         ALOGD("%s %s", displayPtr->concatId(__func__).c_str(), to_string(desiredMode).c_str());
 
         std::scoped_lock lock(displayPtr->desiredModeLock);
@@ -204,7 +204,7 @@
         return false;
     }
 
-    ATRACE_INT(displayPtr->pendingModeFpsTrace.c_str(), mode.getVsyncRate().getIntValue());
+    SFTRACE_INT(displayPtr->pendingModeFpsTrace.c_str(), mode.getVsyncRate().getIntValue());
     return true;
 }
 
@@ -227,8 +227,8 @@
                                                 Fps vsyncRate, Fps renderFps) {
     const auto& displayPtr = FTL_TRY(mDisplays.get(displayId).ok_or(ftl::Unit())).get();
 
-    ATRACE_INT(displayPtr->activeModeFpsTrace.c_str(), vsyncRate.getIntValue());
-    ATRACE_INT(displayPtr->renderRateFpsTrace.c_str(), renderFps.getIntValue());
+    SFTRACE_INT(displayPtr->activeModeFpsTrace.c_str(), vsyncRate.getIntValue());
+    SFTRACE_INT(displayPtr->renderRateFpsTrace.c_str(), renderFps.getIntValue());
 
     displayPtr->selectorPtr->setActiveMode(modeId, renderFps);
 
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 27ea4a9..75b07a8 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -24,6 +24,7 @@
 
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
+#include <common/trace.h>
 #include <compositionengine/CompositionEngine.h>
 #include <compositionengine/Display.h>
 #include <compositionengine/DisplayColorProfile.h>
@@ -398,7 +399,7 @@
 }
 
 void DisplayDevice::updateHdrSdrRatioOverlayRatio(float currentHdrSdrRatio) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     mHdrSdrRatio = currentHdrSdrRatio;
     if (mHdrSdrRatioOverlay) {
         mHdrSdrRatioOverlay->changeHdrSdrRatio(currentHdrSdrRatio);
@@ -440,7 +441,7 @@
 }
 
 void DisplayDevice::updateRefreshRateOverlayRate(Fps refreshRate, Fps renderFps, bool setByHwc) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     if (mRefreshRateOverlay) {
         if (!mRefreshRateOverlay->isSetByHwc() || setByHwc) {
             if (mRefreshRateSelector->isVrrDevice() && !mRefreshRateOverlay->isSetByHwc()) {
@@ -467,6 +468,12 @@
     return false;
 }
 
+void DisplayDevice::onVrrIdle(bool idle) {
+    if (mRefreshRateOverlay) {
+        mRefreshRateOverlay->onVrrIdle(idle);
+    }
+}
+
 void DisplayDevice::animateOverlay() {
     if (mRefreshRateOverlay) {
         mRefreshRateOverlay->animate();
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 3cc8cf5..1b8a3a8 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -196,6 +196,7 @@
     bool isRefreshRateOverlayEnabled() const { return mRefreshRateOverlay != nullptr; }
     void animateOverlay();
     bool onKernelTimerChanged(std::optional<DisplayModeId>, bool timerExpired);
+    void onVrrIdle(bool idle);
 
     // Enables an overlay to be display with the hdr/sdr ratio
     void enableHdrSdrRatioOverlay(bool enable) REQUIRES(kMainThreadContext);
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index 362ab9c..d50a0bc 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -25,9 +25,8 @@
 #include <android/binder_ibinder_platform.h>
 #include <android/binder_manager.h>
 #include <common/FlagManager.h>
-#include <gui/TraceUtils.h>
+#include <common/trace.h>
 #include <log/log.h>
-#include <utils/Trace.h>
 
 #include <aidl/android/hardware/graphics/composer3/BnComposerCallback.h>
 
@@ -677,7 +676,7 @@
 
 Error AidlComposer::presentDisplay(Display display, int* outPresentFence) {
     const auto displayId = translate<int64_t>(display);
-    ATRACE_FORMAT("HwcPresentDisplay %" PRId64, displayId);
+    SFTRACE_FORMAT("HwcPresentDisplay %" PRId64, displayId);
 
     Error error = Error::NONE;
     mMutex.lock_shared();
@@ -810,7 +809,7 @@
                                     int32_t frameIntervalNs, uint32_t* outNumTypes,
                                     uint32_t* outNumRequests) {
     const auto displayId = translate<int64_t>(display);
-    ATRACE_FORMAT("HwcValidateDisplay %" PRId64, displayId);
+    SFTRACE_FORMAT("HwcValidateDisplay %" PRId64, displayId);
 
     Error error = Error::NONE;
     mMutex.lock_shared();
@@ -840,7 +839,7 @@
                                              uint32_t* outNumRequests, int* outPresentFence,
                                              uint32_t* state) {
     const auto displayId = translate<int64_t>(display);
-    ATRACE_FORMAT("HwcPresentOrValidateDisplay %" PRId64, displayId);
+    SFTRACE_FORMAT("HwcPresentOrValidateDisplay %" PRId64, displayId);
 
     Error error = Error::NONE;
     mMutex.lock_shared();
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 3d285a8..73fa855 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -28,16 +28,15 @@
 #include "HWComposer.h"
 
 #include <android-base/properties.h>
+#include <common/trace.h>
 #include <compositionengine/Output.h>
 #include <compositionengine/OutputLayer.h>
 #include <compositionengine/impl/OutputLayerCompositionState.h>
 #include <ftl/concat.h>
-#include <gui/TraceUtils.h>
 #include <log/log.h>
 #include <ui/DebugUtils.h>
 #include <ui/GraphicBuffer.h>
 #include <utils/Errors.h>
-#include <utils/Trace.h>
 
 #include "../Layer.h" // needed only for debugging
 #include "../SurfaceFlingerProperties.h"
@@ -178,8 +177,8 @@
         displayData.lastPresentTimestamp = timestamp;
     }
 
-    ATRACE_INT(ftl::Concat("HW_VSYNC_", displayIdOpt->value).c_str(),
-               displayData.vsyncTraceToggle);
+    SFTRACE_INT(ftl::Concat("HW_VSYNC_", displayIdOpt->value).c_str(),
+                displayData.vsyncTraceToggle);
     displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;
 
     return displayIdOpt;
@@ -428,14 +427,14 @@
         return;
     }
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
     RETURN_IF_HWC_ERROR(error, displayId);
 
     displayData.vsyncEnabled = enabled;
 
-    ATRACE_INT(ftl::Concat("HW_VSYNC_ON_", displayId.value).c_str(),
-               enabled == hal::Vsync::ENABLE ? 1 : 0);
+    SFTRACE_INT(ftl::Concat("HW_VSYNC_ON_", displayId.value).c_str(),
+                enabled == hal::Vsync::ENABLE ? 1 : 0);
 }
 
 status_t HWComposer::setClientTarget(HalDisplayId displayId, uint32_t slot,
@@ -455,7 +454,7 @@
         std::optional<std::chrono::steady_clock::time_point> earliestPresentTime,
         nsecs_t expectedPresentTime, Fps frameInterval,
         std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
 
@@ -493,7 +492,7 @@
     }();
 
     displayData.validateWasSkipped = false;
-    ATRACE_FORMAT("NextFrameInterval %d_Hz", frameInterval.getIntValue());
+    SFTRACE_FORMAT("NextFrameInterval %d_Hz", frameInterval.getIntValue());
     if (canSkipValidate) {
         sp<Fence> outPresentFence = Fence::NO_FENCE;
         uint32_t state = UINT32_MAX;
@@ -568,7 +567,7 @@
 status_t HWComposer::presentAndGetReleaseFences(
         HalDisplayId displayId,
         std::optional<std::chrono::steady_clock::time_point> earliestPresentTime) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
 
@@ -584,7 +583,7 @@
     }
 
     if (earliestPresentTime) {
-        ATRACE_NAME("wait for earliest present time");
+        SFTRACE_NAME("wait for earliest present time");
         std::this_thread::sleep_until(*earliestPresentTime);
     }
 
@@ -897,9 +896,9 @@
 status_t HWComposer::notifyExpectedPresent(PhysicalDisplayId displayId,
                                            TimePoint expectedPresentTime, Fps frameInterval) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
-    ATRACE_FORMAT("%s ExpectedPresentTime in %.2fms frameInterval %.2fms", __func__,
-                  ticks<std::milli, float>(expectedPresentTime - TimePoint::now()),
-                  ticks<std::milli, float>(Duration::fromNs(frameInterval.getPeriodNsecs())));
+    SFTRACE_FORMAT("%s ExpectedPresentTime in %.2fms frameInterval %.2fms", __func__,
+                   ticks<std::milli, float>(expectedPresentTime - TimePoint::now()),
+                   ticks<std::milli, float>(Duration::fromNs(frameInterval.getPeriodNsecs())));
     const auto error = mComposer->notifyExpectedPresent(mDisplayData[displayId].hwcDisplay->getId(),
                                                         expectedPresentTime.ns(),
                                                         frameInterval.getPeriodNsecs());
@@ -1149,7 +1148,7 @@
 
 status_t HWComposer::setIdleTimerEnabled(PhysicalDisplayId displayId,
                                          std::chrono::milliseconds timeout) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
     const auto error = mDisplayData[displayId].hwcDisplay->setIdleTimerEnabled(timeout);
     if (error == hal::Error::UNSUPPORTED) {
@@ -1168,7 +1167,7 @@
 }
 
 Hwc2::AidlTransform HWComposer::getPhysicalDisplayOrientation(PhysicalDisplayId displayId) const {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     RETURN_IF_INVALID_DISPLAY(displayId, Hwc2::AidlTransform::NONE);
     Hwc2::AidlTransform outTransform;
     const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
diff --git a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
index 12ab2c2..c5008d8 100644
--- a/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
@@ -27,11 +27,11 @@
 #include <SurfaceFlingerProperties.h>
 #include <aidl/android/hardware/graphics/common/DisplayHotplugEvent.h>
 #include <android/binder_manager.h>
+#include <common/trace.h>
 #include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
 #include <hidl/HidlTransportSupport.h>
 #include <hidl/HidlTransportUtils.h>
 #include <log/log.h>
-#include <utils/Trace.h>
 
 #include "HWC2.h"
 #include "Hal.h"
@@ -588,7 +588,7 @@
 }
 
 Error HidlComposer::presentDisplay(Display display, int* outPresentFence) {
-    ATRACE_NAME("HwcPresentDisplay");
+    SFTRACE_NAME("HwcPresentDisplay");
     mWriter.selectDisplay(display);
     mWriter.presentDisplay();
 
@@ -676,7 +676,7 @@
 Error HidlComposer::validateDisplay(Display display, nsecs_t /*expectedPresentTime*/,
                                     int32_t /*frameIntervalNs*/, uint32_t* outNumTypes,
                                     uint32_t* outNumRequests) {
-    ATRACE_NAME("HwcValidateDisplay");
+    SFTRACE_NAME("HwcValidateDisplay");
     mWriter.selectDisplay(display);
     mWriter.validateDisplay();
 
@@ -694,7 +694,7 @@
                                              int32_t /*frameIntervalNs*/, uint32_t* outNumTypes,
                                              uint32_t* outNumRequests, int* outPresentFence,
                                              uint32_t* state) {
-    ATRACE_NAME("HwcPresentOrValidateDisplay");
+    SFTRACE_NAME("HwcPresentOrValidateDisplay");
     mWriter.selectDisplay(display);
     mWriter.presentOrvalidateDisplay();
 
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 6c1a813..334c104 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -27,9 +27,9 @@
 #include <optional>
 
 #include <android-base/properties.h>
+#include <common/trace.h>
 #include <utils/Log.h>
 #include <utils/Mutex.h>
-#include <utils/Trace.h>
 
 #include <binder/IServiceManager.h>
 
@@ -74,9 +74,9 @@
 
 void traceExpensiveRendering(bool enabled) {
     if (enabled) {
-        ATRACE_ASYNC_BEGIN("ExpensiveRendering", 0);
+        SFTRACE_ASYNC_BEGIN("ExpensiveRendering", 0);
     } else {
-        ATRACE_ASYNC_END("ExpensiveRendering", 0);
+        SFTRACE_ASYNC_END("ExpensiveRendering", 0);
     }
 }
 
@@ -210,8 +210,8 @@
         ALOGV("Power hint session is not enabled, skip sending session hint");
         return;
     }
-    ATRACE_CALL();
-    if (sTraceHintSessionData) ATRACE_INT("Session hint", static_cast<int>(hint));
+    SFTRACE_CALL();
+    if (sTraceHintSessionData) SFTRACE_INT("Session hint", static_cast<int>(hint));
     {
         std::scoped_lock lock(mHintSessionMutex);
         if (!ensurePowerHintSessionRunning()) {
@@ -295,10 +295,10 @@
         ALOGV("Power hint session is not enabled, skipping target update");
         return;
     }
-    ATRACE_CALL();
+    SFTRACE_CALL();
     {
         mTargetDuration = targetDuration;
-        if (sTraceHintSessionData) ATRACE_INT64("Time target", targetDuration.ns());
+        if (sTraceHintSessionData) SFTRACE_INT64("Time target", targetDuration.ns());
         if (targetDuration == mLastTargetDurationSent) return;
         std::scoped_lock lock(mHintSessionMutex);
         if (!ensurePowerHintSessionRunning()) {
@@ -324,7 +324,7 @@
         ALOGV("Actual work duration power hint cannot be sent, skipping");
         return;
     }
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::optional<WorkDuration> actualDuration = estimateWorkDuration();
     if (!actualDuration.has_value() || actualDuration->durationNanos < 0) {
         ALOGV("Failed to send actual work duration, skipping");
@@ -332,16 +332,16 @@
     }
     actualDuration->durationNanos += sTargetSafetyMargin.ns();
     if (sTraceHintSessionData) {
-        ATRACE_INT64("Measured duration", actualDuration->durationNanos);
-        ATRACE_INT64("Target error term", actualDuration->durationNanos - mTargetDuration.ns());
-        ATRACE_INT64("Reported duration", actualDuration->durationNanos);
+        SFTRACE_INT64("Measured duration", actualDuration->durationNanos);
+        SFTRACE_INT64("Target error term", actualDuration->durationNanos - mTargetDuration.ns());
+        SFTRACE_INT64("Reported duration", actualDuration->durationNanos);
         if (supportsGpuReporting()) {
-            ATRACE_INT64("Reported cpu duration", actualDuration->cpuDurationNanos);
-            ATRACE_INT64("Reported gpu duration", actualDuration->gpuDurationNanos);
+            SFTRACE_INT64("Reported cpu duration", actualDuration->cpuDurationNanos);
+            SFTRACE_INT64("Reported gpu duration", actualDuration->gpuDurationNanos);
         }
-        ATRACE_INT64("Reported target", mLastTargetDurationSent.ns());
-        ATRACE_INT64("Reported target error term",
-                     actualDuration->durationNanos - mLastTargetDurationSent.ns());
+        SFTRACE_INT64("Reported target", mLastTargetDurationSent.ns());
+        SFTRACE_INT64("Reported target error term",
+                      actualDuration->durationNanos - mLastTargetDurationSent.ns());
     }
 
     ALOGV("Sending actual work duration of: %" PRId64 " with cpu: %" PRId64 " and gpu: %" PRId64
@@ -664,9 +664,9 @@
             .gpuDurationNanos = supportsGpuReporting() ? estimatedGpuDuration.ns() : 0,
     };
     if (sTraceHintSessionData) {
-        ATRACE_INT64("Idle duration", idleDuration.ns());
-        ATRACE_INT64("Total duration", totalDuration.ns());
-        ATRACE_INT64("Flinger duration", flingerDuration.ns());
+        SFTRACE_INT64("Idle duration", idleDuration.ns());
+        SFTRACE_INT64("Total duration", totalDuration.ns());
+        SFTRACE_INT64("Flinger duration", flingerDuration.ns());
     }
     return std::make_optional(duration);
 }
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index bc4a41b..1076b2b 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -300,7 +300,7 @@
     bool mSessionConfigSupported = true;
     bool mFirstConfigSupportCheck = true;
 
-    // Whether we should emit ATRACE_INT data for hint sessions
+    // Whether we should emit SFTRACE_INT data for hint sessions
     static const bool sTraceHintSessionData;
 
     // Default target duration for the hint session
diff --git a/services/surfaceflinger/DisplayRenderArea.cpp b/services/surfaceflinger/DisplayRenderArea.cpp
index 55b395b..c63c738 100644
--- a/services/surfaceflinger/DisplayRenderArea.cpp
+++ b/services/surfaceflinger/DisplayRenderArea.cpp
@@ -22,22 +22,20 @@
 std::unique_ptr<RenderArea> DisplayRenderArea::create(wp<const DisplayDevice> displayWeak,
                                                       const Rect& sourceCrop, ui::Size reqSize,
                                                       ui::Dataspace reqDataSpace,
-                                                      bool hintForSeamlessTransition,
-                                                      bool allowSecureLayers) {
+                                                      ftl::Flags<Options> options) {
     if (auto display = displayWeak.promote()) {
         // Using new to access a private constructor.
-        return std::unique_ptr<DisplayRenderArea>(
-                new DisplayRenderArea(std::move(display), sourceCrop, reqSize, reqDataSpace,
-                                      hintForSeamlessTransition, allowSecureLayers));
+        return std::unique_ptr<DisplayRenderArea>(new DisplayRenderArea(std::move(display),
+                                                                        sourceCrop, reqSize,
+                                                                        reqDataSpace, options));
     }
     return nullptr;
 }
 
 DisplayRenderArea::DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop,
                                      ui::Size reqSize, ui::Dataspace reqDataSpace,
-                                     bool hintForSeamlessTransition, bool allowSecureLayers)
-      : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, hintForSeamlessTransition,
-                   allowSecureLayers),
+                                     ftl::Flags<Options> options)
+      : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, options),
         mDisplay(std::move(display)),
         mSourceCrop(sourceCrop) {}
 
@@ -46,7 +44,7 @@
 }
 
 bool DisplayRenderArea::isSecure() const {
-    return mAllowSecureLayers && mDisplay->isSecure();
+    return mOptions.test(Options::CAPTURE_SECURE_LAYERS) && mDisplay->isSecure();
 }
 
 sp<const DisplayDevice> DisplayRenderArea::getDisplayDevice() const {
diff --git a/services/surfaceflinger/DisplayRenderArea.h b/services/surfaceflinger/DisplayRenderArea.h
index 4555a9e..677d019 100644
--- a/services/surfaceflinger/DisplayRenderArea.h
+++ b/services/surfaceflinger/DisplayRenderArea.h
@@ -29,8 +29,7 @@
 public:
     static std::unique_ptr<RenderArea> create(wp<const DisplayDevice>, const Rect& sourceCrop,
                                               ui::Size reqSize, ui::Dataspace,
-                                              bool hintForSeamlessTransition,
-                                              bool allowSecureLayers = true);
+                                              ftl::Flags<Options> options);
 
     const ui::Transform& getTransform() const override;
     bool isSecure() const override;
@@ -39,7 +38,7 @@
 
 private:
     DisplayRenderArea(sp<const DisplayDevice>, const Rect& sourceCrop, ui::Size reqSize,
-                      ui::Dataspace, bool hintForSeamlessTransition, bool allowSecureLayers = true);
+                      ui::Dataspace, ftl::Flags<Options> options);
 
     const sp<const DisplayDevice> mDisplay;
     const Rect mSourceCrop;
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index 2596a25..2a0ee5a 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -22,14 +22,16 @@
 
 #include <android-base/stringprintf.h>
 #include <common/FlagManager.h>
+#include <common/trace.h>
 #include <utils/Log.h>
-#include <utils/Trace.h>
 
 #include <chrono>
 #include <cinttypes>
 #include <numeric>
 #include <unordered_set>
 
+#include "../Jank/JankTracker.h"
+
 namespace android::frametimeline {
 
 using base::StringAppendF;
@@ -357,7 +359,11 @@
 
 void SurfaceFrame::setAcquireFenceTime(nsecs_t acquireFenceTime) {
     std::scoped_lock lock(mMutex);
-    mActuals.endTime = std::max(acquireFenceTime, mActualQueueTime);
+    if (CC_UNLIKELY(acquireFenceTime == Fence::SIGNAL_TIME_PENDING)) {
+        mActuals.endTime = mActualQueueTime;
+    } else {
+        mActuals.endTime = std::max(acquireFenceTime, mActualQueueTime);
+    }
 }
 
 void SurfaceFrame::setDropTime(nsecs_t dropTime) {
@@ -685,6 +691,13 @@
         mTimeStats->incrementJankyFrames({refreshRate, mRenderRate, mOwnerUid, mLayerName,
                                           mGameMode, mJankType, displayDeadlineDelta,
                                           displayPresentDelta, deadlineDelta});
+
+        gui::JankData jd;
+        jd.frameVsyncId = mToken;
+        jd.jankType = mJankType;
+        jd.frameIntervalNs =
+                (mRenderRate ? *mRenderRate : mDisplayFrameRenderRate).getPeriodNsecs();
+        JankTracker::onJankData(mLayerId, jd);
     }
 }
 
@@ -820,7 +833,7 @@
 namespace impl {
 
 int64_t TokenManager::generateTokenForPredictions(TimelineItem&& predictions) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::scoped_lock lock(mMutex);
     while (mPredictions.size() >= kMaxTokens) {
         mPredictions.erase(mPredictions.begin());
@@ -866,7 +879,7 @@
 std::shared_ptr<SurfaceFrame> FrameTimeline::createSurfaceFrameForToken(
         const FrameTimelineInfo& frameTimelineInfo, pid_t ownerPid, uid_t ownerUid, int32_t layerId,
         std::string layerName, std::string debugName, bool isBuffer, GameMode gameMode) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     if (frameTimelineInfo.vsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) {
         return std::make_shared<SurfaceFrame>(frameTimelineInfo, ownerPid, ownerUid, layerId,
                                               std::move(layerName), std::move(debugName),
@@ -902,14 +915,14 @@
 }
 
 void FrameTimeline::addSurfaceFrame(std::shared_ptr<SurfaceFrame> surfaceFrame) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::scoped_lock lock(mMutex);
     mCurrentDisplayFrame->addSurfaceFrame(surfaceFrame);
 }
 
 void FrameTimeline::setSfWakeUp(int64_t token, nsecs_t wakeUpTime, Fps refreshRate,
                                 Fps renderRate) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::scoped_lock lock(mMutex);
     mCurrentDisplayFrame->onSfWakeUp(token, refreshRate, renderRate,
                                      mTokenManager.getPredictionsForToken(token), wakeUpTime);
@@ -918,7 +931,7 @@
 void FrameTimeline::setSfPresent(nsecs_t sfPresentTime,
                                  const std::shared_ptr<FenceTime>& presentFence,
                                  const std::shared_ptr<FenceTime>& gpuFence) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::scoped_lock lock(mMutex);
     mCurrentDisplayFrame->setActualEndTime(sfPresentTime);
     mCurrentDisplayFrame->setGpuFence(gpuFence);
@@ -928,7 +941,7 @@
 }
 
 void FrameTimeline::onCommitNotComposited() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::scoped_lock lock(mMutex);
     mCurrentDisplayFrame->onCommitNotComposited();
     mCurrentDisplayFrame.reset();
@@ -1507,7 +1520,7 @@
 }
 
 void FrameTimeline::parseArgs(const Vector<String16>& args, std::string& result) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::unordered_map<std::string, bool> argsMap;
     for (size_t i = 0; i < args.size(); i++) {
         argsMap[std::string(String8(args[i]).c_str())] = true;
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
index 39a6b77..f4335f3 100644
--- a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
@@ -413,11 +413,11 @@
 
 void LayerHierarchyBuilder::update(LayerLifecycleManager& layerLifecycleManager) {
     if (!mInitialized) {
-        ATRACE_NAME("LayerHierarchyBuilder:init");
+        SFTRACE_NAME("LayerHierarchyBuilder:init");
         init(layerLifecycleManager.getLayers());
     } else if (layerLifecycleManager.getGlobalChanges().test(
                        RequestedLayerState::Changes::Hierarchy)) {
-        ATRACE_NAME("LayerHierarchyBuilder:update");
+        SFTRACE_NAME("LayerHierarchyBuilder:update");
         doUpdate(layerLifecycleManager.getLayers(), layerLifecycleManager.getDestroyedLayers());
     } else {
         return; // nothing to do
@@ -426,7 +426,7 @@
     uint32_t invalidRelativeRoot;
     bool hasRelZLoop = mRoot.hasRelZLoop(invalidRelativeRoot);
     while (hasRelZLoop) {
-        ATRACE_NAME("FixRelZLoop");
+        SFTRACE_NAME("FixRelZLoop");
         TransactionTraceWriter::getInstance().invoke("relz_loop_detected",
                                                      /*overwrite=*/false);
         layerLifecycleManager.fixRelativeZLoop(invalidRelativeRoot);
diff --git a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
index dd5e8bd..f1091a6 100644
--- a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+// #define LOG_NDEBUG 0
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #undef LOG_TAG
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
index 70e3c64..e5f6b7b 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
@@ -322,6 +322,10 @@
             << touchableRegion.bottom << "," << touchableRegion.right << "}"
             << "}";
     }
+
+    if (obj.edgeExtensionEffect.hasEffect()) {
+        out << obj.edgeExtensionEffect;
+    }
     return out;
 }
 
@@ -492,8 +496,10 @@
         requested.what &
                 (layer_state_t::eBufferChanged | layer_state_t::eDataspaceChanged |
                  layer_state_t::eApiChanged | layer_state_t::eShadowRadiusChanged |
-                 layer_state_t::eBlurRegionsChanged | layer_state_t::eStretchChanged)) {
-        forceClientComposition = shadowSettings.length > 0 || stretchEffect.hasEffect();
+                 layer_state_t::eBlurRegionsChanged | layer_state_t::eStretchChanged |
+                 layer_state_t::eEdgeExtensionChanged)) {
+        forceClientComposition = shadowSettings.length > 0 || stretchEffect.hasEffect() ||
+                edgeExtensionEffect.hasEffect();
     }
 
     if (forceUpdate ||
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index ca53a0d..4e09381 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -23,8 +23,8 @@
 #include <optional>
 
 #include <common/FlagManager.h>
+#include <common/trace.h>
 #include <ftl/small_map.h>
-#include <gui/TraceUtils.h>
 #include <ui/DisplayMap.h>
 #include <ui/FloatRect.h>
 
@@ -317,6 +317,21 @@
     }
 }
 
+void updateMetadataAndGameMode(LayerSnapshot& snapshot, const RequestedLayerState& requested,
+                               const LayerSnapshotBuilder::Args& args,
+                               const LayerSnapshot& parentSnapshot) {
+    if (snapshot.changes.test(RequestedLayerState::Changes::GameMode)) {
+        snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE)
+                ? requested.gameMode
+                : parentSnapshot.gameMode;
+    }
+    updateMetadata(snapshot, requested, args);
+    if (args.includeMetadata) {
+        snapshot.layerMetadata = parentSnapshot.layerMetadata;
+        snapshot.layerMetadata.merge(requested.metadata);
+    }
+}
+
 void clearChanges(LayerSnapshot& snapshot) {
     snapshot.changes.clear();
     snapshot.clientChanges = 0;
@@ -352,6 +367,7 @@
     snapshot.geomLayerBounds = getMaxDisplayBounds({});
     snapshot.roundedCorner = RoundedCornerState();
     snapshot.stretchEffect = {};
+    snapshot.edgeExtensionEffect = {};
     snapshot.outputFilter.layerStack = ui::DEFAULT_LAYER_STACK;
     snapshot.outputFilter.toInternalDisplay = false;
     snapshot.isSecure = false;
@@ -387,7 +403,7 @@
 
     // There are only content changes which do not require any child layer snapshots to be updated.
     ALOGV("%s", __func__);
-    ATRACE_NAME("FastPath");
+    SFTRACE_NAME("FastPath");
 
     uint32_t primaryDisplayRotationFlags = getPrimaryDisplayRotationFlags(args.displays);
     if (forceUpdate || args.displayChanges) {
@@ -421,7 +437,7 @@
 }
 
 void LayerSnapshotBuilder::updateSnapshots(const Args& args) {
-    ATRACE_NAME("UpdateSnapshots");
+    SFTRACE_NAME("UpdateSnapshots");
     LayerSnapshot rootSnapshot = args.rootSnapshot;
     if (args.parentCrop) {
         rootSnapshot.geomLayerBounds = *args.parentCrop;
@@ -762,6 +778,11 @@
                                  RequestedLayerState::Changes::Input)) {
             updateInput(snapshot, requested, parentSnapshot, path, args);
         }
+        if (forceUpdate ||
+            (args.includeMetadata &&
+             snapshot.changes.test(RequestedLayerState::Changes::Metadata))) {
+            updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot);
+        }
         return;
     }
 
@@ -791,6 +812,32 @@
                 : parentSnapshot.stretchEffect;
     }
 
+    if (forceUpdate ||
+        (snapshot.clientChanges | parentSnapshot.clientChanges) &
+                layer_state_t::eEdgeExtensionChanged) {
+        if (requested.edgeExtensionParameters.extendLeft ||
+            requested.edgeExtensionParameters.extendRight ||
+            requested.edgeExtensionParameters.extendTop ||
+            requested.edgeExtensionParameters.extendBottom) {
+            // This is the root layer to which the extension is applied
+            snapshot.edgeExtensionEffect =
+                    EdgeExtensionEffect(requested.edgeExtensionParameters.extendLeft,
+                                        requested.edgeExtensionParameters.extendRight,
+                                        requested.edgeExtensionParameters.extendTop,
+                                        requested.edgeExtensionParameters.extendBottom);
+        } else if (parentSnapshot.clientChanges & layer_state_t::eEdgeExtensionChanged) {
+            // Extension is inherited
+            snapshot.edgeExtensionEffect = parentSnapshot.edgeExtensionEffect;
+        } else {
+            // There is no edge extension
+            snapshot.edgeExtensionEffect.reset();
+        }
+        if (snapshot.edgeExtensionEffect.hasEffect()) {
+            snapshot.clientChanges |= layer_state_t::eEdgeExtensionChanged;
+            snapshot.changes |= RequestedLayerState::Changes::Geometry;
+        }
+    }
+
     if (forceUpdate || snapshot.clientChanges & layer_state_t::eColorTransformChanged) {
         if (!parentSnapshot.colorTransformIsIdentity) {
             snapshot.colorTransform = parentSnapshot.colorTransform * requested.colorTransform;
@@ -801,15 +848,8 @@
         }
     }
 
-    if (forceUpdate || snapshot.changes.test(RequestedLayerState::Changes::GameMode)) {
-        snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE)
-                ? requested.gameMode
-                : parentSnapshot.gameMode;
-        updateMetadata(snapshot, requested, args);
-        if (args.includeMetadata) {
-            snapshot.layerMetadata = parentSnapshot.layerMetadata;
-            snapshot.layerMetadata.merge(requested.metadata);
-        }
+    if (forceUpdate || snapshot.changes.test(RequestedLayerState::Changes::Metadata)) {
+        updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot);
     }
 
     if (forceUpdate || snapshot.clientChanges & layer_state_t::eFixedTransformHintChanged ||
@@ -886,6 +926,10 @@
         updateLayerBounds(snapshot, requested, parentSnapshot, primaryDisplayRotationFlags);
     }
 
+    if (snapshot.edgeExtensionEffect.hasEffect()) {
+        updateBoundsForEdgeExtension(snapshot);
+    }
+
     if (forceUpdate || snapshot.clientChanges & layer_state_t::eCornerRadiusChanged ||
         snapshot.changes.any(RequestedLayerState::Changes::Geometry |
                              RequestedLayerState::Changes::BufferUsageFlags)) {
@@ -904,8 +948,8 @@
     }
 
     // computed snapshot properties
-    snapshot.forceClientComposition =
-            snapshot.shadowSettings.length > 0 || snapshot.stretchEffect.hasEffect();
+    snapshot.forceClientComposition = snapshot.shadowSettings.length > 0 ||
+            snapshot.stretchEffect.hasEffect() || snapshot.edgeExtensionEffect.hasEffect();
     snapshot.contentOpaque = snapshot.isContentOpaque();
     snapshot.isOpaque = snapshot.contentOpaque && !snapshot.roundedCorner.hasRoundedCorners() &&
             snapshot.color.a == 1.f;
@@ -960,6 +1004,31 @@
     }
 }
 
+/**
+ * According to the edges that we are requested to extend, we increase the bounds to the maximum
+ * extension allowed by the crop (parent crop + requested crop). The animation that called
+ * Transition#setEdgeExtensionEffect is in charge of setting the requested crop.
+ * @param snapshot
+ */
+void LayerSnapshotBuilder::updateBoundsForEdgeExtension(LayerSnapshot& snapshot) {
+    EdgeExtensionEffect& effect = snapshot.edgeExtensionEffect;
+
+    if (effect.extendsEdge(LEFT)) {
+        snapshot.geomLayerBounds.left = snapshot.geomLayerCrop.left;
+    }
+    if (effect.extendsEdge(RIGHT)) {
+        snapshot.geomLayerBounds.right = snapshot.geomLayerCrop.right;
+    }
+    if (effect.extendsEdge(TOP)) {
+        snapshot.geomLayerBounds.top = snapshot.geomLayerCrop.top;
+    }
+    if (effect.extendsEdge(BOTTOM)) {
+        snapshot.geomLayerBounds.bottom = snapshot.geomLayerCrop.bottom;
+    }
+
+    snapshot.transformedBounds = snapshot.geomLayerTransform.transform(snapshot.geomLayerBounds);
+}
+
 void LayerSnapshotBuilder::updateLayerBounds(LayerSnapshot& snapshot,
                                              const RequestedLayerState& requested,
                                              const LayerSnapshot& parentSnapshot,
@@ -999,11 +1068,12 @@
     FloatRect parentBounds = parentSnapshot.geomLayerBounds;
     parentBounds = snapshot.localTransform.inverse().transform(parentBounds);
     snapshot.geomLayerBounds =
-            (requested.externalTexture) ? snapshot.bufferSize.toFloatRect() : parentBounds;
+            requested.externalTexture ? snapshot.bufferSize.toFloatRect() : parentBounds;
+    snapshot.geomLayerCrop = parentBounds;
     if (!requested.crop.isEmpty()) {
-        snapshot.geomLayerBounds = snapshot.geomLayerBounds.intersect(requested.crop.toFloatRect());
+        snapshot.geomLayerCrop = snapshot.geomLayerCrop.intersect(requested.crop.toFloatRect());
     }
-    snapshot.geomLayerBounds = snapshot.geomLayerBounds.intersect(parentBounds);
+    snapshot.geomLayerBounds = snapshot.geomLayerBounds.intersect(snapshot.geomLayerCrop);
     snapshot.transformedBounds = snapshot.geomLayerTransform.transform(snapshot.geomLayerBounds);
     const Rect geomLayerBoundsWithoutTransparentRegion =
             RequestedLayerState::reduce(Rect(snapshot.geomLayerBounds),
@@ -1178,6 +1248,15 @@
     }
 }
 
+void LayerSnapshotBuilder::forEachSnapshot(const Visitor& visitor,
+                                           const ConstPredicate& predicate) {
+    for (int i = 0; i < mNumInterestingSnapshots; i++) {
+        std::unique_ptr<LayerSnapshot>& snapshot = mSnapshots.at((size_t)i);
+        if (!predicate(*snapshot)) continue;
+        visitor(snapshot);
+    }
+}
+
 void LayerSnapshotBuilder::forEachInputSnapshot(const ConstVisitor& visitor) const {
     for (int i = mNumInterestingSnapshots - 1; i >= 0; i--) {
         LayerSnapshot& snapshot = *mSnapshots[(size_t)i];
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
index 1cec018..f3c56a4 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
@@ -86,6 +86,11 @@
     // Visit each visible snapshot in z-order and move the snapshot if needed
     void forEachVisibleSnapshot(const Visitor& visitor);
 
+    typedef std::function<bool(const LayerSnapshot& snapshot)> ConstPredicate;
+    // Visit each snapshot that satisfies the predicate and move the snapshot if needed with visible
+    // snapshots in z-order
+    void forEachSnapshot(const Visitor& visitor, const ConstPredicate& predicate);
+
     // Visit each snapshot interesting to input reverse z-order
     void forEachInputSnapshot(const ConstVisitor& visitor) const;
 
@@ -108,6 +113,10 @@
     static void resetRelativeState(LayerSnapshot& snapshot);
     static void updateRoundedCorner(LayerSnapshot& snapshot, const RequestedLayerState& layerState,
                                     const LayerSnapshot& parentSnapshot, const Args& args);
+    static bool extensionEdgeSharedWithParent(LayerSnapshot& snapshot,
+                                              const RequestedLayerState& requested,
+                                              const LayerSnapshot& parentSnapshot);
+    static void updateBoundsForEdgeExtension(LayerSnapshot& snapshot);
     void updateLayerBounds(LayerSnapshot& snapshot, const RequestedLayerState& layerState,
                            const LayerSnapshot& parentSnapshot, uint32_t displayRotationFlags);
     static void updateShadows(LayerSnapshot& snapshot, const RequestedLayerState& requested,
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index 3e8d740..17d2610 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -19,7 +19,7 @@
 #undef LOG_TAG
 #define LOG_TAG "SurfaceFlinger"
 
-#include <gui/TraceUtils.h>
+#include <common/trace.h>
 #include <log/log.h>
 #include <private/android_filesystem_config.h>
 #include <sys/types.h>
@@ -328,6 +328,7 @@
                 changes |= RequestedLayerState::Changes::GameMode;
             }
         }
+        changes |= RequestedLayerState::Changes::Metadata;
     }
     if (clientState.what & layer_state_t::eFrameRateChanged) {
         const auto compatibility =
@@ -580,8 +581,8 @@
 bool RequestedLayerState::isSimpleBufferUpdate(const layer_state_t& s) const {
     static constexpr uint64_t requiredFlags = layer_state_t::eBufferChanged;
     if ((s.what & requiredFlags) != requiredFlags) {
-        ATRACE_FORMAT_INSTANT("%s: false [missing required flags 0x%" PRIx64 "]", __func__,
-                              (s.what | requiredFlags) & ~s.what);
+        SFTRACE_FORMAT_INSTANT("%s: false [missing required flags 0x%" PRIx64 "]", __func__,
+                               (s.what | requiredFlags) & ~s.what);
         return false;
     }
 
@@ -593,8 +594,8 @@
                      ? 0
                      : (layer_state_t::eAutoRefreshChanged | layer_state_t::eFlagsChanged));
     if (s.what & deniedFlags) {
-        ATRACE_FORMAT_INSTANT("%s: false [has denied flags 0x%" PRIx64 "]", __func__,
-                              s.what & deniedFlags);
+        SFTRACE_FORMAT_INSTANT("%s: false [has denied flags 0x%" PRIx64 "]", __func__,
+                               s.what & deniedFlags);
         return false;
     }
 
@@ -608,15 +609,16 @@
             layer_state_t::eSidebandStreamChanged | layer_state_t::eColorSpaceAgnosticChanged |
             layer_state_t::eShadowRadiusChanged | layer_state_t::eFixedTransformHintChanged |
             layer_state_t::eTrustedOverlayChanged | layer_state_t::eStretchChanged |
-            layer_state_t::eBufferCropChanged | layer_state_t::eDestinationFrameChanged |
-            layer_state_t::eDimmingEnabledChanged | layer_state_t::eExtendedRangeBrightnessChanged |
+            layer_state_t::eEdgeExtensionChanged | layer_state_t::eBufferCropChanged |
+            layer_state_t::eDestinationFrameChanged | layer_state_t::eDimmingEnabledChanged |
+            layer_state_t::eExtendedRangeBrightnessChanged |
             layer_state_t::eDesiredHdrHeadroomChanged |
             (FlagManager::getInstance().latch_unsignaled_with_auto_refresh_changed()
                      ? layer_state_t::eFlagsChanged
                      : 0);
     if (changedFlags & deniedChanges) {
-        ATRACE_FORMAT_INSTANT("%s: false [has denied changes flags 0x%" PRIx64 "]", __func__,
-                              changedFlags & deniedChanges);
+        SFTRACE_FORMAT_INSTANT("%s: false [has denied changes flags 0x%" PRIx64 "]", __func__,
+                               changedFlags & deniedChanges);
         return false;
     }
 
diff --git a/services/surfaceflinger/FrontEnd/TransactionHandler.cpp b/services/surfaceflinger/FrontEnd/TransactionHandler.cpp
index d3d9509..a1e8213 100644
--- a/services/surfaceflinger/FrontEnd/TransactionHandler.cpp
+++ b/services/surfaceflinger/FrontEnd/TransactionHandler.cpp
@@ -19,9 +19,9 @@
 #define LOG_TAG "SurfaceFlinger"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
+#include <common/trace.h>
 #include <cutils/trace.h>
 #include <utils/Log.h>
-#include <utils/Trace.h>
 #include "FrontEnd/LayerLog.h"
 
 #include "TransactionHandler.h"
@@ -31,7 +31,7 @@
 void TransactionHandler::queueTransaction(TransactionState&& state) {
     mLocklessTransactionQueue.push(std::move(state));
     mPendingTransactionCount.fetch_add(1);
-    ATRACE_INT("TransactionQueue", static_cast<int>(mPendingTransactionCount.load()));
+    SFTRACE_INT("TransactionQueue", static_cast<int>(mPendingTransactionCount.load()));
 }
 
 void TransactionHandler::collectTransactions() {
@@ -71,7 +71,7 @@
     applyUnsignaledBufferTransaction(transactions, flushState);
 
     mPendingTransactionCount.fetch_sub(transactions.size());
-    ATRACE_INT("TransactionQueue", static_cast<int>(mPendingTransactionCount.load()));
+    SFTRACE_INT("TransactionQueue", static_cast<int>(mPendingTransactionCount.load()));
     return transactions;
 }
 
@@ -83,7 +83,7 @@
 
     // only apply an unsignaled buffer transaction if it's the first one
     if (!transactions.empty()) {
-        ATRACE_NAME("fence unsignaled");
+        SFTRACE_NAME("fence unsignaled");
         return;
     }
 
diff --git a/services/surfaceflinger/HdrLayerInfoReporter.cpp b/services/surfaceflinger/HdrLayerInfoReporter.cpp
index 2788332..85921bb 100644
--- a/services/surfaceflinger/HdrLayerInfoReporter.cpp
+++ b/services/surfaceflinger/HdrLayerInfoReporter.cpp
@@ -19,8 +19,8 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #include <android-base/stringprintf.h>
+#include <common/trace.h>
 #include <inttypes.h>
-#include <utils/Trace.h>
 
 #include "HdrLayerInfoReporter.h"
 
@@ -29,7 +29,7 @@
 using base::StringAppendF;
 
 void HdrLayerInfoReporter::dispatchHdrLayerInfo(const HdrLayerInfo& info) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     if (mHdrInfoHistory.size() == 0 || mHdrInfoHistory.back().info != info) {
         mHdrInfoHistory.next() = EventHistoryEntry{info};
     }
@@ -47,7 +47,7 @@
     }
 
     for (const auto& listener : toInvoke) {
-        ATRACE_NAME("invoking onHdrLayerInfoChanged");
+        SFTRACE_NAME("invoking onHdrLayerInfoChanged");
         listener->onHdrLayerInfoChanged(info.numberOfHdrLayers, info.maxW, info.maxH, info.flags,
                                         info.maxDesiredHdrSdrRatio);
     }
diff --git a/services/surfaceflinger/Jank/JankTracker.cpp b/services/surfaceflinger/Jank/JankTracker.cpp
new file mode 100644
index 0000000..8e0e084
--- /dev/null
+++ b/services/surfaceflinger/Jank/JankTracker.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2024 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 "JankTracker.h"
+
+#include <android/gui/IJankListener.h>
+#include "BackgroundExecutor.h"
+
+namespace android {
+
+namespace {
+
+constexpr size_t kJankDataBatchSize = 50;
+
+} // anonymous namespace
+
+std::atomic<size_t> JankTracker::sListenerCount(0);
+std::atomic<bool> JankTracker::sCollectAllJankDataForTesting(false);
+
+JankTracker::~JankTracker() {}
+
+void JankTracker::addJankListener(int32_t layerId, sp<IBinder> listener) {
+    // Increment right away, so that if an onJankData call comes in before the background thread has
+    // added this listener, it will not drop the data.
+    sListenerCount++;
+
+    BackgroundExecutor::getLowPriorityInstance().sendCallbacks(
+            {[layerId, listener = std::move(listener)]() {
+                JankTracker& tracker = getInstance();
+                const std::lock_guard<std::mutex> _l(tracker.mLock);
+                tracker.addJankListenerLocked(layerId, listener);
+            }});
+}
+
+void JankTracker::flushJankData(int32_t layerId) {
+    BackgroundExecutor::getLowPriorityInstance().sendCallbacks(
+            {[layerId]() { getInstance().doFlushJankData(layerId); }});
+}
+
+void JankTracker::removeJankListener(int32_t layerId, sp<IBinder> listener, int64_t afterVsync) {
+    BackgroundExecutor::getLowPriorityInstance().sendCallbacks(
+            {[layerId, listener = std::move(listener), afterVsync]() {
+                JankTracker& tracker = getInstance();
+                const std::lock_guard<std::mutex> _l(tracker.mLock);
+                tracker.markJankListenerForRemovalLocked(layerId, listener, afterVsync);
+            }});
+}
+
+void JankTracker::onJankData(int32_t layerId, gui::JankData data) {
+    if (sListenerCount == 0) {
+        return;
+    }
+
+    BackgroundExecutor::getLowPriorityInstance().sendCallbacks(
+            {[layerId, data = std::move(data)]() {
+                JankTracker& tracker = getInstance();
+
+                tracker.mLock.lock();
+                bool hasListeners = tracker.mJankListeners.count(layerId) > 0;
+                tracker.mLock.unlock();
+
+                if (!hasListeners && !sCollectAllJankDataForTesting) {
+                    return;
+                }
+
+                tracker.mJankDataLock.lock();
+                tracker.mJankData.emplace(layerId, data);
+                size_t count = tracker.mJankData.count(layerId);
+                tracker.mJankDataLock.unlock();
+
+                if (count >= kJankDataBatchSize && !sCollectAllJankDataForTesting) {
+                    tracker.doFlushJankData(layerId);
+                }
+            }});
+}
+
+void JankTracker::addJankListenerLocked(int32_t layerId, sp<IBinder> listener) {
+    for (auto it = mJankListeners.find(layerId); it != mJankListeners.end(); it++) {
+        if (it->second.mListener == listener) {
+            // Undo the duplicate increment in addJankListener.
+            sListenerCount--;
+            return;
+        }
+    }
+
+    mJankListeners.emplace(layerId, std::move(listener));
+}
+
+void JankTracker::doFlushJankData(int32_t layerId) {
+    std::vector<gui::JankData> jankData;
+    int64_t maxVsync = transferAvailableJankData(layerId, jankData);
+
+    std::vector<sp<IBinder>> toSend;
+
+    mLock.lock();
+    for (auto it = mJankListeners.find(layerId); it != mJankListeners.end();) {
+        if (!jankData.empty()) {
+            toSend.emplace_back(it->second.mListener);
+        }
+
+        int64_t removeAfter = it->second.mRemoveAfter;
+        if (removeAfter != -1 && removeAfter <= maxVsync) {
+            it = mJankListeners.erase(it);
+            sListenerCount--;
+        } else {
+            it++;
+        }
+    }
+    mLock.unlock();
+
+    for (const auto& listener : toSend) {
+        binder::Status status = interface_cast<gui::IJankListener>(listener)->onJankData(jankData);
+        if (status.exceptionCode() == binder::Status::EX_NULL_POINTER) {
+            // Remove any listeners, where the App side has gone away, without
+            // deregistering.
+            dropJankListener(layerId, listener);
+        }
+    }
+}
+
+void JankTracker::markJankListenerForRemovalLocked(int32_t layerId, sp<IBinder> listener,
+                                                   int64_t afterVysnc) {
+    for (auto it = mJankListeners.find(layerId); it != mJankListeners.end(); it++) {
+        if (it->second.mListener == listener) {
+            it->second.mRemoveAfter = std::max(static_cast<int64_t>(0), afterVysnc);
+            return;
+        }
+    }
+}
+
+int64_t JankTracker::transferAvailableJankData(int32_t layerId,
+                                               std::vector<gui::JankData>& outJankData) {
+    const std::lock_guard<std::mutex> _l(mJankDataLock);
+    int64_t maxVsync = 0;
+    auto range = mJankData.equal_range(layerId);
+    for (auto it = range.first; it != range.second;) {
+        maxVsync = std::max(it->second.frameVsyncId, maxVsync);
+        outJankData.emplace_back(std::move(it->second));
+        it = mJankData.erase(it);
+    }
+    return maxVsync;
+}
+
+void JankTracker::dropJankListener(int32_t layerId, sp<IBinder> listener) {
+    const std::lock_guard<std::mutex> _l(mLock);
+    for (auto it = mJankListeners.find(layerId); it != mJankListeners.end(); it++) {
+        if (it->second.mListener == listener) {
+            mJankListeners.erase(it);
+            sListenerCount--;
+            return;
+        }
+    }
+}
+
+void JankTracker::clearAndStartCollectingAllJankDataForTesting() {
+    BackgroundExecutor::getLowPriorityInstance().flushQueue();
+
+    // Clear all past tracked jank data.
+    JankTracker& tracker = getInstance();
+    const std::lock_guard<std::mutex> _l(tracker.mJankDataLock);
+    tracker.mJankData.clear();
+
+    // Pretend there's at least one listener.
+    sListenerCount++;
+    sCollectAllJankDataForTesting = true;
+}
+
+std::vector<gui::JankData> JankTracker::getCollectedJankDataForTesting(int32_t layerId) {
+    JankTracker& tracker = getInstance();
+    const std::lock_guard<std::mutex> _l(tracker.mJankDataLock);
+
+    auto range = tracker.mJankData.equal_range(layerId);
+    std::vector<gui::JankData> result;
+    std::transform(range.first, range.second, std::back_inserter(result),
+                   [](std::pair<int32_t, gui::JankData> layerIdToJankData) {
+                       return layerIdToJankData.second;
+                   });
+
+    return result;
+}
+
+void JankTracker::clearAndStopCollectingAllJankDataForTesting() {
+    // Undo startCollectingAllJankDataForTesting.
+    sListenerCount--;
+    sCollectAllJankDataForTesting = false;
+
+    // Clear all tracked jank data.
+    JankTracker& tracker = getInstance();
+    const std::lock_guard<std::mutex> _l(tracker.mJankDataLock);
+    tracker.mJankData.clear();
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/Jank/JankTracker.h b/services/surfaceflinger/Jank/JankTracker.h
new file mode 100644
index 0000000..5917358
--- /dev/null
+++ b/services/surfaceflinger/Jank/JankTracker.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2024 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 <cstdint>
+#include <mutex>
+#include <unordered_map>
+
+#include <android/gui/JankData.h>
+#include <binder/IBinder.h>
+#include <utils/Mutex.h>
+
+namespace android {
+namespace frametimeline {
+class FrameTimelineTest;
+}
+
+/**
+ * JankTracker maintains a backlog of frame jank classification and manages and notififies any
+ * registered jank data listeners.
+ */
+class JankTracker {
+public:
+    ~JankTracker();
+
+    static void addJankListener(int32_t layerId, sp<IBinder> listener);
+    static void flushJankData(int32_t layerId);
+    static void removeJankListener(int32_t layerId, sp<IBinder> listener, int64_t afterVysnc);
+
+    static void onJankData(int32_t layerId, gui::JankData data);
+
+protected:
+    // The following methods can be used to force the tracker to collect all jank data and not
+    // flush it for a short time period and should *only* be used for testing. Every call to
+    // clearAndStartCollectingAllJankDataForTesting needs to be followed by a call to
+    // clearAndStopCollectingAllJankDataForTesting.
+    static void clearAndStartCollectingAllJankDataForTesting();
+    static std::vector<gui::JankData> getCollectedJankDataForTesting(int32_t layerId);
+    static void clearAndStopCollectingAllJankDataForTesting();
+
+    friend class frametimeline::FrameTimelineTest;
+
+private:
+    JankTracker() {}
+    JankTracker(const JankTracker&) = delete;
+    JankTracker(JankTracker&&) = delete;
+
+    JankTracker& operator=(const JankTracker&) = delete;
+    JankTracker& operator=(JankTracker&&) = delete;
+
+    static JankTracker& getInstance() {
+        static JankTracker instance;
+        return instance;
+    }
+
+    void addJankListenerLocked(int32_t layerId, sp<IBinder> listener) REQUIRES(mLock);
+    void doFlushJankData(int32_t layerId);
+    void markJankListenerForRemovalLocked(int32_t layerId, sp<IBinder> listener, int64_t afterVysnc)
+            REQUIRES(mLock);
+
+    int64_t transferAvailableJankData(int32_t layerId, std::vector<gui::JankData>& jankData);
+    void dropJankListener(int32_t layerId, sp<IBinder> listener);
+
+    struct Listener {
+        sp<IBinder> mListener;
+        int64_t mRemoveAfter;
+
+        Listener(sp<IBinder>&& listener) : mListener(listener), mRemoveAfter(-1) {}
+    };
+
+    // We keep track of the current listener count, so that the onJankData call, which is on the
+    // main thread, can short-curcuit the scheduling on the background thread (which involves
+    // locking) if there are no listeners registered, which is the most common case.
+    static std::atomic<size_t> sListenerCount;
+    static std::atomic<bool> sCollectAllJankDataForTesting;
+
+    std::mutex mLock;
+    std::unordered_multimap<int32_t, Listener> mJankListeners GUARDED_BY(mLock);
+    std::mutex mJankDataLock;
+    std::unordered_multimap<int32_t, gui::JankData> mJankData GUARDED_BY(mJankDataLock);
+
+    friend class JankTrackerTest;
+};
+
+} // namespace android
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index d27bfd2..0682fdb 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -27,6 +27,7 @@
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <binder/IPCThreadState.h>
+#include <common/trace.h>
 #include <compositionengine/CompositionEngine.h>
 #include <compositionengine/Display.h>
 #include <compositionengine/LayerFECompositionState.h>
@@ -39,7 +40,6 @@
 #include <ftl/fake_guard.h>
 #include <gui/BufferItem.h>
 #include <gui/Surface.h>
-#include <gui/TraceUtils.h>
 #include <math.h>
 #include <private/android_filesystem_config.h>
 #include <renderengine/RenderEngine.h>
@@ -58,7 +58,6 @@
 #include <utils/Log.h>
 #include <utils/NativeHandle.h>
 #include <utils/StopWatch.h>
-#include <utils/Trace.h>
 
 #include <algorithm>
 #include <mutex>
@@ -767,47 +766,12 @@
     return (p != nullptr) ? p->isSecure() : false;
 }
 
-void Layer::transferAvailableJankData(const std::deque<sp<CallbackHandle>>& handles,
-                                      std::vector<JankData>& jankData) {
-    if (mPendingJankClassifications.empty() ||
-        !mPendingJankClassifications.front()->getJankType()) {
-        return;
-    }
-
-    bool includeJankData = false;
-    for (const auto& handle : handles) {
-        for (const auto& cb : handle->callbackIds) {
-            if (cb.includeJankData) {
-                includeJankData = true;
-                break;
-            }
-        }
-
-        if (includeJankData) {
-            jankData.reserve(mPendingJankClassifications.size());
-            break;
-        }
-    }
-
-    while (!mPendingJankClassifications.empty() &&
-           mPendingJankClassifications.front()->getJankType()) {
-        if (includeJankData) {
-            std::shared_ptr<frametimeline::SurfaceFrame> surfaceFrame =
-                    mPendingJankClassifications.front();
-            jankData.emplace_back(JankData(surfaceFrame->getToken(),
-                                           surfaceFrame->getJankType().value(),
-                                           surfaceFrame->getRenderRate().getPeriodNsecs()));
-        }
-        mPendingJankClassifications.pop_front();
-    }
-}
-
 // ----------------------------------------------------------------------------
 // transaction
 // ----------------------------------------------------------------------------
 
 uint32_t Layer::doTransaction(uint32_t flags) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     // TODO: This is unfortunate.
     mDrawingStateModified = mDrawingState.modified;
@@ -1436,7 +1400,6 @@
     if (fps) {
         surfaceFrame->setRenderRate(*fps);
     }
-    onSurfaceFrameCreated(surfaceFrame);
     return surfaceFrame;
 }
 
@@ -1453,7 +1416,6 @@
     if (fps) {
         surfaceFrame->setRenderRate(*fps);
     }
-    onSurfaceFrameCreated(surfaceFrame);
     return surfaceFrame;
 }
 
@@ -1479,7 +1441,6 @@
     if (fps) {
         surfaceFrame->setRenderRate(*fps);
     }
-    onSurfaceFrameCreated(surfaceFrame);
     addSurfaceFrameDroppedForBuffer(surfaceFrame, postTime);
 }
 
@@ -2579,10 +2540,6 @@
 compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
         const DisplayDevice* display) const {
     if (!display) return nullptr;
-    if (!mFlinger->mLayerLifecycleManagerEnabled) {
-        return display->getCompositionDisplay()->getOutputLayerForLayer(
-                getCompositionEngineLayerFE());
-    }
     sp<LayerFE> layerFE;
     frontend::LayerHierarchy::TraversalPath path{.id = static_cast<uint32_t>(sequence)};
     for (auto& [p, layer] : mLayerFEs) {
@@ -2598,10 +2555,6 @@
 compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
         const DisplayDevice* display, const frontend::LayerHierarchy::TraversalPath& path) const {
     if (!display) return nullptr;
-    if (!mFlinger->mLayerLifecycleManagerEnabled) {
-        return display->getCompositionDisplay()->getOutputLayerForLayer(
-                getCompositionEngineLayerFE());
-    }
     sp<LayerFE> layerFE;
     for (auto& [p, layer] : mLayerFEs) {
         if (p == path) {
@@ -2821,12 +2774,15 @@
     if (!listener) {
         return;
     }
-    ATRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64, getDebugName(), framenumber);
+    SFTRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64, getDebugName(), framenumber);
+    ReleaseCallbackId callbackId{buffer->getId(), framenumber};
+    const sp<Fence>& fence = releaseFence ? releaseFence : Fence::NO_FENCE;
     uint32_t currentMaxAcquiredBufferCount =
             mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
-    listener->onReleaseBuffer({buffer->getId(), framenumber},
-                              releaseFence ? releaseFence : Fence::NO_FENCE,
-                              currentMaxAcquiredBufferCount);
+    listener->onReleaseBuffer(callbackId, fence, currentMaxAcquiredBufferCount);
+    if (mBufferReleaseChannel) {
+        mBufferReleaseChannel->writeReleaseFence(callbackId, fence);
+    }
 }
 
 sp<CallbackHandle> Layer::findCallbackHandle() {
@@ -2942,33 +2898,15 @@
     }
 }
 
-void Layer::onSurfaceFrameCreated(
-        const std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame) {
-    while (mPendingJankClassifications.size() >= kPendingClassificationMaxSurfaceFrames) {
-        // Too many SurfaceFrames pending classification. The front of the deque is probably not
-        // tracked by FrameTimeline and will never be presented. This will only result in a memory
-        // leak.
-        if (hasBufferOrSidebandStreamInDrawing()) {
-            // Only log for layers with a buffer, since we expect the jank data to be drained for
-            // these, while there may be no jank listeners for bufferless layers.
-            ALOGW("Removing the front of pending jank deque from layer - %s to prevent memory leak",
-                  mName.c_str());
-            std::string miniDump = mPendingJankClassifications.front()->miniDump();
-            ALOGD("Head SurfaceFrame mini dump\n%s", miniDump.c_str());
-        }
-        mPendingJankClassifications.pop_front();
-    }
-    mPendingJankClassifications.emplace_back(surfaceFrame);
-}
-
 void Layer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
     for (const auto& handle : mDrawingState.callbackHandles) {
+        handle->bufferReleaseChannel = mBufferReleaseChannel;
         handle->transformHint = mTransformHint;
         handle->dequeueReadyTime = dequeueReadyTime;
         handle->currentMaxAcquiredBufferCount =
                 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
-        ATRACE_FORMAT_INSTANT("releasePendingBuffer %s - %" PRIu64, getDebugName(),
-                              handle->previousReleaseCallbackId.framenumber);
+        SFTRACE_FORMAT_INSTANT("releasePendingBuffer %s - %" PRIu64, getDebugName(),
+                               handle->previousReleaseCallbackId.framenumber);
     }
 
     for (auto& handle : mDrawingState.callbackHandles) {
@@ -2978,10 +2916,7 @@
         }
     }
 
-    std::vector<JankData> jankData;
-    transferAvailableJankData(mDrawingState.callbackHandles, jankData);
-    mFlinger->getTransactionCallbackInvoker().addCallbackHandles(mDrawingState.callbackHandles,
-                                                                 jankData);
+    mFlinger->getTransactionCallbackInvoker().addCallbackHandles(mDrawingState.callbackHandles);
     mDrawingState.callbackHandles = {};
 }
 
@@ -3121,6 +3056,8 @@
         callReleaseBufferCallback(mDrawingState.releaseBufferListener,
                                   mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
                                   mDrawingState.acquireFence);
+        const int32_t layerId = getSequence();
+        mFlinger->mTimeStats->removeTimeRecord(layerId, mDrawingState.frameNumber);
         decrementPendingBufferCount();
         if (mDrawingState.bufferSurfaceFrameTX != nullptr &&
             mDrawingState.bufferSurfaceFrameTX->getPresentState() != PresentState::Presented) {
@@ -3150,13 +3087,13 @@
 bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer,
                       const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime,
                       bool isAutoTimestamp, const FrameTimelineInfo& info) {
-    ATRACE_FORMAT("setBuffer %s - hasBuffer=%s", getDebugName(), (buffer ? "true" : "false"));
+    SFTRACE_FORMAT("setBuffer %s - hasBuffer=%s", getDebugName(), (buffer ? "true" : "false"));
 
     const bool frameNumberChanged =
             bufferData.flags.test(BufferData::BufferDataChange::frameNumberChanged);
     const uint64_t frameNumber =
             frameNumberChanged ? bufferData.frameNumber : mDrawingState.frameNumber + 1;
-    ATRACE_FORMAT_INSTANT("setBuffer %s - %" PRIu64, getDebugName(), frameNumber);
+    SFTRACE_FORMAT_INSTANT("setBuffer %s - %" PRIu64, getDebugName(), frameNumber);
 
     if (mDrawingState.buffer) {
         releasePreviousBuffer();
@@ -3251,10 +3188,10 @@
 }
 
 void Layer::recordLayerHistoryBufferUpdate(const scheduler::LayerProps& layerProps, nsecs_t now) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     const nsecs_t presentTime = [&] {
         if (!mDrawingState.isAutoTimestamp) {
-            ATRACE_FORMAT_INSTANT("desiredPresentTime");
+            SFTRACE_FORMAT_INSTANT("desiredPresentTime");
             return mDrawingState.desiredPresentTime;
         }
 
@@ -3263,7 +3200,7 @@
                     mFlinger->mFrameTimeline->getTokenManager()->getPredictionsForToken(
                             mDrawingState.latchedVsyncId);
             if (prediction.has_value()) {
-                ATRACE_FORMAT_INSTANT("predictedPresentTime");
+                SFTRACE_FORMAT_INSTANT("predictedPresentTime");
                 mMaxTimeForUseVsyncId = prediction->presentTime +
                         scheduler::LayerHistory::kMaxPeriodForHistory.count();
                 return prediction->presentTime;
@@ -3299,9 +3236,9 @@
         return static_cast<nsecs_t>(0);
     }();
 
-    if (ATRACE_ENABLED() && presentTime > 0) {
+    if (SFTRACE_ENABLED() && presentTime > 0) {
         const auto presentIn = TimePoint::fromNs(presentTime) - TimePoint::now();
-        ATRACE_FORMAT_INSTANT("presentIn %s", to_string(presentIn).c_str());
+        SFTRACE_FORMAT_INSTANT("presentIn %s", to_string(presentIn).c_str());
     }
 
     mFlinger->mScheduler->recordLayerHistory(sequence, layerProps, presentTime, now,
@@ -3449,9 +3386,7 @@
     if (!remainingHandles.empty()) {
         // Notify the transaction completed threads these handles are done. These are only the
         // handles that were not added to the mDrawingState, which will be notified later.
-        std::vector<JankData> jankData;
-        transferAvailableJankData(remainingHandles, jankData);
-        mFlinger->getTransactionCallbackInvoker().addCallbackHandles(remainingHandles, jankData);
+        mFlinger->getTransactionCallbackInvoker().addCallbackHandles(remainingHandles);
     }
 
     mReleasePreviousBuffer = false;
@@ -3627,12 +3562,12 @@
         ui::Dataspace dataspace = ui::Dataspace::UNKNOWN;
         status_t err = OK;
         {
-            ATRACE_NAME("getDataspace");
+            SFTRACE_NAME("getDataspace");
             err = mapper.getDataspace(mBufferInfo.mBuffer->getBuffer()->handle, &dataspace);
         }
         if (err != OK || dataspace != mBufferInfo.mDataspace) {
             {
-                ATRACE_NAME("setDataspace");
+                SFTRACE_NAME("setDataspace");
                 err = mapper.setDataspace(mBufferInfo.mBuffer->getBuffer()->handle,
                                           static_cast<ui::Dataspace>(mBufferInfo.mDataspace));
             }
@@ -3696,7 +3631,7 @@
 }
 
 void Layer::tracePendingBufferCount(int32_t pendingBuffers) {
-    ATRACE_INT(mBlastTransactionName.c_str(), pendingBuffers);
+    SFTRACE_INT(mBlastTransactionName.c_str(), pendingBuffers);
 }
 
 /*
@@ -3774,41 +3709,41 @@
                      : layer_state_t::eAutoRefreshChanged);
 
     if ((s.what & requiredFlags) != requiredFlags) {
-        ATRACE_FORMAT_INSTANT("%s: false [missing required flags 0x%" PRIx64 "]", __func__,
-                              (s.what | requiredFlags) & ~s.what);
+        SFTRACE_FORMAT_INSTANT("%s: false [missing required flags 0x%" PRIx64 "]", __func__,
+                               (s.what | requiredFlags) & ~s.what);
         return false;
     }
 
     if (s.what & deniedFlags) {
-        ATRACE_FORMAT_INSTANT("%s: false [has denied flags 0x%" PRIx64 "]", __func__,
-                              s.what & deniedFlags);
+        SFTRACE_FORMAT_INSTANT("%s: false [has denied flags 0x%" PRIx64 "]", __func__,
+                               s.what & deniedFlags);
         return false;
     }
 
     if (s.what & layer_state_t::ePositionChanged) {
         if (mRequestedTransform.tx() != s.x || mRequestedTransform.ty() != s.y) {
-            ATRACE_FORMAT_INSTANT("%s: false [ePositionChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [ePositionChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eAlphaChanged) {
         if (mDrawingState.color.a != s.color.a) {
-            ATRACE_FORMAT_INSTANT("%s: false [eAlphaChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eAlphaChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eColorTransformChanged) {
         if (mDrawingState.colorTransform != s.colorTransform) {
-            ATRACE_FORMAT_INSTANT("%s: false [eColorTransformChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eColorTransformChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eBackgroundColorChanged) {
         if (mDrawingState.bgColorLayer || s.bgColor.a != 0) {
-            ATRACE_FORMAT_INSTANT("%s: false [eBackgroundColorChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eBackgroundColorChanged changed]", __func__);
             return false;
         }
     }
@@ -3818,92 +3753,92 @@
             mRequestedTransform.dtdy() != s.matrix.dtdy ||
             mRequestedTransform.dtdx() != s.matrix.dtdx ||
             mRequestedTransform.dsdy() != s.matrix.dsdy) {
-            ATRACE_FORMAT_INSTANT("%s: false [eMatrixChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eMatrixChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eCornerRadiusChanged) {
         if (mDrawingState.cornerRadius != s.cornerRadius) {
-            ATRACE_FORMAT_INSTANT("%s: false [eCornerRadiusChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eCornerRadiusChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eBackgroundBlurRadiusChanged) {
         if (mDrawingState.backgroundBlurRadius != static_cast<int>(s.backgroundBlurRadius)) {
-            ATRACE_FORMAT_INSTANT("%s: false [eBackgroundBlurRadiusChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eBackgroundBlurRadiusChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eBufferTransformChanged) {
         if (mDrawingState.bufferTransform != s.bufferTransform) {
-            ATRACE_FORMAT_INSTANT("%s: false [eBufferTransformChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eBufferTransformChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eTransformToDisplayInverseChanged) {
         if (mDrawingState.transformToDisplayInverse != s.transformToDisplayInverse) {
-            ATRACE_FORMAT_INSTANT("%s: false [eTransformToDisplayInverseChanged changed]",
-                                  __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eTransformToDisplayInverseChanged changed]",
+                                   __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eCropChanged) {
         if (mDrawingState.crop != s.crop) {
-            ATRACE_FORMAT_INSTANT("%s: false [eCropChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eCropChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eDataspaceChanged) {
         if (mDrawingState.dataspace != s.dataspace) {
-            ATRACE_FORMAT_INSTANT("%s: false [eDataspaceChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eDataspaceChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eHdrMetadataChanged) {
         if (mDrawingState.hdrMetadata != s.hdrMetadata) {
-            ATRACE_FORMAT_INSTANT("%s: false [eHdrMetadataChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eHdrMetadataChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eSidebandStreamChanged) {
         if (mDrawingState.sidebandStream != s.sidebandStream) {
-            ATRACE_FORMAT_INSTANT("%s: false [eSidebandStreamChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eSidebandStreamChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eColorSpaceAgnosticChanged) {
         if (mDrawingState.colorSpaceAgnostic != s.colorSpaceAgnostic) {
-            ATRACE_FORMAT_INSTANT("%s: false [eColorSpaceAgnosticChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eColorSpaceAgnosticChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eShadowRadiusChanged) {
         if (mDrawingState.shadowRadius != s.shadowRadius) {
-            ATRACE_FORMAT_INSTANT("%s: false [eShadowRadiusChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eShadowRadiusChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eFixedTransformHintChanged) {
         if (mDrawingState.fixedTransformHint != s.fixedTransformHint) {
-            ATRACE_FORMAT_INSTANT("%s: false [eFixedTransformHintChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eFixedTransformHintChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eTrustedOverlayChanged) {
         if (mDrawingState.isTrustedOverlay != (s.trustedOverlay == gui::TrustedOverlay::ENABLED)) {
-            ATRACE_FORMAT_INSTANT("%s: false [eTrustedOverlayChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eTrustedOverlayChanged changed]", __func__);
             return false;
         }
     }
@@ -3912,28 +3847,28 @@
         StretchEffect temp = s.stretchEffect;
         temp.sanitize();
         if (mDrawingState.stretchEffect != temp) {
-            ATRACE_FORMAT_INSTANT("%s: false [eStretchChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eStretchChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eBufferCropChanged) {
         if (mDrawingState.bufferCrop != s.bufferCrop) {
-            ATRACE_FORMAT_INSTANT("%s: false [eBufferCropChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eBufferCropChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eDestinationFrameChanged) {
         if (mDrawingState.destinationFrame != s.destinationFrame) {
-            ATRACE_FORMAT_INSTANT("%s: false [eDestinationFrameChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eDestinationFrameChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eDimmingEnabledChanged) {
         if (mDrawingState.dimmingEnabled != s.dimmingEnabled) {
-            ATRACE_FORMAT_INSTANT("%s: false [eDimmingEnabledChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eDimmingEnabledChanged changed]", __func__);
             return false;
         }
     }
@@ -3941,14 +3876,14 @@
     if (s.what & layer_state_t::eExtendedRangeBrightnessChanged) {
         if (mDrawingState.currentHdrSdrRatio != s.currentHdrSdrRatio ||
             mDrawingState.desiredHdrSdrRatio != s.desiredHdrSdrRatio) {
-            ATRACE_FORMAT_INSTANT("%s: false [eExtendedRangeBrightnessChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eExtendedRangeBrightnessChanged changed]", __func__);
             return false;
         }
     }
 
     if (s.what & layer_state_t::eDesiredHdrHeadroomChanged) {
         if (mDrawingState.desiredHdrSdrRatio != s.desiredHdrSdrRatio) {
-            ATRACE_FORMAT_INSTANT("%s: false [eDesiredHdrHeadroomChanged changed]", __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false [eDesiredHdrHeadroomChanged changed]", __func__);
             return false;
         }
     }
@@ -4140,8 +4075,8 @@
 }
 
 bool Layer::latchBufferImpl(bool& recomputeVisibleRegions, nsecs_t latchTime, bool bgColorOnly) {
-    ATRACE_FORMAT_INSTANT("latchBuffer %s - %" PRIu64, getDebugName(),
-                          getDrawingState().frameNumber);
+    SFTRACE_FORMAT_INSTANT("latchBuffer %s - %" PRIu64, getDebugName(),
+                           getDrawingState().frameNumber);
 
     bool refreshRequired = latchSidebandStream(recomputeVisibleRegions);
 
@@ -4152,7 +4087,7 @@
     // If the head buffer's acquire fence hasn't signaled yet, return and
     // try again later
     if (!fenceHasSignaled()) {
-        ATRACE_NAME("!fenceHasSignaled()");
+        SFTRACE_NAME("!fenceHasSignaled()");
         mFlinger->onLayerUpdate();
         return false;
     }
@@ -4437,6 +4372,11 @@
     return haveTrustedPresentationListener;
 }
 
+void Layer::setBufferReleaseChannel(
+        const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel) {
+    mBufferReleaseChannel = channel;
+}
+
 void Layer::updateLastLatchTime(nsecs_t latchTime) {
     mLastLatchTime = latchTime;
 }
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index b9fcd5c..d470738 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -550,6 +550,7 @@
     };
 
     BufferInfo mBufferInfo;
+    std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> mBufferReleaseChannel;
 
     // implements compositionengine::LayerFE
     const compositionengine::LayerFECompositionState* getCompositionState() const;
@@ -813,6 +814,8 @@
 
     bool setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds,
                                     TrustedPresentationListener const& listener);
+    void setBufferReleaseChannel(
+            const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel);
 
     // Creates a new handle each time, so we only expect
     // this to be called once.
@@ -980,7 +983,6 @@
     void preparePerFrameBufferCompositionState();
     void preparePerFrameEffectsCompositionState();
     void gatherBufferInfo();
-    void onSurfaceFrameCreated(const std::shared_ptr<frametimeline::SurfaceFrame>&);
 
     bool isClonedFromAlive() { return getClonedFrom() != nullptr; }
 
@@ -1195,11 +1197,6 @@
 
     bool hasSomethingToDraw() const { return hasEffect() || hasBufferOrSidebandStream(); }
 
-    // Fills the provided vector with the currently available JankData and removes the processed
-    // JankData from the pending list.
-    void transferAvailableJankData(const std::deque<sp<CallbackHandle>>& handles,
-                                   std::vector<JankData>& jankData);
-
     bool shouldOverrideChildrenFrameRate() const {
         return getDrawingState().frameRateSelectionStrategy ==
                 FrameRateSelectionStrategy::OverrideChildren;
@@ -1268,14 +1265,10 @@
     // time.
     std::variant<nsecs_t, sp<Fence>> mCallbackHandleAcquireTimeOrFence = -1;
 
-    std::deque<std::shared_ptr<android::frametimeline::SurfaceFrame>> mPendingJankClassifications;
-    // An upper bound on the number of SurfaceFrames in the pending classifications deque.
-    static constexpr int kPendingClassificationMaxSurfaceFrames = 50;
-
     const std::string mBlastTransactionName{"BufferTX - " + mName};
     // This integer is incremented everytime a buffer arrives at the server for this layer,
     // and decremented when a buffer is dropped or latched. When changed the integer is exported
-    // to systrace with ATRACE_INT and mBlastTransactionName. This way when debugging perf it is
+    // to systrace with SFTRACE_INT and mBlastTransactionName. This way when debugging perf it is
     // possible to see when a buffer arrived at the server, and in which frame it latched.
     //
     // You can understand the trace this way:
diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp
index c2251a8..b05f0ee 100644
--- a/services/surfaceflinger/LayerFE.cpp
+++ b/services/surfaceflinger/LayerFE.cpp
@@ -19,11 +19,10 @@
 #define LOG_TAG "SurfaceFlinger"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
+#include <common/trace.h>
 #include <gui/GLConsumer.h>
-#include <gui/TraceUtils.h>
 #include <math/vec3.h>
 #include <system/window.h>
-#include <utils/Log.h>
 
 #include "LayerFE.h"
 #include "SurfaceFlinger.h"
@@ -122,7 +121,7 @@
 
 std::optional<compositionengine::LayerFE::LayerSettings> LayerFE::prepareClientCompositionInternal(
         compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     compositionengine::LayerFE::LayerSettings layerSettings;
     layerSettings.geometry.boundaries =
             reduce(mSnapshot->geomLayerBounds, mSnapshot->transparentRegionHint);
@@ -174,6 +173,7 @@
             break;
     }
     layerSettings.stretchEffect = mSnapshot->stretchEffect;
+    layerSettings.edgeExtensionEffect = mSnapshot->edgeExtensionEffect;
     // Record the name of the layer for debugging further down the stack.
     layerSettings.name = mSnapshot->name;
 
@@ -214,7 +214,7 @@
 void LayerFE::prepareBufferStateClientComposition(
         compositionengine::LayerFE::LayerSettings& layerSettings,
         compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     if (CC_UNLIKELY(!mSnapshot->externalTexture)) {
         // If there is no buffer for the layer or we have sidebandstream where there is no
         // activeBuffer, then we need to return LayerSettings.
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index 496033b..0d2987c 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -266,6 +266,7 @@
 perfetto::protos::LayersProto LayerProtoFromSnapshotGenerator::generate(
         const frontend::LayerHierarchy& root) {
     mLayersProto.clear_layers();
+    mVisitedLayers.clear();
     std::unordered_set<uint64_t> stackIdsToSkip;
     if ((mTraceFlags & LayerTracing::TRACE_VIRTUAL_DISPLAYS) == 0) {
         for (const auto& [layerStack, displayInfo] : mDisplayInfos) {
@@ -326,6 +327,11 @@
     perfetto::protos::LayerProto* layerProto = mLayersProto.add_layers();
     const frontend::RequestedLayerState& layer = *root.getLayer();
     frontend::LayerSnapshot* snapshot = getSnapshot(path, layer);
+    if (mVisitedLayers.find(snapshot->uniqueSequence) != mVisitedLayers.end()) {
+        TransactionTraceWriter::getInstance().invoke("DuplicateLayer", /* overwrite= */ false);
+        return;
+    }
+    mVisitedLayers.insert(snapshot->uniqueSequence);
     LayerProtoHelper::writeSnapshotToProto(layerProto, layer, *snapshot, mTraceFlags);
 
     for (const auto& [child, variant] : root.mChildren) {
diff --git a/services/surfaceflinger/LayerProtoHelper.h b/services/surfaceflinger/LayerProtoHelper.h
index 20c2260..d672012 100644
--- a/services/surfaceflinger/LayerProtoHelper.h
+++ b/services/surfaceflinger/LayerProtoHelper.h
@@ -101,6 +101,8 @@
     const frontend::DisplayInfos& mDisplayInfos;
     uint32_t mTraceFlags;
     perfetto::protos::LayersProto mLayersProto;
+    std::unordered_set<uint32_t> mVisitedLayers;
+
     // winscope expects all the layers, so provide a snapshot even if it not currently drawing
     std::unordered_map<frontend::LayerHierarchy::TraversalPath, frontend::LayerSnapshot,
                        frontend::LayerHierarchy::TraversalPathHash>
diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp
index f323ce7..bfe6d2a 100644
--- a/services/surfaceflinger/LayerRenderArea.cpp
+++ b/services/surfaceflinger/LayerRenderArea.cpp
@@ -27,10 +27,9 @@
 
 LayerRenderArea::LayerRenderArea(sp<Layer> layer, frontend::LayerSnapshot layerSnapshot,
                                  const Rect& crop, ui::Size reqSize, ui::Dataspace reqDataSpace,
-                                 bool allowSecureLayers, const ui::Transform& layerTransform,
-                                 const Rect& layerBufferSize, bool hintForSeamlessTransition)
-      : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, hintForSeamlessTransition,
-                   allowSecureLayers),
+                                 const ui::Transform& layerTransform, const Rect& layerBufferSize,
+                                 ftl::Flags<RenderArea::Options> options)
+      : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, options),
         mLayer(std::move(layer)),
         mLayerSnapshot(std::move(layerSnapshot)),
         mLayerBufferSize(layerBufferSize),
@@ -42,7 +41,7 @@
 }
 
 bool LayerRenderArea::isSecure() const {
-    return mAllowSecureLayers;
+    return mOptions.test(Options::CAPTURE_SECURE_LAYERS);
 }
 
 sp<const DisplayDevice> LayerRenderArea::getDisplayDevice() const {
diff --git a/services/surfaceflinger/LayerRenderArea.h b/services/surfaceflinger/LayerRenderArea.h
index a12bfca..f72c7c7 100644
--- a/services/surfaceflinger/LayerRenderArea.h
+++ b/services/surfaceflinger/LayerRenderArea.h
@@ -33,9 +33,9 @@
 class LayerRenderArea : public RenderArea {
 public:
     LayerRenderArea(sp<Layer> layer, frontend::LayerSnapshot layerSnapshot, const Rect& crop,
-                    ui::Size reqSize, ui::Dataspace reqDataSpace, bool allowSecureLayers,
+                    ui::Size reqSize, ui::Dataspace reqDataSpace,
                     const ui::Transform& layerTransform, const Rect& layerBufferSize,
-                    bool hintForSeamlessTransition);
+                    ftl::Flags<RenderArea::Options> options);
 
     const ui::Transform& getTransform() const override;
     bool isSecure() const override;
diff --git a/services/surfaceflinger/LocklessQueue.h b/services/surfaceflinger/LocklessQueue.h
index 6b63360..4d0b261 100644
--- a/services/surfaceflinger/LocklessQueue.h
+++ b/services/surfaceflinger/LocklessQueue.h
@@ -15,11 +15,11 @@
  */
 
 #pragma once
+
 #include <atomic>
 #include <optional>
 
-template <typename T>
-// Single consumer multi producer stack. We can understand the two operations independently to see
+// Single consumer multi producer queue. We can understand the two operations independently to see
 // why they are without race condition.
 //
 // push is responsible for maintaining a linked list stored in mPush, and called from multiple
@@ -36,33 +36,27 @@
 // then store the list and pop one element.
 //
 // If we already had something in the pop list we just pop directly.
+template <typename T>
 class LocklessQueue {
 public:
-    class Entry {
-    public:
-        T mValue;
-        std::atomic<Entry*> mNext;
-        Entry(T value) : mValue(value) {}
-    };
-    std::atomic<Entry*> mPush = nullptr;
-    std::atomic<Entry*> mPop = nullptr;
     bool isEmpty() { return (mPush.load() == nullptr) && (mPop.load() == nullptr); }
 
     void push(T value) {
-        Entry* entry = new Entry(value);
+        Entry* entry = new Entry(std::move(value));
         Entry* previousHead = mPush.load(/*std::memory_order_relaxed*/);
         do {
             entry->mNext = previousHead;
         } while (!mPush.compare_exchange_weak(previousHead, entry)); /*std::memory_order_release*/
     }
+
     std::optional<T> pop() {
         Entry* popped = mPop.load(/*std::memory_order_acquire*/);
         if (popped) {
             // Single consumer so this is fine
             mPop.store(popped->mNext /* , std::memory_order_release */);
-            auto value = popped->mValue;
+            auto value = std::move(popped->mValue);
             delete popped;
-            return std::move(value);
+            return value;
         } else {
             Entry* grabbedList = mPush.exchange(nullptr /* , std::memory_order_acquire */);
             if (!grabbedList) return std::nullopt;
@@ -74,9 +68,19 @@
                 grabbedList = next;
             }
             mPop.store(popped /* , std::memory_order_release */);
-            auto value = grabbedList->mValue;
+            auto value = std::move(grabbedList->mValue);
             delete grabbedList;
-            return std::move(value);
+            return value;
         }
     }
+
+private:
+    class Entry {
+    public:
+        T mValue;
+        std::atomic<Entry*> mNext;
+        Entry(T value) : mValue(value) {}
+    };
+    std::atomic<Entry*> mPush = nullptr;
+    std::atomic<Entry*> mPop = nullptr;
 };
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 9527a99..35f12a0 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -28,10 +28,11 @@
 
 namespace android {
 
-auto RefreshRateOverlay::draw(int refreshRate, int renderFps, SkColor color,
+auto RefreshRateOverlay::draw(int refreshRate, int renderFps, bool idle, SkColor color,
                               ui::Transform::RotationFlags rotation, ftl::Flags<Features> features)
         -> Buffers {
     const size_t loopCount = features.test(Features::Spinner) ? 6 : 1;
+    const bool isSetByHwc = features.test(Features::SetByHwc);
 
     Buffers buffers;
     buffers.reserve(loopCount);
@@ -71,7 +72,11 @@
         canvas->setMatrix(canvasTransform);
 
         int left = 0;
-        drawNumber(refreshRate, left, color, *canvas);
+        if (idle && !isSetByHwc) {
+            drawDash(left, *canvas);
+        } else {
+            drawNumber(refreshRate, left, color, *canvas);
+        }
         left += 3 * (kDigitWidth + kDigitSpace);
         if (features.test(Features::Spinner)) {
             switch (i) {
@@ -104,7 +109,11 @@
         left += kDigitWidth + kDigitSpace;
 
         if (features.test(Features::RenderRate)) {
-            drawNumber(renderFps, left, color, *canvas);
+            if (idle) {
+                drawDash(left, *canvas);
+            } else {
+                drawNumber(renderFps, left, color, *canvas);
+            }
         }
         left += 3 * (kDigitWidth + kDigitSpace);
 
@@ -138,6 +147,14 @@
     SegmentDrawer::drawDigit(number % 10, left, color, canvas);
 }
 
+void RefreshRateOverlay::drawDash(int left, SkCanvas& canvas) {
+    left += kDigitWidth + kDigitSpace;
+    SegmentDrawer::drawSegment(SegmentDrawer::Segment::Middle, left, SK_ColorRED, canvas);
+
+    left += kDigitWidth + kDigitSpace;
+    SegmentDrawer::drawSegment(SegmentDrawer::Segment::Middle, left, SK_ColorRED, canvas);
+}
+
 std::unique_ptr<RefreshRateOverlay> RefreshRateOverlay::create(FpsRange range,
                                                                ftl::Flags<Features> features) {
     std::unique_ptr<RefreshRateOverlay> overlay =
@@ -171,7 +188,8 @@
     return mSurfaceControl != nullptr;
 }
 
-auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps) -> const Buffers& {
+auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps, bool idle)
+        -> const Buffers& {
     static const Buffers kNoBuffers;
     if (!mSurfaceControl) return kNoBuffers;
 
@@ -197,8 +215,8 @@
 
     createTransaction().setTransform(mSurfaceControl->get(), transform).apply();
 
-    BufferCache::const_iterator it =
-            mBufferCache.find({refreshRate.getIntValue(), renderFps.getIntValue(), transformHint});
+    BufferCache::const_iterator it = mBufferCache.find(
+            {refreshRate.getIntValue(), renderFps.getIntValue(), transformHint, idle});
     if (it == mBufferCache.end()) {
         const int maxFps = mFpsRange.max.getIntValue();
 
@@ -222,10 +240,10 @@
 
         const SkColor color = colorBase.toSkColor();
 
-        auto buffers = draw(refreshIntFps, renderIntFps, color, transformHint, mFeatures);
+        auto buffers = draw(refreshIntFps, renderIntFps, idle, color, transformHint, mFeatures);
         it = mBufferCache
-                     .try_emplace({refreshIntFps, renderIntFps, transformHint}, std::move(buffers))
-                     .first;
+                     .try_emplace({refreshIntFps, renderIntFps, transformHint, idle},
+                     std::move(buffers)).first;
     }
 
     return it->second;
@@ -257,7 +275,15 @@
 void RefreshRateOverlay::changeRefreshRate(Fps refreshRate, Fps renderFps) {
     mRefreshRate = refreshRate;
     mRenderFps = renderFps;
-    const auto buffer = getOrCreateBuffers(refreshRate, renderFps)[mFrame];
+    const auto buffer = getOrCreateBuffers(refreshRate, renderFps, mIsVrrIdle)[mFrame];
+    createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply();
+}
+
+void RefreshRateOverlay::onVrrIdle(bool idle) {
+    mIsVrrIdle = idle;
+    if (!mRefreshRate || !mRenderFps) return;
+
+    const auto buffer = getOrCreateBuffers(*mRefreshRate, *mRenderFps, mIsVrrIdle)[mFrame];
     createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply();
 }
 
@@ -265,7 +291,7 @@
     if (mFeatures.test(Features::RenderRate) && mRefreshRate &&
         FlagManager::getInstance().misc1()) {
         mRenderFps = renderFps;
-        const auto buffer = getOrCreateBuffers(*mRefreshRate, renderFps)[mFrame];
+        const auto buffer = getOrCreateBuffers(*mRefreshRate, renderFps, mIsVrrIdle)[mFrame];
         createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply();
     }
 }
@@ -273,7 +299,7 @@
 void RefreshRateOverlay::animate() {
     if (!mFeatures.test(Features::Spinner) || !mRefreshRate) return;
 
-    const auto& buffers = getOrCreateBuffers(*mRefreshRate, *mRenderFps);
+    const auto& buffers = getOrCreateBuffers(*mRefreshRate, *mRenderFps, mIsVrrIdle);
     mFrame = (mFrame + 1) % buffers.size();
     const auto buffer = buffers[mFrame];
     createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply();
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index b2896f0..d8aa048 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -57,6 +57,7 @@
     void changeRenderRate(Fps);
     void animate();
     bool isSetByHwc() const { return mFeatures.test(RefreshRateOverlay::Features::SetByHwc); }
+    void onVrrIdle(bool idle);
 
     RefreshRateOverlay(ConstructorTag, FpsRange, ftl::Flags<Features>);
 
@@ -65,11 +66,12 @@
 
     using Buffers = std::vector<sp<GraphicBuffer>>;
 
-    static Buffers draw(int refreshRate, int renderFps, SkColor, ui::Transform::RotationFlags,
-                        ftl::Flags<Features>);
+    static Buffers draw(int refreshRate, int renderFps, bool idle, SkColor,
+                        ui::Transform::RotationFlags, ftl::Flags<Features>);
     static void drawNumber(int number, int left, SkColor, SkCanvas&);
+    static void drawDash(int left, SkCanvas&);
 
-    const Buffers& getOrCreateBuffers(Fps, Fps);
+    const Buffers& getOrCreateBuffers(Fps, Fps, bool);
 
     SurfaceComposerClient::Transaction createTransaction() const;
 
@@ -77,10 +79,11 @@
         int refreshRate;
         int renderFps;
         ui::Transform::RotationFlags flags;
+        bool idle;
 
         bool operator==(Key other) const {
             return refreshRate == other.refreshRate && renderFps == other.renderFps &&
-                    flags == other.flags;
+                    flags == other.flags && idle == other.idle;
         }
     };
 
@@ -89,6 +92,7 @@
 
     std::optional<Fps> mRefreshRate;
     std::optional<Fps> mRenderFps;
+    bool mIsVrrIdle = false;
     size_t mFrame = 0;
 
     const FpsRange mFpsRange; // For color interpolation.
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 5add290..7712d38 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -26,6 +26,7 @@
 
 #include "RegionSamplingThread.h"
 
+#include <common/trace.h>
 #include <compositionengine/Display.h>
 #include <compositionengine/impl/OutputCompositionState.h>
 #include <cutils/properties.h>
@@ -34,7 +35,6 @@
 #include <gui/SyncScreenCaptureListener.h>
 #include <renderengine/impl/ExternalTexture.h>
 #include <ui/DisplayStatInfo.h>
-#include <utils/Trace.h>
 
 #include <string>
 
@@ -148,7 +148,7 @@
     std::lock_guard lock(mThreadControlMutex);
 
     if (mSampleRequestTime.has_value()) {
-        ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::waitForSamplePhase));
+        SFTRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::waitForSamplePhase));
         mSampleRequestTime.reset();
         mFlinger.scheduleSample();
     }
@@ -166,7 +166,7 @@
     if (mLastSampleTime + mTunables.mSamplingPeriod > now) {
         // content changed, but we sampled not too long ago, so we need to sample some time in the
         // future.
-        ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::idleTimerWaiting));
+        SFTRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::idleTimerWaiting));
         mSampleRequestTime = now;
         return;
     }
@@ -175,13 +175,13 @@
         // until the next vsync deadline, defer this sampling work
         // to a later frame, when hopefully there will be more time.
         if (samplingDeadline.has_value() && now + mTunables.mSamplingDuration > *samplingDeadline) {
-            ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::waitForQuietFrame));
+            SFTRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::waitForQuietFrame));
             mSampleRequestTime = mSampleRequestTime.value_or(now);
             return;
         }
     }
 
-    ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::sample));
+    SFTRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::sample));
 
     mSampleRequestTime.reset();
     mLastSampleTime = now;
@@ -247,7 +247,7 @@
 }
 
 void RegionSamplingThread::captureSample() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::lock_guard lock(mSamplingMutex);
 
     if (mDescriptors.empty()) {
@@ -277,7 +277,6 @@
     }
 
     const Rect sampledBounds = sampleRegion.bounds();
-    constexpr bool kHintForSeamlessTransition = false;
 
     std::unordered_set<sp<IRegionSamplingListener>, SpHash<IRegionSamplingListener>> listeners;
 
@@ -350,17 +349,15 @@
 
     SurfaceFlinger::RenderAreaBuilderVariant
             renderAreaBuilder(std::in_place_type<DisplayRenderAreaBuilder>, sampledBounds,
-                              sampledBounds.getSize(), ui::Dataspace::V0_SRGB,
-                              kHintForSeamlessTransition, true /* captureSecureLayers */,
-                              displayWeak);
+                              sampledBounds.getSize(), ui::Dataspace::V0_SRGB, displayWeak,
+                              RenderArea::Options::CAPTURE_SECURE_LAYERS);
 
     FenceResult fenceResult;
     if (FlagManager::getInstance().single_hop_screenshot() &&
-        FlagManager::getInstance().ce_fence_promise()) {
+        FlagManager::getInstance().ce_fence_promise() && mFlinger.mRenderEngine->isThreaded()) {
         std::vector<sp<LayerFE>> layerFEs;
-        auto displayState =
-                mFlinger.getDisplayAndLayerSnapshotsFromMainThread(renderAreaBuilder,
-                                                                   getLayerSnapshotsFn, layerFEs);
+        auto displayState = mFlinger.getSnapshotsFromMainThread(renderAreaBuilder,
+                                                                getLayerSnapshotsFn, layerFEs);
         fenceResult =
                 mFlinger.captureScreenshot(renderAreaBuilder, buffer, kRegionSampling, kGrayscale,
                                            kIsProtected, nullptr, displayState, layerFEs)
@@ -396,7 +393,7 @@
     }
 
     mCachedBuffer = buffer;
-    ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::noWorkNeeded));
+    SFTRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::noWorkNeeded));
 }
 
 // NO_THREAD_SAFETY_ANALYSIS is because std::unique_lock presently lacks thread safety annotations.
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index e8d20af..034e467 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -21,16 +21,23 @@
 class RenderArea {
 public:
     enum class CaptureFill {CLEAR, OPAQUE};
+    enum class Options {
+        // If not set, the secure layer would be blacked out or skipped
+        // when rendered to an insecure render area
+        CAPTURE_SECURE_LAYERS = 1 << 0,
 
+        // If set, the render result may be used for system animations
+        // that must preserve the exact colors of the display
+        HINT_FOR_SEAMLESS_TRANSITION = 1 << 1,
+    };
     static float getCaptureFillValue(CaptureFill captureFill);
 
     RenderArea(ui::Size reqSize, CaptureFill captureFill, ui::Dataspace reqDataSpace,
-               bool hintForSeamlessTransition, bool allowSecureLayers = false)
-          : mAllowSecureLayers(allowSecureLayers),
+               ftl::Flags<Options> options)
+          : mOptions(options),
             mReqSize(reqSize),
             mReqDataSpace(reqDataSpace),
-            mCaptureFill(captureFill),
-            mHintForSeamlessTransition(hintForSeamlessTransition) {}
+            mCaptureFill(captureFill) {}
 
     static std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()> fromTraverseLayersLambda(
             std::function<void(const LayerVector::Visitor&)> traverseLayers) {
@@ -90,16 +97,17 @@
 
     // Returns whether the render result may be used for system animations that
     // must preserve the exact colors of the display.
-    bool getHintForSeamlessTransition() const { return mHintForSeamlessTransition; }
+    bool getHintForSeamlessTransition() const {
+        return mOptions.test(Options::HINT_FOR_SEAMLESS_TRANSITION);
+    }
 
 protected:
-    const bool mAllowSecureLayers;
+    ftl::Flags<Options> mOptions;
 
 private:
     const ui::Size mReqSize;
     const ui::Dataspace mReqDataSpace;
     const CaptureFill mCaptureFill;
-    const bool mHintForSeamlessTransition;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/RenderAreaBuilder.h b/services/surfaceflinger/RenderAreaBuilder.h
index a25c6e0..599fa7e 100644
--- a/services/surfaceflinger/RenderAreaBuilder.h
+++ b/services/surfaceflinger/RenderAreaBuilder.h
@@ -36,50 +36,34 @@
     // Composition data space of the render area
     ui::Dataspace reqDataSpace;
 
-    // If true, the secure layer would be blacked out or skipped
-    // when rendered to an insecure render area
-    bool allowSecureLayers;
-
-    // If true, the render result may be used for system animations
-    // that must preserve the exact colors of the display
-    bool hintForSeamlessTransition;
-
+    ftl::Flags<RenderArea::Options> options;
     virtual std::unique_ptr<RenderArea> build() const = 0;
 
     RenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace,
-                      bool allowSecureLayers, bool hintForSeamlessTransition)
-          : crop(crop),
-            reqSize(reqSize),
-            reqDataSpace(reqDataSpace),
-            allowSecureLayers(allowSecureLayers),
-            hintForSeamlessTransition(hintForSeamlessTransition) {}
+                      ftl::Flags<RenderArea::Options> options)
+          : crop(crop), reqSize(reqSize), reqDataSpace(reqDataSpace), options(options) {}
 
     virtual ~RenderAreaBuilder() = default;
 };
 
 struct DisplayRenderAreaBuilder : RenderAreaBuilder {
     DisplayRenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace,
-                             bool allowSecureLayers, bool hintForSeamlessTransition,
-                             wp<const DisplayDevice> displayWeak)
-          : RenderAreaBuilder(crop, reqSize, reqDataSpace, allowSecureLayers,
-                              hintForSeamlessTransition),
-            displayWeak(displayWeak) {}
+                             wp<const DisplayDevice> displayWeak,
+                             ftl::Flags<RenderArea::Options> options)
+          : RenderAreaBuilder(crop, reqSize, reqDataSpace, options), displayWeak(displayWeak) {}
 
     // Display that render area will be on
     wp<const DisplayDevice> displayWeak;
 
     std::unique_ptr<RenderArea> build() const override {
-        return DisplayRenderArea::create(displayWeak, crop, reqSize, reqDataSpace,
-                                         hintForSeamlessTransition, allowSecureLayers);
+        return DisplayRenderArea::create(displayWeak, crop, reqSize, reqDataSpace, options);
     }
 };
 
 struct LayerRenderAreaBuilder : RenderAreaBuilder {
-    LayerRenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace,
-                           bool allowSecureLayers, bool hintForSeamlessTransition, sp<Layer> layer,
-                           bool childrenOnly)
-          : RenderAreaBuilder(crop, reqSize, reqDataSpace, allowSecureLayers,
-                              hintForSeamlessTransition),
+    LayerRenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace, sp<Layer> layer,
+                           bool childrenOnly, ftl::Flags<RenderArea::Options> options)
+          : RenderAreaBuilder(crop, reqSize, reqDataSpace, options),
             layer(layer),
             childrenOnly(childrenOnly) {}
 
@@ -110,8 +94,8 @@
 
     std::unique_ptr<RenderArea> build() const override {
         return std::make_unique<LayerRenderArea>(layer, std::move(layerSnapshot), crop, reqSize,
-                                                 reqDataSpace, allowSecureLayers, layerTransform,
-                                                 layerBufferSize, hintForSeamlessTransition);
+                                                 reqDataSpace, layerTransform, layerBufferSize,
+                                                 options);
     }
 };
 
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 6b65449..d31fcea 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -33,7 +33,7 @@
 #include <android-base/stringprintf.h>
 
 #include <binder/IPCThreadState.h>
-
+#include <common/trace.h>
 #include <cutils/compiler.h>
 #include <cutils/sched_policy.h>
 
@@ -41,7 +41,6 @@
 #include <gui/SchedulingPolicy.h>
 
 #include <utils/Errors.h>
-#include <utils/Trace.h>
 
 #include <common/FlagManager.h>
 #include <scheduler/VsyncConfig.h>
@@ -226,14 +225,14 @@
 }
 
 binder::Status EventThreadConnection::requestNextVsync() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     mEventThread->requestNextVsync(sp<EventThreadConnection>::fromExisting(this));
     return binder::Status::ok();
 }
 
 binder::Status EventThreadConnection::getLatestVsyncEventData(
         ParcelableVsyncEventData* outVsyncEventData) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     outVsyncEventData->vsync =
             mEventThread->getLatestVsyncEventData(sp<EventThreadConnection>::fromExisting(this),
                                                   systemTime());
diff --git a/services/surfaceflinger/Scheduler/ISchedulerCallback.h b/services/surfaceflinger/Scheduler/ISchedulerCallback.h
index 43cdb5e..f430526 100644
--- a/services/surfaceflinger/Scheduler/ISchedulerCallback.h
+++ b/services/surfaceflinger/Scheduler/ISchedulerCallback.h
@@ -33,6 +33,7 @@
     virtual void onExpectedPresentTimePosted(TimePoint, ftl::NonNull<DisplayModePtr>,
                                              Fps renderRate) = 0;
     virtual void onCommitNotComposited(PhysicalDisplayId pacesetterDisplayId) = 0;
+    virtual void vrrDisplayIdle(bool idle) = 0;
 
 protected:
     ~ISchedulerCallback() = default;
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index a819b79..4fd4c0e 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -21,8 +21,8 @@
 #include "LayerHistory.h"
 
 #include <android-base/stringprintf.h>
+#include <common/trace.h>
 #include <cutils/properties.h>
-#include <gui/TraceUtils.h>
 #include <utils/Log.h>
 #include <utils/Timers.h>
 
@@ -72,7 +72,7 @@
 
 void trace(const LayerInfo& info, LayerHistory::LayerVoteType type, int fps) {
     const auto traceType = [&](LayerHistory::LayerVoteType checkedType, int value) {
-        ATRACE_INT(info.getTraceTag(checkedType), type == checkedType ? value : 0);
+        SFTRACE_INT(info.getTraceTag(checkedType), type == checkedType ? value : 0);
     };
 
     traceType(LayerHistory::LayerVoteType::NoVote, 1);
@@ -190,7 +190,7 @@
 }
 
 auto LayerHistory::summarize(const RefreshRateSelector& selector, nsecs_t now) -> Summary {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     Summary summary;
 
     std::lock_guard lock(mLock);
@@ -204,7 +204,7 @@
         ALOGV("%s has priority: %d %s focused", info->getName().c_str(), frameRateSelectionPriority,
               layerFocused ? "" : "not");
 
-        ATRACE_FORMAT("%s", info->getName().c_str());
+        SFTRACE_FORMAT("%s", info->getName().c_str());
         const auto votes = info->getRefreshRateVote(selector, now);
         for (LayerInfo::LayerVote vote : votes) {
             if (vote.isNoVote()) {
@@ -222,8 +222,8 @@
             const std::string categoryString = vote.category == FrameRateCategory::Default
                     ? ""
                     : base::StringPrintf("category=%s", ftl::enum_string(vote.category).c_str());
-            ATRACE_FORMAT_INSTANT("%s %s %s (%.2f)", ftl::enum_string(vote.type).c_str(),
-                                  to_string(vote.fps).c_str(), categoryString.c_str(), weight);
+            SFTRACE_FORMAT_INSTANT("%s %s %s (%.2f)", ftl::enum_string(vote.type).c_str(),
+                                   to_string(vote.fps).c_str(), categoryString.c_str(), weight);
             summary.push_back({info->getName(), info->getOwnerUid(), vote.type, vote.fps,
                                vote.seamlessness, vote.category, vote.categorySmoothSwitchOnly,
                                weight, layerFocused});
@@ -238,7 +238,7 @@
 }
 
 void LayerHistory::partitionLayers(nsecs_t now, bool isVrrDevice) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     const nsecs_t threshold = getActiveLayerThreshold(now);
 
     // iterate over inactive map
@@ -310,7 +310,7 @@
 
                 if (gameModeFrameRateOverride.isValid()) {
                     info->setLayerVote({gameFrameRateOverrideVoteType, gameModeFrameRateOverride});
-                    ATRACE_FORMAT_INSTANT("GameModeFrameRateOverride");
+                    SFTRACE_FORMAT_INSTANT("GameModeFrameRateOverride");
                     if (CC_UNLIKELY(mTraceEnabled)) {
                         trace(*info, gameFrameRateOverrideVoteType,
                               gameModeFrameRateOverride.getIntValue());
@@ -326,19 +326,19 @@
                 } else if (gameDefaultFrameRateOverride.isValid()) {
                     info->setLayerVote(
                             {gameFrameRateOverrideVoteType, gameDefaultFrameRateOverride});
-                    ATRACE_FORMAT_INSTANT("GameDefaultFrameRateOverride");
+                    SFTRACE_FORMAT_INSTANT("GameDefaultFrameRateOverride");
                     if (CC_UNLIKELY(mTraceEnabled)) {
                         trace(*info, gameFrameRateOverrideVoteType,
                               gameDefaultFrameRateOverride.getIntValue());
                     }
                 } else {
                     if (frameRate.isValid() && !frameRate.isVoteValidForMrr(isVrrDevice)) {
-                        ATRACE_FORMAT_INSTANT("Reset layer to ignore explicit vote on MRR %s: %s "
-                                              "%s %s",
-                                              info->getName().c_str(),
-                                              ftl::enum_string(frameRate.vote.type).c_str(),
-                                              to_string(frameRate.vote.rate).c_str(),
-                                              ftl::enum_string(frameRate.category).c_str());
+                        SFTRACE_FORMAT_INSTANT("Reset layer to ignore explicit vote on MRR %s: %s "
+                                               "%s %s",
+                                               info->getName().c_str(),
+                                               ftl::enum_string(frameRate.vote.type).c_str(),
+                                               to_string(frameRate.vote.rate).c_str(),
+                                               ftl::enum_string(frameRate.category).c_str());
                     }
                     info->resetLayerVote();
                 }
@@ -349,12 +349,12 @@
                                         frameRate.vote.seamlessness, frameRate.category});
                 } else {
                     if (!frameRate.isVoteValidForMrr(isVrrDevice)) {
-                        ATRACE_FORMAT_INSTANT("Reset layer to ignore explicit vote on MRR %s: %s "
-                                              "%s %s",
-                                              info->getName().c_str(),
-                                              ftl::enum_string(frameRate.vote.type).c_str(),
-                                              to_string(frameRate.vote.rate).c_str(),
-                                              ftl::enum_string(frameRate.category).c_str());
+                        SFTRACE_FORMAT_INSTANT("Reset layer to ignore explicit vote on MRR %s: %s "
+                                               "%s %s",
+                                               info->getName().c_str(),
+                                               ftl::enum_string(frameRate.vote.type).c_str(),
+                                               to_string(frameRate.vote.rate).c_str(),
+                                               ftl::enum_string(frameRate.category).c_str());
                     }
                     info->resetLayerVote();
                 }
@@ -421,7 +421,7 @@
 bool LayerHistory::isSmallDirtyArea(uint32_t dirtyArea, float threshold) const {
     const float ratio = (float)dirtyArea / mDisplayArea;
     const bool isSmallDirty = ratio <= threshold;
-    ATRACE_FORMAT_INSTANT("small dirty=%s, ratio=%.3f", isSmallDirty ? "true" : "false", ratio);
+    SFTRACE_FORMAT_INSTANT("small dirty=%s, ratio=%.3f", isSmallDirty ? "true" : "false", ratio);
     return isSmallDirty;
 }
 
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp
index 632f42a..a1a60e3 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp
@@ -27,10 +27,10 @@
 #include <utility>
 
 #include <android/native_window.h>
+#include <common/trace.h>
 #include <cutils/compiler.h>
 #include <cutils/trace.h>
 #include <ftl/enum.h>
-#include <gui/TraceUtils.h>
 #include <system/window.h>
 
 #undef LOG_TAG
@@ -259,7 +259,7 @@
     }
 
     if (smallDirtyCount > 0) {
-        ATRACE_FORMAT_INSTANT("small dirty = %" PRIu32, smallDirtyCount);
+        SFTRACE_FORMAT_INSTANT("small dirty = %" PRIu32, smallDirtyCount);
     }
 
     if (numDeltas == 0) {
@@ -272,7 +272,7 @@
 
 std::optional<Fps> LayerInfo::calculateRefreshRateIfPossible(const RefreshRateSelector& selector,
                                                              nsecs_t now) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     static constexpr float MARGIN = 1.0f; // 1Hz
     if (!hasEnoughDataForHeuristic()) {
         ALOGV("Not enough data");
@@ -307,7 +307,7 @@
 
 LayerInfo::RefreshRateVotes LayerInfo::getRefreshRateVote(const RefreshRateSelector& selector,
                                                           nsecs_t now) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     LayerInfo::RefreshRateVotes votes;
 
     if (mLayerVote.type != LayerHistory::LayerVoteType::Heuristic) {
@@ -315,8 +315,8 @@
             const auto voteType = mLayerVote.type == LayerHistory::LayerVoteType::NoVote
                     ? LayerHistory::LayerVoteType::NoVote
                     : LayerHistory::LayerVoteType::ExplicitCategory;
-            ATRACE_FORMAT_INSTANT("Vote %s (category=%s)", ftl::enum_string(voteType).c_str(),
-                                  ftl::enum_string(mLayerVote.category).c_str());
+            SFTRACE_FORMAT_INSTANT("Vote %s (category=%s)", ftl::enum_string(voteType).c_str(),
+                                   ftl::enum_string(mLayerVote.category).c_str());
             ALOGV("%s voted %s with category: %s", mName.c_str(),
                   ftl::enum_string(voteType).c_str(),
                   ftl::enum_string(mLayerVote.category).c_str());
@@ -326,7 +326,7 @@
 
         if (mLayerVote.fps.isValid() ||
             mLayerVote.type != LayerHistory::LayerVoteType::ExplicitDefault) {
-            ATRACE_FORMAT_INSTANT("Vote %s", ftl::enum_string(mLayerVote.type).c_str());
+            SFTRACE_FORMAT_INSTANT("Vote %s", ftl::enum_string(mLayerVote.type).c_str());
             ALOGV("%s voted %d", mName.c_str(), static_cast<int>(mLayerVote.type));
             votes.push_back({mLayerVote.type, mLayerVote.fps, mLayerVote.seamlessness,
                              FrameRateCategory::Default, mLayerVote.categorySmoothSwitchOnly});
@@ -336,7 +336,7 @@
     }
 
     if (isAnimating(now)) {
-        ATRACE_FORMAT_INSTANT("animating");
+        SFTRACE_FORMAT_INSTANT("animating");
         ALOGV("%s is animating", mName.c_str());
         mLastRefreshRate.animating = true;
         votes.push_back({LayerHistory::LayerVoteType::Max, Fps()});
@@ -345,7 +345,7 @@
 
     // Vote for max refresh rate whenever we're front-buffered.
     if (FlagManager::getInstance().vrr_config() && isFrontBuffered()) {
-        ATRACE_FORMAT_INSTANT("front buffered");
+        SFTRACE_FORMAT_INSTANT("front buffered");
         ALOGV("%s is front-buffered", mName.c_str());
         votes.push_back({LayerHistory::LayerVoteType::Max, Fps()});
         return votes;
@@ -354,7 +354,7 @@
     const LayerInfo::Frequent frequent = isFrequent(now);
     mIsFrequencyConclusive = frequent.isConclusive;
     if (!frequent.isFrequent) {
-        ATRACE_FORMAT_INSTANT("infrequent");
+        SFTRACE_FORMAT_INSTANT("infrequent");
         ALOGV("%s is infrequent", mName.c_str());
         mLastRefreshRate.infrequent = true;
         mLastSmallDirtyCount = 0;
@@ -365,14 +365,14 @@
     }
 
     if (frequent.clearHistory) {
-        ATRACE_FORMAT_INSTANT("frequent.clearHistory");
+        SFTRACE_FORMAT_INSTANT("frequent.clearHistory");
         ALOGV("%s frequent.clearHistory", mName.c_str());
         clearHistory(now);
     }
 
     // Return no vote if the recent frames are small dirty.
     if (frequent.isSmallDirty && !mLastRefreshRate.reported.isValid()) {
-        ATRACE_FORMAT_INSTANT("NoVote (small dirty)");
+        SFTRACE_FORMAT_INSTANT("NoVote (small dirty)");
         ALOGV("%s is small dirty", mName.c_str());
         votes.push_back({LayerHistory::LayerVoteType::NoVote, Fps()});
         return votes;
@@ -380,13 +380,13 @@
 
     auto refreshRate = calculateRefreshRateIfPossible(selector, now);
     if (refreshRate.has_value()) {
-        ATRACE_FORMAT_INSTANT("calculated (%s)", to_string(*refreshRate).c_str());
+        SFTRACE_FORMAT_INSTANT("calculated (%s)", to_string(*refreshRate).c_str());
         ALOGV("%s calculated refresh rate: %s", mName.c_str(), to_string(*refreshRate).c_str());
         votes.push_back({LayerHistory::LayerVoteType::Heuristic, refreshRate.value()});
         return votes;
     }
 
-    ATRACE_FORMAT_INSTANT("Max (can't resolve refresh rate)");
+    SFTRACE_FORMAT_INSTANT("Max (can't resolve refresh rate)");
     ALOGV("%s Max (can't resolve refresh rate)", mName.c_str());
     votes.push_back({LayerHistory::LayerVoteType::Max, Fps()});
     return votes;
@@ -452,7 +452,7 @@
             mHeuristicTraceTagData = makeHeuristicTraceTagData();
         }
 
-        ATRACE_INT(mHeuristicTraceTagData->average.c_str(), refreshRate.getIntValue());
+        SFTRACE_INT(mHeuristicTraceTagData->average.c_str(), refreshRate.getIntValue());
     }
 
     return selectRefreshRate(selector);
@@ -486,9 +486,9 @@
             mHeuristicTraceTagData = makeHeuristicTraceTagData();
         }
 
-        ATRACE_INT(mHeuristicTraceTagData->max.c_str(), max->refreshRate.getIntValue());
-        ATRACE_INT(mHeuristicTraceTagData->min.c_str(), min->refreshRate.getIntValue());
-        ATRACE_INT(mHeuristicTraceTagData->consistent.c_str(), consistent);
+        SFTRACE_INT(mHeuristicTraceTagData->max.c_str(), max->refreshRate.getIntValue());
+        SFTRACE_INT(mHeuristicTraceTagData->min.c_str(), min->refreshRate.getIntValue());
+        SFTRACE_INT(mHeuristicTraceTagData->consistent.c_str(), consistent);
     }
 
     return consistent ? maxClosestRate : Fps();
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index ff88d71..6a67ac5 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -57,7 +57,7 @@
         mHandler(std::move(handler)) {}
 
 void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     // Trace VSYNC-sf
     mVsync.value = (mVsync.value + 1) % 2;
 
@@ -136,7 +136,7 @@
 }
 
 void MessageQueue::setDuration(std::chrono::nanoseconds workDuration) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::lock_guard lock(mVsync.mutex);
     mVsync.workDuration = workDuration;
     mVsync.scheduledFrameTimeOpt =
@@ -189,7 +189,7 @@
 }
 
 void MessageQueue::scheduleFrame() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::lock_guard lock(mVsync.mutex);
     mVsync.scheduledFrameTimeOpt =
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index 2c66492..9f6eab2 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -28,13 +28,12 @@
 
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
+#include <common/trace.h>
 #include <ftl/enum.h>
 #include <ftl/fake_guard.h>
 #include <ftl/match.h>
 #include <ftl/unit.h>
-#include <gui/TraceUtils.h>
 #include <scheduler/FrameRateMode.h>
-#include <utils/Trace.h>
 
 #include "RefreshRateSelector.h"
 
@@ -494,7 +493,7 @@
                                                     GlobalSignals signals, Fps pacesetterFps) const
         -> RankedFrameRates {
     using namespace fps_approx_ops;
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("%s: %zu layers", __func__, layers.size());
 
     const auto& activeMode = *getActiveModeLocked().modePtr;
@@ -508,8 +507,8 @@
                                             });
 
         if (!ranking.empty()) {
-            ATRACE_FORMAT_INSTANT("%s (Follower display)",
-                                  to_string(ranking.front().frameRateMode.fps).c_str());
+            SFTRACE_FORMAT_INSTANT("%s (Follower display)",
+                                   to_string(ranking.front().frameRateMode.fps).c_str());
 
             return {ranking, kNoSignals, pacesetterFps};
         }
@@ -521,8 +520,8 @@
     if (signals.powerOnImminent) {
         ALOGV("Power On Imminent");
         const auto ranking = rankFrameRates(activeMode.getGroup(), RefreshRateOrder::Descending);
-        ATRACE_FORMAT_INSTANT("%s (Power On Imminent)",
-                              to_string(ranking.front().frameRateMode.fps).c_str());
+        SFTRACE_FORMAT_INSTANT("%s (Power On Imminent)",
+                               to_string(ranking.front().frameRateMode.fps).c_str());
         return {ranking, GlobalSignals{.powerOnImminent = true}};
     }
 
@@ -608,8 +607,8 @@
     if (signals.touch && !hasExplicitVoteLayers) {
         ALOGV("Touch Boost");
         const auto ranking = rankFrameRates(anchorGroup, RefreshRateOrder::Descending);
-        ATRACE_FORMAT_INSTANT("%s (Touch Boost)",
-                              to_string(ranking.front().frameRateMode.fps).c_str());
+        SFTRACE_FORMAT_INSTANT("%s (Touch Boost)",
+                               to_string(ranking.front().frameRateMode.fps).c_str());
         return {ranking, GlobalSignals{.touch = true}};
     }
 
@@ -620,26 +619,27 @@
         !(policy->primaryRangeIsSingleRate() && hasExplicitVoteLayers)) {
         ALOGV("Idle");
         const auto ranking = rankFrameRates(activeMode.getGroup(), RefreshRateOrder::Ascending);
-        ATRACE_FORMAT_INSTANT("%s (Idle)", to_string(ranking.front().frameRateMode.fps).c_str());
+        SFTRACE_FORMAT_INSTANT("%s (Idle)", to_string(ranking.front().frameRateMode.fps).c_str());
         return {ranking, GlobalSignals{.idle = true}};
     }
 
     if (layers.empty() || noVoteLayers == layers.size()) {
         ALOGV("No layers with votes");
         const auto ranking = rankFrameRates(anchorGroup, RefreshRateOrder::Descending);
-        ATRACE_FORMAT_INSTANT("%s (No layers with votes)",
-                              to_string(ranking.front().frameRateMode.fps).c_str());
+        SFTRACE_FORMAT_INSTANT("%s (No layers with votes)",
+                               to_string(ranking.front().frameRateMode.fps).c_str());
         return {ranking, kNoSignals};
     }
 
     // If all layers are category NoPreference, use the current config.
     if (noPreferenceLayers + noVoteLayers == layers.size()) {
         ALOGV("All layers NoPreference");
-        const auto ascendingWithPreferred =
-                rankFrameRates(anchorGroup, RefreshRateOrder::Ascending, activeMode.getId());
-        ATRACE_FORMAT_INSTANT("%s (All layers NoPreference)",
-                              to_string(ascendingWithPreferred.front().frameRateMode.fps).c_str());
-        return {ascendingWithPreferred, kNoSignals};
+        constexpr float kScore = std::numeric_limits<float>::max();
+        FrameRateRanking currentMode;
+        currentMode.emplace_back(ScoredFrameRate{getActiveModeLocked(), kScore});
+        SFTRACE_FORMAT_INSTANT("%s (All layers NoPreference)",
+                              to_string(currentMode.front().frameRateMode.fps).c_str());
+        return {currentMode, kNoSignals};
     }
 
     const bool smoothSwitchOnly = categorySmoothSwitchOnlyLayers > 0;
@@ -653,8 +653,8 @@
                                                 return !smoothSwitchOnly ||
                                                         mode.modePtr->getId() == activeModeId;
                                             });
-        ATRACE_FORMAT_INSTANT("%s (All layers Min)",
-                              to_string(ranking.front().frameRateMode.fps).c_str());
+        SFTRACE_FORMAT_INSTANT("%s (All layers Min)",
+                               to_string(ranking.front().frameRateMode.fps).c_str());
         return {ranking, kNoSignals};
     }
 
@@ -847,13 +847,13 @@
         if (noLayerScore) {
             ALOGV("Layers not scored");
             const auto descending = rankFrameRates(anchorGroup, RefreshRateOrder::Descending);
-            ATRACE_FORMAT_INSTANT("%s (Layers not scored)",
-                                  to_string(descending.front().frameRateMode.fps).c_str());
+            SFTRACE_FORMAT_INSTANT("%s (Layers not scored)",
+                                   to_string(descending.front().frameRateMode.fps).c_str());
             return {descending, kNoSignals};
         } else {
             ALOGV("primaryRangeIsSingleRate");
-            ATRACE_FORMAT_INSTANT("%s (primaryRangeIsSingleRate)",
-                                  to_string(ranking.front().frameRateMode.fps).c_str());
+            SFTRACE_FORMAT_INSTANT("%s (primaryRangeIsSingleRate)",
+                                   to_string(ranking.front().frameRateMode.fps).c_str());
             return {ranking, kNoSignals};
         }
     }
@@ -889,8 +889,8 @@
 
         if (scores.front().frameRateMode.fps < touchRefreshRates.front().frameRateMode.fps) {
             ALOGV("Touch Boost");
-            ATRACE_FORMAT_INSTANT("%s (Touch Boost [late])",
-                                  to_string(touchRefreshRates.front().frameRateMode.fps).c_str());
+            SFTRACE_FORMAT_INSTANT("%s (Touch Boost [late])",
+                                   to_string(touchRefreshRates.front().frameRateMode.fps).c_str());
             return {touchRefreshRates, GlobalSignals{.touch = true}};
         }
     }
@@ -901,13 +901,13 @@
         ALOGV("preferredDisplayMode");
         const auto ascendingWithPreferred =
                 rankFrameRates(anchorGroup, RefreshRateOrder::Ascending, activeMode.getId());
-        ATRACE_FORMAT_INSTANT("%s (preferredDisplayMode)",
-                              to_string(ascendingWithPreferred.front().frameRateMode.fps).c_str());
+        SFTRACE_FORMAT_INSTANT("%s (preferredDisplayMode)",
+                               to_string(ascendingWithPreferred.front().frameRateMode.fps).c_str());
         return {ascendingWithPreferred, kNoSignals};
     }
 
     ALOGV("%s (scored)", to_string(ranking.front().frameRateMode.fps).c_str());
-    ATRACE_FORMAT_INSTANT("%s (scored)", to_string(ranking.front().frameRateMode.fps).c_str());
+    SFTRACE_FORMAT_INSTANT("%s (scored)", to_string(ranking.front().frameRateMode.fps).c_str());
     return {ranking, kNoSignals};
 }
 
@@ -949,7 +949,7 @@
                                                 Fps displayRefreshRate,
                                                 GlobalSignals globalSignals) const
         -> UidToFrameRateOverride {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     if (mConfig.enableFrameRateOverride == Config::FrameRateOverride::Disabled) {
         return {};
     }
@@ -1064,8 +1064,13 @@
                                       return lhs < rhs && !ScoredFrameRate::scoresEqual(lhs, rhs);
                                   });
         ALOGV("%s: overriding to %s for uid=%d", __func__, to_string(overrideFps).c_str(), uid);
-        ATRACE_FORMAT_INSTANT("%s: overriding to %s for uid=%d", __func__,
-                              to_string(overrideFps).c_str(), uid);
+        SFTRACE_FORMAT_INSTANT("%s: overriding to %s for uid=%d", __func__,
+                               to_string(overrideFps).c_str(), uid);
+        if (SFTRACE_ENABLED() && FlagManager::getInstance().trace_frame_rate_override()) {
+            std::stringstream ss;
+            ss << "FrameRateOverride " << uid;
+            SFTRACE_INT(ss.str().c_str(), overrideFps.getIntValue());
+        }
         frameRateOverrides.emplace(uid, overrideFps);
     }
 
@@ -1496,7 +1501,7 @@
             return str;
         };
         ALOGV("%s render rates: %s, isVrrDevice? %d", rangeName, stringifyModes().c_str(),
-              mIsVrrDevice);
+              mIsVrrDevice.load());
 
         return frameRateModes;
     };
@@ -1506,7 +1511,6 @@
 }
 
 bool RefreshRateSelector::isVrrDevice() const {
-    std::lock_guard lock(mLock);
     return mIsVrrDevice;
 }
 
@@ -1636,7 +1640,7 @@
         case FrameRateCategory::Normal:
             return FpsRange{60_Hz, 120_Hz};
         case FrameRateCategory::Low:
-            return FpsRange{30_Hz, 120_Hz};
+            return FpsRange{48_Hz, 120_Hz};
         case FrameRateCategory::HighHint:
         case FrameRateCategory::NoPreference:
         case FrameRateCategory::Default:
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.h b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
index 4f491d9..6f9c146 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
@@ -383,6 +383,7 @@
 
         Callbacks platform;
         Callbacks kernel;
+        Callbacks vrr;
     };
 
     void setIdleTimerCallbacks(IdleTimerCallbacks callbacks) EXCLUDES(mIdleTimerCallbacksMutex) {
@@ -501,6 +502,9 @@
     std::optional<IdleTimerCallbacks::Callbacks> getIdleTimerCallbacks() const
             REQUIRES(mIdleTimerCallbacksMutex) {
         if (!mIdleTimerCallbacks) return {};
+
+        if (mIsVrrDevice) return mIdleTimerCallbacks->vrr;
+
         return mConfig.kernelIdleTimerController.has_value() ? mIdleTimerCallbacks->kernel
                                                              : mIdleTimerCallbacks->platform;
     }
@@ -536,7 +540,7 @@
     std::vector<FrameRateMode> mAppRequestFrameRates GUARDED_BY(mLock);
 
     // Caches whether the device is VRR-compatible based on the active display mode.
-    bool mIsVrrDevice GUARDED_BY(mLock) = false;
+    std::atomic_bool mIsVrrDevice = false;
 
     Policy mDisplayManagerPolicy GUARDED_BY(mLock);
     std::optional<Policy> mOverridePolicy GUARDED_BY(mLock);
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 60681a2..0cf7bdc 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -24,12 +24,12 @@
 #include <android-base/stringprintf.h>
 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
+#include <common/trace.h>
 #include <configstore/Utils.h>
 #include <ftl/concat.h>
 #include <ftl/enum.h>
 #include <ftl/fake_guard.h>
 #include <ftl/small_map.h>
-#include <gui/TraceUtils.h>
 #include <gui/WindowInfo.h>
 #include <system/window.h>
 #include <ui/DisplayMap.h>
@@ -82,7 +82,7 @@
     mTouchTimer.reset();
 
     // Stop idle timer and clear callbacks, as the RefreshRateSelector may outlive the Scheduler.
-    demotePacesetterDisplay();
+    demotePacesetterDisplay({.toggleIdleTimer = true});
 }
 
 void Scheduler::initVsync(frametimeline::TokenManager& tokenManager,
@@ -117,35 +117,45 @@
     }
 }
 
-void Scheduler::setPacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt) {
-    demotePacesetterDisplay();
+void Scheduler::setPacesetterDisplay(PhysicalDisplayId pacesetterId) {
+    constexpr PromotionParams kPromotionParams = {.toggleIdleTimer = true};
 
-    promotePacesetterDisplay(pacesetterIdOpt);
+    demotePacesetterDisplay(kPromotionParams);
+    promotePacesetterDisplay(pacesetterId, kPromotionParams);
 }
 
-void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr) {
+void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
+                                PhysicalDisplayId activeDisplayId) {
     auto schedulePtr =
             std::make_shared<VsyncSchedule>(selectorPtr->getActiveMode().modePtr, mFeatures,
                                             [this](PhysicalDisplayId id, bool enable) {
                                                 onHardwareVsyncRequest(id, enable);
                                             });
 
-    registerDisplayInternal(displayId, std::move(selectorPtr), std::move(schedulePtr));
+    registerDisplayInternal(displayId, std::move(selectorPtr), std::move(schedulePtr),
+                            activeDisplayId);
 }
 
 void Scheduler::registerDisplayInternal(PhysicalDisplayId displayId,
                                         RefreshRateSelectorPtr selectorPtr,
-                                        VsyncSchedulePtr schedulePtr) {
-    demotePacesetterDisplay();
+                                        VsyncSchedulePtr schedulePtr,
+                                        PhysicalDisplayId activeDisplayId) {
+    const bool isPrimary = (ftl::FakeGuard(mDisplayLock), !mPacesetterDisplayId);
 
-    auto [pacesetterVsyncSchedule, isNew] = [&]() FTL_FAKE_GUARD(kMainThreadContext) {
+    // Start the idle timer for the first registered (i.e. primary) display.
+    const PromotionParams promotionParams = {.toggleIdleTimer = isPrimary};
+
+    demotePacesetterDisplay(promotionParams);
+
+    auto [pacesetterVsyncSchedule, isNew] = [&]() REQUIRES(kMainThreadContext) {
         std::scoped_lock lock(mDisplayLock);
         const bool isNew = mDisplays
                                    .emplace_or_replace(displayId, displayId, std::move(selectorPtr),
                                                        std::move(schedulePtr), mFeatures)
                                    .second;
 
-        return std::make_pair(promotePacesetterDisplayLocked(), isNew);
+        return std::make_pair(promotePacesetterDisplayLocked(activeDisplayId, promotionParams),
+                              isNew);
     }();
 
     applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
@@ -158,10 +168,13 @@
     dispatchHotplug(displayId, Hotplug::Connected);
 }
 
-void Scheduler::unregisterDisplay(PhysicalDisplayId displayId) {
+void Scheduler::unregisterDisplay(PhysicalDisplayId displayId, PhysicalDisplayId activeDisplayId) {
+    LOG_ALWAYS_FATAL_IF(displayId == activeDisplayId, "Cannot unregister the active display!");
+
     dispatchHotplug(displayId, Hotplug::Disconnected);
 
-    demotePacesetterDisplay();
+    constexpr PromotionParams kPromotionParams = {.toggleIdleTimer = false};
+    demotePacesetterDisplay(kPromotionParams);
 
     std::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule;
     {
@@ -173,7 +186,7 @@
         // headless virtual display.)
         LOG_ALWAYS_FATAL_IF(mDisplays.empty(), "Cannot unregister all displays!");
 
-        pacesetterVsyncSchedule = promotePacesetterDisplayLocked();
+        pacesetterVsyncSchedule = promotePacesetterDisplayLocked(activeDisplayId, kPromotionParams);
     }
     applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
 }
@@ -245,8 +258,8 @@
         const auto period = pacesetterPtr->targeterPtr->target().expectedFrameDuration();
         const auto skipDuration = Duration::fromNs(
                 static_cast<nsecs_t>(period.ns() * mPacesetterFrameDurationFractionToSkip));
-        ATRACE_FORMAT("Injecting jank for %f%% of the frame (%" PRId64 " ns)",
-                      mPacesetterFrameDurationFractionToSkip * 100, skipDuration.ns());
+        SFTRACE_FORMAT("Injecting jank for %f%% of the frame (%" PRId64 " ns)",
+                       mPacesetterFrameDurationFractionToSkip * 100, skipDuration.ns());
         std::this_thread::sleep_for(skipDuration);
         mPacesetterFrameDurationFractionToSkip = 0.f;
     }
@@ -277,7 +290,7 @@
         return true;
     }
 
-    ATRACE_FORMAT("%s uid: %d frameRate: %s", __func__, uid, to_string(*frameRate).c_str());
+    SFTRACE_FORMAT("%s uid: %d frameRate: %s", __func__, uid, to_string(*frameRate).c_str());
     return getVsyncSchedule()->getTracker().isVSyncInPhase(expectedVsyncTime.ns(), *frameRate);
 }
 
@@ -505,7 +518,7 @@
 }
 
 void Scheduler::resyncAllToHardwareVsync(bool allowToEnable) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::scoped_lock lock(mDisplayLock);
     ftl::FakeGuard guard(kMainThreadContext);
 
@@ -539,12 +552,12 @@
 
 void Scheduler::onHardwareVsyncRequest(PhysicalDisplayId id, bool enabled) {
     static const auto& whence = __func__;
-    ATRACE_NAME(ftl::Concat(whence, ' ', id.value, ' ', enabled).c_str());
+    SFTRACE_NAME(ftl::Concat(whence, ' ', id.value, ' ', enabled).c_str());
 
     // On main thread to serialize reads/writes of pending hardware VSYNC state.
     static_cast<void>(
             schedule([=, this]() FTL_FAKE_GUARD(mDisplayLock) FTL_FAKE_GUARD(kMainThreadContext) {
-                ATRACE_NAME(ftl::Concat(whence, ' ', id.value, ' ', enabled).c_str());
+                SFTRACE_NAME(ftl::Concat(whence, ' ', id.value, ' ', enabled).c_str());
 
                 if (const auto displayOpt = mDisplays.get(id)) {
                     auto& display = displayOpt->get();
@@ -626,7 +639,7 @@
 }
 
 void Scheduler::addPresentFence(PhysicalDisplayId id, std::shared_ptr<FenceTime> fence) {
-    ATRACE_NAME(ftl::Concat(__func__, ' ', id.value).c_str());
+    SFTRACE_NAME(ftl::Concat(__func__, ' ', id.value).c_str());
     const auto scheduleOpt =
             (ftl::FakeGuard(mDisplayLock), mDisplays.get(id)).and_then([](const Display& display) {
                 return display.powerMode == hal::PowerMode::OFF
@@ -689,7 +702,7 @@
     const auto selectorPtr = pacesetterSelectorPtr();
     if (!selectorPtr->canSwitch()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     LayerHistory::Summary summary = mLayerHistory.summarize(*selectorPtr, systemTime());
     applyPolicy(&Policy::contentRequirements, std::move(summary));
@@ -774,7 +787,7 @@
 }
 
 void Scheduler::kernelIdleTimerCallback(TimerState state) {
-    ATRACE_INT("ExpiredKernelIdleTimer", static_cast<int>(state));
+    SFTRACE_INT("ExpiredKernelIdleTimer", static_cast<int>(state));
 
     // TODO(145561154): cleanup the kernel idle timer implementation and the refresh rate
     // magic number
@@ -805,7 +818,7 @@
 
 void Scheduler::idleTimerCallback(TimerState state) {
     applyPolicy(&Policy::idleTimer, state);
-    ATRACE_INT("ExpiredIdleTimer", static_cast<int>(state));
+    SFTRACE_INT("ExpiredIdleTimer", static_cast<int>(state));
 }
 
 void Scheduler::touchTimerCallback(TimerState state) {
@@ -817,12 +830,12 @@
     if (applyPolicy(&Policy::touch, touch).touch) {
         mLayerHistory.clear();
     }
-    ATRACE_INT("TouchState", static_cast<int>(touch));
+    SFTRACE_INT("TouchState", static_cast<int>(touch));
 }
 
 void Scheduler::displayPowerTimerCallback(TimerState state) {
     applyPolicy(&Policy::displayPowerTimer, state);
-    ATRACE_INT("ExpiredDisplayPowerTimer", static_cast<int>(state));
+    SFTRACE_INT("ExpiredDisplayPowerTimer", static_cast<int>(state));
 }
 
 void Scheduler::dump(utils::Dumper& dumper) const {
@@ -912,35 +925,38 @@
     return mFrameRateOverrideMappings.updateFrameRateOverridesByContent(frameRateOverrides);
 }
 
-void Scheduler::promotePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt) {
+void Scheduler::promotePacesetterDisplay(PhysicalDisplayId pacesetterId, PromotionParams params) {
     std::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule;
-
     {
         std::scoped_lock lock(mDisplayLock);
-        pacesetterVsyncSchedule = promotePacesetterDisplayLocked(pacesetterIdOpt);
+        pacesetterVsyncSchedule = promotePacesetterDisplayLocked(pacesetterId, params);
     }
 
     applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
 }
 
 std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked(
-        std::optional<PhysicalDisplayId> pacesetterIdOpt) {
-    // TODO(b/241286431): Choose the pacesetter display.
-    mPacesetterDisplayId = pacesetterIdOpt.value_or(mDisplays.begin()->first);
-    ALOGI("Display %s is the pacesetter", to_string(*mPacesetterDisplayId).c_str());
+        PhysicalDisplayId pacesetterId, PromotionParams params) {
+    // TODO: b/241286431 - Choose the pacesetter among mDisplays.
+    mPacesetterDisplayId = pacesetterId;
+    ALOGI("Display %s is the pacesetter", to_string(pacesetterId).c_str());
 
     std::shared_ptr<VsyncSchedule> newVsyncSchedulePtr;
     if (const auto pacesetterOpt = pacesetterDisplayLocked()) {
         const Display& pacesetter = *pacesetterOpt;
 
-        pacesetter.selectorPtr->setIdleTimerCallbacks(
-                {.platform = {.onReset = [this] { idleTimerCallback(TimerState::Reset); },
-                              .onExpired = [this] { idleTimerCallback(TimerState::Expired); }},
-                 .kernel = {.onReset = [this] { kernelIdleTimerCallback(TimerState::Reset); },
-                            .onExpired =
-                                    [this] { kernelIdleTimerCallback(TimerState::Expired); }}});
+        if (!FlagManager::getInstance().connected_display() || params.toggleIdleTimer) {
+            pacesetter.selectorPtr->setIdleTimerCallbacks(
+                    {.platform = {.onReset = [this] { idleTimerCallback(TimerState::Reset); },
+                                  .onExpired = [this] { idleTimerCallback(TimerState::Expired); }},
+                     .kernel = {.onReset = [this] { kernelIdleTimerCallback(TimerState::Reset); },
+                                .onExpired =
+                                        [this] { kernelIdleTimerCallback(TimerState::Expired); }},
+                     .vrr = {.onReset = [this] { mSchedulerCallback.vrrDisplayIdle(false); },
+                             .onExpired = [this] { mSchedulerCallback.vrrDisplayIdle(true); }}});
 
-        pacesetter.selectorPtr->startIdleTimer();
+            pacesetter.selectorPtr->startIdleTimer();
+        }
 
         newVsyncSchedulePtr = pacesetter.schedulePtr;
 
@@ -960,11 +976,14 @@
     }
 }
 
-void Scheduler::demotePacesetterDisplay() {
-    // No need to lock for reads on kMainThreadContext.
-    if (const auto pacesetterPtr = FTL_FAKE_GUARD(mDisplayLock, pacesetterSelectorPtrLocked())) {
-        pacesetterPtr->stopIdleTimer();
-        pacesetterPtr->clearIdleTimerCallbacks();
+void Scheduler::demotePacesetterDisplay(PromotionParams params) {
+    if (!FlagManager::getInstance().connected_display() || params.toggleIdleTimer) {
+        // No need to lock for reads on kMainThreadContext.
+        if (const auto pacesetterPtr =
+                    FTL_FAKE_GUARD(mDisplayLock, pacesetterSelectorPtrLocked())) {
+            pacesetterPtr->stopIdleTimer();
+            pacesetterPtr->clearIdleTimerCallbacks();
+        }
     }
 
     // Clear state that depends on the pacesetter's RefreshRateSelector.
@@ -985,7 +1004,7 @@
     auto& layerChoreographers = choreographers->second;
 
     layerChoreographers.frameRate = fps;
-    ATRACE_FORMAT_INSTANT("%s: %s for %s", __func__, to_string(fps).c_str(), layer.name.c_str());
+    SFTRACE_FORMAT_INSTANT("%s: %s for %s", __func__, to_string(fps).c_str(), layer.name.c_str());
     ALOGV("%s: %s for %s", __func__, to_string(fps).c_str(), layer.name.c_str());
 
     auto it = layerChoreographers.connections.begin();
@@ -1067,13 +1086,13 @@
 
 void Scheduler::updateAttachedChoreographers(
         const surfaceflinger::frontend::LayerHierarchy& layerHierarchy, Fps displayRefreshRate) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     updateAttachedChoreographersInternal(layerHierarchy, displayRefreshRate, 0);
 }
 
 template <typename S, typename T>
 auto Scheduler::applyPolicy(S Policy::*statePtr, T&& newState) -> GlobalSignals {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::vector<display::DisplayModeRequest> modeRequests;
     GlobalSignals consideredSignals;
 
@@ -1113,8 +1132,10 @@
                                                 .emitEvent = !choice.consideredSignals.idle});
         }
 
-        frameRateOverridesChanged = updateFrameRateOverridesLocked(consideredSignals, modeOpt->fps);
-
+        if (!FlagManager::getInstance().vrr_bugfix_dropped_frame()) {
+            frameRateOverridesChanged =
+                    updateFrameRateOverridesLocked(consideredSignals, modeOpt->fps);
+        }
         if (mPolicy.modeOpt != modeOpt) {
             mPolicy.modeOpt = modeOpt;
             refreshRateChanged = true;
@@ -1129,6 +1150,12 @@
     if (refreshRateChanged) {
         mSchedulerCallback.requestDisplayModes(std::move(modeRequests));
     }
+
+    if (FlagManager::getInstance().vrr_bugfix_dropped_frame()) {
+        std::scoped_lock lock(mPolicyLock);
+        frameRateOverridesChanged =
+                updateFrameRateOverridesLocked(consideredSignals, mPolicy.modeOpt->fps);
+    }
     if (frameRateOverridesChanged) {
         mSchedulerCallback.triggerOnFrameRateOverridesChanged();
     }
@@ -1136,7 +1163,7 @@
 }
 
 auto Scheduler::chooseDisplayModes() const -> DisplayModeChoiceMap {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     DisplayModeChoiceMap modeChoices;
     const auto globalSignals = makeGlobalSignals();
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index ccaa05f..94583db 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -92,8 +92,8 @@
 
     void startTimers();
 
-    // TODO(b/241285191): Remove this API by promoting pacesetter in onScreen{Acquired,Released}.
-    void setPacesetterDisplay(std::optional<PhysicalDisplayId>) REQUIRES(kMainThreadContext)
+    // TODO: b/241285191 - Remove this API by promoting pacesetter in onScreen{Acquired,Released}.
+    void setPacesetterDisplay(PhysicalDisplayId) REQUIRES(kMainThreadContext)
             EXCLUDES(mDisplayLock);
 
     using RefreshRateSelectorPtr = std::shared_ptr<RefreshRateSelector>;
@@ -101,9 +101,16 @@
     using ConstVsyncSchedulePtr = std::shared_ptr<const VsyncSchedule>;
     using VsyncSchedulePtr = std::shared_ptr<VsyncSchedule>;
 
-    void registerDisplay(PhysicalDisplayId, RefreshRateSelectorPtr) REQUIRES(kMainThreadContext)
+    // After registration/unregistration, `activeDisplayId` is promoted to pacesetter. Note that the
+    // active display is never unregistered, since hotplug disconnect never happens for activatable
+    // displays, i.e. a foldable's internal displays or otherwise the (internal or external) primary
+    // display.
+    // TODO: b/255635821 - Remove active display parameters.
+    void registerDisplay(PhysicalDisplayId, RefreshRateSelectorPtr,
+                         PhysicalDisplayId activeDisplayId) REQUIRES(kMainThreadContext)
             EXCLUDES(mDisplayLock);
-    void unregisterDisplay(PhysicalDisplayId) REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
+    void unregisterDisplay(PhysicalDisplayId, PhysicalDisplayId activeDisplayId)
+            REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
 
     void run();
 
@@ -370,9 +377,16 @@
     void resyncAllToHardwareVsync(bool allowToEnable) EXCLUDES(mDisplayLock);
     void setVsyncConfig(const VsyncConfig&, Period vsyncPeriod);
 
-    // Chooses a pacesetter among the registered displays, unless `pacesetterIdOpt` is specified.
-    // The new `mPacesetterDisplayId` is never `std::nullopt`.
-    void promotePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt = std::nullopt)
+    // TODO: b/241286431 - Remove this option, which assumes that the pacesetter does not change
+    // when a (secondary) display is registered or unregistered. In the short term, this avoids
+    // a deadlock where the main thread joins with the timer thread as the timer thread waits to
+    // lock a mutex held by the main thread.
+    struct PromotionParams {
+        // Whether to stop and start the idle timer. Ignored unless connected_display flag is set.
+        bool toggleIdleTimer;
+    };
+
+    void promotePacesetterDisplay(PhysicalDisplayId pacesetterId, PromotionParams)
             REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
 
     // Changes to the displays (e.g. registering and unregistering) must be made
@@ -381,17 +395,20 @@
     // MessageQueue and EventThread need to use the new pacesetter's
     // VsyncSchedule, and this must happen while mDisplayLock is *not* locked,
     // or else we may deadlock with EventThread.
-    std::shared_ptr<VsyncSchedule> promotePacesetterDisplayLocked(
-            std::optional<PhysicalDisplayId> pacesetterIdOpt = std::nullopt)
+    std::shared_ptr<VsyncSchedule> promotePacesetterDisplayLocked(PhysicalDisplayId pacesetterId,
+                                                                  PromotionParams)
             REQUIRES(kMainThreadContext, mDisplayLock);
     void applyNewVsyncSchedule(std::shared_ptr<VsyncSchedule>) EXCLUDES(mDisplayLock);
 
-    // Blocks until the pacesetter's idle timer thread exits. `mDisplayLock` must not be locked by
-    // the caller on the main thread to avoid deadlock, since the timer thread locks it before exit.
-    void demotePacesetterDisplay() REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock, mPolicyLock);
+    // If toggleIdleTimer is true, the calling thread blocks until the pacesetter's idle timer
+    // thread exits, in which case mDisplayLock must not be locked by the caller to avoid deadlock,
+    // since the timer thread locks it before exit.
+    void demotePacesetterDisplay(PromotionParams) REQUIRES(kMainThreadContext)
+            EXCLUDES(mDisplayLock, mPolicyLock);
 
-    void registerDisplayInternal(PhysicalDisplayId, RefreshRateSelectorPtr, VsyncSchedulePtr)
-            REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
+    void registerDisplayInternal(PhysicalDisplayId, RefreshRateSelectorPtr, VsyncSchedulePtr,
+                                 PhysicalDisplayId activeDisplayId) REQUIRES(kMainThreadContext)
+            EXCLUDES(mDisplayLock);
 
     struct Policy;
 
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
index 6d6b70d..900bce0 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
@@ -19,8 +19,8 @@
 #include <vector>
 
 #include <android-base/stringprintf.h>
+#include <common/trace.h>
 #include <ftl/concat.h>
-#include <gui/TraceUtils.h>
 #include <log/log_main.h>
 
 #include <scheduler/TimeKeeper.h>
@@ -45,14 +45,14 @@
 }
 
 void traceEntry(const VSyncDispatchTimerQueueEntry& entry, nsecs_t now) {
-    if (!ATRACE_ENABLED() || !entry.wakeupTime().has_value() || !entry.targetVsync().has_value()) {
+    if (!SFTRACE_ENABLED() || !entry.wakeupTime().has_value() || !entry.targetVsync().has_value()) {
         return;
     }
 
     ftl::Concat trace(ftl::truncated<5>(entry.name()), " alarm in ",
                       ns2us(*entry.wakeupTime() - now), "us; VSYNC in ",
                       ns2us(*entry.targetVsync() - now), "us");
-    ATRACE_FORMAT_INSTANT(trace.c_str());
+    SFTRACE_FORMAT_INSTANT(trace.c_str());
 }
 
 } // namespace
@@ -98,7 +98,7 @@
 
 ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing,
                                                       VSyncTracker& tracker, nsecs_t now) {
-    ATRACE_NAME("VSyncDispatchTimerQueueEntry::schedule");
+    SFTRACE_NAME("VSyncDispatchTimerQueueEntry::schedule");
     auto nextVsyncTime =
             tracker.nextAnticipatedVSyncTimeFrom(std::max(timing.lastVsync,
                                                           now + timing.workDuration +
@@ -110,8 +110,8 @@
             mArmedInfo && (nextVsyncTime > (mArmedInfo->mActualVsyncTime + mMinVsyncDistance));
     bool const wouldSkipAWakeup =
             mArmedInfo && ((nextWakeupTime > (mArmedInfo->mActualWakeupTime + mMinVsyncDistance)));
-    ATRACE_FORMAT_INSTANT("%s: wouldSkipAVsyncTarget=%d wouldSkipAWakeup=%d", mName.c_str(),
-                          wouldSkipAVsyncTarget, wouldSkipAWakeup);
+    SFTRACE_FORMAT_INSTANT("%s: wouldSkipAVsyncTarget=%d wouldSkipAWakeup=%d", mName.c_str(),
+                           wouldSkipAVsyncTarget, wouldSkipAWakeup);
     if (FlagManager::getInstance().dont_skip_on_early_ro()) {
         if (wouldSkipAVsyncTarget || wouldSkipAWakeup) {
             nextVsyncTime = mArmedInfo->mActualVsyncTime;
@@ -154,13 +154,13 @@
     bool const nextVsyncTooClose = mLastDispatchTime &&
             (nextVsyncTime - *mLastDispatchTime + mMinVsyncDistance) <= currentPeriod;
     if (alreadyDispatchedForVsync) {
-        ATRACE_FORMAT_INSTANT("alreadyDispatchedForVsync");
+        SFTRACE_FORMAT_INSTANT("alreadyDispatchedForVsync");
         return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + mMinVsyncDistance,
                                                     *mLastDispatchTime);
     }
 
     if (nextVsyncTooClose) {
-        ATRACE_FORMAT_INSTANT("nextVsyncTooClose");
+        SFTRACE_FORMAT_INSTANT("nextVsyncTooClose");
         return tracker.nextAnticipatedVSyncTimeFrom(*mLastDispatchTime + currentPeriod,
                                                     *mLastDispatchTime + currentPeriod);
     }
@@ -172,7 +172,7 @@
                                                 VSyncDispatch::ScheduleTiming timing,
                                                 std::optional<ArmingInfo> armedInfo) const
         -> ArmingInfo {
-    ATRACE_NAME("VSyncDispatchTimerQueueEntry::getArmedInfo");
+    SFTRACE_NAME("VSyncDispatchTimerQueueEntry::getArmedInfo");
     const auto earliestReadyBy = now + timing.workDuration + timing.readyDuration;
     const auto earliestVsync = std::max(earliestReadyBy, timing.lastVsync);
 
@@ -188,8 +188,8 @@
                 armedInfo && (nextVsyncTime > (armedInfo->mActualVsyncTime + mMinVsyncDistance));
         bool const wouldSkipAWakeup =
                 armedInfo && (nextWakeupTime > (armedInfo->mActualWakeupTime + mMinVsyncDistance));
-        ATRACE_FORMAT_INSTANT("%s: wouldSkipAVsyncTarget=%d wouldSkipAWakeup=%d", mName.c_str(),
-                              wouldSkipAVsyncTarget, wouldSkipAWakeup);
+        SFTRACE_FORMAT_INSTANT("%s: wouldSkipAVsyncTarget=%d wouldSkipAWakeup=%d", mName.c_str(),
+                               wouldSkipAVsyncTarget, wouldSkipAWakeup);
         if (wouldSkipAVsyncTarget || wouldSkipAWakeup) {
             return *armedInfo;
         }
@@ -199,7 +199,7 @@
 }
 
 void VSyncDispatchTimerQueueEntry::update(VSyncTracker& tracker, nsecs_t now) {
-    ATRACE_NAME("VSyncDispatchTimerQueueEntry::update");
+    SFTRACE_NAME("VSyncDispatchTimerQueueEntry::update");
     if (!mArmedInfo && !mWorkloadUpdateInfo) {
         return;
     }
@@ -208,9 +208,9 @@
         const auto workDelta = mWorkloadUpdateInfo->workDuration - mScheduleTiming.workDuration;
         const auto readyDelta = mWorkloadUpdateInfo->readyDuration - mScheduleTiming.readyDuration;
         const auto lastVsyncDelta = mWorkloadUpdateInfo->lastVsync - mScheduleTiming.lastVsync;
-        ATRACE_FORMAT_INSTANT("Workload updated workDelta=%" PRId64 " readyDelta=%" PRId64
-                              " lastVsyncDelta=%" PRId64,
-                              workDelta, readyDelta, lastVsyncDelta);
+        SFTRACE_FORMAT_INSTANT("Workload updated workDelta=%" PRId64 " readyDelta=%" PRId64
+                               " lastVsyncDelta=%" PRId64,
+                               workDelta, readyDelta, lastVsyncDelta);
         mScheduleTiming = *mWorkloadUpdateInfo;
         mWorkloadUpdateInfo.reset();
     }
@@ -310,7 +310,7 @@
 
 void VSyncDispatchTimerQueue::rearmTimerSkippingUpdateFor(
         nsecs_t now, CallbackMap::const_iterator skipUpdateIt) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::optional<nsecs_t> min;
     std::optional<nsecs_t> targetVsync;
     std::optional<std::string_view> nextWakeupName;
@@ -337,13 +337,13 @@
     if (min && min < mIntendedWakeupTime) {
         setTimer(*min, now);
     } else {
-        ATRACE_NAME("cancel timer");
+        SFTRACE_NAME("cancel timer");
         cancelTimer();
     }
 }
 
 void VSyncDispatchTimerQueue::timerCallback() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     struct Invocation {
         std::shared_ptr<VSyncDispatchTimerQueueEntry> callback;
         nsecs_t vsyncTimestamp;
@@ -383,7 +383,7 @@
 
     for (auto const& invocation : invocations) {
         ftl::Concat trace(ftl::truncated<5>(invocation.callback->name()));
-        ATRACE_FORMAT("%s: %s", __func__, trace.c_str());
+        SFTRACE_FORMAT("%s: %s", __func__, trace.c_str());
         invocation.callback->callback(invocation.vsyncTimestamp, invocation.wakeupTimestamp,
                                       invocation.deadlineTimestamp);
     }
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index dd3c4b0..ee7eda1 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -30,10 +30,10 @@
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <common/FlagManager.h>
+#include <common/trace.h>
 #include <cutils/compiler.h>
 #include <cutils/properties.h>
 #include <ftl/concat.h>
-#include <gui/TraceUtils.h>
 #include <utils/Log.h>
 
 #include "RefreshRateSelector.h"
@@ -77,7 +77,7 @@
 }
 
 inline void VSyncPredictor::traceInt64(const char* name, int64_t value) const {
-    ATRACE_INT64(ftl::Concat(ftl::truncated<14>(name), " ", mId.value).c_str(), value);
+    SFTRACE_INT64(ftl::Concat(ftl::truncated<14>(name), " ", mId.value).c_str(), value);
 }
 
 inline size_t VSyncPredictor::next(size_t i) const {
@@ -98,7 +98,7 @@
             (timestamp - aValidTimestamp) % idealPeriod() * kMaxPercent / idealPeriod();
     if (percent >= kOutlierTolerancePercent &&
         percent <= (kMaxPercent - kOutlierTolerancePercent)) {
-        ATRACE_FORMAT_INSTANT("timestamp is not aligned with model");
+        SFTRACE_FORMAT_INSTANT("timestamp is not aligned with model");
         return false;
     }
 
@@ -109,7 +109,7 @@
     const auto distancePercent = std::abs(*iter - timestamp) * kMaxPercent / idealPeriod();
     if (distancePercent < kOutlierTolerancePercent) {
         // duplicate timestamp
-        ATRACE_FORMAT_INSTANT("duplicate timestamp");
+        SFTRACE_FORMAT_INSTANT("duplicate timestamp");
         return false;
     }
     return true;
@@ -135,7 +135,7 @@
 }
 
 bool VSyncPredictor::addVsyncTimestamp(nsecs_t timestamp) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::lock_guard lock(mMutex);
 
@@ -155,8 +155,8 @@
         } else {
             mKnownTimestamp = timestamp;
         }
-        ATRACE_FORMAT_INSTANT("timestamp rejected. mKnownTimestamp was %.2fms ago",
-                              (mClock->now() - *mKnownTimestamp) / 1e6f);
+        SFTRACE_FORMAT_INSTANT("timestamp rejected. mKnownTimestamp was %.2fms ago",
+                               (mClock->now() - *mKnownTimestamp) / 1e6f);
         return false;
     }
 
@@ -297,7 +297,7 @@
 
 nsecs_t VSyncPredictor::nextAnticipatedVSyncTimeFrom(nsecs_t timePoint,
                                                      std::optional<nsecs_t> lastVsyncOpt) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::lock_guard lock(mMutex);
 
     const auto now = TimePoint::fromNs(mClock->now());
@@ -330,8 +330,8 @@
 
     if (*vsyncOpt > mLastCommittedVsync) {
         mLastCommittedVsync = *vsyncOpt;
-        ATRACE_FORMAT_INSTANT("mLastCommittedVsync in %.2fms",
-                              float(mLastCommittedVsync.ns() - mClock->now()) / 1e6f);
+        SFTRACE_FORMAT_INSTANT("mLastCommittedVsync in %.2fms",
+                               float(mLastCommittedVsync.ns() - mClock->now()) / 1e6f);
     }
 
     return vsyncOpt->ns();
@@ -360,7 +360,11 @@
     purgeTimelines(now);
 
     for (auto& timeline : mTimelines) {
-        if (timeline.validUntil() && timeline.validUntil()->ns() > vsync) {
+        const bool isVsyncValid = FlagManager::getInstance().vrr_bugfix_24q4()
+                ? timeline.isWithin(TimePoint::fromNs(vsync)) ==
+                        VsyncTimeline::VsyncOnTimeline::Unique
+                : timeline.validUntil() && timeline.validUntil()->ns() > vsync;
+        if (isVsyncValid) {
             return timeline.isVSyncInPhase(model, vsync, frameRate);
         }
     }
@@ -370,7 +374,7 @@
 }
 
 void VSyncPredictor::setRenderRate(Fps renderRate, bool applyImmediately) {
-    ATRACE_FORMAT("%s %s", __func__, to_string(renderRate).c_str());
+    SFTRACE_FORMAT("%s %s", __func__, to_string(renderRate).c_str());
     ALOGV("%s %s: RenderRate %s ", __func__, to_string(mId).c_str(), to_string(renderRate).c_str());
     std::lock_guard lock(mMutex);
     const auto prevRenderRate = mRenderRateOpt;
@@ -378,7 +382,7 @@
     const auto renderPeriodDelta =
             prevRenderRate ? prevRenderRate->getPeriodNsecs() - renderRate.getPeriodNsecs() : 0;
     if (applyImmediately) {
-        ATRACE_FORMAT_INSTANT("applyImmediately");
+        SFTRACE_FORMAT_INSTANT("applyImmediately");
         while (mTimelines.size() > 1) {
             mTimelines.pop_front();
         }
@@ -390,13 +394,20 @@
     const bool newRenderRateIsHigher = renderPeriodDelta > renderRate.getPeriodNsecs() &&
             mLastCommittedVsync.ns() - mClock->now() > 2 * renderRate.getPeriodNsecs();
     if (newRenderRateIsHigher) {
-        ATRACE_FORMAT_INSTANT("newRenderRateIsHigher");
+        SFTRACE_FORMAT_INSTANT("newRenderRateIsHigher");
         mTimelines.clear();
         mLastCommittedVsync = TimePoint::fromNs(0);
 
     } else {
-        mTimelines.back().freeze(
-                TimePoint::fromNs(mLastCommittedVsync.ns() + mIdealPeriod.ns() / 2));
+        if (FlagManager::getInstance().vrr_bugfix_24q4()) {
+            // We need to freeze the timeline at the committed vsync, and
+            // then use with threshold adjustments when required to avoid
+            // marginal errors when checking the vsync on the timeline.
+            mTimelines.back().freeze(mLastCommittedVsync);
+        } else {
+            mTimelines.back().freeze(
+                    TimePoint::fromNs(mLastCommittedVsync.ns() + mIdealPeriod.ns() / 2));
+        }
     }
     mTimelines.emplace_back(mLastCommittedVsync, mIdealPeriod, renderRate);
     purgeTimelines(TimePoint::fromNs(mClock->now()));
@@ -405,7 +416,7 @@
 void VSyncPredictor::setDisplayModePtr(ftl::NonNull<DisplayModePtr> modePtr) {
     LOG_ALWAYS_FATAL_IF(mId != modePtr->getPhysicalDisplayId(),
                         "mode does not belong to the display");
-    ATRACE_FORMAT("%s %s", __func__, to_string(*modePtr).c_str());
+    SFTRACE_FORMAT("%s %s", __func__, to_string(*modePtr).c_str());
     const auto timeout = modePtr->getVrrConfig()
             ? modePtr->getVrrConfig()->notifyExpectedPresentConfig
             : std::nullopt;
@@ -433,7 +444,7 @@
 
 Duration VSyncPredictor::ensureMinFrameDurationIsKept(TimePoint expectedPresentTime,
                                                       TimePoint lastConfirmedPresentTime) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (mNumVsyncsForFrame <= 1) {
         return 0ns;
@@ -446,14 +457,15 @@
     auto prev = lastConfirmedPresentTime.ns();
     for (auto& current : mPastExpectedPresentTimes) {
         if (CC_UNLIKELY(mTraceOn)) {
-            ATRACE_FORMAT_INSTANT("current %.2f past last signaled fence",
-                                  static_cast<float>(current.ns() - lastConfirmedPresentTime.ns()) /
-                                          1e6f);
+            SFTRACE_FORMAT_INSTANT("current %.2f past last signaled fence",
+                                   static_cast<float>(current.ns() -
+                                                      lastConfirmedPresentTime.ns()) /
+                                           1e6f);
         }
 
         const auto minPeriodViolation = current.ns() - prev + threshold < minFramePeriod;
         if (minPeriodViolation) {
-            ATRACE_NAME("minPeriodViolation");
+            SFTRACE_NAME("minPeriodViolation");
             current = TimePoint::fromNs(prev + minFramePeriod);
             prev = current.ns();
         } else {
@@ -475,18 +487,18 @@
     return 0ns;
 }
 
-void VSyncPredictor::onFrameBegin(TimePoint expectedPresentTime,
-                                  TimePoint lastConfirmedPresentTime) {
-    ATRACE_NAME("VSyncPredictor::onFrameBegin");
+void VSyncPredictor::onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) {
+    SFTRACE_NAME("VSyncPredictor::onFrameBegin");
     std::lock_guard lock(mMutex);
 
     if (!mDisplayModePtr->getVrrConfig()) return;
 
+    const auto [lastConfirmedPresentTime, lastConfirmedExpectedPresentTime] = lastSignaledFrameTime;
     if (CC_UNLIKELY(mTraceOn)) {
-        ATRACE_FORMAT_INSTANT("vsync is %.2f past last signaled fence",
-                              static_cast<float>(expectedPresentTime.ns() -
-                                                 lastConfirmedPresentTime.ns()) /
-                                      1e6f);
+        SFTRACE_FORMAT_INSTANT("vsync is %.2f past last signaled fence",
+                               static_cast<float>(expectedPresentTime.ns() -
+                                                  lastConfirmedPresentTime.ns()) /
+                                       1e6f);
     }
     const auto currentPeriod = mRateMap.find(idealPeriod())->second.slope;
     const auto threshold = currentPeriod / 2;
@@ -497,9 +509,9 @@
         const bool frontIsBeforeConfirmed = front < lastConfirmedPresentTime.ns() + threshold;
         if (frontIsBeforeConfirmed) {
             if (CC_UNLIKELY(mTraceOn)) {
-                ATRACE_FORMAT_INSTANT("Discarding old vsync - %.2f before last signaled fence",
-                                      static_cast<float>(lastConfirmedPresentTime.ns() - front) /
-                                              1e6f);
+                SFTRACE_FORMAT_INSTANT("Discarding old vsync - %.2f before last signaled fence",
+                                       static_cast<float>(lastConfirmedPresentTime.ns() - front) /
+                                               1e6f);
             }
             mPastExpectedPresentTimes.pop_front();
         } else {
@@ -507,6 +519,11 @@
         }
     }
 
+    if (lastConfirmedExpectedPresentTime.ns() - lastConfirmedPresentTime.ns() > threshold) {
+        SFTRACE_FORMAT_INSTANT("lastFramePresentedEarly");
+        return;
+    }
+
     const auto phase = ensureMinFrameDurationIsKept(expectedPresentTime, lastConfirmedPresentTime);
     if (phase > 0ns) {
         mMissedVsync = {expectedPresentTime, minFramePeriodLocked()};
@@ -514,7 +531,7 @@
 }
 
 void VSyncPredictor::onFrameMissed(TimePoint expectedPresentTime) {
-    ATRACE_NAME("VSyncPredictor::onFrameMissed");
+    SFTRACE_NAME("VSyncPredictor::onFrameMissed");
 
     std::lock_guard lock(mMutex);
     if (!mDisplayModePtr->getVrrConfig()) return;
@@ -540,7 +557,7 @@
 }
 
 void VSyncPredictor::clearTimestamps() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (!mTimestamps.empty()) {
         auto const maxRb = *std::max_element(mTimestamps.begin(), mTimestamps.end());
@@ -602,7 +619,7 @@
     if (mRenderRateOpt &&
         mLastCommittedVsync.ns() + mRenderRateOpt->getPeriodNsecs() * kEnoughFramesToBreakPhase <
                 mClock->now()) {
-        ATRACE_FORMAT_INSTANT("kEnoughFramesToBreakPhase");
+        SFTRACE_FORMAT_INSTANT("kEnoughFramesToBreakPhase");
         mTimelines.clear();
         mLastCommittedVsync = TimePoint::fromNs(0);
         mTimelines.emplace_back(mLastCommittedVsync, mIdealPeriod, mRenderRateOpt);
@@ -611,7 +628,10 @@
 
     while (mTimelines.size() > 1) {
         const auto validUntilOpt = mTimelines.front().validUntil();
-        if (validUntilOpt && *validUntilOpt < now) {
+        const bool isTimelineOutDated = FlagManager::getInstance().vrr_bugfix_24q4()
+                ? mTimelines.front().isWithin(now) == VsyncTimeline::VsyncOnTimeline::Outside
+                : validUntilOpt && *validUntilOpt < now;
+        if (isTimelineOutDated) {
             mTimelines.pop_front();
         } else {
             break;
@@ -635,16 +655,16 @@
 
 void VSyncPredictor::VsyncTimeline::freeze(TimePoint lastVsync) {
     LOG_ALWAYS_FATAL_IF(mValidUntil.has_value());
-    ATRACE_FORMAT_INSTANT("renderRate %s valid for %.2f",
-                          mRenderRateOpt ? to_string(*mRenderRateOpt).c_str() : "NA",
-                          float(lastVsync.ns() - TimePoint::now().ns()) / 1e6f);
+    SFTRACE_FORMAT_INSTANT("renderRate %s valid for %.2f",
+                           mRenderRateOpt ? to_string(*mRenderRateOpt).c_str() : "NA",
+                           float(lastVsync.ns() - TimePoint::now().ns()) / 1e6f);
     mValidUntil = lastVsync;
 }
 
 std::optional<TimePoint> VSyncPredictor::VsyncTimeline::nextAnticipatedVSyncTimeFrom(
         Model model, std::optional<Period> minFramePeriodOpt, nsecs_t vsync,
         MissedVsync missedVsync, std::optional<nsecs_t> lastVsyncOpt) {
-    ATRACE_FORMAT("renderRate %s", mRenderRateOpt ? to_string(*mRenderRateOpt).c_str() : "NA");
+    SFTRACE_FORMAT("renderRate %s", mRenderRateOpt ? to_string(*mRenderRateOpt).c_str() : "NA");
 
     nsecs_t vsyncTime = snapToVsyncAlignedWithRenderRate(model, vsync);
     const auto threshold = model.slope / 2;
@@ -658,32 +678,38 @@
             // on whether we skipped the frame (onFrameMissed) or not (onFrameBegin) we apply a
             // different fixup. There is no need to to shift the vsync timeline again.
             vsyncTime += missedVsync.fixup.ns();
-            ATRACE_FORMAT_INSTANT("lastFrameMissed");
+            SFTRACE_FORMAT_INSTANT("lastFrameMissed");
         } else if (mightBackpressure && lastVsyncOpt) {
-            // lastVsyncOpt is based on the old timeline before we shifted it. we should correct it
-            // first before trying to use it.
-            lastVsyncOpt = snapToVsyncAlignedWithRenderRate(model, *lastVsyncOpt);
+            if (!FlagManager::getInstance().vrr_bugfix_24q4()) {
+                // lastVsyncOpt does not need to be corrected with the new rate, and
+                // it should be used as is to avoid skipping a frame when changing rates are
+                // aligned at vsync time.
+                lastVsyncOpt = snapToVsyncAlignedWithRenderRate(model, *lastVsyncOpt);
+            }
             const auto vsyncDiff = vsyncTime - *lastVsyncOpt;
             if (vsyncDiff <= minFramePeriodOpt->ns() - threshold) {
                 // avoid a duplicate vsync
-                ATRACE_FORMAT_INSTANT("skipping a vsync to avoid duplicate frame. next in %.2f "
-                                      "which "
-                                      "is %.2f "
-                                      "from "
-                                      "prev. "
-                                      "adjust by %.2f",
-                                      static_cast<float>(vsyncTime - TimePoint::now().ns()) / 1e6f,
-                                      static_cast<float>(vsyncDiff) / 1e6f,
-                                      static_cast<float>(mRenderRateOpt->getPeriodNsecs()) / 1e6f);
+                SFTRACE_FORMAT_INSTANT("skipping a vsync to avoid duplicate frame. next in %.2f "
+                                       "which "
+                                       "is %.2f "
+                                       "from "
+                                       "prev. "
+                                       "adjust by %.2f",
+                                       static_cast<float>(vsyncTime - TimePoint::now().ns()) / 1e6f,
+                                       static_cast<float>(vsyncDiff) / 1e6f,
+                                       static_cast<float>(mRenderRateOpt->getPeriodNsecs()) / 1e6f);
                 vsyncTime += mRenderRateOpt->getPeriodNsecs();
             }
         }
     }
 
-    ATRACE_FORMAT_INSTANT("vsync in %.2fms", float(vsyncTime - TimePoint::now().ns()) / 1e6f);
-    if (mValidUntil && vsyncTime > mValidUntil->ns()) {
-        ATRACE_FORMAT_INSTANT("no longer valid for vsync in %.2f",
-                              static_cast<float>(vsyncTime - TimePoint::now().ns()) / 1e6f);
+    SFTRACE_FORMAT_INSTANT("vsync in %.2fms", float(vsyncTime - TimePoint::now().ns()) / 1e6f);
+    const bool isVsyncInvalid = FlagManager::getInstance().vrr_bugfix_24q4()
+            ? isWithin(TimePoint::fromNs(vsyncTime)) == VsyncOnTimeline::Outside
+            : mValidUntil && vsyncTime > mValidUntil->ns();
+    if (isVsyncInvalid) {
+        SFTRACE_FORMAT_INSTANT("no longer valid for vsync in %.2f",
+                               static_cast<float>(vsyncTime - TimePoint::now().ns()) / 1e6f);
         return std::nullopt;
     }
 
@@ -747,18 +773,32 @@
         return true;
     }
     const auto vsyncSequence = getVsyncSequenceLocked(model, vsync);
-    ATRACE_FORMAT_INSTANT("vsync in: %.2f sequence: %" PRId64 " divisor: %zu",
-                          getVsyncIn(now, vsyncSequence.vsyncTime), vsyncSequence.seq, divisor);
+    SFTRACE_FORMAT_INSTANT("vsync in: %.2f sequence: %" PRId64 " divisor: %zu",
+                           getVsyncIn(now, vsyncSequence.vsyncTime), vsyncSequence.seq, divisor);
     return vsyncSequence.seq % divisor == 0;
 }
 
 void VSyncPredictor::VsyncTimeline::shiftVsyncSequence(Duration phase) {
     if (mLastVsyncSequence) {
-        ATRACE_FORMAT_INSTANT("adjusting vsync by %.2f", static_cast<float>(phase.ns()) / 1e6f);
+        SFTRACE_FORMAT_INSTANT("adjusting vsync by %.2f", static_cast<float>(phase.ns()) / 1e6f);
         mLastVsyncSequence->vsyncTime += phase.ns();
     }
 }
 
+VSyncPredictor::VsyncTimeline::VsyncOnTimeline VSyncPredictor::VsyncTimeline::isWithin(
+        TimePoint vsync) {
+    const auto threshold = mIdealPeriod.ns() / 2;
+    if (!mValidUntil || vsync.ns() < mValidUntil->ns() - threshold) {
+        // if mValidUntil is absent then timeline is not frozen and
+        // vsync should be unique to that timeline.
+        return VsyncOnTimeline::Unique;
+    }
+    if (vsync.ns() > mValidUntil->ns() + threshold) {
+        return VsyncOnTimeline::Outside;
+    }
+    return VsyncOnTimeline::Shared;
+}
+
 } // namespace android::scheduler
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h
index 8ce61d8..9e1c90b 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.h
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h
@@ -22,6 +22,7 @@
 #include <vector>
 
 #include <android-base/thread_annotations.h>
+#include <scheduler/FrameTime.h>
 #include <scheduler/TimeKeeper.h>
 #include <ui/DisplayId.h>
 
@@ -77,7 +78,7 @@
 
     void setRenderRate(Fps, bool applyImmediately) final EXCLUDES(mMutex);
 
-    void onFrameBegin(TimePoint expectedPresentTime, TimePoint lastConfirmedPresentTime) final
+    void onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) final
             EXCLUDES(mMutex);
     void onFrameMissed(TimePoint expectedPresentTime) final EXCLUDES(mMutex);
 
@@ -106,6 +107,13 @@
         void shiftVsyncSequence(Duration phase);
         void setRenderRate(std::optional<Fps> renderRateOpt) { mRenderRateOpt = renderRateOpt; }
 
+        enum class VsyncOnTimeline {
+            Unique,  // Within timeline, not shared with next timeline.
+            Shared,  // Within timeline, shared with next timeline.
+            Outside, // Outside of the timeline.
+        };
+        VsyncOnTimeline isWithin(TimePoint vsync);
+
     private:
         nsecs_t snapToVsyncAlignedWithRenderRate(Model model, nsecs_t vsync);
         VsyncSequence getVsyncSequenceLocked(Model, nsecs_t vsync);
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index 8038364..2455822 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -20,11 +20,10 @@
 //#define LOG_NDEBUG 0
 
 #include <assert.h>
+#include <common/trace.h>
 #include <cutils/properties.h>
 #include <ftl/concat.h>
-#include <gui/TraceUtils.h>
 #include <log/log.h>
-#include <utils/Trace.h>
 
 #include "../TracedOrdinal.h"
 #include "VSyncDispatch.h"
@@ -53,7 +52,7 @@
 VSyncReactor::~VSyncReactor() = default;
 
 bool VSyncReactor::addPresentFence(std::shared_ptr<FenceTime> fence) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (!fence) {
         return false;
@@ -66,8 +65,8 @@
 
     std::lock_guard lock(mMutex);
     if (mExternalIgnoreFences || mInternalIgnoreFences) {
-        ATRACE_FORMAT_INSTANT("mExternalIgnoreFences=%d mInternalIgnoreFences=%d",
-            mExternalIgnoreFences, mInternalIgnoreFences);
+        SFTRACE_FORMAT_INSTANT("mExternalIgnoreFences=%d mInternalIgnoreFences=%d",
+                               mExternalIgnoreFences, mInternalIgnoreFences);
         return true;
     }
 
@@ -121,7 +120,7 @@
 }
 
 void VSyncReactor::startPeriodTransitionInternal(ftl::NonNull<DisplayModePtr> modePtr) {
-    ATRACE_FORMAT("%s %" PRIu64, __func__, mId.value);
+    SFTRACE_FORMAT("%s %" PRIu64, __func__, mId.value);
     mPeriodConfirmationInProgress = true;
     mModePtrTransitioningTo = modePtr.get();
     mMoreSamplesNeeded = true;
@@ -129,15 +128,15 @@
 }
 
 void VSyncReactor::endPeriodTransition() {
-    ATRACE_FORMAT("%s %" PRIu64, __func__, mId.value);
+    SFTRACE_FORMAT("%s %" PRIu64, __func__, mId.value);
     mModePtrTransitioningTo.reset();
     mPeriodConfirmationInProgress = false;
     mLastHwVsync.reset();
 }
 
 void VSyncReactor::onDisplayModeChanged(ftl::NonNull<DisplayModePtr> modePtr, bool force) {
-    ATRACE_INT64(ftl::Concat("VSR-", __func__, " ", mId.value).c_str(),
-                 modePtr->getVsyncRate().getPeriodNsecs());
+    SFTRACE_INT64(ftl::Concat("VSR-", __func__, " ", mId.value).c_str(),
+                  modePtr->getVsyncRate().getPeriodNsecs());
     std::lock_guard lock(mMutex);
     mLastHwVsync.reset();
 
@@ -191,7 +190,7 @@
 
     std::lock_guard lock(mMutex);
     if (periodConfirmed(timestamp, hwcVsyncPeriod)) {
-        ATRACE_FORMAT("VSR %" PRIu64 ": period confirmed", mId.value);
+        SFTRACE_FORMAT("VSR %" PRIu64 ": period confirmed", mId.value);
         if (mModePtrTransitioningTo) {
             mTracker.setDisplayModePtr(ftl::as_non_null(mModePtrTransitioningTo));
             *periodFlushed = true;
@@ -205,12 +204,12 @@
         endPeriodTransition();
         mMoreSamplesNeeded = mTracker.needsMoreSamples();
     } else if (mPeriodConfirmationInProgress) {
-        ATRACE_FORMAT("VSR %" PRIu64 ": still confirming period", mId.value);
+        SFTRACE_FORMAT("VSR %" PRIu64 ": still confirming period", mId.value);
         mLastHwVsync = timestamp;
         mMoreSamplesNeeded = true;
         *periodFlushed = false;
     } else {
-        ATRACE_FORMAT("VSR %" PRIu64 ": adding sample", mId.value);
+        SFTRACE_FORMAT("VSR %" PRIu64 ": adding sample", mId.value);
         *periodFlushed = false;
         mTracker.addVsyncTimestamp(timestamp);
         mMoreSamplesNeeded = mTracker.needsMoreSamples();
diff --git a/services/surfaceflinger/Scheduler/VSyncTracker.h b/services/surfaceflinger/Scheduler/VSyncTracker.h
index 134d28e..3376fad 100644
--- a/services/surfaceflinger/Scheduler/VSyncTracker.h
+++ b/services/surfaceflinger/Scheduler/VSyncTracker.h
@@ -21,6 +21,7 @@
 
 #include <scheduler/Fps.h>
 #include <scheduler/FrameRateMode.h>
+#include <scheduler/FrameTime.h>
 
 #include "VSyncDispatch.h"
 
@@ -112,8 +113,7 @@
      */
     virtual void setRenderRate(Fps, bool applyImmediately) = 0;
 
-    virtual void onFrameBegin(TimePoint expectedPresentTime,
-                              TimePoint lastConfirmedPresentTime) = 0;
+    virtual void onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) = 0;
 
     virtual void onFrameMissed(TimePoint expectedPresentTime) = 0;
 
diff --git a/services/surfaceflinger/Scheduler/VsyncModulator.cpp b/services/surfaceflinger/Scheduler/VsyncModulator.cpp
index 586357f..fa377e9 100644
--- a/services/surfaceflinger/Scheduler/VsyncModulator.cpp
+++ b/services/surfaceflinger/Scheduler/VsyncModulator.cpp
@@ -22,8 +22,8 @@
 #include "VsyncModulator.h"
 
 #include <android-base/properties.h>
+#include <common/trace.h>
 #include <log/log.h>
-#include <utils/Trace.h>
 
 #include <chrono>
 #include <cinttypes>
@@ -72,7 +72,7 @@
     }
 
     if (mTraceDetailedInfo) {
-        ATRACE_INT("mEarlyWakeup", static_cast<int>(mEarlyWakeupRequests.size()));
+        SFTRACE_INT("mEarlyWakeup", static_cast<int>(mEarlyWakeupRequests.size()));
     }
 
     if (mEarlyWakeupRequests.empty() && schedule == Schedule::EarlyEnd) {
@@ -172,9 +172,9 @@
         const bool isEarlyGpu = &offsets == &mVsyncConfigSet.earlyGpu;
         const bool isLate = &offsets == &mVsyncConfigSet.late;
 
-        ATRACE_INT("Vsync-EarlyOffsetsOn", isEarly);
-        ATRACE_INT("Vsync-EarlyGpuOffsetsOn", isEarlyGpu);
-        ATRACE_INT("Vsync-LateOffsetsOn", isLate);
+        SFTRACE_INT("Vsync-EarlyOffsetsOn", isEarly);
+        SFTRACE_INT("Vsync-EarlyGpuOffsetsOn", isEarlyGpu);
+        SFTRACE_INT("Vsync-LateOffsetsOn", isLate);
     }
 
     return offsets;
diff --git a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
index 2fa3318..d3e312a 100644
--- a/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
+++ b/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
@@ -18,8 +18,8 @@
 
 #include <common/FlagManager.h>
 
+#include <common/trace.h>
 #include <ftl/fake_guard.h>
-#include <gui/TraceUtils.h>
 #include <scheduler/Fps.h>
 #include <scheduler/Timer.h>
 
@@ -182,7 +182,7 @@
 }
 
 void VsyncSchedule::enableHardwareVsyncLocked() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     if (mHwVsyncState == HwVsyncState::Disabled) {
         getTracker().resetModel();
         mRequestHardwareVsync(mId, true);
@@ -191,7 +191,7 @@
 }
 
 void VsyncSchedule::disableHardwareVsync(bool disallow) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::lock_guard<std::mutex> lock(mHwVsyncLock);
     switch (mHwVsyncState) {
         case HwVsyncState::Enabled:
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
index d37d2dc..38cb446 100644
--- a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
@@ -26,6 +26,7 @@
 #include <ui/FenceTime.h>
 
 #include <scheduler/Features.h>
+#include <scheduler/FrameTime.h>
 #include <scheduler/Time.h>
 #include <scheduler/VsyncId.h>
 #include <scheduler/interface/CompositeResult.h>
@@ -57,13 +58,6 @@
     // The time of the VSYNC that preceded this frame. See `presentFenceForPastVsync` for details.
     TimePoint pastVsyncTime(Period minFramePeriod) const;
 
-    // The present fence for the frame that had targeted the most recent VSYNC before this frame.
-    // If the target VSYNC for any given frame is more than `vsyncPeriod` in the future, then the
-    // VSYNC of at least one previous frame has not yet passed. In other words, this is NOT the
-    // `presentFenceForPreviousFrame` if running N VSYNCs ahead, but the one that should have been
-    // signaled by now (unless that frame missed).
-    FenceTimePtr presentFenceForPastVsync(Period minFramePeriod) const;
-
     // Equivalent to `presentFenceForPastVsync` unless running N VSYNCs ahead.
     const FenceTimePtr& presentFenceForPreviousFrame() const {
         return mPresentFences.front().fenceTime;
@@ -72,7 +66,7 @@
     bool isFramePending() const { return mFramePending; }
     bool didMissFrame() const { return mFrameMissed; }
     bool didMissHwcFrame() const { return mHwcFrameMissed && !mGpuFrameMissed; }
-    TimePoint lastSignaledFrameTime() const { return mLastSignaledFrameTime; };
+    FrameTime lastSignaledFrameTime() const { return mLastSignaledFrameTime; }
 
 protected:
     explicit FrameTarget(const std::string& displayLabel);
@@ -106,10 +100,17 @@
         FenceTimePtr fenceTime = FenceTime::NO_FENCE;
         TimePoint expectedPresentTime = TimePoint();
     };
+
+    // The present fence for the frame that had targeted the most recent VSYNC before this frame.
+    // If the target VSYNC for any given frame is more than `vsyncPeriod` in the future, then the
+    // VSYNC of at least one previous frame has not yet passed. In other words, this is NOT the
+    // `presentFenceForPreviousFrame` if running N VSYNCs ahead, but the one that should have been
+    // signaled by now (unless that frame missed).
+    FenceWithFenceTime presentFenceForPastVsync(Period minFramePeriod) const;
     std::array<FenceWithFenceTime, 2> mPresentFences;
     utils::RingBuffer<FenceWithFenceTime, 5> mFenceWithFenceTimes;
 
-    TimePoint mLastSignaledFrameTime;
+    FrameTime mLastSignaledFrameTime;
 
 private:
     friend class FrameTargeterTestBase;
@@ -120,16 +121,17 @@
         return expectedFrameDuration() > (N - 1) * minFramePeriod;
     }
 
-    const FenceTimePtr pastVsyncTimePtr() const {
-        auto pastFenceTimePtr = FenceTime::NO_FENCE;
+    FenceWithFenceTime pastVsyncTimePtr() const {
+        FenceWithFenceTime pastFenceWithFenceTime;
         for (size_t i = 0; i < mFenceWithFenceTimes.size(); i++) {
-            const auto& [_, fenceTimePtr, expectedPresentTime] = mFenceWithFenceTimes[i];
-            if (expectedPresentTime > mFrameBeginTime) {
-                return pastFenceTimePtr;
+            const auto& fenceWithFenceTime = mFenceWithFenceTimes[i];
+            // TODO(b/354007767) Fix the below condition to avoid frame drop
+            if (fenceWithFenceTime.expectedPresentTime > mFrameBeginTime) {
+                return pastFenceWithFenceTime;
             }
-            pastFenceTimePtr = fenceTimePtr;
+            pastFenceWithFenceTime = fenceWithFenceTime;
         }
-        return pastFenceTimePtr;
+        return pastFenceWithFenceTime;
     }
 };
 
diff --git a/libs/tracing_perfetto/include/trace_result.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameTime.h
similarity index 76%
rename from libs/tracing_perfetto/include/trace_result.h
rename to services/surfaceflinger/Scheduler/include/scheduler/FrameTime.h
index f7581fc..ed5c899 100644
--- a/libs/tracing_perfetto/include/trace_result.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameTime.h
@@ -14,17 +14,13 @@
  * limitations under the License.
  */
 
-#ifndef TRACE_RESULT_H
-#define TRACE_RESULT_H
+#pragma once
 
-namespace tracing_perfetto {
+#include <scheduler/Time.h>
 
-enum class Result {
-  SUCCESS,
-  NOT_SUPPORTED,
-  INVALID_INPUT,
+namespace android::scheduler {
+struct FrameTime {
+    TimePoint signalTime;
+    TimePoint expectedPresentTime;
 };
-
-}
-
-#endif  // TRACE_RESULT_H
+} // namespace android::scheduler
\ No newline at end of file
diff --git a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
index badd21e..1d248fb 100644
--- a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
+++ b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
@@ -14,9 +14,8 @@
  * limitations under the License.
  */
 
-#include <gui/TraceUtils.h>
-
 #include <common/FlagManager.h>
+#include <common/trace.h>
 #include <scheduler/FrameTargeter.h>
 #include <scheduler/IVsyncSource.h>
 
@@ -34,12 +33,12 @@
     return mExpectedPresentTime - Period::fromNs(minFramePeriod.ns() << shift);
 }
 
-FenceTimePtr FrameTarget::presentFenceForPastVsync(Period minFramePeriod) const {
+FrameTarget::FenceWithFenceTime FrameTarget::presentFenceForPastVsync(Period minFramePeriod) const {
     if (FlagManager::getInstance().allow_n_vsyncs_in_targeter()) {
         return pastVsyncTimePtr();
     }
     const size_t i = static_cast<size_t>(targetsVsyncsAhead<2>(minFramePeriod));
-    return mPresentFences[i].fenceTime;
+    return mPresentFences[i];
 }
 
 bool FrameTarget::wouldPresentEarly(Period minFramePeriod) const {
@@ -52,7 +51,7 @@
         return true;
     }
 
-    const auto fence = presentFenceForPastVsync(minFramePeriod);
+    const auto fence = presentFenceForPastVsync(minFramePeriod).fenceTime;
     return fence->isValid() && fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
 }
 
@@ -90,11 +89,11 @@
         mEarliestPresentTime = computeEarliestPresentTime(minFramePeriod, args.hwcMinWorkDuration);
     }
 
-    ATRACE_FORMAT("%s %" PRId64 " vsyncIn %.2fms%s", __func__, ftl::to_underlying(args.vsyncId),
-                  ticks<std::milli, float>(mExpectedPresentTime - TimePoint::now()),
-                  mExpectedPresentTime == args.expectedVsyncTime ? "" : " (adjusted)");
+    SFTRACE_FORMAT("%s %" PRId64 " vsyncIn %.2fms%s", __func__, ftl::to_underlying(args.vsyncId),
+                   ticks<std::milli, float>(mExpectedPresentTime - TimePoint::now()),
+                   mExpectedPresentTime == args.expectedVsyncTime ? "" : " (adjusted)");
 
-    const FenceTimePtr& pastPresentFence = presentFenceForPastVsync(minFramePeriod);
+    FenceWithFenceTime pastPresentFence = presentFenceForPastVsync(minFramePeriod);
 
     // In cases where the present fence is about to fire, give it a small grace period instead of
     // giving up on the frame.
@@ -106,8 +105,8 @@
 
     // Pending frames may trigger backpressure propagation.
     const auto& isFencePending = *isFencePendingFuncPtr;
-    mFramePending = pastPresentFence != FenceTime::NO_FENCE &&
-            isFencePending(pastPresentFence, graceTimeForPresentFenceMs);
+    mFramePending = pastPresentFence.fenceTime != FenceTime::NO_FENCE &&
+            isFencePending(pastPresentFence.fenceTime, graceTimeForPresentFenceMs);
 
     // A frame is missed if the prior frame is still pending. If no longer pending, then we still
     // count the frame as missed if the predicted present time was further in the past than when the
@@ -115,9 +114,10 @@
     // than a typical frame duration, but should not be so small that it reports reasonable drift as
     // a missed frame.
     mFrameMissed = mFramePending || [&] {
-        const nsecs_t pastPresentTime = pastPresentFence->getSignalTime();
+        const nsecs_t pastPresentTime = pastPresentFence.fenceTime->getSignalTime();
         if (pastPresentTime < 0) return false;
-        mLastSignaledFrameTime = TimePoint::fromNs(pastPresentTime);
+        mLastSignaledFrameTime = {.signalTime = TimePoint::fromNs(pastPresentTime),
+                                  .expectedPresentTime = pastPresentFence.expectedPresentTime};
         const nsecs_t frameMissedSlop = vsyncPeriod.ns() / 2;
         return lastScheduledPresentTime.ns() < pastPresentTime - frameMissedSlop;
     }();
@@ -165,7 +165,7 @@
 }
 
 bool FrameTargeter::isFencePending(const FenceTimePtr& fence, int graceTimeMs) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     const status_t status = fence->wait(graceTimeMs);
 
     // This is the same as Fence::Status::Unsignaled, but it saves a call to getStatus,
diff --git a/services/surfaceflinger/Scheduler/src/Timer.cpp b/services/surfaceflinger/Scheduler/src/Timer.cpp
index eeb9c60..20c58eb 100644
--- a/services/surfaceflinger/Scheduler/src/Timer.cpp
+++ b/services/surfaceflinger/Scheduler/src/Timer.cpp
@@ -24,10 +24,10 @@
 #include <sys/timerfd.h>
 #include <sys/unistd.h>
 
+#include <common/trace.h>
 #include <ftl/concat.h>
 #include <ftl/enum.h>
 #include <log/log.h>
-#include <utils/Trace.h>
 
 #include <scheduler/Timer.h>
 
@@ -188,9 +188,9 @@
         int nfds = epoll_wait(mEpollFd, events, DispatchType::MAX_DISPATCH_TYPE, -1);
 
         setDebugState(DebugState::Running);
-        if (ATRACE_ENABLED()) {
+        if (SFTRACE_ENABLED()) {
             ftl::Concat trace("TimerIteration #", iteration++);
-            ATRACE_NAME(trace.c_str());
+            SFTRACE_NAME(trace.c_str());
         }
 
         if (nfds == -1) {
diff --git a/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp b/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp
index 5448eec..190d062 100644
--- a/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp
+++ b/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp
@@ -57,6 +57,10 @@
         return target().wouldPresentEarly(minFramePeriod);
     }
 
+    FrameTarget::FenceWithFenceTime presentFenceForPastVsync(Period minFramePeriod) const {
+        return target().presentFenceForPastVsync(minFramePeriod);
+    }
+
     struct Frame {
         Frame(FrameTargeterTestBase* testPtr, VsyncId vsyncId, TimePoint& frameBeginTime,
               Duration frameDuration, Fps refreshRate, Fps peakRefreshRate,
@@ -181,7 +185,7 @@
         const auto fence = frame.end();
 
         EXPECT_EQ(target().pastVsyncTime(kPeriod), frameBeginTime + kFrameDuration - kPeriod);
-        EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), fence);
+        EXPECT_EQ(presentFenceForPastVsync(kPeriod).fenceTime, fence);
     }
 }
 
@@ -200,7 +204,7 @@
         const auto fence = frame.end();
 
         EXPECT_EQ(target().pastVsyncTime(kPeriod), frameBeginTime + kFrameDuration - 2 * kPeriod);
-        EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), previousFence);
+        EXPECT_EQ(presentFenceForPastVsync(kPeriod).fenceTime, previousFence);
 
         previousFence = fence;
     }
@@ -222,7 +226,7 @@
 
         const auto pastVsyncTime = frameBeginTime + kFrameDuration - 2 * kPeriod;
         EXPECT_EQ(target().pastVsyncTime(kPeriod), pastVsyncTime);
-        EXPECT_EQ(target().presentFenceForPastVsync(kFrameDuration), previousFence);
+        EXPECT_EQ(presentFenceForPastVsync(kFrameDuration).fenceTime, previousFence);
 
         frameBeginTime += kPeriod;
         previousFence = fence;
@@ -248,7 +252,7 @@
         const auto fence = frame.end();
 
         EXPECT_EQ(target().pastVsyncTime(kPeriod), frameBeginTime + kFrameDuration - 2 * kPeriod);
-        EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), previousFence);
+        EXPECT_EQ(presentFenceForPastVsync(kPeriod).fenceTime, previousFence);
 
         previousFence = fence;
     }
@@ -274,7 +278,7 @@
 
         const auto pastVsyncTime = frameBeginTime + kFrameDuration - 2 * kPeriod;
         EXPECT_EQ(target().pastVsyncTime(kPeriod), pastVsyncTime);
-        EXPECT_EQ(target().presentFenceForPastVsync(kFrameDuration), previousFence);
+        EXPECT_EQ(presentFenceForPastVsync(kFrameDuration).fenceTime, previousFence);
 
         frameBeginTime += kPeriod;
         previousFence = fence;
@@ -283,7 +287,7 @@
 
 TEST_F(FrameTargeterTest, doesNotDetectEarlyPresentIfNoFence) {
     constexpr Period kPeriod = (60_Hz).getPeriod();
-    EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), FenceTime::NO_FENCE);
+    EXPECT_EQ(presentFenceForPastVsync(kPeriod).fenceTime, FenceTime::NO_FENCE);
     EXPECT_FALSE(wouldPresentEarly(kPeriod));
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f9262a0..f617638 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -42,6 +42,7 @@
 #include <binder/PermissionCache.h>
 #include <com_android_graphics_surfaceflinger_flags.h>
 #include <common/FlagManager.h>
+#include <common/trace.h>
 #include <compositionengine/CompositionEngine.h>
 #include <compositionengine/CompositionRefreshArgs.h>
 #include <compositionengine/Display.h>
@@ -71,7 +72,6 @@
 #include <gui/LayerState.h>
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
-#include <gui/TraceUtils.h>
 #include <hidl/ServiceManagement.h>
 #include <layerproto/LayerProtoParser.h>
 #include <linux/sched/types.h>
@@ -143,6 +143,7 @@
 #include "FrontEnd/LayerLog.h"
 #include "FrontEnd/LayerSnapshot.h"
 #include "HdrLayerInfoReporter.h"
+#include "Jank/JankTracker.h"
 #include "Layer.h"
 #include "LayerProtoHelper.h"
 #include "LayerRenderArea.h"
@@ -433,7 +434,7 @@
 }
 
 SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGI("SurfaceFlinger is starting");
 
     hasSyncFramework = running_without_sync_framework(true);
@@ -533,9 +534,6 @@
 
     mIgnoreHdrCameraLayers = ignore_hdr_camera_layers(false);
 
-    mLayerLifecycleManagerEnabled =
-            base::GetBoolProperty("persist.debug.sf.enable_layer_lifecycle_manager"s, true);
-
     // These are set by the HWC implementation to indicate that they will use the workarounds.
     mIsHotplugErrViaNegVsync =
             base::GetBoolProperty("debug.sf.hwc_hotplug_error_via_neg_vsync"s, false);
@@ -728,6 +726,7 @@
     mBootFinished = true;
     FlagManager::getMutableInstance().markBootCompleted();
 
+    ::tracing_perfetto::registerWithPerfetto();
     mInitBootPropsFuture.wait();
     mRenderEnginePrimeCacheFuture.wait();
 
@@ -860,7 +859,7 @@
 }
 
 void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGI(  "SurfaceFlinger's main thread ready to run. "
             "Initializing graphics H/W...");
     addTransactionReadyFilters();
@@ -1312,7 +1311,7 @@
     const auto mode = desiredMode.mode;
     const auto displayId = mode.modePtr->getPhysicalDisplayId();
 
-    ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
+    SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
 
     const bool emitEvent = desiredMode.emitEvent;
 
@@ -1365,7 +1364,7 @@
 
 status_t SurfaceFlinger::setActiveModeFromBackdoor(const sp<display::DisplayToken>& displayToken,
                                                    DisplayModeId modeId, Fps minFps, Fps maxFps) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (!displayToken) {
         return BAD_VALUE;
@@ -1414,8 +1413,10 @@
     return future.get();
 }
 
+// TODO: b/241285876 - Restore thread safety analysis once mStateLock below is unconditional.
+[[clang::no_thread_safety_analysis]]
 void SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) {
-    ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
+    SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
 
     const auto pendingModeOpt = mDisplayModeController.getPendingMode(displayId);
     if (!pendingModeOpt) {
@@ -1429,7 +1430,7 @@
     if (const auto oldResolution =
                 mDisplayModeController.getActiveMode(displayId).modePtr->getResolution();
         oldResolution != activeMode.modePtr->getResolution()) {
-        Mutex::Autolock lock(mStateLock);
+        ConditionalLock lock(mStateLock, !FlagManager::getInstance().connected_display());
 
         auto& state = mCurrentState.displays.editValueFor(getPhysicalDisplayTokenLocked(displayId));
         // We need to generate new sequenceId in order to recreate the display (and this
@@ -1479,11 +1480,9 @@
 }
 
 void SurfaceFlinger::initiateDisplayModeChanges() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
-    std::optional<PhysicalDisplayId> displayToUpdateImmediately;
-
-    for (const auto& [displayId, physical] : FTL_FAKE_GUARD(mStateLock, mPhysicalDisplays)) {
+    for (const auto& [displayId, physical] : mPhysicalDisplays) {
         auto desiredModeOpt = mDisplayModeController.getDesiredMode(displayId);
         if (!desiredModeOpt) {
             continue;
@@ -1536,21 +1535,14 @@
         if (outTimeline.refreshRequired) {
             scheduleComposite(FrameHint::kNone);
         } else {
-            // TODO(b/255635711): Remove `displayToUpdateImmediately` to `finalizeDisplayModeChange`
-            // for all displays. This was only needed when the loop iterated over `mDisplays` rather
-            // than `mPhysicalDisplays`.
-            displayToUpdateImmediately = displayId;
-        }
-    }
+            // HWC has requested to apply the mode change immediately rather than on the next frame.
+            finalizeDisplayModeChange(displayId);
 
-    if (displayToUpdateImmediately) {
-        const auto displayId = *displayToUpdateImmediately;
-        finalizeDisplayModeChange(displayId);
-
-        const auto desiredModeOpt = mDisplayModeController.getDesiredMode(displayId);
-        if (desiredModeOpt &&
-            mDisplayModeController.getActiveMode(displayId) == desiredModeOpt->mode) {
-            applyActiveMode(displayId);
+            const auto desiredModeOpt = mDisplayModeController.getDesiredMode(displayId);
+            if (desiredModeOpt &&
+                mDisplayModeController.getActiveMode(displayId) == desiredModeOpt->mode) {
+                applyActiveMode(displayId);
+            }
         }
     }
 }
@@ -1558,7 +1550,7 @@
 void SurfaceFlinger::disableExpensiveRendering() {
     const char* const whence = __func__;
     auto future = mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
-        ATRACE_NAME(whence);
+        SFTRACE_NAME(whence);
         if (mPowerAdvisor->isUsingExpensiveRendering()) {
             for (const auto& [_, display] : mDisplays) {
                 constexpr bool kDisable = false;
@@ -2223,9 +2215,9 @@
         }
     }
 
-    ATRACE_NAME(vsyncPeriod
-                        ? ftl::Concat(__func__, ' ', hwcDisplayId, ' ', *vsyncPeriod, "ns").c_str()
-                        : ftl::Concat(__func__, ' ', hwcDisplayId).c_str());
+    SFTRACE_NAME(vsyncPeriod
+                         ? ftl::Concat(__func__, ' ', hwcDisplayId, ' ', *vsyncPeriod, "ns").c_str()
+                         : ftl::Concat(__func__, ' ', hwcDisplayId).c_str());
 
     Mutex::Autolock lock(mStateLock);
     if (const auto displayIdOpt = getHwComposer().onVsync(hwcDisplayId, timestamp)) {
@@ -2283,12 +2275,12 @@
 }
 
 void SurfaceFlinger::onComposerHalVsyncIdle(hal::HWDisplayId) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     mScheduler->forceNextResync();
 }
 
 void SurfaceFlinger::onRefreshRateChangedDebug(const RefreshRateChangedDebugData& data) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     const char* const whence = __func__;
     static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(
                                                    kMainThreadContext) {
@@ -2297,7 +2289,7 @@
                 const Fps refreshRate = Fps::fromPeriodNsecs(
                         getHwComposer().getComposer()->isVrrSupported() ? data.refreshPeriodNanos
                                                                         : data.vsyncPeriodNanos);
-                ATRACE_FORMAT("%s refresh rate = %d", whence, refreshRate.getIntValue());
+                SFTRACE_FORMAT("%s refresh rate = %d", whence, refreshRate.getIntValue());
 
                 const auto renderRate = mDisplayModeController.getActiveMode(*displayIdOpt).fps;
                 constexpr bool kSetByHwc = true;
@@ -2317,7 +2309,7 @@
 bool SurfaceFlinger::updateLayerSnapshotsLegacy(VsyncId vsyncId, nsecs_t frameTimeNs,
                                                 bool flushTransactions,
                                                 bool& outTransactionsAreEmpty) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     frontend::Update update;
     if (flushTransactions) {
         update = flushLifecycleUpdates();
@@ -2416,10 +2408,10 @@
 bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs,
                                           bool flushTransactions, bool& outTransactionsAreEmpty) {
     using Changes = frontend::RequestedLayerState::Changes;
-    ATRACE_CALL();
+    SFTRACE_CALL();
     frontend::Update update;
     if (flushTransactions) {
-        ATRACE_NAME("TransactionHandler:flushTransactions");
+        SFTRACE_NAME("TransactionHandler:flushTransactions");
         // Locking:
         // 1. to prevent onHandleDestroyed from being called while the state lock is held,
         // we must keep a copy of the transactions (specifically the composer
@@ -2471,7 +2463,7 @@
     mustComposite |= applyAndCommitDisplayTransactionStatesLocked(update.transactions);
 
     {
-        ATRACE_NAME("LayerSnapshotBuilder:update");
+        SFTRACE_NAME("LayerSnapshotBuilder:update");
         frontend::LayerSnapshotBuilder::Args
                 args{.root = mLayerHierarchyBuilder.getHierarchy(),
                      .layerLifecycleManager = mLayerLifecycleManager,
@@ -2512,7 +2504,7 @@
     }
 
     bool newDataLatched = false;
-    ATRACE_NAME("DisplayCallbackAndStatsUpdates");
+    SFTRACE_NAME("DisplayCallbackAndStatsUpdates");
     mustComposite |= applyTransactionsLocked(update.transactions, vsyncId);
     traverseLegacyLayers([&](Layer* layer) { layer->commitTransaction(); });
     const nsecs_t latchTime = systemTime();
@@ -2578,7 +2570,7 @@
     }
 
     {
-        ATRACE_NAME("LLM:commitChanges");
+        SFTRACE_NAME("LLM:commitChanges");
         mLayerLifecycleManager.commitChanges();
     }
 
@@ -2601,7 +2593,7 @@
     const scheduler::FrameTarget& pacesetterFrameTarget = *frameTargets.get(pacesetterId)->get();
 
     const VsyncId vsyncId = pacesetterFrameTarget.vsyncId();
-    ATRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str());
+    SFTRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str());
 
     if (pacesetterFrameTarget.didMissFrame()) {
         mTimeStats->incrementMissedFrames();
@@ -2618,9 +2610,13 @@
         return false;
     }
 
-    for (const auto [displayId, _] : frameTargets) {
-        if (mDisplayModeController.isModeSetPending(displayId)) {
-            finalizeDisplayModeChange(displayId);
+    {
+        ConditionalLock lock(mStateLock, FlagManager::getInstance().connected_display());
+
+        for (const auto [displayId, _] : frameTargets) {
+            if (mDisplayModeController.isModeSetPending(displayId)) {
+                finalizeDisplayModeChange(displayId);
+            }
         }
     }
 
@@ -2677,11 +2673,8 @@
 
         const bool flushTransactions = clearTransactionFlags(eTransactionFlushNeeded);
         bool transactionsAreEmpty = false;
-        if (mLayerLifecycleManagerEnabled) {
-            mustComposite |=
-                    updateLayerSnapshots(vsyncId, pacesetterFrameTarget.frameBeginTime().ns(),
-                                         flushTransactions, transactionsAreEmpty);
-        }
+        mustComposite |= updateLayerSnapshots(vsyncId, pacesetterFrameTarget.frameBeginTime().ns(),
+                                              flushTransactions, transactionsAreEmpty);
 
         // Tell VsyncTracker that we are going to present this frame before scheduling
         // setTransactionFlags which will schedule another SF frame. This was if the tracker
@@ -2715,13 +2708,18 @@
         mUpdateAttachedChoreographer = false;
 
         Mutex::Autolock lock(mStateLock);
-        mScheduler->chooseRefreshRateForContent(mLayerLifecycleManagerEnabled
-                                                        ? &mLayerHierarchyBuilder.getHierarchy()
-                                                        : nullptr,
+        mScheduler->chooseRefreshRateForContent(&mLayerHierarchyBuilder.getHierarchy(),
                                                 updateAttachedChoreographer);
+
+        if (FlagManager::getInstance().connected_display()) {
+            initiateDisplayModeChanges();
+        }
     }
 
-    initiateDisplayModeChanges();
+    if (!FlagManager::getInstance().connected_display()) {
+        ftl::FakeGuard guard(mStateLock);
+        initiateDisplayModeChanges();
+    }
 
     updateCursorAsync();
     if (!mustComposite) {
@@ -2743,7 +2741,7 @@
             frameTargeters.get(pacesetterId)->get()->target();
 
     const VsyncId vsyncId = pacesetterTarget.vsyncId();
-    ATRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str());
+    SFTRACE_NAME(ftl::Concat(__func__, ' ', ftl::to_underlying(vsyncId)).c_str());
 
     compositionengine::CompositionRefreshArgs refreshArgs;
     refreshArgs.powerCallback = this;
@@ -2831,7 +2829,7 @@
     constexpr bool kCursorOnly = false;
     const auto layers = moveSnapshotsToCompositionArgs(refreshArgs, kCursorOnly);
 
-    if (mLayerLifecycleManagerEnabled && !mVisibleRegionsDirty) {
+    if (!mVisibleRegionsDirty) {
         for (const auto& [token, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
             auto compositionDisplay = display->getCompositionDisplay();
             if (!compositionDisplay->getState().isEnabled) continue;
@@ -2907,6 +2905,7 @@
         }
     }
 
+    SFTRACE_NAME("postComposition");
     mTimeStats->recordFrameDuration(pacesetterTarget.frameBeginTime().ns(), systemTime());
 
     // Send a power hint after presentation is finished.
@@ -3002,7 +3001,7 @@
 }
 
 void SurfaceFlinger::updateLayerGeometry() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (mVisibleRegionsDirty) {
         computeLayerBounds();
@@ -3086,7 +3085,7 @@
 void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId,
                                             const scheduler::FrameTargeters& frameTargeters,
                                             nsecs_t presentStartTime) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     ui::PhysicalDisplayMap<PhysicalDisplayId, std::shared_ptr<FenceTime>> presentFences;
     ui::PhysicalDisplayMap<PhysicalDisplayId, const sp<Fence>> gpuCompositionDoneFences;
@@ -3246,28 +3245,20 @@
                         }
                     };
 
-            if (mLayerLifecycleManagerEnabled) {
-                mLayerSnapshotBuilder.forEachVisibleSnapshot(
-                        [&, compositionDisplay = compositionDisplay](
-                                std::unique_ptr<frontend::LayerSnapshot>&
-                                        snapshot) FTL_FAKE_GUARD(kMainThreadContext) {
-                            auto it = mLegacyLayers.find(snapshot->sequence);
-                            LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
-                                                            "Couldnt find layer object for %s",
-                                                            snapshot->getDebugString().c_str());
-                            auto& legacyLayer = it->second;
-                            sp<LayerFE> layerFe =
-                                    legacyLayer->getCompositionEngineLayerFE(snapshot->path);
+            mLayerSnapshotBuilder.forEachVisibleSnapshot(
+                    [&, compositionDisplay = compositionDisplay](
+                            std::unique_ptr<frontend::LayerSnapshot>& snapshot)
+                            FTL_FAKE_GUARD(kMainThreadContext) {
+                                auto it = mLegacyLayers.find(snapshot->sequence);
+                                LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
+                                                                "Couldnt find layer object for %s",
+                                                                snapshot->getDebugString().c_str());
+                                auto& legacyLayer = it->second;
+                                sp<LayerFE> layerFe =
+                                        legacyLayer->getCompositionEngineLayerFE(snapshot->path);
 
-                            updateInfoFn(compositionDisplay, *snapshot, layerFe);
-                        });
-            } else {
-                mDrawingState.traverse([&, compositionDisplay = compositionDisplay](Layer* layer) {
-                    const auto layerFe = layer->getCompositionEngineLayerFE();
-                    const frontend::LayerSnapshot& snapshot = *layer->getLayerSnapshot();
-                    updateInfoFn(compositionDisplay, snapshot, layerFe);
-                });
-            }
+                                updateInfoFn(compositionDisplay, *snapshot, layerFe);
+                            });
             listener->dispatchHdrLayerInfo(info);
         }
     }
@@ -3313,9 +3304,8 @@
             if (!layer->hasTrustedPresentationListener()) {
                 return;
             }
-            const frontend::LayerSnapshot* snapshot = mLayerLifecycleManagerEnabled
-                    ? mLayerSnapshotBuilder.getSnapshot(layer->sequence)
-                    : layer->getLayerSnapshot();
+            const frontend::LayerSnapshot* snapshot =
+                    mLayerSnapshotBuilder.getSnapshot(layer->sequence);
             std::optional<const DisplayDevice*> displayOpt = std::nullopt;
             if (snapshot) {
                 displayOpt = layerStackToDisplay.get(snapshot->outputFilter.layerStack);
@@ -3327,11 +3317,11 @@
         });
     }
 
-    // Even though ATRACE_INT64 already checks if tracing is enabled, it doesn't prevent the
+    // Even though SFTRACE_INT64 already checks if tracing is enabled, it doesn't prevent the
     // side-effect of getTotalSize(), so we check that again here
-    if (ATRACE_ENABLED()) {
+    if (SFTRACE_ENABLED()) {
         // getTotalSize returns the total number of buffers that were allocated by SurfaceFlinger
-        ATRACE_INT64("Total Buffer Size", GraphicBufferAllocator::get().getTotalSize());
+        SFTRACE_INT64("Total Buffer Size", GraphicBufferAllocator::get().getTotalSize());
     }
 
     logFrameStats(presentTime);
@@ -3368,7 +3358,7 @@
 }
 
 void SurfaceFlinger::commitTransactions() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     mDebugInTransaction = systemTime();
 
     // Here we're guaranteed that some transaction flags are set
@@ -3381,7 +3371,7 @@
 }
 
 void SurfaceFlinger::commitTransactionsLegacy() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     // Keep a copy of the drawing state (that is going to be overwritten
     // by commitTransactionsLocked) outside of mStateLock so that the side
@@ -3660,7 +3650,12 @@
     state.physical = {.id = displayId,
                       .hwcDisplayId = hwcDisplayId,
                       .activeMode = std::move(activeMode)};
-    state.isSecure = connectionType == ui::DisplayConnectionType::Internal;
+    if (mIsHdcpViaNegVsync) {
+        state.isSecure = connectionType == ui::DisplayConnectionType::Internal;
+    } else {
+        // TODO(b/349703362): Remove this when HDCP aidl API becomes ready
+        state.isSecure = true; // All physical displays are currently considered secure.
+    }
     state.isProtected = true;
     state.displayName = std::move(info.name);
 
@@ -3769,7 +3764,7 @@
     if (const auto& physical = state.physical) {
         const auto& mode = *physical->activeMode;
         mDisplayModeController.setActiveMode(physical->id, mode.getId(), mode.getVsyncRate(),
-                                             mode.getVsyncRate());
+                                             mode.getPeakFps());
     }
 
     display->setLayerFilter(makeLayerFilterForDisplay(display->getId(), state.layerStack));
@@ -3855,7 +3850,8 @@
         ftl::FakeGuard guard(kMainThreadContext);
 
         // For hotplug reconnect, renew the registration since display modes have been reloaded.
-        mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector());
+        mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(),
+                                    mActiveDisplayId);
     }
 
     if (display->isVirtual()) {
@@ -3894,7 +3890,7 @@
         if (display->isVirtual()) {
             releaseVirtualDisplay(display->getVirtualId());
         } else {
-            mScheduler->unregisterDisplay(display->getPhysicalId());
+            mScheduler->unregisterDisplay(display->getPhysicalId(), mActiveDisplayId);
         }
     }
 
@@ -4034,13 +4030,6 @@
     // Commit display transactions.
     const bool displayTransactionNeeded = transactionFlags & eDisplayTransactionNeeded;
     mFrontEndDisplayInfosChanged = displayTransactionNeeded;
-    if (displayTransactionNeeded && !mLayerLifecycleManagerEnabled) {
-        processDisplayChangesLocked();
-        mFrontEndDisplayInfos.clear();
-        for (const auto& [_, display] : mDisplays) {
-            mFrontEndDisplayInfos.try_emplace(display->getLayerStack(), display->getFrontEndInfo());
-        }
-    }
     mForceTransactionDisplayChange = displayTransactionNeeded;
 
     if (mSomeChildrenChanged) {
@@ -4128,7 +4117,7 @@
     if (!mInputFlinger || (!mUpdateInputInfo && mInputWindowCommands.empty())) {
         return;
     }
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::vector<WindowInfo> windowInfos;
     std::vector<DisplayInfo> displayInfos;
@@ -4158,7 +4147,7 @@
                                                               std::move(mInputWindowCommands),
                                                       inputFlinger = mInputFlinger, this,
                                                       visibleWindowsChanged, vsyncId, frameTime]() {
-        ATRACE_NAME("BackgroundExecutor::updateInputFlinger");
+        SFTRACE_NAME("BackgroundExecutor::updateInputFlinger");
         if (updateWindowInfo) {
             mWindowInfosListenerInvoker
                     ->windowInfosChanged(gui::WindowInfosUpdate{std::move(windowInfos),
@@ -4221,23 +4210,10 @@
     outWindowInfos.reserve(sNumWindowInfos);
     sNumWindowInfos = 0;
 
-    if (mLayerLifecycleManagerEnabled) {
-        mLayerSnapshotBuilder.forEachInputSnapshot(
-                [&outWindowInfos](const frontend::LayerSnapshot& snapshot) {
-                    outWindowInfos.push_back(snapshot.inputInfo);
-                });
-    } else {
-        mDrawingState.traverseInReverseZOrder([&](Layer* layer) FTL_FAKE_GUARD(kMainThreadContext) {
-            if (!layer->needsInputInfo()) return;
-            const auto opt =
-                    mFrontEndDisplayInfos.get(layer->getLayerStack())
-                            .transform([](const frontend::DisplayInfo& info) {
-                                return Layer::InputDisplayArgs{&info.transform, info.isSecure};
-                            });
-
-            outWindowInfos.push_back(layer->fillInputInfo(opt.value_or(Layer::InputDisplayArgs{})));
-        });
-    }
+    mLayerSnapshotBuilder.forEachInputSnapshot(
+            [&outWindowInfos](const frontend::LayerSnapshot& snapshot) {
+                outWindowInfos.push_back(snapshot.inputInfo);
+            });
 
     sNumWindowInfos = outWindowInfos.size();
 
@@ -4271,7 +4247,7 @@
         return;
     }
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     // If this is called from the main thread mStateLock must be locked before
     // Currently the only way to call this function from the main thread is from
@@ -4310,11 +4286,9 @@
 }
 
 void SurfaceFlinger::onChoreographerAttached() {
-    ATRACE_CALL();
-    if (mLayerLifecycleManagerEnabled) {
-        mUpdateAttachedChoreographer = true;
-        scheduleCommit(FrameHint::kNone);
-    }
+    SFTRACE_CALL();
+    mUpdateAttachedChoreographer = true;
+    scheduleCommit(FrameHint::kNone);
 }
 
 void SurfaceFlinger::onExpectedPresentTimePosted(TimePoint expectedPresentTime,
@@ -4506,7 +4480,8 @@
                                              getFactory(), activeRefreshRate, *mTimeStats);
 
     // The pacesetter must be registered before EventThread creation below.
-    mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector());
+    mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(),
+                                mActiveDisplayId);
     if (FlagManager::getInstance().vrr_config()) {
         mScheduler->setRenderRate(display->getPhysicalId(), activeMode.fps,
                                   /*applyImmediately*/ true);
@@ -4537,7 +4512,7 @@
 }
 
 void SurfaceFlinger::doCommitTransactions() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (!mLayersPendingRemoval.isEmpty()) {
         // Notify removed layers now that they can't be drawn from
@@ -4618,7 +4593,7 @@
 }
 
 bool SurfaceFlinger::latchBuffers() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     const nsecs_t latchTime = systemTime();
 
@@ -4795,7 +4770,7 @@
 
 uint32_t SurfaceFlinger::clearTransactionFlags(uint32_t mask) {
     uint32_t transactionFlags = mTransactionFlags.fetch_and(~mask);
-    ATRACE_INT("mTransactionFlags", transactionFlags);
+    SFTRACE_INT("mTransactionFlags", transactionFlags);
     return transactionFlags & mask;
 }
 
@@ -4803,7 +4778,7 @@
                                          const sp<IBinder>& applyToken, FrameHint frameHint) {
     mScheduler->modulateVsync({}, &VsyncModulator::setTransactionSchedule, schedule, applyToken);
     uint32_t transactionFlags = mTransactionFlags.fetch_or(mask);
-    ATRACE_INT("mTransactionFlags", transactionFlags);
+    SFTRACE_INT("mTransactionFlags", transactionFlags);
 
     if (const bool scheduled = transactionFlags & mask; !scheduled) {
         scheduleCommit(frameHint);
@@ -4828,8 +4803,8 @@
     // for stability reasons.
     if (!transaction.isAutoTimestamp && desiredPresentTime >= expectedPresentTime &&
         desiredPresentTime < expectedPresentTime + 1s) {
-        ATRACE_FORMAT("not current desiredPresentTime: %" PRId64 " expectedPresentTime: %" PRId64,
-                      desiredPresentTime, expectedPresentTime);
+        SFTRACE_FORMAT("not current desiredPresentTime: %" PRId64 " expectedPresentTime: %" PRId64,
+                       desiredPresentTime, expectedPresentTime);
         return TransactionReadiness::NotReady;
     }
 
@@ -4841,117 +4816,22 @@
     // incorrectly as the frame rate of SF changed before it drained the older transactions.
     if (ftl::to_underlying(vsyncId) == FrameTimelineInfo::INVALID_VSYNC_ID &&
         !mScheduler->isVsyncValid(expectedPresentTime, transaction.originUid)) {
-        ATRACE_FORMAT("!isVsyncValid expectedPresentTime: %" PRId64 " uid: %d", expectedPresentTime,
-                      transaction.originUid);
+        SFTRACE_FORMAT("!isVsyncValid expectedPresentTime: %" PRId64 " uid: %d",
+                       expectedPresentTime, transaction.originUid);
         return TransactionReadiness::NotReady;
     }
 
     // If the client didn't specify desiredPresentTime, use the vsyncId to determine the
     // expected present time of this transaction.
     if (transaction.isAutoTimestamp && frameIsEarly(expectedPresentTime, vsyncId)) {
-        ATRACE_FORMAT("frameIsEarly vsyncId: %" PRId64 " expectedPresentTime: %" PRId64,
-                      transaction.frameTimelineInfo.vsyncId, expectedPresentTime);
+        SFTRACE_FORMAT("frameIsEarly vsyncId: %" PRId64 " expectedPresentTime: %" PRId64,
+                       transaction.frameTimelineInfo.vsyncId, expectedPresentTime);
         return TransactionReadiness::NotReady;
     }
 
     return TransactionReadiness::Ready;
 }
 
-TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferCheckLegacy(
-        const TransactionHandler::TransactionFlushState& flushState) {
-    using TransactionReadiness = TransactionHandler::TransactionReadiness;
-    auto ready = TransactionReadiness::Ready;
-    flushState.transaction->traverseStatesWithBuffersWhileTrue([&](const ResolvedComposerState&
-                                                                           resolvedState) -> bool {
-        sp<Layer> layer = LayerHandle::getLayer(resolvedState.state.surface);
-
-        const auto& transaction = *flushState.transaction;
-        const auto& s = resolvedState.state;
-        // check for barrier frames
-        if (s.bufferData->hasBarrier) {
-            // The current producerId is already a newer producer than the buffer that has a
-            // barrier. This means the incoming buffer is older and we can release it here. We
-            // don't wait on the barrier since we know that's stale information.
-            if (layer->getDrawingState().barrierProducerId > s.bufferData->producerId) {
-                layer->callReleaseBufferCallback(s.bufferData->releaseBufferListener,
-                                                 resolvedState.externalTexture->getBuffer(),
-                                                 s.bufferData->frameNumber,
-                                                 s.bufferData->acquireFence);
-                // Delete the entire state at this point and not just release the buffer because
-                // everything associated with the Layer in this Transaction is now out of date.
-                ATRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d",
-                              layer->getDebugName(), layer->getDrawingState().barrierProducerId,
-                              s.bufferData->producerId);
-                return TraverseBuffersReturnValues::DELETE_AND_CONTINUE_TRAVERSAL;
-            }
-
-            if (layer->getDrawingState().barrierFrameNumber < s.bufferData->barrierFrameNumber) {
-                const bool willApplyBarrierFrame =
-                        flushState.bufferLayersReadyToPresent.contains(s.surface.get()) &&
-                        ((flushState.bufferLayersReadyToPresent.get(s.surface.get()) >=
-                          s.bufferData->barrierFrameNumber));
-                if (!willApplyBarrierFrame) {
-                    ATRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64 " > %" PRId64,
-                                  layer->getDebugName(),
-                                  layer->getDrawingState().barrierFrameNumber,
-                                  s.bufferData->barrierFrameNumber);
-                    ready = TransactionReadiness::NotReadyBarrier;
-                    return TraverseBuffersReturnValues::STOP_TRAVERSAL;
-                }
-            }
-        }
-
-        // If backpressure is enabled and we already have a buffer to commit, keep
-        // the transaction in the queue.
-        const bool hasPendingBuffer =
-                flushState.bufferLayersReadyToPresent.contains(s.surface.get());
-        if (layer->backpressureEnabled() && hasPendingBuffer && transaction.isAutoTimestamp) {
-            ATRACE_FORMAT("hasPendingBuffer %s", layer->getDebugName());
-            ready = TransactionReadiness::NotReady;
-            return TraverseBuffersReturnValues::STOP_TRAVERSAL;
-        }
-
-        const bool acquireFenceAvailable = s.bufferData &&
-                s.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged) &&
-                s.bufferData->acquireFence;
-        const bool fenceSignaled = !acquireFenceAvailable ||
-                s.bufferData->acquireFence->getStatus() != Fence::Status::Unsignaled;
-        if (!fenceSignaled) {
-            // check fence status
-            const bool allowLatchUnsignaled = shouldLatchUnsignaled(s, transaction.states.size(),
-                                                                    flushState.firstTransaction) &&
-                    layer->isSimpleBufferUpdate(s);
-
-            if (allowLatchUnsignaled) {
-                ATRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s",
-                              layer->getDebugName());
-                ready = TransactionReadiness::NotReadyUnsignaled;
-            } else {
-                ready = TransactionReadiness::NotReady;
-                auto& listener = s.bufferData->releaseBufferListener;
-                if (listener &&
-                    (flushState.queueProcessTime - transaction.postTime) >
-                            std::chrono::nanoseconds(4s).count()) {
-                    // Used to add a stalled transaction which uses an internal lock.
-                    ftl::FakeGuard guard(kMainThreadContext);
-                    mTransactionHandler
-                            .onTransactionQueueStalled(transaction.id,
-                                                       {.pid = layer->getOwnerPid(),
-                                                        .layerId = static_cast<uint32_t>(
-                                                                layer->getSequence()),
-                                                        .layerName = layer->getDebugName(),
-                                                        .bufferId = s.bufferData->getId(),
-                                                        .frameNumber = s.bufferData->frameNumber});
-                }
-                ATRACE_FORMAT("fence unsignaled %s", layer->getDebugName());
-                return TraverseBuffersReturnValues::STOP_TRAVERSAL;
-            }
-        }
-        return TraverseBuffersReturnValues::CONTINUE_TRAVERSAL;
-    });
-    return ready;
-}
-
 TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferCheck(
         const TransactionHandler::TransactionFlushState& flushState) {
     using TransactionReadiness = TransactionHandler::TransactionReadiness;
@@ -4973,8 +4853,8 @@
                             uint32_t currentMaxAcquiredBufferCount =
                                     getMaxAcquiredBufferCountForCurrentRefreshRate(
                                             layer->ownerUid.val());
-                            ATRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64,
-                                                  layer->name.c_str(), s.bufferData->frameNumber);
+                            SFTRACE_FORMAT_INSTANT("callReleaseBufferCallback %s - %" PRIu64,
+                                                   layer->name.c_str(), s.bufferData->frameNumber);
                             s.bufferData->releaseBufferListener
                                     ->onReleaseBuffer({resolvedState.externalTexture->getBuffer()
                                                                ->getId(),
@@ -4988,9 +4868,9 @@
                         // Delete the entire state at this point and not just release the buffer
                         // because everything associated with the Layer in this Transaction is now
                         // out of date.
-                        ATRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d",
-                                      layer->name.c_str(), layer->barrierProducerId,
-                                      s.bufferData->producerId);
+                        SFTRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d",
+                                       layer->name.c_str(), layer->barrierProducerId,
+                                       s.bufferData->producerId);
                         return TraverseBuffersReturnValues::DELETE_AND_CONTINUE_TRAVERSAL;
                     }
 
@@ -5000,10 +4880,10 @@
                                 ((flushState.bufferLayersReadyToPresent.get(s.surface.get()) >=
                                   s.bufferData->barrierFrameNumber));
                         if (!willApplyBarrierFrame) {
-                            ATRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64
-                                          " > %" PRId64,
-                                          layer->name.c_str(), layer->barrierFrameNumber,
-                                          s.bufferData->barrierFrameNumber);
+                            SFTRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64
+                                           " > %" PRId64,
+                                           layer->name.c_str(), layer->barrierFrameNumber,
+                                           s.bufferData->barrierFrameNumber);
                             ready = TransactionReadiness::NotReadyBarrier;
                             return TraverseBuffersReturnValues::STOP_TRAVERSAL;
                         }
@@ -5016,7 +4896,7 @@
                         flushState.bufferLayersReadyToPresent.contains(s.surface.get());
                 if (layer->backpressureEnabled() && hasPendingBuffer &&
                     transaction.isAutoTimestamp) {
-                    ATRACE_FORMAT("hasPendingBuffer %s", layer->name.c_str());
+                    SFTRACE_FORMAT("hasPendingBuffer %s", layer->name.c_str());
                     ready = TransactionReadiness::NotReady;
                     return TraverseBuffersReturnValues::STOP_TRAVERSAL;
                 }
@@ -5033,8 +4913,8 @@
                                                   flushState.firstTransaction) &&
                             layer->isSimpleBufferUpdate(s);
                     if (allowLatchUnsignaled) {
-                        ATRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s",
-                                      layer->name.c_str());
+                        SFTRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s",
+                                       layer->name.c_str());
                         ready = TransactionReadiness::NotReadyUnsignaled;
                     } else {
                         ready = TransactionReadiness::NotReady;
@@ -5051,7 +4931,7 @@
                                                                 .frameNumber =
                                                                         s.bufferData->frameNumber});
                         }
-                        ATRACE_FORMAT("fence unsignaled %s", layer->name.c_str());
+                        SFTRACE_FORMAT("fence unsignaled %s", layer->name.c_str());
                         return TraverseBuffersReturnValues::STOP_TRAVERSAL;
                     }
                 }
@@ -5063,15 +4943,8 @@
 void SurfaceFlinger::addTransactionReadyFilters() {
     mTransactionHandler.addTransactionReadyFilter(
             std::bind(&SurfaceFlinger::transactionReadyTimelineCheck, this, std::placeholders::_1));
-    if (mLayerLifecycleManagerEnabled) {
-        mTransactionHandler.addTransactionReadyFilter(
-                std::bind(&SurfaceFlinger::transactionReadyBufferCheck, this,
-                          std::placeholders::_1));
-    } else {
-        mTransactionHandler.addTransactionReadyFilter(
-                std::bind(&SurfaceFlinger::transactionReadyBufferCheckLegacy, this,
-                          std::placeholders::_1));
-    }
+    mTransactionHandler.addTransactionReadyFilter(
+            std::bind(&SurfaceFlinger::transactionReadyBufferCheck, this, std::placeholders::_1));
 }
 
 // For tests only
@@ -5132,22 +5005,22 @@
 bool SurfaceFlinger::shouldLatchUnsignaled(const layer_state_t& state, size_t numStates,
                                            bool firstTransaction) const {
     if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::Disabled) {
-        ATRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::Disabled)", __func__);
+        SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::Disabled)", __func__);
         return false;
     }
 
     // We only want to latch unsignaled when a single layer is updated in this
     // transaction (i.e. not a blast sync transaction).
     if (numStates != 1) {
-        ATRACE_FORMAT_INSTANT("%s: false (numStates=%zu)", __func__, numStates);
+        SFTRACE_FORMAT_INSTANT("%s: false (numStates=%zu)", __func__, numStates);
         return false;
     }
 
     if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer) {
         if (!firstTransaction) {
-            ATRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; not first "
-                                  "transaction)",
-                                  __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; not first "
+                                   "transaction)",
+                                   __func__);
             return false;
         }
 
@@ -5155,9 +5028,9 @@
         // as it leads to jank due to RenderEngine waiting for unsignaled buffer
         // or window animations being slow.
         if (mScheduler->vsyncModulator().isVsyncConfigEarly()) {
-            ATRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; "
-                                  "isVsyncConfigEarly)",
-                                  __func__);
+            SFTRACE_FORMAT_INSTANT("%s: false (LatchUnsignaledConfig::AutoSingleLayer; "
+                                   "isVsyncConfigEarly)",
+                                   __func__);
             return false;
         }
     }
@@ -5172,7 +5045,7 @@
         const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks,
         const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId,
         const std::vector<uint64_t>& mergedTransactionIds) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     IPCThreadState* ipc = IPCThreadState::self();
     const int originPid = ipc->getCallingPid();
@@ -5303,11 +5176,6 @@
                                            const std::vector<ListenerCallbacks>& listenerCallbacks,
                                            int originPid, int originUid, uint64_t transactionId) {
     uint32_t transactionFlags = 0;
-    if (!mLayerLifecycleManagerEnabled) {
-        for (DisplayState& display : displays) {
-            transactionFlags |= setDisplayStateLocked(display);
-        }
-    }
 
     // start and end registration for listeners w/ no surface so they can get their callback.  Note
     // that listeners with SurfaceControls will start registration during setClientStateLocked
@@ -5315,27 +5183,11 @@
     for (const auto& listener : listenerCallbacks) {
         mTransactionCallbackInvoker.addEmptyTransaction(listener);
     }
-    nsecs_t now = systemTime();
     uint32_t clientStateFlags = 0;
     for (auto& resolvedState : states) {
         clientStateFlags |=
                 updateLayerCallbacksAndStats(frameTimelineInfo, resolvedState, desiredPresentTime,
                                              isAutoTimestamp, postTime, transactionId);
-        if (!mLayerLifecycleManagerEnabled) {
-            if ((flags & eAnimation) && resolvedState.state.surface) {
-                if (const auto layer = LayerHandle::getLayer(resolvedState.state.surface)) {
-                    const auto layerProps = scheduler::LayerProps{
-                            .visible = layer->isVisible(),
-                            .bounds = layer->getBounds(),
-                            .transform = layer->getTransform(),
-                            .setFrameRateVote = layer->getFrameRateForLayerTree(),
-                            .frameRateSelectionPriority = layer->getFrameRateSelectionPriority(),
-                            .isFrontBuffered = layer->isFrontBuffered(),
-                    };
-                    layer->recordLayerHistoryAnimationTx(layerProps, now);
-                }
-            }
-        }
     }
 
     transactionFlags |= clientStateFlags;
@@ -5505,10 +5357,8 @@
     }
     if (layer == nullptr) {
         for (auto& [listener, callbackIds] : s.listeners) {
-            mTransactionCallbackInvoker.addCallbackHandle(sp<CallbackHandle>::make(listener,
-                                                                                   callbackIds,
-                                                                                   s.surface),
-                                                          std::vector<JankData>());
+            mTransactionCallbackInvoker.addCallbackHandle(
+                    sp<CallbackHandle>::make(listener, callbackIds, s.surface));
         }
         return 0;
     }
@@ -5866,10 +5716,8 @@
     }
     if (layer == nullptr) {
         for (auto& [listener, callbackIds] : s.listeners) {
-            mTransactionCallbackInvoker.addCallbackHandle(sp<CallbackHandle>::make(listener,
-                                                                                   callbackIds,
-                                                                                   s.surface),
-                                                          std::vector<JankData>());
+            mTransactionCallbackInvoker.addCallbackHandle(
+                    sp<CallbackHandle>::make(listener, callbackIds, s.surface));
         }
         return 0;
     }
@@ -5941,6 +5789,10 @@
         }
     }
 
+    if (what & layer_state_t::eBufferReleaseChannelChanged) {
+        layer->setBufferReleaseChannel(s.bufferReleaseChannel);
+    }
+
     const auto& requestedLayerState = mLayerLifecycleManager.getLayerFromId(layer->getSequence());
     bool willPresentCurrentTransaction = requestedLayerState &&
             (requestedLayerState->hasReadyFrame() ||
@@ -6112,6 +5964,8 @@
         mTransactionHandler.onLayerDestroyed(layerId);
     }
 
+    JankTracker::flushJankData(layerId);
+
     Mutex::Autolock lock(mStateLock);
     markLayerPendingRemovalLocked(layer);
     layer->onHandleDestroyed();
@@ -6389,15 +6243,23 @@
         return NO_ERROR;
     }
 
-    // Traversal of drawing state must happen on the main thread.
-    // Otherwise, SortedVector may have shared ownership during concurrent
-    // traversals, which can result in use-after-frees.
+    // Collect debug data from main thread
     std::string compositionLayers;
     mScheduler
             ->schedule([&]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(kMainThreadContext) {
                 dumpVisibleFrontEnd(compositionLayers);
             })
             .get();
+    // get window info listener data without the state lock
+    auto windowInfosDebug = mWindowInfosListenerInvoker->getDebugInfo();
+    compositionLayers.append("Window Infos:\n");
+    StringAppendF(&compositionLayers, "  max send vsync id: %" PRId64 "\n",
+                  ftl::to_underlying(windowInfosDebug.maxSendDelayVsyncId));
+    StringAppendF(&compositionLayers, "  max send delay (ns): %" PRId64 " ns\n",
+                  windowInfosDebug.maxSendDelayDuration);
+    StringAppendF(&compositionLayers, "  unsent messages: %zu\n",
+                  windowInfosDebug.pendingMessageCount);
+    compositionLayers.append("\n");
     dumpAll(args, compositionLayers, result);
     write(fd, result.c_str(), result.size());
     return NO_ERROR;
@@ -6449,7 +6311,7 @@
     if (now - sTimestamp < 30min) return;
     sTimestamp = now;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     mDrawingState.traverse([&](Layer* layer) { layer->logFrameStats(); });
 }
 
@@ -6641,53 +6503,35 @@
 }
 
 void SurfaceFlinger::dumpVisibleFrontEnd(std::string& result) {
-    if (!mLayerLifecycleManagerEnabled) {
-        StringAppendF(&result, "Composition layers\n");
-        mDrawingState.traverseInZOrder([&](Layer* layer) {
-            auto* compositionState = layer->getCompositionState();
-            if (!compositionState || !compositionState->isVisible) return;
-            android::base::StringAppendF(&result, "* Layer %p (%s)\n", layer,
-                                         layer->getDebugName() ? layer->getDebugName()
-                                                               : "<unknown>");
-            compositionState->dump(result);
-        });
-
-        StringAppendF(&result, "Offscreen Layers\n");
-        for (Layer* offscreenLayer : mOffscreenLayers) {
-            offscreenLayer->traverse(LayerVector::StateSet::Drawing,
-                                     [&](Layer* layer) { layer->dumpOffscreenDebugInfo(result); });
-        }
-    } else {
-        std::ostringstream out;
-        out << "\nComposition list\n";
-        ui::LayerStack lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
-        mLayerSnapshotBuilder.forEachVisibleSnapshot(
-                [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) {
-                    if (snapshot->hasSomethingToDraw()) {
-                        if (lastPrintedLayerStackHeader != snapshot->outputFilter.layerStack) {
-                            lastPrintedLayerStackHeader = snapshot->outputFilter.layerStack;
-                            out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
-                        }
-                        out << "  " << *snapshot << "\n";
+    std::ostringstream out;
+    out << "\nComposition list\n";
+    ui::LayerStack lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
+    mLayerSnapshotBuilder.forEachVisibleSnapshot(
+            [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) {
+                if (snapshot->hasSomethingToDraw()) {
+                    if (lastPrintedLayerStackHeader != snapshot->outputFilter.layerStack) {
+                        lastPrintedLayerStackHeader = snapshot->outputFilter.layerStack;
+                        out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
                     }
-                });
+                    out << "  " << *snapshot << "\n";
+                }
+            });
 
-        out << "\nInput list\n";
-        lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
-        mLayerSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) {
-            if (lastPrintedLayerStackHeader != snapshot.outputFilter.layerStack) {
-                lastPrintedLayerStackHeader = snapshot.outputFilter.layerStack;
-                out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
-            }
-            out << "  " << snapshot << "\n";
-        });
+    out << "\nInput list\n";
+    lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
+    mLayerSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) {
+        if (lastPrintedLayerStackHeader != snapshot.outputFilter.layerStack) {
+            lastPrintedLayerStackHeader = snapshot.outputFilter.layerStack;
+            out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
+        }
+        out << "  " << snapshot << "\n";
+    });
 
-        out << "\nLayer Hierarchy\n"
-            << mLayerHierarchyBuilder.getHierarchy() << "\nOffscreen Hierarchy\n"
-            << mLayerHierarchyBuilder.getOffscreenHierarchy() << "\n\n";
-        result = out.str();
-        dumpHwcLayersMinidump(result);
-    }
+    out << "\nLayer Hierarchy\n"
+        << mLayerHierarchyBuilder.getHierarchy() << "\nOffscreen Hierarchy\n"
+        << mLayerHierarchyBuilder.getOffscreenHierarchy() << "\n\n";
+    result = out.str();
+    dumpHwcLayersMinidump(result);
 }
 
 perfetto::protos::LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
@@ -6748,14 +6592,24 @@
     rootProto->set_name("Offscreen Root");
     rootProto->set_parent(-1);
 
-    for (Layer* offscreenLayer : mOffscreenLayers) {
-        // Add layer as child of the fake root
-        rootProto->add_children(offscreenLayer->sequence);
+    perfetto::protos::LayersProto offscreenLayers =
+            LayerProtoFromSnapshotGenerator(mLayerSnapshotBuilder, mFrontEndDisplayInfos,
+                                            mLegacyLayers, traceFlags)
+                    .generate(mLayerHierarchyBuilder.getOffscreenHierarchy());
 
-        // Add layer
-        auto* layerProto = offscreenLayer->writeToProto(layersProto, traceFlags);
-        layerProto->set_parent(offscreenRootLayerId);
+    for (int i = 0; i < offscreenLayers.layers_size(); i++) {
+        perfetto::protos::LayerProto* layerProto = offscreenLayers.mutable_layers()->Mutable(i);
+        if (layerProto->parent() == -1) {
+            layerProto->set_parent(offscreenRootLayerId);
+            // Add layer as child of the fake root
+            rootProto->add_children(layerProto->id());
+        }
     }
+
+    layersProto.mutable_layers()->Reserve(layersProto.layers_size() +
+                                          offscreenLayers.layers_size());
+    std::copy(offscreenLayers.layers().begin(), offscreenLayers.layers().end(),
+              RepeatedFieldBackInserter(layersProto.mutable_layers()));
 }
 
 perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) {
@@ -6780,27 +6634,7 @@
     result.append(future.get());
 }
 
-void SurfaceFlinger::dumpHwcLayersMinidumpLockedLegacy(std::string& result) const {
-    for (const auto& [token, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
-        const auto displayId = HalDisplayId::tryCast(display->getId());
-        if (!displayId) {
-            continue;
-        }
-
-        StringAppendF(&result, "Display %s (%s) HWC layers:\n", to_string(*displayId).c_str(),
-                      displayId == mActiveDisplayId ? "active" : "inactive");
-        Layer::miniDumpHeader(result);
-
-        const DisplayDevice& ref = *display;
-        mDrawingState.traverseInZOrder([&](Layer* layer) { layer->miniDumpLegacy(result, ref); });
-        result.append("\n");
-    }
-}
-
 void SurfaceFlinger::dumpHwcLayersMinidump(std::string& result) const {
-    if (!mLayerLifecycleManagerEnabled) {
-        return dumpHwcLayersMinidumpLockedLegacy(result);
-    }
     for (const auto& [token, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
         const auto displayId = HalDisplayId::tryCast(display->getId());
         if (!displayId) {
@@ -6880,8 +6714,7 @@
      * Dump the visible layer list
      */
     colorizer.bold(result);
-    StringAppendF(&result, "SurfaceFlinger New Frontend Enabled:%s\n",
-                  mLayerLifecycleManagerEnabled ? "true" : "false");
+    StringAppendF(&result, "SurfaceFlinger New Frontend Enabled:%s\n", "true");
     StringAppendF(&result, "Active Layers - layers with client handles (count = %zu)\n",
                   mNumLayers.load());
     colorizer.reset(result);
@@ -6980,15 +6813,6 @@
 
     result.append(mTimeStats->miniDump());
     result.append("\n");
-
-    result.append("Window Infos:\n");
-    auto windowInfosDebug = mWindowInfosListenerInvoker->getDebugInfo();
-    StringAppendF(&result, "  max send vsync id: %" PRId64 "\n",
-                  ftl::to_underlying(windowInfosDebug.maxSendDelayVsyncId));
-    StringAppendF(&result, "  max send delay (ns): %" PRId64 " ns\n",
-                  windowInfosDebug.maxSendDelayDuration);
-    StringAppendF(&result, "  unsent messages: %zu\n", windowInfosDebug.pendingMessageCount);
-    result.append("\n");
 }
 
 mat4 SurfaceFlinger::calculateColorMatrix(float saturation) {
@@ -7701,6 +7525,22 @@
     }));
 }
 
+void SurfaceFlinger::vrrDisplayIdle(bool idle) {
+    // Update the overlay on the main thread to avoid race conditions with
+    // RefreshRateSelector::getActiveMode
+    static_cast<void>(mScheduler->schedule([=, this] {
+        const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
+        if (!display) {
+            ALOGW("%s: default display is null", __func__);
+            return;
+        }
+        if (!display->isRefreshRateOverlayEnabled()) return;
+
+        display->onVrrIdle(idle);
+        mScheduler->scheduleFrame();
+    }));
+}
+
 std::pair<std::optional<KernelIdleTimerController>, std::chrono::milliseconds>
 SurfaceFlinger::getKernelIdleTimerProperties(PhysicalDisplayId displayId) {
     const bool isKernelIdleTimerHwcSupported = getHwComposer().getComposer()->isSupported(
@@ -7763,7 +7603,7 @@
     switch (action) {
         case KernelIdleTimerAction::TurnOff:
             if (mKernelIdleTimerEnabled) {
-                ATRACE_INT("KernelIdleTimer", 0);
+                SFTRACE_INT("KernelIdleTimer", 0);
                 std::chrono::milliseconds constexpr kTimerDisabledTimeout = 0ms;
                 updateKernelIdleTimer(kTimerDisabledTimeout, kernelIdleTimerController.value(),
                                       display->getPhysicalId());
@@ -7772,7 +7612,7 @@
             break;
         case KernelIdleTimerAction::TurnOn:
             if (!mKernelIdleTimerEnabled) {
-                ATRACE_INT("KernelIdleTimer", 1);
+                SFTRACE_INT("KernelIdleTimer", 1);
                 const std::chrono::milliseconds timeout =
                         display->refreshRateSelector().getIdleTimerTimeout();
                 updateKernelIdleTimer(timeout, kernelIdleTimerController.value(),
@@ -7901,7 +7741,7 @@
 
 void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args,
                                     const sp<IScreenCaptureListener>& captureListener) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     status_t validate = validateScreenshotPermissions(args);
     if (validate != OK) {
@@ -7957,10 +7797,13 @@
     GetLayerSnapshotsFunction getLayerSnapshotsFn =
             getLayerSnapshotsForScreenshots(layerStack, args.uid, std::move(excludeLayerIds));
 
+    ftl::Flags<RenderArea::Options> options;
+    if (args.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS;
+    if (args.hintForSeamlessTransition)
+        options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION;
     captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>,
                                                  args.sourceCrop, reqSize, args.dataspace,
-                                                 args.hintForSeamlessTransition,
-                                                 args.captureSecureLayers, displayWeak),
+                                                 displayWeak, options),
                         getLayerSnapshotsFn, reqSize, args.pixelFormat, args.allowProtected,
                         args.grayscale, captureListener);
 }
@@ -8011,10 +7854,12 @@
     constexpr bool kAllowProtected = false;
     constexpr bool kGrayscale = false;
 
+    ftl::Flags<RenderArea::Options> options;
+    if (args.hintForSeamlessTransition)
+        options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION;
     captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>,
-                                                 Rect(), size, args.dataspace,
-                                                 args.hintForSeamlessTransition,
-                                                 false /* captureSecureLayers */, displayWeak),
+                                                 Rect(), size, args.dataspace, displayWeak,
+                                                 options),
                         getLayerSnapshotsFn, size, args.pixelFormat, kAllowProtected, kGrayscale,
                         captureListener);
 }
@@ -8027,7 +7872,7 @@
 
 void SurfaceFlinger::captureLayers(const LayerCaptureArgs& args,
                                    const sp<IScreenCaptureListener>& captureListener) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     status_t validate = validateScreenshotPermissions(args);
     if (validate != OK) {
@@ -8113,10 +7958,13 @@
         return;
     }
 
+    ftl::Flags<RenderArea::Options> options;
+    if (args.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS;
+    if (args.hintForSeamlessTransition)
+        options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION;
     captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<LayerRenderAreaBuilder>, crop,
-                                                 reqSize, dataspace, args.captureSecureLayers,
-                                                 args.hintForSeamlessTransition, parent,
-                                                 args.childrenOnly),
+                                                 reqSize, dataspace, parent, args.childrenOnly,
+                                                 options),
                         getLayerSnapshotsFn, reqSize, args.pixelFormat, args.allowProtected,
                         args.grayscale, captureListener);
 }
@@ -8152,12 +8000,12 @@
 // Accessing display requires mStateLock, and contention for this lock
 // is reduced when grabbed from the main thread, thus also reducing
 // risk of deadlocks.
-std::optional<SurfaceFlinger::OutputCompositionState>
-SurfaceFlinger::getDisplayAndLayerSnapshotsFromMainThread(
+std::optional<SurfaceFlinger::OutputCompositionState> SurfaceFlinger::getSnapshotsFromMainThread(
         RenderAreaBuilderVariant& renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn,
         std::vector<sp<LayerFE>>& layerFEs) {
     return mScheduler
             ->schedule([=, this, &renderAreaBuilder, &layerFEs]() REQUIRES(kMainThreadContext) {
+                SFTRACE_NAME("getSnapshotsFromMainThread");
                 auto layers = getLayerSnapshotsFn();
                 for (auto& [layer, layerFE] : layers) {
                     attachReleaseFenceFutureToLayer(layer, layerFE.get(), ui::INVALID_LAYER_STACK);
@@ -8173,7 +8021,7 @@
                                          ui::Size bufferSize, ui::PixelFormat reqPixelFormat,
                                          bool allowProtected, bool grayscale,
                                          const sp<IScreenCaptureListener>& captureListener) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (exceedsMaxRenderTargetSize(bufferSize.getWidth(), bufferSize.getHeight())) {
         ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32
@@ -8184,11 +8032,10 @@
     }
 
     if (FlagManager::getInstance().single_hop_screenshot() &&
-        FlagManager::getInstance().ce_fence_promise()) {
+        FlagManager::getInstance().ce_fence_promise() && mRenderEngine->isThreaded()) {
         std::vector<sp<LayerFE>> layerFEs;
         auto displayState =
-                getDisplayAndLayerSnapshotsFromMainThread(renderAreaBuilder, getLayerSnapshotsFn,
-                                                          layerFEs);
+                getSnapshotsFromMainThread(renderAreaBuilder, getLayerSnapshotsFn, layerFEs);
 
         const bool supportsProtected = getRenderEngine().supportsProtectedContent();
         bool hasProtectedLayer = false;
@@ -8311,7 +8158,7 @@
         const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
         bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener,
         std::optional<OutputCompositionState>& displayState, std::vector<sp<LayerFE>>& layerFEs) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     ScreenCaptureResults captureResults;
     std::unique_ptr<const RenderArea> renderArea =
@@ -8351,7 +8198,7 @@
         RenderAreaBuilderVariant renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn,
         const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
         bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     auto takeScreenshotFn = [=, this, renderAreaBuilder = std::move(renderAreaBuilder)]() REQUIRES(
                                     kMainThreadContext) mutable -> ftl::SharedFuture<FenceResult> {
@@ -8415,7 +8262,7 @@
         bool grayscale, bool isProtected, ScreenCaptureResults& captureResults,
         std::optional<OutputCompositionState>& displayState,
         std::vector<std::pair<Layer*, sp<LayerFE>>>& layers, std::vector<sp<LayerFE>>& layerFEs) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     for (auto& layerFE : layerFEs) {
         frontend::LayerSnapshot* snapshot = layerFE->mSnapshot.get();
@@ -8558,10 +8405,8 @@
     // to CompositionEngine::present.
     ftl::SharedFuture<FenceResult> presentFuture;
     if (FlagManager::getInstance().single_hop_screenshot() &&
-        FlagManager::getInstance().ce_fence_promise()) {
-        presentFuture = mRenderEngine->isThreaded()
-                ? ftl::yield(present()).share()
-                : mScheduler->schedule(std::move(present)).share();
+        FlagManager::getInstance().ce_fence_promise() && mRenderEngine->isThreaded()) {
+        presentFuture = ftl::yield(present()).share();
     } else {
         presentFuture = mRenderEngine->isThreaded() ? ftl::defer(std::move(present)).share()
                                                     : ftl::yield(present()).share();
@@ -8593,12 +8438,8 @@
 }
 
 void SurfaceFlinger::traverseLegacyLayers(const LayerVector::Visitor& visitor) const {
-    if (mLayerLifecycleManagerEnabled) {
-        for (auto& layer : mLegacyLayers) {
-            visitor(layer.second.get());
-        }
-    } else {
-        mDrawingState.traverse(visitor);
+    for (auto& layer : mLegacyLayers) {
+        visitor(layer.second.get());
     }
 }
 
@@ -8616,42 +8457,6 @@
     layersSortedByZ.traverseInReverseZOrder(stateSet, visitor);
 }
 
-void SurfaceFlinger::traverseLayersInLayerStack(ui::LayerStack layerStack, const int32_t uid,
-                                                std::unordered_set<uint32_t> excludeLayerIds,
-                                                const LayerVector::Visitor& visitor) {
-    // We loop through the first level of layers without traversing,
-    // as we need to determine which layers belong to the requested display.
-    for (const auto& layer : mDrawingState.layersSortedByZ) {
-        if (layer->getLayerStack() != layerStack) {
-            continue;
-        }
-        // relative layers are traversed in Layer::traverseInZOrder
-        layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
-            if (layer->isInternalDisplayOverlay()) {
-                return;
-            }
-            if (!layer->isVisible()) {
-                return;
-            }
-            if (uid != CaptureArgs::UNSET_UID && layer->getOwnerUid() != uid) {
-                return;
-            }
-
-            if (!excludeLayerIds.empty()) {
-                auto p = sp<Layer>::fromExisting(layer);
-                while (p != nullptr) {
-                    if (excludeLayerIds.count(p->sequence) != 0) {
-                        return;
-                    }
-                    p = p->getParent();
-                }
-            }
-
-            visitor(layer);
-        });
-    }
-}
-
 ftl::Optional<scheduler::FrameRateMode> SurfaceFlinger::getPreferredDisplayMode(
         PhysicalDisplayId displayId, DisplayModeId defaultModeId) const {
     if (const auto schedulerMode = mScheduler->getPreferredDisplayMode();
@@ -8673,7 +8478,7 @@
         const sp<DisplayDevice>& display,
         const scheduler::RefreshRateSelector::PolicyVariant& policy) {
     const auto displayId = display->getPhysicalId();
-    ATRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
+    SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
 
     Mutex::Autolock lock(mStateLock);
 
@@ -8766,7 +8571,7 @@
 
 status_t SurfaceFlinger::setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
                                                     const gui::DisplayModeSpecs& specs) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (!displayToken) {
         return BAD_VALUE;
@@ -8800,7 +8605,7 @@
 
 status_t SurfaceFlinger::getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
                                                     gui::DisplayModeSpecs* outSpecs) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (!displayToken || !outSpecs) {
         return BAD_VALUE;
@@ -9092,7 +8897,7 @@
 
 void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveDisplayPtr,
                                                   const DisplayDevice& activeDisplay) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     if (inactiveDisplayPtr) {
         inactiveDisplayPtr->getCompositionDisplay()->setLayerCachingTexturePoolEnabled(false);
@@ -9315,81 +9120,49 @@
 void SurfaceFlinger::moveSnapshotsFromCompositionArgs(
         compositionengine::CompositionRefreshArgs& refreshArgs,
         const std::vector<std::pair<Layer*, LayerFE*>>& layers) {
-    if (mLayerLifecycleManagerEnabled) {
-        std::vector<std::unique_ptr<frontend::LayerSnapshot>>& snapshots =
-                mLayerSnapshotBuilder.getSnapshots();
-        for (auto [_, layerFE] : layers) {
-            auto i = layerFE->mSnapshot->globalZ;
-            snapshots[i] = std::move(layerFE->mSnapshot);
-        }
-    }
-    if (!mLayerLifecycleManagerEnabled) {
-        for (auto [layer, layerFE] : layers) {
-            layer->updateLayerSnapshot(std::move(layerFE->mSnapshot));
-        }
+    std::vector<std::unique_ptr<frontend::LayerSnapshot>>& snapshots =
+            mLayerSnapshotBuilder.getSnapshots();
+    for (auto [_, layerFE] : layers) {
+        auto i = layerFE->mSnapshot->globalZ;
+        snapshots[i] = std::move(layerFE->mSnapshot);
     }
 }
 
 std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToCompositionArgs(
         compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly) {
     std::vector<std::pair<Layer*, LayerFE*>> layers;
-    if (mLayerLifecycleManagerEnabled) {
-        nsecs_t currentTime = systemTime();
-        mLayerSnapshotBuilder.forEachVisibleSnapshot(
-                [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD(
-                        kMainThreadContext) {
-                    if (cursorOnly &&
-                        snapshot->compositionType !=
-                                aidl::android::hardware::graphics::composer3::Composition::CURSOR) {
-                        return;
-                    }
-
-                    if (!snapshot->hasSomethingToDraw()) {
-                        return;
-                    }
-
-                    auto it = mLegacyLayers.find(snapshot->sequence);
-                    LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
-                                                    "Couldnt find layer object for %s",
-                                                    snapshot->getDebugString().c_str());
-                    auto& legacyLayer = it->second;
-                    sp<LayerFE> layerFE = legacyLayer->getCompositionEngineLayerFE(snapshot->path);
-                    snapshot->fps = getLayerFramerate(currentTime, snapshot->sequence);
-                    layerFE->mSnapshot = std::move(snapshot);
-                    refreshArgs.layers.push_back(layerFE);
-                    layers.emplace_back(legacyLayer.get(), layerFE.get());
-                });
-    }
-    if (!mLayerLifecycleManagerEnabled) {
-        auto moveSnapshots = [&layers, &refreshArgs, cursorOnly](Layer* layer) {
-            if (const auto& layerFE = layer->getCompositionEngineLayerFE()) {
+    nsecs_t currentTime = systemTime();
+    const bool needsMetadata = mCompositionEngine->getFeatureFlags().test(
+            compositionengine::Feature::kSnapshotLayerMetadata);
+    mLayerSnapshotBuilder.forEachSnapshot(
+            [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD(
+                    kMainThreadContext) {
                 if (cursorOnly &&
-                    layer->getLayerSnapshot()->compositionType !=
-                            aidl::android::hardware::graphics::composer3::Composition::CURSOR)
+                    snapshot->compositionType !=
+                            aidl::android::hardware::graphics::composer3::Composition::CURSOR) {
                     return;
-                layer->updateSnapshot(refreshArgs.updatingGeometryThisFrame);
-                layerFE->mSnapshot = layer->stealLayerSnapshot();
+                }
+
+                if (!snapshot->hasSomethingToDraw()) {
+                    return;
+                }
+
+                auto it = mLegacyLayers.find(snapshot->sequence);
+                LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
+                                                "Couldnt find layer object for %s",
+                                                snapshot->getDebugString().c_str());
+                auto& legacyLayer = it->second;
+                sp<LayerFE> layerFE = legacyLayer->getCompositionEngineLayerFE(snapshot->path);
+                snapshot->fps = getLayerFramerate(currentTime, snapshot->sequence);
+                layerFE->mSnapshot = std::move(snapshot);
                 refreshArgs.layers.push_back(layerFE);
-                layers.emplace_back(layer, layerFE.get());
-            }
-        };
-
-        if (cursorOnly || !mVisibleRegionsDirty) {
-            // for hot path avoid traversals by walking though the previous composition list
-            for (sp<Layer> layer : mPreviouslyComposedLayers) {
-                moveSnapshots(layer.get());
-            }
-        } else {
-            mPreviouslyComposedLayers.clear();
-            mDrawingState.traverseInZOrder(
-                    [&moveSnapshots](Layer* layer) { moveSnapshots(layer); });
-            mPreviouslyComposedLayers.reserve(layers.size());
-            for (auto [layer, _] : layers) {
-                mPreviouslyComposedLayers.push_back(sp<Layer>::fromExisting(layer));
-            }
-        }
-    }
-
+                layers.emplace_back(legacyLayer.get(), layerFE.get());
+            },
+            [needsMetadata](const frontend::LayerSnapshot& snapshot) {
+                return snapshot.isVisible ||
+                        (needsMetadata &&
+                         snapshot.changes.test(frontend::RequestedLayerState::Changes::Metadata));
+            });
     return layers;
 }
 
@@ -9518,7 +9291,7 @@
 
 frontend::Update SurfaceFlinger::flushLifecycleUpdates() {
     frontend::Update update;
-    ATRACE_NAME("TransactionHandler:flushTransactions");
+    SFTRACE_NAME("TransactionHandler:flushTransactions");
     // Locking:
     // 1. to prevent onHandleDestroyed from being called while the state lock is held,
     // we must keep a copy of the transactions (specifically the composer
@@ -9564,7 +9337,7 @@
 
 perfetto::protos::LayersSnapshotProto SurfaceFlinger::takeLayersSnapshotProto(
         uint32_t traceFlags, TimePoint time, VsyncId vsyncId, bool visibleRegionDirty) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     perfetto::protos::LayersSnapshotProto snapshot;
     snapshot.set_elapsed_realtime_nanos(time.ns());
     snapshot.set_vsync_id(ftl::to_underlying(vsyncId));
@@ -10454,6 +10227,28 @@
     return ::android::binder::Status::ok();
 }
 
+binder::Status SurfaceComposerAIDL::addJankListener(const sp<IBinder>& layerHandle,
+                                                    const sp<gui::IJankListener>& listener) {
+    sp<Layer> layer = LayerHandle::getLayer(layerHandle);
+    if (layer == nullptr) {
+        return binder::Status::fromExceptionCode(binder::Status::EX_NULL_POINTER);
+    }
+    JankTracker::addJankListener(layer->sequence, IInterface::asBinder(listener));
+    return binder::Status::ok();
+}
+
+binder::Status SurfaceComposerAIDL::flushJankData(int32_t layerId) {
+    JankTracker::flushJankData(layerId);
+    return binder::Status::ok();
+}
+
+binder::Status SurfaceComposerAIDL::removeJankListener(int32_t layerId,
+                                                       const sp<gui::IJankListener>& listener,
+                                                       int64_t afterVsync) {
+    JankTracker::removeJankListener(layerId, IInterface::asBinder(listener), afterVsync);
+    return binder::Status::ok();
+}
+
 status_t SurfaceComposerAIDL::checkAccessPermission(bool usePermissionCache) {
     if (!mFlinger->callingThreadHasUnscopedSurfaceFlingerAccess(usePermissionCache)) {
         IPCThreadState* ipc = IPCThreadState::self();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 7762bbe..89ade4e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -27,7 +27,9 @@
 #include <android/gui/BnSurfaceComposer.h>
 #include <android/gui/DisplayStatInfo.h>
 #include <android/gui/DisplayState.h>
+#include <android/gui/IJankListener.h>
 #include <android/gui/ISurfaceComposerClient.h>
+#include <common/trace.h>
 #include <cutils/atomic.h>
 #include <cutils/compiler.h>
 #include <ftl/algorithm.h>
@@ -52,7 +54,6 @@
 #include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
 #include <utils/SortedVector.h>
-#include <utils/Trace.h>
 #include <utils/threads.h>
 
 #include <compositionengine/OutputColorSetting.h>
@@ -449,7 +450,7 @@
             if (it != mCounterByLayerHandle.end()) {
                 auto [name, pendingBuffers] = it->second;
                 int32_t count = ++(*pendingBuffers);
-                ATRACE_INT(name.c_str(), count);
+                SFTRACE_INT(name.c_str(), count);
             } else {
                 ALOGW("Handle not found! %p", layerHandle);
             }
@@ -703,6 +704,7 @@
                                      Fps renderRate) override;
     void onCommitNotComposited(PhysicalDisplayId pacesetterDisplayId) override
             REQUIRES(kMainThreadContext);
+    void vrrDisplayIdle(bool idle) override;
 
     // ICEPowerCallback overrides:
     void notifyCpuLoadUp() override;
@@ -737,9 +739,9 @@
     status_t setActiveModeFromBackdoor(const sp<display::DisplayToken>&, DisplayModeId, Fps minFps,
                                        Fps maxFps);
 
-    void initiateDisplayModeChanges() REQUIRES(kMainThreadContext) EXCLUDES(mStateLock);
+    void initiateDisplayModeChanges() REQUIRES(kMainThreadContext) REQUIRES(mStateLock);
     void finalizeDisplayModeChange(PhysicalDisplayId) REQUIRES(kMainThreadContext)
-            EXCLUDES(mStateLock);
+            REQUIRES(mStateLock);
 
     void dropModeRequest(PhysicalDisplayId) REQUIRES(kMainThreadContext);
     void applyActiveMode(PhysicalDisplayId) REQUIRES(kMainThreadContext);
@@ -825,9 +827,6 @@
     TransactionHandler::TransactionReadiness transactionReadyTimelineCheck(
             const TransactionHandler::TransactionFlushState& flushState)
             REQUIRES(kMainThreadContext);
-    TransactionHandler::TransactionReadiness transactionReadyBufferCheckLegacy(
-            const TransactionHandler::TransactionFlushState& flushState)
-            REQUIRES(kMainThreadContext);
     TransactionHandler::TransactionReadiness transactionReadyBufferCheck(
             const TransactionHandler::TransactionFlushState& flushState)
             REQUIRES(kMainThreadContext);
@@ -896,7 +895,7 @@
 
     using OutputCompositionState = compositionengine::impl::OutputCompositionState;
 
-    std::optional<OutputCompositionState> getDisplayAndLayerSnapshotsFromMainThread(
+    std::optional<OutputCompositionState> getSnapshotsFromMainThread(
             RenderAreaBuilderVariant& renderAreaBuilder,
             GetLayerSnapshotsFunction getLayerSnapshotsFn, std::vector<sp<LayerFE>>& layerFEs);
 
@@ -933,12 +932,6 @@
             std::vector<std::pair<Layer*, sp<LayerFE>>>& layers,
             std::vector<sp<LayerFE>>& layerFEs);
 
-    // If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a
-    // matching ownerUid
-    void traverseLayersInLayerStack(ui::LayerStack, const int32_t uid,
-                                    std::unordered_set<uint32_t> excludeLayerIds,
-                                    const LayerVector::Visitor&);
-
     void readPersistentProperties();
 
     uint32_t getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const;
@@ -1155,7 +1148,6 @@
     void dumpAll(const DumpArgs& args, const std::string& compositionLayers,
                  std::string& result) const EXCLUDES(mStateLock);
     void dumpHwcLayersMinidump(std::string& result) const REQUIRES(mStateLock, kMainThreadContext);
-    void dumpHwcLayersMinidumpLockedLegacy(std::string& result) const REQUIRES(mStateLock);
 
     void appendSfConfigString(std::string& result) const;
     void listLayers(std::string& result) const REQUIRES(kMainThreadContext);
@@ -1182,7 +1174,8 @@
     perfetto::protos::LayersProto dumpDrawingStateProto(uint32_t traceFlags) const
             REQUIRES(kMainThreadContext);
     void dumpOffscreenLayersProto(perfetto::protos::LayersProto& layersProto,
-                                  uint32_t traceFlags = LayerTracing::TRACE_ALL) const;
+                                  uint32_t traceFlags = LayerTracing::TRACE_ALL) const
+            REQUIRES(kMainThreadContext);
     google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> dumpDisplayProto() const;
     void doActiveLayersTracingIfNeeded(bool isCompositionComputed, bool visibleRegionDirty,
                                        TimePoint, VsyncId) REQUIRES(kMainThreadContext);
@@ -1503,8 +1496,6 @@
     }
 
     bool mPowerHintSessionEnabled;
-
-    bool mLayerLifecycleManagerEnabled = false;
     // Whether a display should be turned on when initialized
     bool mSkipPowerOnForQuiescent;
 
@@ -1693,6 +1684,11 @@
             int pid, std::optional<gui::StalledTransactionInfo>* outInfo) override;
     binder::Status getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) override;
     binder::Status notifyShutdown() override;
+    binder::Status addJankListener(const sp<IBinder>& layer,
+                                   const sp<gui::IJankListener>& listener) override;
+    binder::Status flushJankData(int32_t layerId) override;
+    binder::Status removeJankListener(int32_t layerId, const sp<gui::IJankListener>& listener,
+                                      int64_t afterVsync) override;
 
 private:
     static const constexpr bool kUsePermissionCache = true;
diff --git a/services/surfaceflinger/TimeStats/Android.bp b/services/surfaceflinger/TimeStats/Android.bp
index a631074..a6a0152 100644
--- a/services/surfaceflinger/TimeStats/Android.bp
+++ b/services/surfaceflinger/TimeStats/Android.bp
@@ -20,10 +20,12 @@
         "libtimestats_atoms_proto",
         "libui",
         "libutils",
+        "libtracing_perfetto",
     ],
 
     static_libs: [
         "libtimestats_proto",
+        "libsurfaceflinger_common",
     ],
 
     export_static_lib_headers: [
diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp
index 368cb41..c60ded6 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.cpp
+++ b/services/surfaceflinger/TimeStats/TimeStats.cpp
@@ -19,11 +19,11 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #include <android-base/stringprintf.h>
+#include <common/trace.h>
 #include <log/log.h>
 #include <timestatsatomsproto/TimeStatsAtomsProtoHeader.h>
 #include <utils/String8.h>
 #include <utils/Timers.h>
-#include <utils/Trace.h>
 
 #include <algorithm>
 #include <chrono>
@@ -271,7 +271,7 @@
 }
 
 void TimeStats::parseArgs(bool asProto, const Vector<String16>& args, std::string& result) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::unordered_map<std::string, int32_t> argsMap;
     for (size_t index = 0; index < args.size(); ++index) {
@@ -304,7 +304,7 @@
 }
 
 std::string TimeStats::miniDump() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::string result = "TimeStats miniDump:\n";
     std::lock_guard<std::mutex> lock(mMutex);
@@ -318,7 +318,7 @@
 void TimeStats::incrementTotalFrames() {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
     mTimeStats.totalFramesLegacy++;
@@ -327,7 +327,7 @@
 void TimeStats::incrementMissedFrames() {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
     mTimeStats.missedFramesLegacy++;
@@ -338,7 +338,7 @@
         return;
     }
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
     if (record.changed) mTimeStats.compositionStrategyChangesLegacy++;
@@ -351,7 +351,7 @@
 void TimeStats::incrementRefreshRateSwitches() {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
     mTimeStats.refreshRateSwitchesLegacy++;
@@ -445,7 +445,7 @@
                                                    std::optional<Fps> renderRate,
                                                    SetFrameRateVote frameRateVote,
                                                    GameMode gameMode) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-flushAvailableRecordsToStatsLocked", layerId);
 
     LayerRecord& layerRecord = mTimeStatsTracker[layerId];
@@ -568,7 +568,7 @@
                             uid_t uid, nsecs_t postTime, GameMode gameMode) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-[%" PRIu64 "]-[%s]-PostTime[%" PRId64 "]", layerId, frameNumber, layerName.c_str(),
           postTime);
 
@@ -612,7 +612,7 @@
 void TimeStats::setLatchTime(int32_t layerId, uint64_t frameNumber, nsecs_t latchTime) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-[%" PRIu64 "]-LatchTime[%" PRId64 "]", layerId, frameNumber, latchTime);
 
     std::lock_guard<std::mutex> lock(mMutex);
@@ -630,7 +630,7 @@
 void TimeStats::incrementLatchSkipped(int32_t layerId, LatchSkipReason reason) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-LatchSkipped-Reason[%d]", layerId,
           static_cast<std::underlying_type<LatchSkipReason>::type>(reason));
 
@@ -648,7 +648,7 @@
 void TimeStats::incrementBadDesiredPresent(int32_t layerId) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-BadDesiredPresent", layerId);
 
     std::lock_guard<std::mutex> lock(mMutex);
@@ -660,7 +660,7 @@
 void TimeStats::setDesiredTime(int32_t layerId, uint64_t frameNumber, nsecs_t desiredTime) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-[%" PRIu64 "]-DesiredTime[%" PRId64 "]", layerId, frameNumber, desiredTime);
 
     std::lock_guard<std::mutex> lock(mMutex);
@@ -678,7 +678,7 @@
 void TimeStats::setAcquireTime(int32_t layerId, uint64_t frameNumber, nsecs_t acquireTime) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-[%" PRIu64 "]-AcquireTime[%" PRId64 "]", layerId, frameNumber, acquireTime);
 
     std::lock_guard<std::mutex> lock(mMutex);
@@ -697,7 +697,7 @@
                                 const std::shared_ptr<FenceTime>& acquireFence) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-[%" PRIu64 "]-AcquireFenceTime[%" PRId64 "]", layerId, frameNumber,
           acquireFence->getSignalTime());
 
@@ -718,7 +718,7 @@
                                SetFrameRateVote frameRateVote, GameMode gameMode) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-[%" PRIu64 "]-PresentTime[%" PRId64 "]", layerId, frameNumber, presentTime);
 
     std::lock_guard<std::mutex> lock(mMutex);
@@ -744,7 +744,7 @@
                                 SetFrameRateVote frameRateVote, GameMode gameMode) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-[%" PRIu64 "]-PresentFenceTime[%" PRId64 "]", layerId, frameNumber,
           presentFence->getSignalTime());
 
@@ -805,7 +805,7 @@
 void TimeStats::incrementJankyFrames(const JankyFramesInfo& info) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::lock_guard<std::mutex> lock(mMutex);
 
     // Only update layer stats if we're already tracking the layer in TimeStats.
@@ -861,7 +861,7 @@
 }
 
 void TimeStats::onDestroy(int32_t layerId) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-onDestroy", layerId);
     std::lock_guard<std::mutex> lock(mMutex);
     mTimeStatsTracker.erase(layerId);
@@ -870,7 +870,7 @@
 void TimeStats::removeTimeRecord(int32_t layerId, uint64_t frameNumber) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     ALOGV("[%d]-[%" PRIu64 "]-removeTimeRecord", layerId, frameNumber);
 
     std::lock_guard<std::mutex> lock(mMutex);
@@ -935,7 +935,7 @@
 }
 
 void TimeStats::flushAvailableGlobalRecordsToStatsLocked() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     while (!mGlobalRecord.presentFences.empty()) {
         const nsecs_t curPresentTime = mGlobalRecord.presentFences.front()->getSignalTime();
@@ -992,7 +992,7 @@
 void TimeStats::setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
     std::lock_guard<std::mutex> lock(mMutex);
     if (presentFence == nullptr || !presentFence->isValid()) {
         mGlobalRecord.prevPresentTime = 0;
@@ -1022,7 +1022,7 @@
 void TimeStats::enable() {
     if (mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
     mEnabled.store(true);
@@ -1034,7 +1034,7 @@
 void TimeStats::disable() {
     if (!mEnabled.load()) return;
 
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
     flushPowerTimeLocked();
@@ -1051,7 +1051,7 @@
 }
 
 void TimeStats::clearGlobalLocked() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     mTimeStats.statsStartLegacy = (mEnabled.load() ? static_cast<int64_t>(std::time(0)) : 0);
     mTimeStats.statsEndLegacy = 0;
@@ -1078,7 +1078,7 @@
 }
 
 void TimeStats::clearLayersLocked() {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     mTimeStatsTracker.clear();
 
@@ -1093,7 +1093,7 @@
 }
 
 void TimeStats::dump(bool asProto, std::optional<uint32_t> maxLayers, std::string& result) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
     if (mTimeStats.statsStartLegacy == 0) {
diff --git a/services/surfaceflinger/TracedOrdinal.h b/services/surfaceflinger/TracedOrdinal.h
index 1adc3a5..51f33a6 100644
--- a/services/surfaceflinger/TracedOrdinal.h
+++ b/services/surfaceflinger/TracedOrdinal.h
@@ -21,8 +21,8 @@
 #include <functional>
 #include <string>
 
+#include <common/trace.h>
 #include <cutils/compiler.h>
-#include <utils/Trace.h>
 
 namespace android {
 
@@ -79,7 +79,7 @@
 
 private:
     void trace() {
-        if (CC_LIKELY(!ATRACE_ENABLED())) {
+        if (CC_LIKELY(!SFTRACE_ENABLED())) {
             return;
         }
 
@@ -88,13 +88,13 @@
         }
 
         if (!signbit(mData)) {
-            ATRACE_INT64(mName.c_str(), to_int64(mData));
+            SFTRACE_INT64(mName.c_str(), to_int64(mData));
             if (mHasGoneNegative) {
-                ATRACE_INT64(mNameNegative.c_str(), 0);
+                SFTRACE_INT64(mNameNegative.c_str(), 0);
             }
         } else {
-            ATRACE_INT64(mNameNegative.c_str(), -to_int64(mData));
-            ATRACE_INT64(mName.c_str(), 0);
+            SFTRACE_INT64(mNameNegative.c_str(), -to_int64(mData));
+            SFTRACE_INT64(mName.c_str(), 0);
         }
     }
 
diff --git a/services/surfaceflinger/Tracing/LayerTracing.cpp b/services/surfaceflinger/Tracing/LayerTracing.cpp
index 41bcdf0..d40b888 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.cpp
+++ b/services/surfaceflinger/Tracing/LayerTracing.cpp
@@ -24,10 +24,10 @@
 #include "Tracing/tools/LayerTraceGenerator.h"
 #include "TransactionTracing.h"
 
+#include <common/trace.h>
 #include <log/log.h>
 #include <perfetto/tracing.h>
 #include <utils/Timers.h>
-#include <utils/Trace.h>
 
 namespace android {
 
@@ -134,7 +134,7 @@
 
 void LayerTracing::addProtoSnapshotToOstream(perfetto::protos::LayersSnapshotProto&& snapshot,
                                              Mode mode) {
-    ATRACE_CALL();
+    SFTRACE_CALL();
     if (mOutStream) {
         writeSnapshotToStream(std::move(snapshot));
     } else {
diff --git a/services/surfaceflinger/Tracing/TransactionRingBuffer.h b/services/surfaceflinger/Tracing/TransactionRingBuffer.h
index 7d1d3fd..2b66391 100644
--- a/services/surfaceflinger/Tracing/TransactionRingBuffer.h
+++ b/services/surfaceflinger/Tracing/TransactionRingBuffer.h
@@ -19,13 +19,12 @@
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
 
+#include <common/trace.h>
 #include <log/log.h>
 #include <utils/Errors.h>
 #include <utils/Timers.h>
-#include <utils/Trace.h>
 #include <chrono>
 #include <fstream>
-#include <queue>
 
 namespace android {
 
@@ -57,7 +56,7 @@
     }
 
     status_t appendToStream(FileProto& fileProto, std::ofstream& out) {
-        ATRACE_CALL();
+        SFTRACE_CALL();
         writeToProto(fileProto);
         std::string output;
         if (!fileProto.SerializeToString(&output)) {
diff --git a/services/surfaceflinger/Tracing/tools/Android.bp b/services/surfaceflinger/Tracing/tools/Android.bp
index 8afca41..63c1b37 100644
--- a/services/surfaceflinger/Tracing/tools/Android.bp
+++ b/services/surfaceflinger/Tracing/tools/Android.bp
@@ -28,6 +28,7 @@
         "libsurfaceflinger_mocks_defaults",
         "librenderengine_deps",
         "surfaceflinger_defaults",
+        "libsurfaceflinger_common_deps",
     ],
     srcs: [
         ":libsurfaceflinger_sources",
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp
index 222ae30..9ea0f5f 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.cpp
+++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp
@@ -27,10 +27,9 @@
 #include "BackgroundExecutor.h"
 #include "Utils/FenceUtils.h"
 
-#include <cinttypes>
-
 #include <binder/IInterface.h>
 #include <common/FlagManager.h>
+#include <common/trace.h>
 #include <utils/RefBase.h>
 
 namespace android {
@@ -64,13 +63,12 @@
     if (handles.empty()) {
         return NO_ERROR;
     }
-    const std::vector<JankData>& jankData = std::vector<JankData>();
     for (const auto& handle : handles) {
         if (!containsOnCommitCallbacks(handle->callbackIds)) {
             outRemainingHandles.push_back(handle);
             continue;
         }
-        status_t err = addCallbackHandle(handle, jankData);
+        status_t err = addCallbackHandle(handle);
         if (err != NO_ERROR) {
             return err;
         }
@@ -80,12 +78,12 @@
 }
 
 status_t TransactionCallbackInvoker::addCallbackHandles(
-        const std::deque<sp<CallbackHandle>>& handles, const std::vector<JankData>& jankData) {
+        const std::deque<sp<CallbackHandle>>& handles) {
     if (handles.empty()) {
         return NO_ERROR;
     }
     for (const auto& handle : handles) {
-        status_t err = addCallbackHandle(handle, jankData);
+        status_t err = addCallbackHandle(handle);
         if (err != NO_ERROR) {
             return err;
         }
@@ -111,8 +109,7 @@
     return NO_ERROR;
 }
 
-status_t TransactionCallbackInvoker::addCallbackHandle(const sp<CallbackHandle>& handle,
-        const std::vector<JankData>& jankData) {
+status_t TransactionCallbackInvoker::addCallbackHandle(const sp<CallbackHandle>& handle) {
     // If we can't find the transaction stats something has gone wrong. The client should call
     // startRegistration before trying to add a callback handle.
     TransactionStats* transactionStats;
@@ -151,8 +148,13 @@
                                                     handle->previousReleaseFence,
                                                     handle->transformHint,
                                                     handle->currentMaxAcquiredBufferCount,
-                                                    eventStats, jankData,
-                                                    handle->previousReleaseCallbackId);
+                                                    eventStats, handle->previousReleaseCallbackId);
+        if (handle->bufferReleaseChannel &&
+            handle->previousReleaseCallbackId != ReleaseCallbackId::INVALID_ID) {
+            mBufferReleases.emplace_back(handle->bufferReleaseChannel,
+                                         handle->previousReleaseCallbackId,
+                                         handle->previousReleaseFence);
+        }
     }
     return NO_ERROR;
 }
@@ -162,9 +164,14 @@
 }
 
 void TransactionCallbackInvoker::sendCallbacks(bool onCommitOnly) {
+    for (const auto& bufferRelease : mBufferReleases) {
+        bufferRelease.channel->writeReleaseFence(bufferRelease.callbackId, bufferRelease.fence);
+    }
+    mBufferReleases.clear();
+
     // For each listener
     auto completedTransactionsItr = mCompletedTransactions.begin();
-    BackgroundExecutor::Callbacks callbacks;
+    ftl::SmallVector<ListenerStats, 10> listenerStatsToSend;
     while (completedTransactionsItr != mCompletedTransactions.end()) {
         auto& [listener, transactionStatsDeque] = *completedTransactionsItr;
         ListenerStats listenerStats;
@@ -199,10 +206,7 @@
                 // keep it as an IBinder due to consistency reasons: if we
                 // interface_cast at the IPC boundary when reading a Parcel,
                 // we get pointers that compare unequal in the SF process.
-                callbacks.emplace_back([stats = std::move(listenerStats)]() {
-                    interface_cast<ITransactionCompletedListener>(stats.listener)
-                            ->onTransactionCompleted(stats);
-                });
+                listenerStatsToSend.emplace_back(std::move(listenerStats));
             }
         }
         completedTransactionsItr++;
@@ -212,7 +216,14 @@
         mPresentFence.clear();
     }
 
-    BackgroundExecutor::getInstance().sendCallbacks(std::move(callbacks));
+    BackgroundExecutor::getInstance().sendCallbacks(
+            {[listenerStatsToSend = std::move(listenerStatsToSend)]() {
+                SFTRACE_NAME("TransactionCallbackInvoker::sendCallbacks");
+                for (auto& stats : listenerStatsToSend) {
+                    interface_cast<ITransactionCompletedListener>(stats.listener)
+                            ->onTransactionCompleted(stats);
+                }
+            }});
 }
 
 // -----------------------------------------------------------------------
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.h b/services/surfaceflinger/TransactionCallbackInvoker.h
index cb7150b..f74f964 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.h
+++ b/services/surfaceflinger/TransactionCallbackInvoker.h
@@ -28,6 +28,7 @@
 #include <android-base/thread_annotations.h>
 #include <binder/IBinder.h>
 #include <ftl/future.h>
+#include <gui/BufferReleaseChannel.h>
 #include <gui/ITransactionCompletedListener.h>
 #include <ui/Fence.h>
 #include <ui/FenceResult.h>
@@ -59,12 +60,12 @@
     uint64_t frameNumber = 0;
     uint64_t previousFrameNumber = 0;
     ReleaseCallbackId previousReleaseCallbackId = ReleaseCallbackId::INVALID_ID;
+    std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> bufferReleaseChannel;
 };
 
 class TransactionCallbackInvoker {
 public:
-    status_t addCallbackHandles(const std::deque<sp<CallbackHandle>>& handles,
-                                const std::vector<JankData>& jankData);
+    status_t addCallbackHandles(const std::deque<sp<CallbackHandle>>& handles);
     status_t addOnCommitCallbackHandles(const std::deque<sp<CallbackHandle>>& handles,
                                              std::deque<sp<CallbackHandle>>& outRemainingHandles);
 
@@ -77,9 +78,7 @@
         mCompletedTransactions.clear();
     }
 
-    status_t addCallbackHandle(const sp<CallbackHandle>& handle,
-                               const std::vector<JankData>& jankData);
-
+    status_t addCallbackHandle(const sp<CallbackHandle>& handle);
 
 private:
     status_t findOrCreateTransactionStats(const sp<IBinder>& listener,
@@ -89,6 +88,13 @@
     std::unordered_map<sp<IBinder>, std::deque<TransactionStats>, IListenerHash>
         mCompletedTransactions;
 
+    struct BufferRelease {
+        std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> channel;
+        ReleaseCallbackId callbackId;
+        sp<Fence> fence;
+    };
+    std::vector<BufferRelease> mBufferReleases;
+
     sp<Fence> mPresentFence;
 };
 
diff --git a/services/surfaceflinger/WindowInfosListenerInvoker.cpp b/services/surfaceflinger/WindowInfosListenerInvoker.cpp
index effbfdb..895e054 100644
--- a/services/surfaceflinger/WindowInfosListenerInvoker.cpp
+++ b/services/surfaceflinger/WindowInfosListenerInvoker.cpp
@@ -17,8 +17,8 @@
 #include <android/gui/BnWindowInfosPublisher.h>
 #include <android/gui/IWindowInfosPublisher.h>
 #include <android/gui/WindowInfosListenerInfo.h>
+#include <common/trace.h>
 #include <gui/ISurfaceComposer.h>
-#include <gui/TraceUtils.h>
 #include <gui/WindowInfosUpdate.h>
 #include <scheduler/Time.h>
 
@@ -42,7 +42,7 @@
 
     BackgroundExecutor::getInstance().sendCallbacks(
             {[this, listener = std::move(listener), listenerId]() {
-                ATRACE_NAME("WindowInfosListenerInvoker::addWindowInfosListener");
+                SFTRACE_NAME("WindowInfosListenerInvoker::addWindowInfosListener");
                 sp<IBinder> asBinder = IInterface::asBinder(listener);
                 asBinder->linkToDeath(sp<DeathRecipient>::fromExisting(this));
                 mWindowInfosListeners.try_emplace(asBinder,
@@ -53,7 +53,7 @@
 void WindowInfosListenerInvoker::removeWindowInfosListener(
         const sp<IWindowInfosListener>& listener) {
     BackgroundExecutor::getInstance().sendCallbacks({[this, listener]() {
-        ATRACE_NAME("WindowInfosListenerInvoker::removeWindowInfosListener");
+        SFTRACE_NAME("WindowInfosListenerInvoker::removeWindowInfosListener");
         sp<IBinder> asBinder = IInterface::asBinder(listener);
         asBinder->unlinkToDeath(sp<DeathRecipient>::fromExisting(this));
         eraseListenerAndAckMessages(asBinder);
@@ -62,7 +62,7 @@
 
 void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) {
     BackgroundExecutor::getInstance().sendCallbacks({[this, who]() {
-        ATRACE_NAME("WindowInfosListenerInvoker::binderDied");
+        SFTRACE_NAME("WindowInfosListenerInvoker::binderDied");
         eraseListenerAndAckMessages(who);
     }});
 }
@@ -146,7 +146,7 @@
 WindowInfosListenerInvoker::DebugInfo WindowInfosListenerInvoker::getDebugInfo() {
     DebugInfo result;
     BackgroundExecutor::getInstance().sendCallbacks({[&, this]() {
-        ATRACE_NAME("WindowInfosListenerInvoker::getDebugInfo");
+        SFTRACE_NAME("WindowInfosListenerInvoker::getDebugInfo");
         updateMaxSendDelay();
         result = mDebugInfo;
         result.pendingMessageCount = mUnackedState.size();
@@ -169,7 +169,7 @@
 binder::Status WindowInfosListenerInvoker::ackWindowInfosReceived(int64_t vsyncId,
                                                                   int64_t listenerId) {
     BackgroundExecutor::getInstance().sendCallbacks({[this, vsyncId, listenerId]() {
-        ATRACE_NAME("WindowInfosListenerInvoker::ackWindowInfosReceived");
+        SFTRACE_NAME("WindowInfosListenerInvoker::ackWindowInfosReceived");
         auto it = mUnackedState.find(vsyncId);
         if (it == mUnackedState.end()) {
             return;
diff --git a/services/surfaceflinger/common/Android.bp b/services/surfaceflinger/common/Android.bp
index c3594bc..f9c99bf 100644
--- a/services/surfaceflinger/common/Android.bp
+++ b/services/surfaceflinger/common/Android.bp
@@ -18,6 +18,7 @@
         "libSurfaceFlingerProp",
         "server_configurable_flags",
         "libaconfig_storage_read_api_cc",
+        "libtracing_perfetto",
     ],
     static_libs: [
         "librenderengine_includes",
@@ -27,6 +28,7 @@
     ],
     local_include_dirs: ["include"],
     export_include_dirs: ["include"],
+    export_shared_lib_headers: ["libtracing_perfetto"],
 }
 
 cc_library_static {
@@ -38,6 +40,7 @@
         "libsurfaceflingerflags",
         "android.os.flags-aconfig-cc",
         "android.server.display.flags-aconfig-cc",
+        "libguiflags_no_apex",
     ],
 }
 
@@ -50,6 +53,7 @@
         "libsurfaceflingerflags_test",
         "android.os.flags-aconfig-cc-test",
         "android.server.display.flags-aconfig-cc",
+        "libguiflags_no_apex",
     ],
 }
 
@@ -58,12 +62,14 @@
     shared_libs: [
         "server_configurable_flags",
         "libaconfig_storage_read_api_cc",
+        "libtracing_perfetto",
     ],
     static_libs: [
         "libsurfaceflinger_common",
         "libsurfaceflingerflags",
         "android.os.flags-aconfig-cc",
         "android.server.display.flags-aconfig-cc",
+        "libguiflags_no_apex",
     ],
 }
 
@@ -72,11 +78,13 @@
     shared_libs: [
         "server_configurable_flags",
         "libaconfig_storage_read_api_cc",
+        "libtracing_perfetto",
     ],
     static_libs: [
         "libsurfaceflinger_common_test",
         "libsurfaceflingerflags_test",
         "android.os.flags-aconfig-cc-test",
         "android.server.display.flags-aconfig-cc",
+        "libguiflags_no_apex",
     ],
 }
diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp
index 4216771..a56bb51 100644
--- a/services/surfaceflinger/common/FlagManager.cpp
+++ b/services/surfaceflinger/common/FlagManager.cpp
@@ -27,6 +27,7 @@
 #include <cinttypes>
 
 #include <android_os.h>
+#include <com_android_graphics_libgui_flags.h>
 #include <com_android_graphics_surfaceflinger_flags.h>
 #include <com_android_server_display_feature_flags.h>
 
@@ -135,6 +136,7 @@
     DUMP_READ_ONLY_FLAG(vulkan_renderengine);
     DUMP_READ_ONLY_FLAG(renderable_buffer_usage);
     DUMP_READ_ONLY_FLAG(vrr_bugfix_24q4);
+    DUMP_READ_ONLY_FLAG(vrr_bugfix_dropped_frame);
     DUMP_READ_ONLY_FLAG(restore_blur_step);
     DUMP_READ_ONLY_FLAG(dont_skip_on_early_ro);
     DUMP_READ_ONLY_FLAG(protected_if_client);
@@ -151,6 +153,7 @@
     DUMP_READ_ONLY_FLAG(flush_buffer_slots_to_uncache);
     DUMP_READ_ONLY_FLAG(force_compile_graphite_renderengine);
     DUMP_READ_ONLY_FLAG(single_hop_screenshot);
+    DUMP_READ_ONLY_FLAG(trace_frame_rate_override);
 
 #undef DUMP_READ_ONLY_FLAG
 #undef DUMP_SERVER_FLAG
@@ -240,6 +243,7 @@
 FLAG_MANAGER_READ_ONLY_FLAG(dont_skip_on_early_ro, "")
 FLAG_MANAGER_READ_ONLY_FLAG(protected_if_client, "")
 FLAG_MANAGER_READ_ONLY_FLAG(vrr_bugfix_24q4, "");
+FLAG_MANAGER_READ_ONLY_FLAG(vrr_bugfix_dropped_frame, "")
 FLAG_MANAGER_READ_ONLY_FLAG(ce_fence_promise, "");
 FLAG_MANAGER_READ_ONLY_FLAG(graphite_renderengine, "debug.renderengine.graphite")
 FLAG_MANAGER_READ_ONLY_FLAG(latch_unsignaled_with_auto_refresh_changed, "");
@@ -264,5 +268,7 @@
 FLAG_MANAGER_READ_ONLY_FLAG_IMPORTED(idle_screen_refresh_rate_timeout, "",
                                      com::android::server::display::feature::flags)
 FLAG_MANAGER_READ_ONLY_FLAG_IMPORTED(adpf_use_fmq_channel_fixed, "", android::os)
+FLAG_MANAGER_READ_ONLY_FLAG_IMPORTED(trace_frame_rate_override, "",
+                                     com::android::graphics::libgui::flags);
 
 } // namespace android
diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h
index 22118ab..8799295 100644
--- a/services/surfaceflinger/common/include/common/FlagManager.h
+++ b/services/surfaceflinger/common/include/common/FlagManager.h
@@ -73,6 +73,7 @@
     bool screenshot_fence_preservation() const;
     bool vulkan_renderengine() const;
     bool vrr_bugfix_24q4() const;
+    bool vrr_bugfix_dropped_frame() const;
     bool renderable_buffer_usage() const;
     bool restore_blur_step() const;
     bool dont_skip_on_early_ro() const;
@@ -90,6 +91,7 @@
     bool flush_buffer_slots_to_uncache() const;
     bool force_compile_graphite_renderengine() const;
     bool single_hop_screenshot() const;
+    bool trace_frame_rate_override() const;
 
 protected:
     // overridden for unit tests
diff --git a/services/surfaceflinger/common/include/common/trace.h b/services/surfaceflinger/common/include/common/trace.h
new file mode 100644
index 0000000..0d7ac9b
--- /dev/null
+++ b/services/surfaceflinger/common/include/common/trace.h
@@ -0,0 +1,90 @@
+
+/*
+ * Copyright 2024 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
+
+#ifndef ATRACE_TAG
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#endif
+
+#include <cutils/trace.h>
+#include <tracing_perfetto.h>
+
+// prevent using atrace directly, calls should go through tracing_perfetto lib
+#undef ATRACE_ENABLED
+#undef ATRACE_BEGIN
+#undef ATRACE_END
+#undef ATRACE_ASYNC_BEGIN
+#undef ATRACE_ASYNC_END
+#undef ATRACE_ASYNC_FOR_TRACK_BEGIN
+#undef ATRACE_ASYNC_FOR_TRACK_END
+#undef ATRACE_INSTANT
+#undef ATRACE_INSTANT_FOR_TRACK
+#undef ATRACE_INT
+#undef ATRACE_INT64
+#undef ATRACE_CALL
+#undef ATRACE_NAME
+#undef ATRACE_FORMAT
+#undef ATRACE_FORMAT_INSTANT
+
+#define SFTRACE_ENABLED() ::tracing_perfetto::isTagEnabled(ATRACE_TAG)
+#define SFTRACE_BEGIN(name) ::tracing_perfetto::traceBegin(ATRACE_TAG, name)
+#define SFTRACE_END() ::tracing_perfetto::traceEnd(ATRACE_TAG)
+#define SFTRACE_ASYNC_BEGIN(name, cookie) \
+    ::tracing_perfetto::traceAsyncBegin(ATRACE_TAG, name, cookie)
+#define SFTRACE_ASYNC_END(name, cookie) ::tracing_perfetto::traceAsyncEnd(ATRACE_TAG, name, cookie)
+#define SFTRACE_ASYNC_FOR_TRACK_BEGIN(track_name, name, cookie) \
+    ::tracing_perfetto::traceAsyncBeginForTrack(ATRACE_TAG, track_name, name, cookie)
+#define SFTRACE_ASYNC_FOR_TRACK_END(track_name, cookie) \
+    ::tracing_perfetto::traceAsyncEndForTrack(ATRACE_TAG, track_name, cookie)
+#define SFTRACE_INSTANT(name) ::tracing_perfetto::traceInstant(ATRACE_TAG, name)
+#define SFTRACE_FORMAT_INSTANT(fmt, ...) \
+    ::tracing_perfetto::traceFormatInstant(ATRACE_TAG, fmt, ##__VA_ARGS__)
+#define SFTRACE_INSTANT_FOR_TRACK(trackName, name) \
+    ::tracing_perfetto::traceInstantForTrack(ATRACE_TAG, trackName, name)
+#define SFTRACE_INT(name, value) ::tracing_perfetto::traceCounter32(ATRACE_TAG, name, value)
+#define SFTRACE_INT64(name, value) ::tracing_perfetto::traceCounter(ATRACE_TAG, name, value)
+
+// SFTRACE_NAME traces from its location until the end of its enclosing scope.
+#define _PASTE(x, y) x##y
+#define PASTE(x, y) _PASTE(x, y)
+#define SFTRACE_NAME(name) ::android::ScopedTrace PASTE(___tracer, __LINE__)(name)
+// SFTRACE_CALL is an SFTRACE_NAME that uses the current function name.
+#define SFTRACE_CALL() SFTRACE_NAME(__FUNCTION__)
+
+#define SFTRACE_FORMAT(fmt, ...) \
+    ::android::ScopedTrace PASTE(___tracer, __LINE__)(fmt, ##__VA_ARGS__)
+
+#define ALOGE_AND_TRACE(fmt, ...)                   \
+    do {                                            \
+        ALOGE(fmt, ##__VA_ARGS__);                  \
+        SFTRACE_FORMAT_INSTANT(fmt, ##__VA_ARGS__); \
+    } while (false)
+
+namespace android {
+
+class ScopedTrace {
+public:
+    template <typename... Args>
+    inline ScopedTrace(const char* fmt, Args&&... args) {
+        ::tracing_perfetto::traceFormatBegin(ATRACE_TAG, fmt, std::forward<Args>(args)...);
+    }
+    inline ScopedTrace(const char* name) { SFTRACE_BEGIN(name); }
+    inline ~ScopedTrace() { SFTRACE_END(); }
+};
+
+} // namespace android
diff --git a/services/surfaceflinger/surfaceflinger.rc b/services/surfaceflinger/surfaceflinger.rc
index 39d7bd9..dfdd4aa 100644
--- a/services/surfaceflinger/surfaceflinger.rc
+++ b/services/surfaceflinger/surfaceflinger.rc
@@ -5,6 +5,3 @@
     capabilities SYS_NICE
     onrestart restart --only-if-running zygote
     task_profiles HighPerformance
-    socket pdx/system/vr/display/client     stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
-    socket pdx/system/vr/display/manager    stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
-    socket pdx/system/vr/display/vsync      stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
diff --git a/services/surfaceflinger/surfaceflinger_flags_new.aconfig b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
index f4d4ee9..919ec17 100644
--- a/services/surfaceflinger/surfaceflinger_flags_new.aconfig
+++ b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
@@ -136,4 +136,15 @@
   }
 } # vrr_bugfix_24q4
 
+flag {
+  name: "vrr_bugfix_dropped_frame"
+  namespace: "core_graphics"
+  description: "bug fix for VRR dropped frame"
+  bug: "343603085"
+  is_fixed_read_only: true
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+} # vrr_bugfix_dropped_frame
+
 # IMPORTANT - please keep alphabetize to reduce merge conflicts
diff --git a/services/surfaceflinger/tests/benchmarks/Android.bp b/services/surfaceflinger/tests/benchmarks/Android.bp
new file mode 100644
index 0000000..1c47be34
--- /dev/null
+++ b/services/surfaceflinger/tests/benchmarks/Android.bp
@@ -0,0 +1,31 @@
+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_benchmark {
+    name: "surfaceflinger_microbenchmarks",
+    srcs: [
+        ":libsurfaceflinger_mock_sources",
+        ":libsurfaceflinger_sources",
+        "*.cpp",
+    ],
+    defaults: [
+        "libsurfaceflinger_mocks_defaults",
+        "skia_renderengine_deps",
+        "surfaceflinger_defaults",
+    ],
+    static_libs: [
+        "libgmock",
+        "libgtest",
+        "libc++fs",
+    ],
+    header_libs: [
+        "libsurfaceflinger_mocks_headers",
+        "surfaceflinger_tests_common_headers",
+    ],
+}
diff --git a/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp b/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp
new file mode 100644
index 0000000..7641a45
--- /dev/null
+++ b/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 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 <optional>
+
+#include <benchmark/benchmark.h>
+
+#include <Client.h> // temporarily needed for LayerCreationArgs
+#include <FrontEnd/LayerCreationArgs.h>
+#include <FrontEnd/LayerLifecycleManager.h>
+#include <LayerLifecycleManagerHelper.h>
+
+namespace android::surfaceflinger {
+
+namespace {
+
+using namespace android::surfaceflinger::frontend;
+
+static void addRemoveLayers(benchmark::State& state) {
+    LayerLifecycleManager lifecycleManager;
+    for (auto _ : state) {
+        std::vector<std::unique_ptr<RequestedLayerState>> layers;
+        layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(1));
+        layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(2));
+        layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(3));
+        lifecycleManager.addLayers(std::move(layers));
+        lifecycleManager.onHandlesDestroyed({{1, "1"}, {2, "2"}, {3, "3"}});
+        lifecycleManager.commitChanges();
+    }
+}
+BENCHMARK(addRemoveLayers);
+
+static void updateClientStates(benchmark::State& state) {
+    LayerLifecycleManager lifecycleManager;
+    std::vector<std::unique_ptr<RequestedLayerState>> layers;
+    layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(1));
+    lifecycleManager.addLayers(std::move(layers));
+    lifecycleManager.commitChanges();
+    std::vector<TransactionState> transactions;
+    transactions.emplace_back();
+    transactions.back().states.push_back({});
+    auto& transactionState = transactions.back().states.front();
+    transactionState.state.what = layer_state_t::eColorChanged;
+    transactionState.state.color.rgb = {0.f, 0.f, 0.f};
+    transactionState.layerId = 1;
+    lifecycleManager.applyTransactions(transactions);
+    lifecycleManager.commitChanges();
+    int i = 0;
+    for (auto s : state) {
+        if (i++ % 100 == 0) i = 0;
+        transactionState.state.color.b = static_cast<float>(i / 100.f);
+        lifecycleManager.applyTransactions(transactions);
+        lifecycleManager.commitChanges();
+    }
+}
+BENCHMARK(updateClientStates);
+
+static void updateClientStatesNoChanges(benchmark::State& state) {
+    LayerLifecycleManager lifecycleManager;
+    std::vector<std::unique_ptr<RequestedLayerState>> layers;
+    layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(1));
+    lifecycleManager.addLayers(std::move(layers));
+    std::vector<TransactionState> transactions;
+    transactions.emplace_back();
+    transactions.back().states.push_back({});
+    auto& transactionState = transactions.back().states.front();
+    transactionState.state.what = layer_state_t::eColorChanged;
+    transactionState.state.color.rgb = {0.f, 0.f, 0.f};
+    transactionState.layerId = 1;
+    lifecycleManager.applyTransactions(transactions);
+    lifecycleManager.commitChanges();
+    for (auto _ : state) {
+        lifecycleManager.applyTransactions(transactions);
+        lifecycleManager.commitChanges();
+    }
+}
+BENCHMARK(updateClientStatesNoChanges);
+
+} // namespace
+} // namespace android::surfaceflinger
diff --git a/services/surfaceflinger/tests/benchmarks/LocklessQueue_benchmarks.cpp b/services/surfaceflinger/tests/benchmarks/LocklessQueue_benchmarks.cpp
new file mode 100644
index 0000000..60bd58a
--- /dev/null
+++ b/services/surfaceflinger/tests/benchmarks/LocklessQueue_benchmarks.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 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 <optional>
+
+#include <benchmark/benchmark.h>
+
+#include <LocklessQueue.h>
+
+namespace android::surfaceflinger {
+
+namespace {
+static void pushPop(benchmark::State& state) {
+    LocklessQueue<std::vector<uint32_t>> queue;
+    for (auto _ : state) {
+        queue.push({10, 5});
+        std::vector<uint32_t> poppedValue = *queue.pop();
+        benchmark::DoNotOptimize(poppedValue);
+    }
+}
+BENCHMARK(pushPop);
+
+} // namespace
+} // namespace android::surfaceflinger
diff --git a/libs/tracing_perfetto/include/trace_result.h b/services/surfaceflinger/tests/benchmarks/main.cpp
similarity index 70%
copy from libs/tracing_perfetto/include/trace_result.h
copy to services/surfaceflinger/tests/benchmarks/main.cpp
index f7581fc..685c7c6 100644
--- a/libs/tracing_perfetto/include/trace_result.h
+++ b/services/surfaceflinger/tests/benchmarks/main.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2024 The Android Open Source Project
+ * Copyright (C) 2024 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.
@@ -14,17 +14,5 @@
  * limitations under the License.
  */
 
-#ifndef TRACE_RESULT_H
-#define TRACE_RESULT_H
-
-namespace tracing_perfetto {
-
-enum class Result {
-  SUCCESS,
-  NOT_SUPPORTED,
-  INVALID_INPUT,
-};
-
-}
-
-#endif  // TRACE_RESULT_H
+#include <benchmark/benchmark.h>
+BENCHMARK_MAIN();
diff --git a/libs/vr/Android.bp b/services/surfaceflinger/tests/common/Android.bp
similarity index 76%
rename from libs/vr/Android.bp
rename to services/surfaceflinger/tests/common/Android.bp
index b308895..2dfa8af 100644
--- a/libs/vr/Android.bp
+++ b/services/surfaceflinger/tests/common/Android.bp
@@ -4,11 +4,10 @@
     // all of the 'license_kinds' from "frameworks_native_license"
     // to get the below license kinds:
     //   SPDX-license-identifier-Apache-2.0
-    //   SPDX-license-identifier-BSD
-    //   legacy_notice
     default_applicable_licenses: ["frameworks_native_license"],
 }
 
-subdirs = [
-    "*",
-]
+cc_library_headers {
+    name: "surfaceflinger_tests_common_headers",
+    export_include_dirs: ["."],
+}
diff --git a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h
new file mode 100644
index 0000000..2e5913b
--- /dev/null
+++ b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h
@@ -0,0 +1,479 @@
+/*
+ * Copyright 2024 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 <gui/fake/BufferData.h>
+#include <renderengine/mock/FakeExternalTexture.h>
+#include <ui/ShadowSettings.h>
+
+#include <Client.h> // temporarily needed for LayerCreationArgs
+#include <FrontEnd/LayerCreationArgs.h>
+#include <FrontEnd/LayerHierarchy.h>
+#include <FrontEnd/LayerLifecycleManager.h>
+#include <FrontEnd/LayerSnapshotBuilder.h>
+
+namespace android::surfaceflinger::frontend {
+
+class LayerLifecycleManagerHelper {
+public:
+    LayerLifecycleManagerHelper(LayerLifecycleManager& layerLifecycleManager)
+          : mLifecycleManager(layerLifecycleManager) {}
+    ~LayerLifecycleManagerHelper() = default;
+
+    static LayerCreationArgs createArgs(uint32_t id, bool canBeRoot, uint32_t parentId,
+                                        uint32_t layerIdToMirror) {
+        LayerCreationArgs args(std::make_optional(id));
+        args.name = "testlayer";
+        args.addToRoot = canBeRoot;
+        args.parentId = parentId;
+        args.layerIdToMirror = layerIdToMirror;
+        return args;
+    }
+
+    static LayerCreationArgs createDisplayMirrorArgs(uint32_t id,
+                                                     ui::LayerStack layerStackToMirror) {
+        LayerCreationArgs args(std::make_optional(id));
+        args.name = "testlayer";
+        args.addToRoot = true;
+        args.layerStackToMirror = layerStackToMirror;
+        return args;
+    }
+
+    static std::unique_ptr<RequestedLayerState> rootLayer(uint32_t id) {
+        return std::make_unique<RequestedLayerState>(createArgs(/*id=*/id, /*canBeRoot=*/true,
+                                                                /*parent=*/UNASSIGNED_LAYER_ID,
+                                                                /*mirror=*/UNASSIGNED_LAYER_ID));
+    }
+
+    static std::unique_ptr<RequestedLayerState> childLayer(uint32_t id, uint32_t parentId) {
+        return std::make_unique<RequestedLayerState>(createArgs(/*id=*/id, /*canBeRoot=*/false,
+                                                                parentId,
+                                                                /*mirror=*/UNASSIGNED_LAYER_ID));
+    }
+
+    static std::vector<TransactionState> setZTransaction(uint32_t id, int32_t z) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.z = z;
+        return transactions;
+    }
+
+    void createRootLayer(uint32_t id) {
+        std::vector<std::unique_ptr<RequestedLayerState>> layers;
+        layers.emplace_back(std::make_unique<RequestedLayerState>(
+                createArgs(/*id=*/id, /*canBeRoot=*/true, /*parent=*/UNASSIGNED_LAYER_ID,
+                           /*mirror=*/UNASSIGNED_LAYER_ID)));
+        mLifecycleManager.addLayers(std::move(layers));
+    }
+
+    void createDisplayMirrorLayer(uint32_t id, ui::LayerStack layerStack) {
+        std::vector<std::unique_ptr<RequestedLayerState>> layers;
+        layers.emplace_back(std::make_unique<RequestedLayerState>(
+                createDisplayMirrorArgs(/*id=*/id, layerStack)));
+        mLifecycleManager.addLayers(std::move(layers));
+    }
+
+    void createLayer(uint32_t id, uint32_t parentId) {
+        std::vector<std::unique_ptr<RequestedLayerState>> layers;
+        layers.emplace_back(std::make_unique<RequestedLayerState>(
+                createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/parentId,
+                           /*mirror=*/UNASSIGNED_LAYER_ID)));
+        mLifecycleManager.addLayers(std::move(layers));
+    }
+
+    std::vector<TransactionState> reparentLayerTransaction(uint32_t id, uint32_t newParentId) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+        transactions.back().states.front().parentId = newParentId;
+        transactions.back().states.front().state.what = layer_state_t::eReparent;
+        transactions.back().states.front().relativeParentId = UNASSIGNED_LAYER_ID;
+        transactions.back().states.front().layerId = id;
+        return transactions;
+    }
+
+    void reparentLayer(uint32_t id, uint32_t newParentId) {
+        mLifecycleManager.applyTransactions(reparentLayerTransaction(id, newParentId));
+    }
+
+    std::vector<TransactionState> relativeLayerTransaction(uint32_t id, uint32_t relativeParentId) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+        transactions.back().states.front().relativeParentId = relativeParentId;
+        transactions.back().states.front().state.what = layer_state_t::eRelativeLayerChanged;
+        transactions.back().states.front().layerId = id;
+        return transactions;
+    }
+
+    void reparentRelativeLayer(uint32_t id, uint32_t relativeParentId) {
+        mLifecycleManager.applyTransactions(relativeLayerTransaction(id, relativeParentId));
+    }
+
+    void removeRelativeZ(uint32_t id) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+        transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
+        transactions.back().states.front().layerId = id;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setPosition(uint32_t id, float x, float y) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+        transactions.back().states.front().state.what = layer_state_t::ePositionChanged;
+        transactions.back().states.front().state.x = x;
+        transactions.back().states.front().state.y = y;
+        transactions.back().states.front().layerId = id;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void mirrorLayer(uint32_t id, uint32_t parentId, uint32_t layerIdToMirror) {
+        std::vector<std::unique_ptr<RequestedLayerState>> layers;
+        layers.emplace_back(std::make_unique<RequestedLayerState>(
+                createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/parentId,
+                           /*mirror=*/layerIdToMirror)));
+        mLifecycleManager.addLayers(std::move(layers));
+    }
+
+    void updateBackgroundColor(uint32_t id, half alpha) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+        transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged;
+        transactions.back().states.front().state.bgColor.a = alpha;
+        transactions.back().states.front().layerId = id;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void destroyLayerHandle(uint32_t id) { mLifecycleManager.onHandlesDestroyed({{id, "test"}}); }
+
+    void setZ(uint32_t id, int32_t z) {
+        mLifecycleManager.applyTransactions(setZTransaction(id, z));
+    }
+
+    void setCrop(uint32_t id, const Rect& crop) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eCropChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.crop = crop;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setFlags(uint32_t id, uint32_t mask, uint32_t flags) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eFlagsChanged;
+        transactions.back().states.front().state.flags = flags;
+        transactions.back().states.front().state.mask = mask;
+        transactions.back().states.front().layerId = id;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setAlpha(uint32_t id, float alpha) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eAlphaChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.color.a = static_cast<half>(alpha);
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void hideLayer(uint32_t id) {
+        setFlags(id, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden);
+    }
+
+    void showLayer(uint32_t id) { setFlags(id, layer_state_t::eLayerHidden, 0); }
+
+    void setColor(uint32_t id, half3 rgb = half3(1._hf, 1._hf, 1._hf)) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+        transactions.back().states.front().state.what = layer_state_t::eColorChanged;
+        transactions.back().states.front().state.color.rgb = rgb;
+        transactions.back().states.front().layerId = id;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setLayerStack(uint32_t id, int32_t layerStack) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eLayerStackChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.layerStack = ui::LayerStack::fromValue(layerStack);
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setTouchableRegion(uint32_t id, Region region) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.windowInfoHandle =
+                sp<gui::WindowInfoHandle>::make();
+        auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
+        inputInfo->touchableRegion = region;
+        inputInfo->token = sp<BBinder>::make();
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setInputInfo(uint32_t id, std::function<void(gui::WindowInfo&)> configureInput) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.windowInfoHandle =
+                sp<gui::WindowInfoHandle>::make();
+        auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
+        if (!inputInfo->token) {
+            inputInfo->token = sp<BBinder>::make();
+        }
+        configureInput(*inputInfo);
+
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setTouchableRegionCrop(uint32_t id, Region region, uint32_t touchCropId,
+                                bool replaceTouchableRegionWithCrop) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.windowInfoHandle =
+                sp<gui::WindowInfoHandle>::make();
+        auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
+        inputInfo->touchableRegion = region;
+        inputInfo->replaceTouchableRegionWithCrop = replaceTouchableRegionWithCrop;
+        transactions.back().states.front().touchCropId = touchCropId;
+
+        inputInfo->token = sp<BBinder>::make();
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setBackgroundBlurRadius(uint32_t id, uint32_t backgroundBlurRadius) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eBackgroundBlurRadiusChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.backgroundBlurRadius = backgroundBlurRadius;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setFrameRateSelectionPriority(uint32_t id, int32_t priority) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eFrameRateSelectionPriority;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.frameRateSelectionPriority = priority;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setFrameRate(uint32_t id, float frameRate, int8_t compatibility,
+                      int8_t changeFrameRateStrategy) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eFrameRateChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.frameRate = frameRate;
+        transactions.back().states.front().state.frameRateCompatibility = compatibility;
+        transactions.back().states.front().state.changeFrameRateStrategy = changeFrameRateStrategy;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setFrameRateCategory(uint32_t id, int8_t frameRateCategory) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eFrameRateCategoryChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.frameRateCategory = frameRateCategory;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setFrameRateSelectionStrategy(uint32_t id, int8_t strategy) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what =
+                layer_state_t::eFrameRateSelectionStrategyChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.frameRateSelectionStrategy = strategy;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setDefaultFrameRateCompatibility(uint32_t id, int8_t defaultFrameRateCompatibility) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what =
+                layer_state_t::eDefaultFrameRateCompatibilityChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.defaultFrameRateCompatibility =
+                defaultFrameRateCompatibility;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setRoundedCorners(uint32_t id, float radius) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eCornerRadiusChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.cornerRadius = radius;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setBuffer(uint32_t id, std::shared_ptr<renderengine::ExternalTexture> texture) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eBufferChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().externalTexture = texture;
+        transactions.back().states.front().state.bufferData =
+                std::make_shared<fake::BufferData>(texture->getId(), texture->getWidth(),
+                                                   texture->getHeight(), texture->getPixelFormat(),
+                                                   texture->getUsage());
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setBuffer(uint32_t id) {
+        static uint64_t sBufferId = 1;
+        setBuffer(id,
+                  std::make_shared<renderengine::mock::
+                                           FakeExternalTexture>(1U /*width*/, 1U /*height*/,
+                                                                sBufferId++,
+                                                                HAL_PIXEL_FORMAT_RGBA_8888,
+                                                                GRALLOC_USAGE_PROTECTED /*usage*/));
+    }
+
+    void setBufferCrop(uint32_t id, const Rect& bufferCrop) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eBufferCropChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.bufferCrop = bufferCrop;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setDamageRegion(uint32_t id, const Region& damageRegion) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eSurfaceDamageRegionChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.surfaceDamageRegion = damageRegion;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setDataspace(uint32_t id, ui::Dataspace dataspace) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eDataspaceChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.dataspace = dataspace;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setMatrix(uint32_t id, float dsdx, float dtdx, float dtdy, float dsdy) {
+        layer_state_t::matrix22_t matrix{dsdx, dtdx, dtdy, dsdy};
+
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eMatrixChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.matrix = matrix;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setShadowRadius(uint32_t id, float shadowRadius) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eShadowRadiusChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.shadowRadius = shadowRadius;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setTrustedOverlay(uint32_t id, gui::TrustedOverlay trustedOverlay) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eTrustedOverlayChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.trustedOverlay = trustedOverlay;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+    void setDropInputMode(uint32_t id, gui::DropInputMode dropInputMode) {
+        std::vector<TransactionState> transactions;
+        transactions.emplace_back();
+        transactions.back().states.push_back({});
+
+        transactions.back().states.front().state.what = layer_state_t::eDropInputModeChanged;
+        transactions.back().states.front().layerId = id;
+        transactions.back().states.front().state.dropInputMode = dropInputMode;
+        mLifecycleManager.applyTransactions(transactions);
+    }
+
+private:
+    LayerLifecycleManager& mLifecycleManager;
+};
+
+} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 98d5754..9ebef8c 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -58,6 +58,7 @@
     ],
     test_suites: ["device-tests"],
     static_libs: ["libc++fs"],
+    header_libs: ["surfaceflinger_tests_common_headers"],
     srcs: [
         ":libsurfaceflinger_mock_sources",
         ":libsurfaceflinger_sources",
@@ -84,6 +85,7 @@
         "FrameTimelineTest.cpp",
         "GameModeTest.cpp",
         "HWComposerTest.cpp",
+        "JankTrackerTest.cpp",
         "OneShotTimerTest.cpp",
         "LayerHistoryTest.cpp",
         "LayerHistoryIntegrationTest.cpp",
@@ -208,6 +210,7 @@
         "libsync",
         "libui",
         "libutils",
+        "libtracing_perfetto",
     ],
     header_libs: [
         "android.hardware.graphics.composer3-command-buffer",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 08973de..23d3c16 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -15,7 +15,6 @@
  */
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
-#include "renderengine/ExternalTexture.h"
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wconversion"
 #pragma clang diagnostic ignored "-Wextra"
@@ -31,6 +30,7 @@
 #include <gui/IProducerListener.h>
 #include <gui/LayerMetadata.h>
 #include <log/log.h>
+#include <renderengine/ExternalTexture.h>
 #include <renderengine/mock/FakeExternalTexture.h>
 #include <renderengine/mock/RenderEngine.h>
 #include <system/window.h>
@@ -70,6 +70,7 @@
 
 using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
 using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
+using namespace ftl::flag_operators;
 
 constexpr hal::HWDisplayId HWC_DISPLAY = FakeHwcDisplayInjector::DEFAULT_HWC_DISPLAY_ID;
 constexpr hal::HWLayerId HWC_LAYER = 5000;
@@ -148,7 +149,6 @@
     sp<compositionengine::mock::DisplaySurface> mDisplaySurface =
             sp<compositionengine::mock::DisplaySurface>::make();
     sp<mock::NativeWindow> mNativeWindow = sp<mock::NativeWindow>::make();
-    std::vector<sp<Layer>> mAuxiliaryLayers;
 
     sp<GraphicBuffer> mBuffer =
             sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_8888,
@@ -193,20 +193,19 @@
 template <typename LayerCase>
 void CompositionTest::captureScreenComposition() {
     LayerCase::setupForScreenCapture(this);
+    mFlinger.commit();
 
     const Rect sourceCrop(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
     constexpr bool regionSampling = false;
 
-    auto renderArea = DisplayRenderArea::create(mDisplay, sourceCrop, sourceCrop.getSize(),
-                                                ui::Dataspace::V0_SRGB, true, true);
+    auto renderArea =
+            DisplayRenderArea::create(mDisplay, sourceCrop, sourceCrop.getSize(),
+                                      ui::Dataspace::V0_SRGB,
+                                      RenderArea::Options::CAPTURE_SECURE_LAYERS |
+                                              RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION);
 
-    auto traverseLayers = [this](const LayerVector::Visitor& visitor) {
-        return mFlinger.traverseLayersInLayerStack(mDisplay->getLayerStack(),
-                                                   CaptureArgs::UNSET_UID, {}, visitor);
-    };
-
-    // TODO: Use SurfaceFlinger::getLayerSnapshotsForScreenshots instead of this legacy function
-    auto getLayerSnapshotsFn = RenderArea::fromTraverseLayersLambda(traverseLayers);
+    auto getLayerSnapshotsFn = mFlinger.getLayerSnapshotsForScreenshotsFn(mDisplay->getLayerStack(),
+                                                                          CaptureArgs::UNSET_UID);
 
     const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
             GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
@@ -458,7 +457,7 @@
     static constexpr IComposerClient::BlendMode BLENDMODE =
             IComposerClient::BlendMode::PREMULTIPLIED;
 
-    static void setupLatchedBuffer(CompositionTest* test, sp<Layer> layer) {
+    static void setupLatchedBuffer(CompositionTest* test, frontend::RequestedLayerState& layer) {
         Mock::VerifyAndClear(test->mRenderEngine);
 
         const auto buffer = std::make_shared<
@@ -468,21 +467,15 @@
                                                          LayerProperties::FORMAT,
                                                          LayerProperties::USAGE |
                                                                  GraphicBuffer::USAGE_HW_TEXTURE);
-
-        auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
-        layerDrawingState.crop = Rect(0, 0, LayerProperties::HEIGHT, LayerProperties::WIDTH);
-        layerDrawingState.buffer = buffer;
-        layerDrawingState.acquireFence = Fence::NO_FENCE;
-        layerDrawingState.dataspace = ui::Dataspace::UNKNOWN;
-        layer->setSurfaceDamageRegion(
-                Region(Rect(LayerProperties::HEIGHT, LayerProperties::WIDTH)));
-
-        bool ignoredRecomputeVisibleRegions;
-        layer->latchBuffer(ignoredRecomputeVisibleRegions, 0);
+        layer.crop = Rect(0, 0, LayerProperties::HEIGHT, LayerProperties::WIDTH);
+        layer.externalTexture = buffer;
+        layer.bufferData->acquireFence = Fence::NO_FENCE;
+        layer.dataspace = ui::Dataspace::UNKNOWN;
+        layer.surfaceDamageRegion = Region(Rect(LayerProperties::HEIGHT, LayerProperties::WIDTH));
         Mock::VerifyAndClear(test->mRenderEngine);
     }
 
-    static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
+    static void setupLayerState(CompositionTest* test, frontend::RequestedLayerState& layer) {
         setupLatchedBuffer(test, layer);
     }
 
@@ -666,14 +659,12 @@
     using Base = BaseLayerProperties<SidebandLayerProperties>;
     static constexpr IComposerClient::BlendMode BLENDMODE = IComposerClient::BlendMode::NONE;
 
-    static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
+    static void setupLayerState(CompositionTest* test, frontend::RequestedLayerState& layer) {
         sp<NativeHandle> stream =
                 NativeHandle::create(reinterpret_cast<native_handle_t*>(DEFAULT_SIDEBAND_STREAM),
                                      false);
-        test->mFlinger.setLayerSidebandStream(layer, stream);
-        auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
-        layerDrawingState.crop =
-                Rect(0, 0, SidebandLayerProperties::HEIGHT, SidebandLayerProperties::WIDTH);
+        layer.sidebandStream = stream;
+        layer.crop = Rect(0, 0, SidebandLayerProperties::HEIGHT, SidebandLayerProperties::WIDTH);
     }
 
     static void setupHwcSetSourceCropBufferCallExpectations(CompositionTest* test) {
@@ -751,17 +742,17 @@
 struct CursorLayerProperties : public BaseLayerProperties<CursorLayerProperties> {
     using Base = BaseLayerProperties<CursorLayerProperties>;
 
-    static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
+    static void setupLayerState(CompositionTest* test, frontend::RequestedLayerState& layer) {
         Base::setupLayerState(test, layer);
-        test->mFlinger.setLayerPotentialCursor(layer, true);
+        layer.potentialCursor = true;
     }
 };
 
 struct NoLayerVariant {
-    using FlingerLayerType = sp<Layer>;
-
-    static FlingerLayerType createLayer(CompositionTest*) { return FlingerLayerType(); }
-    static void injectLayer(CompositionTest*, FlingerLayerType) {}
+    static frontend::RequestedLayerState createLayer(CompositionTest*) {
+        return {LayerCreationArgs()};
+    }
+    static void injectLayer(CompositionTest*, frontend::RequestedLayerState&) {}
     static void cleanupInjectedLayers(CompositionTest*) {}
 
     static void setupCallExpectationsForDirtyGeometry(CompositionTest*) {}
@@ -771,10 +762,10 @@
 template <typename LayerProperties>
 struct BaseLayerVariant {
     template <typename L, typename F>
-    static sp<L> createLayerWithFactory(CompositionTest* test, F factory) {
+    static frontend::RequestedLayerState createLayerWithFactory(CompositionTest* test, F factory) {
         EXPECT_CALL(*test->mFlinger.scheduler(), postMessage(_)).Times(0);
 
-        sp<L> layer = factory();
+        auto layer = factory();
 
         // Layer should be registered with scheduler.
         EXPECT_EQ(1u, test->mFlinger.scheduler()->layerHistorySize());
@@ -788,27 +779,26 @@
         return layer;
     }
 
-    template <typename L>
-    static void initLayerDrawingStateAndComputeBounds(CompositionTest* test, sp<L> layer) {
-        auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
-        layerDrawingState.layerStack = LAYER_STACK;
-        layerDrawingState.color = half4(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
-                                        LayerProperties::COLOR[2], LayerProperties::COLOR[3]);
-        layer->computeBounds(FloatRect(0, 0, 100, 100), ui::Transform(), 0.f /* shadowRadius */);
+    static void initLayerDrawingStateAndComputeBounds(CompositionTest* test,
+                                                      frontend::RequestedLayerState& layer) {
+        layer.layerStack = LAYER_STACK;
+        layer.color = half4(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
+                            LayerProperties::COLOR[2], LayerProperties::COLOR[3]);
     }
 
-    static void injectLayer(CompositionTest* test, sp<Layer> layer) {
+    static void injectLayer(CompositionTest* test, frontend::RequestedLayerState& layer) {
         EXPECT_CALL(*test->mComposer, createLayer(HWC_DISPLAY, _))
                 .WillOnce(DoAll(SetArgPointee<1>(HWC_LAYER), Return(Error::NONE)));
-
+        auto legacyLayer = test->mFlinger.getLegacyLayer(layer.id);
         auto outputLayer = test->mDisplay->getCompositionDisplay()->injectOutputLayerForTest(
-                layer->getCompositionEngineLayerFE());
+                legacyLayer->getCompositionEngineLayerFE({.id = layer.id}));
         outputLayer->editState().visibleRegion = Region(Rect(0, 0, 100, 100));
         outputLayer->editState().outputSpaceVisibleRegion = Region(Rect(0, 0, 100, 100));
 
         Mock::VerifyAndClear(test->mComposer);
 
-        test->mFlinger.mutableDrawingState().layersSortedByZ.add(layer);
+        auto layerCopy = std::make_unique<frontend::RequestedLayerState>(layer);
+        test->mFlinger.addLayer(layerCopy);
         test->mFlinger.mutableVisibleRegionsDirty() = true;
     }
 
@@ -816,10 +806,9 @@
         EXPECT_CALL(*test->mComposer, destroyLayer(HWC_DISPLAY, HWC_LAYER))
                 .WillOnce(Return(Error::NONE));
 
+        test->mFlinger.destroyAllLayerHandles();
         test->mDisplay->getCompositionDisplay()->clearOutputLayers();
-        test->mFlinger.mutableDrawingState().layersSortedByZ.clear();
         test->mFlinger.mutablePreviouslyComposedLayers().clear();
-
         // Layer should be unregistered with scheduler.
         test->mFlinger.commit();
         EXPECT_EQ(0u, test->mFlinger.scheduler()->layerHistorySize());
@@ -829,17 +818,17 @@
 template <typename LayerProperties>
 struct EffectLayerVariant : public BaseLayerVariant<LayerProperties> {
     using Base = BaseLayerVariant<LayerProperties>;
-    using FlingerLayerType = sp<Layer>;
-
-    static FlingerLayerType createLayer(CompositionTest* test) {
-        FlingerLayerType layer = Base::template createLayerWithFactory<Layer>(test, [test]() {
-            return sp<Layer>::make(LayerCreationArgs(test->mFlinger.flinger(), sp<Client>(),
-                                                     "test-layer", LayerProperties::LAYER_FLAGS,
-                                                     LayerMetadata()));
+    static frontend::RequestedLayerState createLayer(CompositionTest* test) {
+        frontend::RequestedLayerState layer = Base::template createLayerWithFactory<
+                frontend::RequestedLayerState>(test, [test]() {
+            auto args = LayerCreationArgs(test->mFlinger.flinger(), sp<Client>(), "test-layer",
+                                          LayerProperties::LAYER_FLAGS, LayerMetadata());
+            auto legacyLayer = sp<Layer>::make(args);
+            test->mFlinger.injectLegacyLayer(legacyLayer);
+            return frontend::RequestedLayerState(args);
         });
 
-        auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
-        layerDrawingState.crop = Rect(0, 0, LayerProperties::HEIGHT, LayerProperties::WIDTH);
+        layer.crop = Rect(0, 0, LayerProperties::HEIGHT, LayerProperties::WIDTH);
         return layer;
     }
 
@@ -865,13 +854,15 @@
 template <typename LayerProperties>
 struct BufferLayerVariant : public BaseLayerVariant<LayerProperties> {
     using Base = BaseLayerVariant<LayerProperties>;
-    using FlingerLayerType = sp<Layer>;
 
-    static FlingerLayerType createLayer(CompositionTest* test) {
-        FlingerLayerType layer = Base::template createLayerWithFactory<Layer>(test, [test]() {
+    static frontend::RequestedLayerState createLayer(CompositionTest* test) {
+        frontend::RequestedLayerState layer = Base::template createLayerWithFactory<
+                frontend::RequestedLayerState>(test, [test]() {
             LayerCreationArgs args(test->mFlinger.flinger(), sp<Client>(), "test-layer",
                                    LayerProperties::LAYER_FLAGS, LayerMetadata());
-            return sp<Layer>::make(args);
+            auto legacyLayer = sp<Layer>::make(args);
+            test->mFlinger.injectLegacyLayer(legacyLayer);
+            return frontend::RequestedLayerState(args);
         });
 
         LayerProperties::setupLayerState(test, layer);
@@ -913,13 +904,14 @@
 template <typename LayerProperties>
 struct ContainerLayerVariant : public BaseLayerVariant<LayerProperties> {
     using Base = BaseLayerVariant<LayerProperties>;
-    using FlingerLayerType = sp<Layer>;
 
-    static FlingerLayerType createLayer(CompositionTest* test) {
+    static frontend::RequestedLayerState createLayer(CompositionTest* test) {
         LayerCreationArgs args(test->mFlinger.flinger(), sp<Client>(), "test-container-layer",
                                LayerProperties::LAYER_FLAGS, LayerMetadata());
-        FlingerLayerType layer = sp<Layer>::make(args);
-        Base::template initLayerDrawingStateAndComputeBounds(test, layer);
+        sp<Layer> legacyLayer = sp<Layer>::make(args);
+        test->mFlinger.injectLegacyLayer(legacyLayer);
+        frontend::RequestedLayerState layer(args);
+        Base::initLayerDrawingStateAndComputeBounds(test, layer);
         return layer;
     }
 };
@@ -927,29 +919,19 @@
 template <typename LayerVariant, typename ParentLayerVariant>
 struct ChildLayerVariant : public LayerVariant {
     using Base = LayerVariant;
-    using FlingerLayerType = typename LayerVariant::FlingerLayerType;
     using ParentBase = ParentLayerVariant;
 
-    static FlingerLayerType createLayer(CompositionTest* test) {
+    static frontend::RequestedLayerState createLayer(CompositionTest* test) {
         // Need to create child layer first. Otherwise layer history size will be 2.
-        FlingerLayerType layer = Base::createLayer(test);
-
-        typename ParentBase::FlingerLayerType parentLayer = ParentBase::createLayer(test);
-        parentLayer->addChild(layer);
-        test->mFlinger.setLayerDrawingParent(layer, parentLayer);
-
-        test->mAuxiliaryLayers.push_back(parentLayer);
-
+        frontend::RequestedLayerState layer = Base::createLayer(test);
+        frontend::RequestedLayerState parentLayer = ParentBase::createLayer(test);
+        layer.parentId = parentLayer.id;
+        auto layerCopy = std::make_unique<frontend::RequestedLayerState>(parentLayer);
+        test->mFlinger.addLayer(layerCopy);
         return layer;
     }
 
-    static void cleanupInjectedLayers(CompositionTest* test) {
-        // Clear auxiliary layers first so that child layer can be successfully destroyed in the
-        // following call.
-        test->mAuxiliaryLayers.clear();
-
-        Base::cleanupInjectedLayers(test);
-    }
+    static void cleanupInjectedLayers(CompositionTest* test) { Base::cleanupInjectedLayers(test); }
 };
 
 /* ------------------------------------------------------------------------
@@ -1012,7 +994,7 @@
  */
 
 struct CompositionResultBaseVariant {
-    static void setupLayerState(CompositionTest*, sp<Layer>) {}
+    static void setupLayerState(CompositionTest*, frontend::RequestedLayerState&) {}
 
     template <typename Case>
     static void setupCallExpectationsForDirtyGeometry(CompositionTest* test) {
@@ -1052,9 +1034,8 @@
 };
 
 struct ForcedClientCompositionResultVariant : public CompositionResultBaseVariant {
-    static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
-        const auto outputLayer =
-                TestableSurfaceFlinger::findOutputLayerForDisplay(layer, test->mDisplay);
+    static void setupLayerState(CompositionTest* test, frontend::RequestedLayerState& layer) {
+        const auto outputLayer = test->mFlinger.findOutputLayerForDisplay(layer.id, test->mDisplay);
         LOG_FATAL_IF(!outputLayer);
         outputLayer->editState().forceClientComposition = true;
     }
@@ -1075,7 +1056,7 @@
 };
 
 struct ForcedClientCompositionViaDebugOptionResultVariant : public CompositionResultBaseVariant {
-    static void setupLayerState(CompositionTest* test, sp<Layer>) {
+    static void setupLayerState(CompositionTest* test, frontend::RequestedLayerState&) {
         test->mFlinger.mutableDebugDisableHWC() = true;
     }
 
@@ -1095,7 +1076,7 @@
 };
 
 struct EmptyScreenshotResultVariant {
-    static void setupLayerState(CompositionTest*, sp<Layer>) {}
+    static void setupLayerState(CompositionTest*, frontend::RequestedLayerState&) {}
 
     template <typename Case>
     static void setupCallExpectations(CompositionTest*) {}
@@ -1361,28 +1342,6 @@
  *  Layers with a parent layer with ISurfaceComposerClient::eSecure, on a non-secure display
  */
 
-TEST_F(CompositionTest,
-       HWCComposedBufferLayerWithSecureParentLayerOnInsecureDisplayWithDirtyGeometry) {
-    displayRefreshCompositionDirtyGeometry<CompositionCase<
-            InsecureDisplaySetupVariant,
-            ChildLayerVariant<BufferLayerVariant<ParentSecureLayerProperties>,
-                              ContainerLayerVariant<SecureLayerProperties>>,
-            KeepCompositionTypeVariant<
-                    aidl::android::hardware::graphics::composer3::Composition::CLIENT>,
-            ForcedClientCompositionResultVariant>>();
-}
-
-TEST_F(CompositionTest,
-       HWCComposedBufferLayerWithSecureParentLayerOnInsecureDisplayWithDirtyFrame) {
-    displayRefreshCompositionDirtyFrame<CompositionCase<
-            InsecureDisplaySetupVariant,
-            ChildLayerVariant<BufferLayerVariant<ParentSecureLayerProperties>,
-                              ContainerLayerVariant<SecureLayerProperties>>,
-            KeepCompositionTypeVariant<
-                    aidl::android::hardware::graphics::composer3::Composition::CLIENT>,
-            ForcedClientCompositionResultVariant>>();
-}
-
 TEST_F(CompositionTest, captureScreenBufferLayerWithSecureParentLayerOnInsecureDisplay) {
     captureScreenComposition<
             CompositionCase<InsecureDisplaySetupVariant,
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
index f26336a..db3c0a1 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
@@ -498,9 +498,7 @@
 constexpr int PHYSICAL_DISPLAY_FLAGS = 0x1;
 
 template <typename PhysicalDisplay, int width, int height,
-          Secure secure = (PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal)
-                  ? Secure::TRUE
-                  : Secure::FALSE>
+          Secure secure = (PhysicalDisplay::SECURE) ? Secure::TRUE : Secure::FALSE>
 struct PhysicalDisplayVariant
       : DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, Async::FALSE, secure,
                        PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY,
@@ -515,16 +513,18 @@
 struct PrimaryDisplay {
     static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal;
     static constexpr Primary PRIMARY = Primary::TRUE;
+    static constexpr bool SECURE = true;
     static constexpr uint8_t PORT = 255;
     static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
     static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
     static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
 };
 
-template <ui::DisplayConnectionType connectionType, bool hasIdentificationData>
+template <ui::DisplayConnectionType connectionType, bool hasIdentificationData, bool secure>
 struct SecondaryDisplay {
     static constexpr auto CONNECTION_TYPE = connectionType;
     static constexpr Primary PRIMARY = Primary::FALSE;
+    static constexpr bool SECURE = secure;
     static constexpr uint8_t PORT = 254;
     static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
     static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
@@ -533,9 +533,14 @@
                                                                   : getExternalEdid;
 };
 
+constexpr bool kSecure = true;
+constexpr bool kNonSecure = false;
+
+template <bool secure>
 struct TertiaryDisplay {
     static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External;
     static constexpr Primary PRIMARY = Primary::FALSE;
+    static constexpr bool SECURE = secure;
     static constexpr uint8_t PORT = 253;
     static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
     static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
@@ -545,14 +550,26 @@
 
 using InnerDisplayVariant = PhysicalDisplayVariant<PrimaryDisplay<true>, 1840, 2208>;
 using OuterDisplayVariant =
-        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal, true>, 1080,
-                               2092>;
+        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal,
+                                                /*hasIdentificationData=*/true, kSecure>,
+                               1080, 2092>;
+using OuterDisplayNonSecureVariant =
+        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal,
+                                                /*hasIdentificationData=*/true, kNonSecure>,
+                               1080, 2092>;
 
 using ExternalDisplayVariant =
-        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External, false>, 1920,
-                               1280>;
+        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External,
+                                                /*hasIdentificationData=*/false, kSecure>,
+                               1920, 1280>;
+using ExternalDisplayNonSecureVariant =
+        PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External,
+                                                /*hasIdentificationData=*/false, kNonSecure>,
+                               1920, 1280>;
 
-using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200>;
+using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay<kSecure>, 1600, 1200>;
+using TertiaryDisplayNonSecureVariant =
+        PhysicalDisplayVariant<TertiaryDisplay<kNonSecure>, 1600, 1200>;
 
 // A virtual display not supported by the HWC.
 constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
@@ -750,10 +767,18 @@
         Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
              HdrNotSupportedVariant<ExternalDisplayVariant>,
              NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
+using SimpleExternalDisplayNonSecureCase =
+        Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayNonSecureVariant>,
+             HdrNotSupportedVariant<ExternalDisplayNonSecureVariant>,
+             NoPerFrameMetadataSupportVariant<ExternalDisplayNonSecureVariant>>;
 using SimpleTertiaryDisplayCase =
         Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
              HdrNotSupportedVariant<TertiaryDisplayVariant>,
              NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
+using SimpleTertiaryDisplayNonSecureCase =
+        Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayNonSecureVariant>,
+             HdrNotSupportedVariant<TertiaryDisplayNonSecureVariant>,
+             NoPerFrameMetadataSupportVariant<TertiaryDisplayNonSecureVariant>>;
 
 using NonHwcVirtualDisplayCase =
         Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
index dac9265..9be0fc3 100644
--- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
@@ -15,6 +15,8 @@
  */
 
 #include <common/test/FlagUtils.h>
+#include "BackgroundExecutor.h"
+#include "Jank/JankTracker.h"
 #include "com_android_graphics_surfaceflinger_flags.h"
 #include "gmock/gmock-spec-builders.h"
 #include "mock/MockTimeStats.h"
@@ -90,8 +92,12 @@
         mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
         maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
         maxTokens = mTokenManager->kMaxTokens;
+
+        JankTracker::clearAndStartCollectingAllJankDataForTesting();
     }
 
+    void TearDown() override { JankTracker::clearAndStopCollectingAllJankDataForTesting(); }
+
     // Each tracing session can be used for a single block of Start -> Stop.
     static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
         perfetto::TraceConfig cfg;
@@ -175,6 +181,16 @@
                 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
     }
 
+    std::vector<gui::JankData> getLayerOneJankData() {
+        BackgroundExecutor::getLowPriorityInstance().flushQueue();
+        return JankTracker::getCollectedJankDataForTesting(sLayerIdOne);
+    }
+
+    std::vector<gui::JankData> getLayerTwoJankData() {
+        BackgroundExecutor::getLowPriorityInstance().flushQueue();
+        return JankTracker::getCollectedJankDataForTesting(sLayerIdTwo);
+    }
+
     std::shared_ptr<mock::TimeStats> mTimeStats;
     std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
     impl::TokenManager* mTokenManager;
@@ -339,6 +355,9 @@
     EXPECT_NE(surfaceFrame1->getJankSeverityType(), std::nullopt);
     EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
     EXPECT_NE(surfaceFrame2->getJankSeverityType(), std::nullopt);
+
+    EXPECT_EQ(getLayerOneJankData().size(), 1u);
+    EXPECT_EQ(getLayerTwoJankData().size(), 1u);
 }
 
 TEST_F(FrameTimelineTest, displayFrameSkippedComposition) {
@@ -446,6 +465,8 @@
     // The window should have slided by 1 now and the previous 0th display frame
     // should have been removed from the deque
     EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
+
+    EXPECT_EQ(getLayerOneJankData().size(), *maxDisplayFrames);
 }
 
 TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
@@ -458,6 +479,16 @@
     EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
 }
 
+TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceUnsignaled) {
+    auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
+                                                                   "acquireFenceAfterQueue",
+                                                                   "acquireFenceAfterQueue",
+                                                                   /*isBuffer*/ true, sGameMode);
+    surfaceFrame->setActualQueueTime(123);
+    surfaceFrame->setAcquireFenceTime(Fence::SIGNAL_TIME_PENDING);
+    EXPECT_EQ(surfaceFrame->getActuals().endTime, 123);
+}
+
 TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
     auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
                                                                    "acquireFenceAfterQueue",
@@ -575,6 +606,8 @@
     presentFence1->signalForTest(70);
 
     mFrameTimeline->setSfPresent(59, presentFence1);
+
+    EXPECT_EQ(getLayerOneJankData().size(), 0u);
 }
 
 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
@@ -603,6 +636,10 @@
     presentFence1->signalForTest(70);
 
     mFrameTimeline->setSfPresent(62, presentFence1);
+
+    auto jankData = getLayerOneJankData();
+    EXPECT_EQ(jankData.size(), 1u);
+    EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerCpuDeadlineMissed);
 }
 
 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
@@ -633,6 +670,10 @@
     presentFence1->signalForTest(70);
 
     mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
+
+    auto jankData = getLayerOneJankData();
+    EXPECT_EQ(jankData.size(), 1u);
+    EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerGpuDeadlineMissed);
 }
 
 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
@@ -661,6 +702,10 @@
     mFrameTimeline->setSfPresent(56, presentFence1);
     EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
     EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
+
+    auto jankData = getLayerOneJankData();
+    EXPECT_EQ(jankData.size(), 1u);
+    EXPECT_EQ(jankData[0].jankType, JankType::DisplayHAL);
 }
 
 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
@@ -691,6 +736,10 @@
 
     EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
     EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
+
+    auto jankData = getLayerOneJankData();
+    EXPECT_EQ(jankData.size(), 1u);
+    EXPECT_EQ(jankData[0].jankType, JankType::AppDeadlineMissed);
 }
 
 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
@@ -721,6 +770,10 @@
 
     EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
     EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
+
+    auto jankData = getLayerOneJankData();
+    EXPECT_EQ(jankData.size(), 1u);
+    EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerScheduling);
 }
 
 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
@@ -751,6 +804,10 @@
 
     EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
     EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
+
+    auto jankData = getLayerOneJankData();
+    EXPECT_EQ(jankData.size(), 1u);
+    EXPECT_EQ(jankData[0].jankType, JankType::PredictionError);
 }
 
 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
@@ -782,6 +839,10 @@
 
     EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
     EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
+
+    auto jankData = getLayerOneJankData();
+    EXPECT_EQ(jankData.size(), 1u);
+    EXPECT_EQ(jankData[0].jankType, JankType::BufferStuffing);
 }
 
 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
@@ -814,6 +875,10 @@
 
     EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
     EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
+
+    auto jankData = getLayerOneJankData();
+    EXPECT_EQ(jankData.size(), 1u);
+    EXPECT_EQ(jankData[0].jankType, JankType::AppDeadlineMissed);
 }
 
 TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
@@ -858,6 +923,10 @@
     EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
     EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
     EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
+
+    auto jankData = getLayerOneJankData();
+    EXPECT_EQ(jankData.size(), 1u);
+    EXPECT_EQ(jankData[0].jankType, JankType::Unknown | JankType::AppDeadlineMissed);
 }
 
 /*
@@ -1789,6 +1858,10 @@
     EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
     EXPECT_EQ(displayFrame->getJankType(), JankType::None);
     EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
+
+    auto jankData = getLayerOneJankData();
+    EXPECT_EQ(jankData.size(), 1u);
+    EXPECT_EQ(jankData[0].jankType, JankType::None);
 }
 
 TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
diff --git a/services/surfaceflinger/tests/unittests/JankTrackerTest.cpp b/services/surfaceflinger/tests/unittests/JankTrackerTest.cpp
new file mode 100644
index 0000000..2941a14
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/JankTrackerTest.cpp
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2024 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/gui/BnJankListener.h>
+#include <binder/IInterface.h>
+#include "BackgroundExecutor.h"
+#include "Jank/JankTracker.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace android {
+
+namespace {
+
+using namespace testing;
+
+class MockJankListener : public gui::BnJankListener {
+public:
+    MockJankListener() = default;
+    ~MockJankListener() override = default;
+
+    MOCK_METHOD(binder::Status, onJankData, (const std::vector<gui::JankData>& jankData),
+                (override));
+};
+
+} // anonymous namespace
+
+class JankTrackerTest : public Test {
+public:
+    JankTrackerTest() {}
+
+    void SetUp() override { mListener = sp<StrictMock<MockJankListener>>::make(); }
+
+    void addJankListener(int32_t layerId) {
+        JankTracker::addJankListener(layerId, IInterface::asBinder(mListener));
+    }
+
+    void removeJankListener(int32_t layerId, int64_t after) {
+        JankTracker::removeJankListener(layerId, IInterface::asBinder(mListener), after);
+    }
+
+    void addJankData(int32_t layerId, int jankType) {
+        gui::JankData data;
+        data.frameVsyncId = mVsyncId++;
+        data.jankType = jankType;
+        data.frameIntervalNs = 8333333;
+        JankTracker::onJankData(layerId, data);
+    }
+
+    void flushBackgroundThread() { BackgroundExecutor::getLowPriorityInstance().flushQueue(); }
+
+    size_t listenerCount() { return JankTracker::sListenerCount; }
+
+    std::vector<gui::JankData> getCollectedJankData(int32_t layerId) {
+        return JankTracker::getCollectedJankDataForTesting(layerId);
+    }
+
+    sp<StrictMock<MockJankListener>> mListener = nullptr;
+    int64_t mVsyncId = 1000;
+};
+
+TEST_F(JankTrackerTest, jankDataIsTrackedAndPropagated) {
+    ASSERT_EQ(listenerCount(), 0u);
+
+    EXPECT_CALL(*mListener.get(), onJankData(SizeIs(3)))
+            .WillOnce([](const std::vector<gui::JankData>& jankData) {
+                EXPECT_EQ(jankData[0].frameVsyncId, 1000);
+                EXPECT_EQ(jankData[0].jankType, 1);
+                EXPECT_EQ(jankData[0].frameIntervalNs, 8333333);
+
+                EXPECT_EQ(jankData[1].frameVsyncId, 1001);
+                EXPECT_EQ(jankData[1].jankType, 2);
+                EXPECT_EQ(jankData[1].frameIntervalNs, 8333333);
+
+                EXPECT_EQ(jankData[2].frameVsyncId, 1002);
+                EXPECT_EQ(jankData[2].jankType, 3);
+                EXPECT_EQ(jankData[2].frameIntervalNs, 8333333);
+                return binder::Status::ok();
+            });
+    EXPECT_CALL(*mListener.get(), onJankData(SizeIs(2)))
+            .WillOnce([](const std::vector<gui::JankData>& jankData) {
+                EXPECT_EQ(jankData[0].frameVsyncId, 1003);
+                EXPECT_EQ(jankData[0].jankType, 4);
+                EXPECT_EQ(jankData[0].frameIntervalNs, 8333333);
+
+                EXPECT_EQ(jankData[1].frameVsyncId, 1004);
+                EXPECT_EQ(jankData[1].jankType, 5);
+                EXPECT_EQ(jankData[1].frameIntervalNs, 8333333);
+
+                return binder::Status::ok();
+            });
+
+    addJankListener(123);
+    addJankData(123, 1);
+    addJankData(123, 2);
+    addJankData(123, 3);
+    JankTracker::flushJankData(123);
+    addJankData(123, 4);
+    removeJankListener(123, mVsyncId);
+    addJankData(123, 5);
+    JankTracker::flushJankData(123);
+    addJankData(123, 6);
+    JankTracker::flushJankData(123);
+    removeJankListener(123, 0);
+
+    flushBackgroundThread();
+}
+
+TEST_F(JankTrackerTest, jankDataIsAutomaticallyFlushedInBatches) {
+    ASSERT_EQ(listenerCount(), 0u);
+
+    // needs to be larger than kJankDataBatchSize in JankTracker.cpp.
+    constexpr size_t kNumberOfJankDataToSend = 234;
+
+    size_t jankDataReceived = 0;
+    size_t numBatchesReceived = 0;
+
+    EXPECT_CALL(*mListener.get(), onJankData(_))
+            .WillRepeatedly([&](const std::vector<gui::JankData>& jankData) {
+                jankDataReceived += jankData.size();
+                numBatchesReceived++;
+                return binder::Status::ok();
+            });
+
+    addJankListener(123);
+    for (size_t i = 0; i < kNumberOfJankDataToSend; i++) {
+        addJankData(123, 0);
+    }
+
+    flushBackgroundThread();
+    // Check that we got some data, without explicitly flushing.
+    EXPECT_GT(jankDataReceived, 0u);
+    EXPECT_GT(numBatchesReceived, 0u);
+    EXPECT_LT(numBatchesReceived, jankDataReceived); // batches should be > size 1.
+
+    removeJankListener(123, 0);
+    JankTracker::flushJankData(123);
+    flushBackgroundThread();
+    EXPECT_EQ(jankDataReceived, kNumberOfJankDataToSend);
+}
+
+TEST_F(JankTrackerTest, jankListenerIsRemovedWhenReturningNullError) {
+    ASSERT_EQ(listenerCount(), 0u);
+
+    EXPECT_CALL(*mListener.get(), onJankData(SizeIs(3)))
+            .WillOnce(Return(binder::Status::fromExceptionCode(binder::Status::EX_NULL_POINTER)));
+
+    addJankListener(123);
+    addJankData(123, 1);
+    addJankData(123, 2);
+    addJankData(123, 3);
+    JankTracker::flushJankData(123);
+    addJankData(123, 4);
+    addJankData(123, 5);
+    JankTracker::flushJankData(123);
+    flushBackgroundThread();
+
+    EXPECT_EQ(listenerCount(), 0u);
+}
+
+TEST_F(JankTrackerTest, jankDataIsDroppedIfNobodyIsListening) {
+    ASSERT_EQ(listenerCount(), 0u);
+
+    addJankData(123, 1);
+    addJankData(123, 2);
+    addJankData(123, 3);
+    flushBackgroundThread();
+
+    EXPECT_EQ(getCollectedJankData(123).size(), 0u);
+}
+
+TEST_F(JankTrackerTest, listenerCountTracksRegistrations) {
+    ASSERT_EQ(listenerCount(), 0u);
+
+    addJankListener(123);
+    addJankListener(456);
+    flushBackgroundThread();
+    EXPECT_EQ(listenerCount(), 2u);
+
+    removeJankListener(123, 0);
+    JankTracker::flushJankData(123);
+    removeJankListener(456, 0);
+    JankTracker::flushJankData(456);
+    flushBackgroundThread();
+    EXPECT_EQ(listenerCount(), 0u);
+}
+
+TEST_F(JankTrackerTest, listenerCountIsAccurateOnDuplicateRegistration) {
+    ASSERT_EQ(listenerCount(), 0u);
+
+    addJankListener(123);
+    addJankListener(123);
+    flushBackgroundThread();
+    EXPECT_EQ(listenerCount(), 1u);
+
+    removeJankListener(123, 0);
+    JankTracker::flushJankData(123);
+    flushBackgroundThread();
+    EXPECT_EQ(listenerCount(), 0u);
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index 8b3303c..37cda3e 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -25,13 +25,15 @@
 #include "FrontEnd/LayerCreationArgs.h"
 #include "FrontEnd/LayerHierarchy.h"
 #include "FrontEnd/LayerLifecycleManager.h"
+#include "LayerLifecycleManagerHelper.h"
+
 #include "FrontEnd/LayerSnapshotBuilder.h"
 
 namespace android::surfaceflinger::frontend {
 
-class LayerHierarchyTestBase : public testing::Test {
+class LayerHierarchyTestBase : public testing::Test, public LayerLifecycleManagerHelper {
 protected:
-    LayerHierarchyTestBase() {
+    LayerHierarchyTestBase() : LayerLifecycleManagerHelper(mLifecycleManager) {
         // tree with 3 levels of children
         // ROOT
         // ├── 1
@@ -55,24 +57,6 @@
         createLayer(1221, 122);
     }
 
-    LayerCreationArgs createArgs(uint32_t id, bool canBeRoot, uint32_t parentId,
-                                 uint32_t layerIdToMirror) {
-        LayerCreationArgs args(std::make_optional(id));
-        args.name = "testlayer";
-        args.addToRoot = canBeRoot;
-        args.parentId = parentId;
-        args.layerIdToMirror = layerIdToMirror;
-        return args;
-    }
-
-    LayerCreationArgs createDisplayMirrorArgs(uint32_t id, ui::LayerStack layerStackToMirror) {
-        LayerCreationArgs args(std::make_optional(id));
-        args.name = "testlayer";
-        args.addToRoot = true;
-        args.layerStackToMirror = layerStackToMirror;
-        return args;
-    }
-
     std::vector<uint32_t> getTraversalPath(const LayerHierarchy& hierarchy) const {
         std::vector<uint32_t> layerIds;
         hierarchy.traverse([&layerIds = layerIds](const LayerHierarchy& hierarchy,
@@ -94,98 +78,6 @@
         return layerIds;
     }
 
-    virtual void createRootLayer(uint32_t id) {
-        std::vector<std::unique_ptr<RequestedLayerState>> layers;
-        layers.emplace_back(std::make_unique<RequestedLayerState>(
-                createArgs(/*id=*/id, /*canBeRoot=*/true, /*parent=*/UNASSIGNED_LAYER_ID,
-                           /*mirror=*/UNASSIGNED_LAYER_ID)));
-        mLifecycleManager.addLayers(std::move(layers));
-    }
-
-    void createDisplayMirrorLayer(uint32_t id, ui::LayerStack layerStack) {
-        std::vector<std::unique_ptr<RequestedLayerState>> layers;
-        layers.emplace_back(std::make_unique<RequestedLayerState>(
-                createDisplayMirrorArgs(/*id=*/id, layerStack)));
-        mLifecycleManager.addLayers(std::move(layers));
-    }
-
-    virtual void createLayer(uint32_t id, uint32_t parentId) {
-        std::vector<std::unique_ptr<RequestedLayerState>> layers;
-        layers.emplace_back(std::make_unique<RequestedLayerState>(
-                createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/parentId,
-                           /*mirror=*/UNASSIGNED_LAYER_ID)));
-        mLifecycleManager.addLayers(std::move(layers));
-    }
-
-    std::vector<TransactionState> reparentLayerTransaction(uint32_t id, uint32_t newParentId) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-        transactions.back().states.front().parentId = newParentId;
-        transactions.back().states.front().state.what = layer_state_t::eReparent;
-        transactions.back().states.front().relativeParentId = UNASSIGNED_LAYER_ID;
-        transactions.back().states.front().layerId = id;
-        return transactions;
-    }
-
-    void reparentLayer(uint32_t id, uint32_t newParentId) {
-        mLifecycleManager.applyTransactions(reparentLayerTransaction(id, newParentId));
-    }
-
-    std::vector<TransactionState> relativeLayerTransaction(uint32_t id, uint32_t relativeParentId) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-        transactions.back().states.front().relativeParentId = relativeParentId;
-        transactions.back().states.front().state.what = layer_state_t::eRelativeLayerChanged;
-        transactions.back().states.front().layerId = id;
-        return transactions;
-    }
-
-    void reparentRelativeLayer(uint32_t id, uint32_t relativeParentId) {
-        mLifecycleManager.applyTransactions(relativeLayerTransaction(id, relativeParentId));
-    }
-
-    void removeRelativeZ(uint32_t id) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-        transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
-        transactions.back().states.front().layerId = id;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setPosition(uint32_t id, float x, float y) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-        transactions.back().states.front().state.what = layer_state_t::ePositionChanged;
-        transactions.back().states.front().state.x = x;
-        transactions.back().states.front().state.y = y;
-        transactions.back().states.front().layerId = id;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    virtual void mirrorLayer(uint32_t id, uint32_t parentId, uint32_t layerIdToMirror) {
-        std::vector<std::unique_ptr<RequestedLayerState>> layers;
-        layers.emplace_back(std::make_unique<RequestedLayerState>(
-                createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/parentId,
-                           /*mirror=*/layerIdToMirror)));
-        mLifecycleManager.addLayers(std::move(layers));
-    }
-
-    void updateBackgroundColor(uint32_t id, half alpha) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-        transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged;
-        transactions.back().states.front().state.bgColor.a = alpha;
-        transactions.back().states.front().layerId = id;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void destroyLayerHandle(uint32_t id) { mLifecycleManager.onHandlesDestroyed({{id, "test"}}); }
-
     void updateAndVerify(LayerHierarchyBuilder& hierarchyBuilder) {
         hierarchyBuilder.update(mLifecycleManager);
         mLifecycleManager.commitChanges();
@@ -201,321 +93,6 @@
                 mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy));
     }
 
-    std::vector<TransactionState> setZTransaction(uint32_t id, int32_t z) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.z = z;
-        return transactions;
-    }
-
-    void setZ(uint32_t id, int32_t z) {
-        mLifecycleManager.applyTransactions(setZTransaction(id, z));
-    }
-
-    void setCrop(uint32_t id, const Rect& crop) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eCropChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.crop = crop;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setFlags(uint32_t id, uint32_t mask, uint32_t flags) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eFlagsChanged;
-        transactions.back().states.front().state.flags = flags;
-        transactions.back().states.front().state.mask = mask;
-        transactions.back().states.front().layerId = id;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setAlpha(uint32_t id, float alpha) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eAlphaChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.color.a = static_cast<half>(alpha);
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void hideLayer(uint32_t id) {
-        setFlags(id, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden);
-    }
-
-    void showLayer(uint32_t id) { setFlags(id, layer_state_t::eLayerHidden, 0); }
-
-    void setColor(uint32_t id, half3 rgb = half3(1._hf, 1._hf, 1._hf)) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-        transactions.back().states.front().state.what = layer_state_t::eColorChanged;
-        transactions.back().states.front().state.color.rgb = rgb;
-        transactions.back().states.front().layerId = id;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setLayerStack(uint32_t id, int32_t layerStack) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eLayerStackChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.layerStack = ui::LayerStack::fromValue(layerStack);
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setTouchableRegion(uint32_t id, Region region) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.windowInfoHandle =
-                sp<gui::WindowInfoHandle>::make();
-        auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
-        inputInfo->touchableRegion = region;
-        inputInfo->token = sp<BBinder>::make();
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setInputInfo(uint32_t id, std::function<void(gui::WindowInfo&)> configureInput) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.windowInfoHandle =
-                sp<gui::WindowInfoHandle>::make();
-        auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
-        if (!inputInfo->token) {
-            inputInfo->token = sp<BBinder>::make();
-        }
-        configureInput(*inputInfo);
-
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setTouchableRegionCrop(uint32_t id, Region region, uint32_t touchCropId,
-                                bool replaceTouchableRegionWithCrop) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.windowInfoHandle =
-                sp<gui::WindowInfoHandle>::make();
-        auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
-        inputInfo->touchableRegion = region;
-        inputInfo->replaceTouchableRegionWithCrop = replaceTouchableRegionWithCrop;
-        transactions.back().states.front().touchCropId = touchCropId;
-
-        inputInfo->token = sp<BBinder>::make();
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setBackgroundBlurRadius(uint32_t id, uint32_t backgroundBlurRadius) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eBackgroundBlurRadiusChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.backgroundBlurRadius = backgroundBlurRadius;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setFrameRateSelectionPriority(uint32_t id, int32_t priority) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eFrameRateSelectionPriority;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.frameRateSelectionPriority = priority;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setFrameRate(uint32_t id, float frameRate, int8_t compatibility,
-                      int8_t changeFrameRateStrategy) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eFrameRateChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.frameRate = frameRate;
-        transactions.back().states.front().state.frameRateCompatibility = compatibility;
-        transactions.back().states.front().state.changeFrameRateStrategy = changeFrameRateStrategy;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setFrameRateCategory(uint32_t id, int8_t frameRateCategory) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eFrameRateCategoryChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.frameRateCategory = frameRateCategory;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setFrameRateSelectionStrategy(uint32_t id, int8_t strategy) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what =
-                layer_state_t::eFrameRateSelectionStrategyChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.frameRateSelectionStrategy = strategy;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setDefaultFrameRateCompatibility(uint32_t id, int8_t defaultFrameRateCompatibility) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what =
-                layer_state_t::eDefaultFrameRateCompatibilityChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.defaultFrameRateCompatibility =
-                defaultFrameRateCompatibility;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setRoundedCorners(uint32_t id, float radius) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eCornerRadiusChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.cornerRadius = radius;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setBuffer(uint32_t id, std::shared_ptr<renderengine::ExternalTexture> texture) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eBufferChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().externalTexture = texture;
-        transactions.back().states.front().state.bufferData =
-                std::make_shared<fake::BufferData>(texture->getId(), texture->getWidth(),
-                                                   texture->getHeight(), texture->getPixelFormat(),
-                                                   texture->getUsage());
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setBuffer(uint32_t id) {
-        static uint64_t sBufferId = 1;
-        setBuffer(id,
-                  std::make_shared<renderengine::mock::
-                                           FakeExternalTexture>(1U /*width*/, 1U /*height*/,
-                                                                sBufferId++,
-                                                                HAL_PIXEL_FORMAT_RGBA_8888,
-                                                                GRALLOC_USAGE_PROTECTED /*usage*/));
-    }
-
-    void setBufferCrop(uint32_t id, const Rect& bufferCrop) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eBufferCropChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.bufferCrop = bufferCrop;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setDamageRegion(uint32_t id, const Region& damageRegion) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eSurfaceDamageRegionChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.surfaceDamageRegion = damageRegion;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setDataspace(uint32_t id, ui::Dataspace dataspace) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eDataspaceChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.dataspace = dataspace;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setMatrix(uint32_t id, float dsdx, float dtdx, float dtdy, float dsdy) {
-        layer_state_t::matrix22_t matrix{dsdx, dtdx, dtdy, dsdy};
-
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eMatrixChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.matrix = matrix;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setShadowRadius(uint32_t id, float shadowRadius) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eShadowRadiusChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.shadowRadius = shadowRadius;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setTrustedOverlay(uint32_t id, gui::TrustedOverlay trustedOverlay) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eTrustedOverlayChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.trustedOverlay = trustedOverlay;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
-    void setDropInputMode(uint32_t id, gui::DropInputMode dropInputMode) {
-        std::vector<TransactionState> transactions;
-        transactions.emplace_back();
-        transactions.back().states.push_back({});
-
-        transactions.back().states.front().state.what = layer_state_t::eDropInputModeChanged;
-        transactions.back().states.front().layerId = id;
-        transactions.back().states.front().state.dropInputMode = dropInputMode;
-        mLifecycleManager.applyTransactions(transactions);
-    }
-
     LayerLifecycleManager mLifecycleManager;
 };
 
@@ -523,21 +100,6 @@
 protected:
     LayerSnapshotTestBase() : LayerHierarchyTestBase() {}
 
-    void createRootLayer(uint32_t id) override {
-        LayerHierarchyTestBase::createRootLayer(id);
-        setColor(id);
-    }
-
-    void createLayer(uint32_t id, uint32_t parentId) override {
-        LayerHierarchyTestBase::createLayer(id, parentId);
-        setColor(parentId);
-    }
-
-    void mirrorLayer(uint32_t id, uint32_t parent, uint32_t layerToMirror) override {
-        LayerHierarchyTestBase::mirrorLayer(id, parent, layerToMirror);
-        setColor(id);
-    }
-
     void update(LayerSnapshotBuilder& snapshotBuilder) {
         mHierarchyBuilder.update(mLifecycleManager);
         LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(),
diff --git a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
index 97bd79f..b4efe0f 100644
--- a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
@@ -61,18 +61,6 @@
 
 class LayerLifecycleManagerTest : public LayerHierarchyTestBase {
 protected:
-    std::unique_ptr<RequestedLayerState> rootLayer(uint32_t id) {
-        return std::make_unique<RequestedLayerState>(createArgs(/*id=*/id, /*canBeRoot=*/true,
-                                                                /*parent=*/UNASSIGNED_LAYER_ID,
-                                                                /*mirror=*/UNASSIGNED_LAYER_ID));
-    }
-
-    std::unique_ptr<RequestedLayerState> childLayer(uint32_t id, uint32_t parentId) {
-        return std::make_unique<RequestedLayerState>(createArgs(/*id=*/id, /*canBeRoot=*/false,
-                                                                parentId,
-                                                                /*mirror=*/UNASSIGNED_LAYER_ID));
-    }
-
     RequestedLayerState* getRequestedLayerState(LayerLifecycleManager& lifecycleManager,
                                                 uint32_t layerId) {
         return lifecycleManager.getLayerFromId(layerId);
@@ -538,7 +526,8 @@
               ftl::Flags<RequestedLayerState::Changes>(
                       RequestedLayerState::Changes::Content |
                       RequestedLayerState::Changes::AffectsChildren |
-                      RequestedLayerState::Changes::VisibleRegion)
+                      RequestedLayerState::Changes::VisibleRegion |
+                      RequestedLayerState::Changes::Input)
                       .string());
     EXPECT_EQ(mLifecycleManager.getChangedLayers()[0]->color.a, static_cast<half>(startingAlpha));
     mLifecycleManager.commitChanges();
@@ -551,7 +540,8 @@
               ftl::Flags<RequestedLayerState::Changes>(
                       RequestedLayerState::Changes::Content |
                       RequestedLayerState::Changes::AffectsChildren |
-                      RequestedLayerState::Changes::VisibleRegion)
+                      RequestedLayerState::Changes::VisibleRegion |
+                      RequestedLayerState::Changes::Input)
                       .string());
     EXPECT_EQ(mLifecycleManager.getChangedLayers()[0]->color.a, static_cast<half>(endingAlpha));
     mLifecycleManager.commitChanges();
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index dedb292..54d4659 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -291,13 +291,106 @@
     transactions.back().states.front().layerId = 1;
     transactions.back().states.front().state.layerId = static_cast<int32_t>(1);
     mLifecycleManager.applyTransactions(transactions);
-    EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::GameMode);
+    EXPECT_EQ(mLifecycleManager.getGlobalChanges(),
+              RequestedLayerState::Changes::GameMode | RequestedLayerState::Changes::Metadata);
     UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
     EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eMetadataChanged);
     EXPECT_EQ(static_cast<int32_t>(getSnapshot(1)->gameMode), 42);
     EXPECT_EQ(static_cast<int32_t>(getSnapshot(11)->gameMode), 42);
 }
 
+TEST_F(LayerSnapshotTest, UpdateMetadata) {
+    std::vector<TransactionState> transactions;
+    transactions.emplace_back();
+    transactions.back().states.push_back({});
+    transactions.back().states.front().state.what = layer_state_t::eMetadataChanged;
+    // This test focuses on metadata used by ARC++ to ensure LayerMetadata is updated correctly,
+    // and not using stale data.
+    transactions.back().states.front().state.metadata = LayerMetadata();
+    transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_UID, 123);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_WINDOW_TYPE, 234);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_TASK_ID, 345);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_MOUSE_CURSOR, 456);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_ACCESSIBILITY_ID, 567);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_PID, 678);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_CALLING_UID, 789);
+
+    transactions.back().states.front().layerId = 1;
+    transactions.back().states.front().state.layerId = static_cast<int32_t>(1);
+
+    mLifecycleManager.applyTransactions(transactions);
+    EXPECT_EQ(mLifecycleManager.getGlobalChanges(), RequestedLayerState::Changes::Metadata);
+
+    // Setting includeMetadata=true to ensure metadata update is applied to LayerSnapshot
+    LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(),
+                                    .layerLifecycleManager = mLifecycleManager,
+                                    .includeMetadata = true,
+                                    .displays = mFrontEndDisplayInfos,
+                                    .globalShadowSettings = globalShadowSettings,
+                                    .supportsBlur = true,
+                                    .supportedLayerGenericMetadata = {},
+                                    .genericLayerMetadataKeyMap = {}};
+    update(mSnapshotBuilder, args);
+
+    EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eMetadataChanged);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_UID, -1), 123);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_WINDOW_TYPE, -1), 234);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_TASK_ID, -1), 345);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_MOUSE_CURSOR, -1), 456);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_ACCESSIBILITY_ID, -1), 567);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_PID, -1), 678);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_CALLING_UID, -1), 789);
+}
+
+TEST_F(LayerSnapshotTest, UpdateMetadataOfHiddenLayers) {
+    hideLayer(1);
+
+    std::vector<TransactionState> transactions;
+    transactions.emplace_back();
+    transactions.back().states.push_back({});
+    transactions.back().states.front().state.what = layer_state_t::eMetadataChanged;
+    // This test focuses on metadata used by ARC++ to ensure LayerMetadata is updated correctly,
+    // and not using stale data.
+    transactions.back().states.front().state.metadata = LayerMetadata();
+    transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_UID, 123);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_WINDOW_TYPE, 234);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_TASK_ID, 345);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_MOUSE_CURSOR, 456);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_ACCESSIBILITY_ID, 567);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_OWNER_PID, 678);
+    transactions.back().states.front().state.metadata.setInt32(METADATA_CALLING_UID, 789);
+
+    transactions.back().states.front().layerId = 1;
+    transactions.back().states.front().state.layerId = static_cast<int32_t>(1);
+
+    mLifecycleManager.applyTransactions(transactions);
+    EXPECT_EQ(mLifecycleManager.getGlobalChanges(),
+              RequestedLayerState::Changes::Metadata | RequestedLayerState::Changes::Visibility |
+                      RequestedLayerState::Changes::VisibleRegion |
+                      RequestedLayerState::Changes::AffectsChildren);
+
+    // Setting includeMetadata=true to ensure metadata update is applied to LayerSnapshot
+    LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(),
+                                    .layerLifecycleManager = mLifecycleManager,
+                                    .includeMetadata = true,
+                                    .displays = mFrontEndDisplayInfos,
+                                    .globalShadowSettings = globalShadowSettings,
+                                    .supportsBlur = true,
+                                    .supportedLayerGenericMetadata = {},
+                                    .genericLayerMetadataKeyMap = {}};
+    update(mSnapshotBuilder, args);
+
+    EXPECT_EQ(static_cast<int64_t>(getSnapshot(1)->clientChanges),
+              layer_state_t::eMetadataChanged | layer_state_t::eFlagsChanged);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_UID, -1), 123);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_WINDOW_TYPE, -1), 234);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_TASK_ID, -1), 345);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_MOUSE_CURSOR, -1), 456);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_ACCESSIBILITY_ID, -1), 567);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_OWNER_PID, -1), 678);
+    EXPECT_EQ(getSnapshot(1)->layerMetadata.getInt32(METADATA_CALLING_UID, -1), 789);
+}
+
 TEST_F(LayerSnapshotTest, NoLayerVoteForParentWithChildVotes) {
     // ROOT
     // ├── 1
@@ -1172,6 +1265,16 @@
             gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
 }
 
+TEST_F(LayerSnapshotTest, alphaChangesPropagateToInput) {
+    Region touch{Rect{0, 0, 1000, 1000}};
+    setTouchableRegion(1, touch);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+
+    setAlpha(1, 0.5f);
+    UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+    EXPECT_EQ(getSnapshot(1)->inputInfo.alpha, 0.5f);
+}
+
 TEST_F(LayerSnapshotTest, isFrontBuffered) {
     setBuffer(1,
               std::make_shared<renderengine::mock::FakeExternalTexture>(
@@ -1294,6 +1397,17 @@
     EXPECT_TRUE(foundInputLayer);
 }
 
+TEST_F(LayerSnapshotTest, ForEachSnapshotsWithPredicate) {
+    std::vector<uint32_t> visitedUniqueSequences;
+    mSnapshotBuilder.forEachSnapshot(
+            [&](const std::unique_ptr<frontend::LayerSnapshot>& snapshot) {
+                visitedUniqueSequences.push_back(snapshot->uniqueSequence);
+            },
+            [](const frontend::LayerSnapshot& snapshot) { return snapshot.uniqueSequence == 111; });
+    EXPECT_EQ(visitedUniqueSequences.size(), 1u);
+    EXPECT_EQ(visitedUniqueSequences[0], 111u);
+}
+
 TEST_F(LayerSnapshotTest, canOccludePresentation) {
     setFlags(12, layer_state_t::eCanOccludePresentation, layer_state_t::eCanOccludePresentation);
     LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(),
diff --git a/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp b/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp
index e74f643..c879280 100644
--- a/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp
@@ -706,7 +706,7 @@
     testGpuScenario(config, res);
     EXPECT_EQ(res.gpuDurationNanos, 0L);
     EXPECT_EQ(res.cpuDurationNanos, 0L);
-    EXPECT_GE(res.durationNanos, toNanos(30ms + getErrorMargin()));
+    EXPECT_GE(res.durationNanos, toNanos(29ms + getErrorMargin()));
     EXPECT_LE(res.durationNanos, toNanos(31ms + getErrorMargin()));
 }
 
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
index cf9a7d3..06c4e30 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
@@ -1562,7 +1562,7 @@
             // When frame rates get an equal score, the lower is chosen, unless there are Max votes.
             {0_Hz, FrameRateCategory::High, 90_Hz},
             {0_Hz, FrameRateCategory::Normal, 60_Hz},
-            {0_Hz, FrameRateCategory::Low, 30_Hz},
+            {0_Hz, FrameRateCategory::Low, 60_Hz},
             {0_Hz, FrameRateCategory::NoPreference, 60_Hz},
 
             // Cases that have both desired frame rate and frame rate category requirements.
@@ -1609,6 +1609,77 @@
     }
 }
 
+TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_120_vrr) {
+    if (GetParam() != Config::FrameRateOverride::Enabled) {
+        return;
+    }
+
+    SET_FLAG_FOR_TEST(flags::vrr_config, true);
+    // Device with VRR config mode
+    auto selector = createSelector(kVrrMode_120, kModeId120);
+
+    struct Case {
+        // Params
+        Fps desiredFrameRate = 0_Hz;
+        FrameRateCategory frameRateCategory = FrameRateCategory::Default;
+
+        // Expected result
+        Fps expectedFrameRate = 0_Hz;
+    };
+
+    // Prepare a table with the vote and the expected refresh rate
+    const std::initializer_list<Case> testCases = {
+            // Cases that only have frame rate category requirements, but no desired frame rate.
+            // When frame rates get an equal score, the lower is chosen, unless there are Max votes.
+            {0_Hz, FrameRateCategory::High, 120_Hz},
+            {0_Hz, FrameRateCategory::Normal, 60_Hz},
+            {0_Hz, FrameRateCategory::Low, 48_Hz},
+            {0_Hz, FrameRateCategory::NoPreference, 120_Hz},
+
+            // Cases that have both desired frame rate and frame rate category requirements.
+            {24_Hz, FrameRateCategory::High, 120_Hz},
+            {30_Hz, FrameRateCategory::High, 120_Hz},
+            {12_Hz, FrameRateCategory::Normal, 60_Hz},
+            {24_Hz, FrameRateCategory::Low, 48_Hz},
+            {30_Hz, FrameRateCategory::NoPreference, 30_Hz},
+
+            // Cases that only have desired frame rate.
+            {30_Hz, FrameRateCategory::Default, 30_Hz},
+    };
+
+    for (auto testCase : testCases) {
+        std::vector<LayerRequirement> layers;
+        ALOGI("**** %s: Testing desiredFrameRate=%s, frameRateCategory=%s", __func__,
+              to_string(testCase.desiredFrameRate).c_str(),
+              ftl::enum_string(testCase.frameRateCategory).c_str());
+
+        if (testCase.desiredFrameRate.isValid()) {
+            std::stringstream ss;
+            ss << to_string(testCase.desiredFrameRate) << "ExplicitDefault";
+            LayerRequirement layer = {.name = ss.str(),
+                                      .vote = LayerVoteType::ExplicitDefault,
+                                      .desiredRefreshRate = testCase.desiredFrameRate,
+                                      .weight = 1.f};
+            layers.push_back(layer);
+        }
+
+        if (testCase.frameRateCategory != FrameRateCategory::Default) {
+            std::stringstream ss;
+            ss << "ExplicitCategory (" << ftl::enum_string(testCase.frameRateCategory) << ")";
+            LayerRequirement layer = {.name = ss.str(),
+                                      .vote = LayerVoteType::ExplicitCategory,
+                                      .frameRateCategory = testCase.frameRateCategory,
+                                      .weight = 1.f};
+            layers.push_back(layer);
+        }
+
+        EXPECT_EQ(testCase.expectedFrameRate, selector.getBestFrameRateMode(layers).fps)
+                << "Did not get expected frame rate for frameRate="
+                << to_string(testCase.desiredFrameRate)
+                << " category=" << ftl::enum_string(testCase.frameRateCategory);
+    }
+}
+
 TEST_P(RefreshRateSelectorTest,
        getBestFrameRateMode_withFrameRateCategoryMultiLayers_30_60_90_120) {
     auto selector = createSelector(makeModes(kMode30, kMode60, kMode90, kMode120), kModeId60);
@@ -2140,14 +2211,14 @@
             // These layers may switch modes because smoothSwitchOnly=false.
             {FrameRateCategory::Default, false, 120_Hz, kModeId120},
             {FrameRateCategory::NoPreference, false, 120_Hz, kModeId120},
-            {FrameRateCategory::Low, false, 30_Hz, kModeId60},
+            {FrameRateCategory::Low, false, 60_Hz, kModeId60},
             {FrameRateCategory::Normal, false, 60_Hz, kModeId60},
             {FrameRateCategory::High, false, 120_Hz, kModeId120},
 
             // These layers cannot change mode due to smoothSwitchOnly, and will definitely use
             // active mode (120Hz).
             {FrameRateCategory::NoPreference, true, 120_Hz, kModeId120},
-            {FrameRateCategory::Low, true, 40_Hz, kModeId120},
+            {FrameRateCategory::Low, true, 120_Hz, kModeId120},
             {FrameRateCategory::Normal, true, 120_Hz, kModeId120},
             {FrameRateCategory::High, true, 120_Hz, kModeId120},
     };
@@ -2207,13 +2278,13 @@
             {FrameRateCategory::Default, false, 120_Hz},
             // TODO(b/266481656): Once this bug is fixed, NoPreference should be a lower frame rate.
             {FrameRateCategory::NoPreference, false, 120_Hz},
-            {FrameRateCategory::Low, false, 30_Hz},
+            {FrameRateCategory::Low, false, 48_Hz},
             {FrameRateCategory::Normal, false, 60_Hz},
             {FrameRateCategory::High, false, 120_Hz},
             {FrameRateCategory::Default, true, 120_Hz},
             // TODO(b/266481656): Once this bug is fixed, NoPreference should be a lower frame rate.
             {FrameRateCategory::NoPreference, true, 120_Hz},
-            {FrameRateCategory::Low, true, 30_Hz},
+            {FrameRateCategory::Low, true, 48_Hz},
             {FrameRateCategory::Normal, true, 60_Hz},
             {FrameRateCategory::High, true, 120_Hz},
     };
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 4fb0690..3df724a 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -34,6 +34,7 @@
 #include "mock/MockSchedulerCallback.h"
 
 #include <FrontEnd/LayerHierarchy.h>
+#include <scheduler/FrameTime.h>
 
 #include <com_android_graphics_surfaceflinger_flags.h>
 #include "FpsOps.h"
@@ -343,12 +344,15 @@
 }
 
 TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
+    constexpr PhysicalDisplayId kActiveDisplayId = kDisplayId1;
     mScheduler->registerDisplay(kDisplayId1,
                                 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
-                                                                      kDisplay1Mode60->getId()));
+                                                                      kDisplay1Mode60->getId()),
+                                kActiveDisplayId);
     mScheduler->registerDisplay(kDisplayId2,
                                 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
-                                                                      kDisplay2Mode60->getId()));
+                                                                      kDisplay2Mode60->getId()),
+                                kActiveDisplayId);
 
     mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
     mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON);
@@ -411,10 +415,10 @@
     {
         // The kDisplayId3 does not support 120Hz, The pacesetter display rate is chosen to be 120
         // Hz. In this case only the display kDisplayId3 choose 60Hz as it does not support 120Hz.
-        mScheduler
-                ->registerDisplay(kDisplayId3,
-                                  std::make_shared<RefreshRateSelector>(kDisplay3Modes,
-                                                                        kDisplay3Mode60->getId()));
+        mScheduler->registerDisplay(kDisplayId3,
+                                    std::make_shared<RefreshRateSelector>(kDisplay3Modes,
+                                                                          kDisplay3Mode60->getId()),
+                                    kActiveDisplayId);
         mScheduler->setDisplayPowerMode(kDisplayId3, hal::PowerMode::ON);
 
         const GlobalSignals globalSignals = {.touch = true};
@@ -457,12 +461,15 @@
 }
 
 TEST_F(SchedulerTest, onFrameSignalMultipleDisplays) {
+    constexpr PhysicalDisplayId kActiveDisplayId = kDisplayId1;
     mScheduler->registerDisplay(kDisplayId1,
                                 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
-                                                                      kDisplay1Mode60->getId()));
+                                                                      kDisplay1Mode60->getId()),
+                                kActiveDisplayId);
     mScheduler->registerDisplay(kDisplayId2,
                                 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
-                                                                      kDisplay2Mode60->getId()));
+                                                                      kDisplay2Mode60->getId()),
+                                kActiveDisplayId);
 
     using VsyncIds = std::vector<std::pair<PhysicalDisplayId, VsyncId>>;
 
@@ -585,7 +592,8 @@
                                 mFlinger.getTimeStats(),
                                 mSchedulerCallback};
 
-    scheduler.registerDisplay(kMode->getPhysicalDisplayId(), vrrSelectorPtr, vrrTracker);
+    scheduler.registerDisplay(kMode->getPhysicalDisplayId(), vrrSelectorPtr, std::nullopt,
+                              vrrTracker);
     vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
     scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate, /*applyImmediately*/ false);
     vrrTracker->addVsyncTimestamp(0);
@@ -600,7 +608,8 @@
                                              TimePoint::fromNs(2000)));
 
     // Not crossing the min frame period
-    vrrTracker->onFrameBegin(TimePoint::fromNs(2000), TimePoint::fromNs(1500));
+    vrrTracker->onFrameBegin(TimePoint::fromNs(2000),
+                             {TimePoint::fromNs(1500), TimePoint::fromNs(1500)});
     EXPECT_EQ(Fps::fromPeriodNsecs(1000),
               scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
                                              TimePoint::fromNs(2500)));
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_ColorMatrixTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_ColorMatrixTest.cpp
index ff7612e..d638024 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_ColorMatrixTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_ColorMatrixTest.cpp
@@ -28,7 +28,6 @@
 class ColorMatrixTest : public CommitAndCompositeTest {};
 
 TEST_F(ColorMatrixTest, colorMatrixChanged) {
-    mFlinger.enableLayerLifecycleManager();
     EXPECT_COLOR_MATRIX_CHANGED(true, true);
     mFlinger.mutableTransactionFlags() |= eTransactionNeeded;
 
@@ -46,7 +45,6 @@
 }
 
 TEST_F(ColorMatrixTest, colorMatrixChangedAfterDisplayTransaction) {
-    mFlinger.enableLayerLifecycleManager();
     EXPECT_COLOR_MATRIX_CHANGED(true, true);
     mFlinger.mutableTransactionFlags() |= eTransactionNeeded;
 
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
index 0c3e875..4b0a7c3 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
@@ -42,6 +42,47 @@
 using android::hardware::graphics::composer::V2_4::Error;
 using android::hardware::graphics::composer::V2_4::VsyncPeriodChangeTimeline;
 
+MATCHER_P2(ModeSettledTo, dmc, modeId, "") {
+    const auto displayId = arg->getPhysicalId();
+
+    if (const auto desiredOpt = dmc->getDesiredMode(displayId)) {
+        *result_listener << "Unsettled desired mode "
+                         << ftl::to_underlying(desiredOpt->mode.modePtr->getId());
+        return false;
+    }
+
+    if (dmc->getActiveMode(displayId).modePtr->getId() != modeId) {
+        *result_listener << "Settled to unexpected active mode " << ftl::to_underlying(modeId);
+        return false;
+    }
+
+    return true;
+}
+
+MATCHER_P2(ModeSwitchingTo, flinger, modeId, "") {
+    const auto displayId = arg->getPhysicalId();
+    auto& dmc = flinger->mutableDisplayModeController();
+
+    if (!dmc.getDesiredMode(displayId)) {
+        *result_listener << "No desired mode";
+        return false;
+    }
+
+    if (dmc.getDesiredMode(displayId)->mode.modePtr->getId() != modeId) {
+        *result_listener << "Unexpected desired mode " << ftl::to_underlying(modeId);
+        return false;
+    }
+
+    // VsyncModulator should react to mode switches on the pacesetter display.
+    if (displayId == flinger->scheduler()->pacesetterDisplayId() &&
+        !flinger->scheduler()->vsyncModulator().isVsyncConfigEarly()) {
+        *result_listener << "VsyncModulator did not shift to early phase";
+        return false;
+    }
+
+    return true;
+}
+
 class DisplayModeSwitchingTest : public DisplayTransactionTest {
 public:
     void SetUp() override {
@@ -58,8 +99,7 @@
 
         setupScheduler(selectorPtr);
 
-        mFlinger.onComposerHalHotplugEvent(PrimaryDisplayVariant::HWC_DISPLAY_ID,
-                                           DisplayHotplugEvent::CONNECTED);
+        mFlinger.onComposerHalHotplugEvent(kInnerDisplayHwcId, DisplayHotplugEvent::CONNECTED);
         mFlinger.configureAndCommit();
 
         auto vsyncController = std::make_unique<mock::VsyncController>();
@@ -87,8 +127,13 @@
     static constexpr HWDisplayId kInnerDisplayHwcId = PrimaryDisplayVariant::HWC_DISPLAY_ID;
     static constexpr HWDisplayId kOuterDisplayHwcId = kInnerDisplayHwcId + 1;
 
+    static constexpr PhysicalDisplayId kOuterDisplayId = PhysicalDisplayId::fromPort(254u);
+
     auto injectOuterDisplay() {
-        constexpr PhysicalDisplayId kOuterDisplayId = PhysicalDisplayId::fromPort(254u);
+        // For the inner display, this is handled by setupHwcHotplugCallExpectations.
+        EXPECT_CALL(*mComposer, getDisplayConnectionType(kOuterDisplayHwcId, _))
+                .WillOnce(DoAll(SetArgPointee<1>(IComposerClient::DisplayConnectionType::INTERNAL),
+                                Return(hal::V2_4::Error::NONE)));
 
         constexpr bool kIsPrimary = false;
         TestableSurfaceFlinger::FakeHwcDisplayInjector(kOuterDisplayId, hal::DisplayType::PHYSICAL,
@@ -169,129 +214,139 @@
                             TestableSurfaceFlinger::SchedulerCallbackImpl::kNoOp);
 }
 
-TEST_F(DisplayModeSwitchingTest, changeRefreshRateOnActiveDisplayWithRefreshRequired) {
-    ftl::FakeGuard guard(kMainThreadContext);
+TEST_F(DisplayModeSwitchingTest, changeRefreshRateWithRefreshRequired) {
+    EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId60));
 
-    EXPECT_FALSE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getActiveMode(mDisplayId).modePtr->getId(), kModeId60);
+    EXPECT_EQ(NO_ERROR,
+              mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
+                                                  mock::createDisplayModeSpecs(kModeId90, 120_Hz)));
 
-    mFlinger.onActiveDisplayChanged(nullptr, *mDisplay);
-
-    mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                        mock::createDisplayModeSpecs(kModeId90, false, 0, 120));
-
-    ASSERT_TRUE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getDesiredMode(mDisplayId)->mode.modePtr->getId(), kModeId90);
-    EXPECT_EQ(dmc().getActiveMode(mDisplayId).modePtr->getId(), kModeId60);
+    EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
 
     // Verify that next commit will call setActiveConfigWithConstraints in HWC
     const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
-    EXPECT_SET_ACTIVE_CONFIG(PrimaryDisplayVariant::HWC_DISPLAY_ID, kModeId90);
+    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90);
 
     mFlinger.commit();
-
     Mock::VerifyAndClearExpectations(mComposer);
 
-    EXPECT_TRUE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getActiveMode(mDisplayId).modePtr->getId(), kModeId60);
+    EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
 
     // Verify that the next commit will complete the mode change and send
     // a onModeChanged event to the framework.
 
     EXPECT_CALL(*mAppEventThread,
                 onModeChanged(scheduler::FrameRateMode{90_Hz, ftl::as_non_null(kMode90)}));
+
     mFlinger.commit();
     Mock::VerifyAndClearExpectations(mAppEventThread);
 
-    EXPECT_FALSE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getActiveMode(mDisplayId).modePtr->getId(), kModeId90);
+    EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId90));
 }
 
-TEST_F(DisplayModeSwitchingTest, changeRefreshRateOnActiveDisplayWithoutRefreshRequired) {
-    ftl::FakeGuard guard(kMainThreadContext);
+TEST_F(DisplayModeSwitchingTest, changeRefreshRateWithoutRefreshRequired) {
+    EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId60));
 
-    EXPECT_FALSE(dmc().getDesiredMode(mDisplayId));
+    constexpr bool kAllowGroupSwitching = true;
+    EXPECT_EQ(NO_ERROR,
+              mFlinger.setDesiredDisplayModeSpecs(
+                      mDisplay->getDisplayToken().promote(),
+                      mock::createDisplayModeSpecs(kModeId90, 120_Hz, kAllowGroupSwitching)));
 
-    mFlinger.onActiveDisplayChanged(nullptr, *mDisplay);
-
-    mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                        mock::createDisplayModeSpecs(kModeId90, true, 0, 120));
-
-    ASSERT_TRUE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getDesiredMode(mDisplayId)->mode.modePtr->getId(), kModeId90);
-    EXPECT_EQ(dmc().getActiveMode(mDisplayId).modePtr->getId(), kModeId60);
+    EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
 
     // Verify that next commit will call setActiveConfigWithConstraints in HWC
     // and complete the mode change.
     const VsyncPeriodChangeTimeline timeline{.refreshRequired = false};
-    EXPECT_SET_ACTIVE_CONFIG(PrimaryDisplayVariant::HWC_DISPLAY_ID, kModeId90);
+    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90);
 
     EXPECT_CALL(*mAppEventThread,
                 onModeChanged(scheduler::FrameRateMode{90_Hz, ftl::as_non_null(kMode90)}));
 
     mFlinger.commit();
 
-    EXPECT_FALSE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getActiveMode(mDisplayId).modePtr->getId(), kModeId90);
+    EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId90));
 }
 
-TEST_F(DisplayModeSwitchingTest, twoConsecutiveSetDesiredDisplayModeSpecs) {
-    ftl::FakeGuard guard(kMainThreadContext);
+TEST_F(DisplayModeSwitchingTest, changeRefreshRateOnTwoDisplaysWithoutRefreshRequired) {
+    const auto [innerDisplay, outerDisplay] = injectOuterDisplay();
 
-    // Test that if we call setDesiredDisplayModeSpecs while a previous mode change
-    // is still being processed the later call will be respected.
+    EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId60));
+    EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId120));
 
-    EXPECT_FALSE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getActiveMode(mDisplayId).modePtr->getId(), kModeId60);
+    EXPECT_EQ(NO_ERROR,
+              mFlinger.setDesiredDisplayModeSpecs(innerDisplay->getDisplayToken().promote(),
+                                                  mock::createDisplayModeSpecs(kModeId90, 120_Hz,
+                                                                               true)));
+    EXPECT_EQ(NO_ERROR,
+              mFlinger.setDesiredDisplayModeSpecs(outerDisplay->getDisplayToken().promote(),
+                                                  mock::createDisplayModeSpecs(kModeId60, 60_Hz,
+                                                                               true)));
 
-    mFlinger.onActiveDisplayChanged(nullptr, *mDisplay);
-
-    mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                        mock::createDisplayModeSpecs(kModeId90, false, 0, 120));
-
-    const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
-    EXPECT_SET_ACTIVE_CONFIG(PrimaryDisplayVariant::HWC_DISPLAY_ID, kModeId90);
-
-    mFlinger.commit();
-
-    mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                        mock::createDisplayModeSpecs(kModeId120, false, 0, 180));
-
-    ASSERT_TRUE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getDesiredMode(mDisplayId)->mode.modePtr->getId(), kModeId120);
-
-    EXPECT_SET_ACTIVE_CONFIG(PrimaryDisplayVariant::HWC_DISPLAY_ID, kModeId120);
-
-    mFlinger.commit();
-
-    ASSERT_TRUE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getDesiredMode(mDisplayId)->mode.modePtr->getId(), kModeId120);
-
-    mFlinger.commit();
-
-    EXPECT_FALSE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getActiveMode(mDisplayId).modePtr->getId(), kModeId120);
-}
-
-TEST_F(DisplayModeSwitchingTest, changeResolutionOnActiveDisplayWithoutRefreshRequired) {
-    ftl::FakeGuard guard(kMainThreadContext);
-
-    EXPECT_FALSE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getActiveMode(mDisplayId).modePtr->getId(), kModeId60);
-
-    mFlinger.onActiveDisplayChanged(nullptr, *mDisplay);
-
-    mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                        mock::createDisplayModeSpecs(kModeId90_4K, false, 0, 120));
-
-    ASSERT_TRUE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getDesiredMode(mDisplayId)->mode.modePtr->getId(), kModeId90_4K);
-    EXPECT_EQ(dmc().getActiveMode(mDisplayId).modePtr->getId(), kModeId60);
+    EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
+    EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
 
     // Verify that next commit will call setActiveConfigWithConstraints in HWC
     // and complete the mode change.
     const VsyncPeriodChangeTimeline timeline{.refreshRequired = false};
-    EXPECT_SET_ACTIVE_CONFIG(PrimaryDisplayVariant::HWC_DISPLAY_ID, kModeId90_4K);
+    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90);
+    EXPECT_SET_ACTIVE_CONFIG(kOuterDisplayHwcId, kModeId60);
+
+    EXPECT_CALL(*mAppEventThread, onModeChanged(_)).Times(2);
+
+    mFlinger.commit();
+
+    EXPECT_THAT(innerDisplay, ModeSettledTo(&dmc(), kModeId90));
+    EXPECT_THAT(outerDisplay, ModeSettledTo(&dmc(), kModeId60));
+}
+
+TEST_F(DisplayModeSwitchingTest, twoConsecutiveSetDesiredDisplayModeSpecs) {
+    // Test that if we call setDesiredDisplayModeSpecs while a previous mode change
+    // is still being processed the later call will be respected.
+
+    EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId60));
+
+    EXPECT_EQ(NO_ERROR,
+              mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
+                                                  mock::createDisplayModeSpecs(kModeId90, 120_Hz)));
+
+    const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
+    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90);
+
+    mFlinger.commit();
+
+    EXPECT_EQ(NO_ERROR,
+              mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
+                                                  mock::createDisplayModeSpecs(kModeId120,
+                                                                               180_Hz)));
+
+    EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId120));
+
+    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId120);
+
+    mFlinger.commit();
+
+    EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId120));
+
+    mFlinger.commit();
+
+    EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId120));
+}
+
+TEST_F(DisplayModeSwitchingTest, changeResolutionWithoutRefreshRequired) {
+    EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId60));
+
+    EXPECT_EQ(NO_ERROR,
+              mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
+                                                  mock::createDisplayModeSpecs(kModeId90_4K,
+                                                                               120_Hz)));
+
+    EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId90_4K));
+
+    // Verify that next commit will call setActiveConfigWithConstraints in HWC
+    // and complete the mode change.
+    const VsyncPeriodChangeTimeline timeline{.refreshRequired = false};
+    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90_4K);
 
     EXPECT_CALL(*mAppEventThread, onHotplugReceived(mDisplayId, true));
 
@@ -310,61 +365,12 @@
 
     mFlinger.commit();
 
-    EXPECT_FALSE(dmc().getDesiredMode(mDisplayId));
-    EXPECT_EQ(dmc().getActiveMode(mDisplayId).modePtr->getId(), kModeId90_4K);
-}
-
-MATCHER_P2(ModeSwitchingTo, flinger, modeId, "") {
-    const auto displayId = arg->getPhysicalId();
-    auto& dmc = flinger->mutableDisplayModeController();
-
-    if (!dmc.getDesiredMode(displayId)) {
-        *result_listener << "No desired mode";
-        return false;
-    }
-
-    if (dmc.getDesiredMode(displayId)->mode.modePtr->getId() != modeId) {
-        *result_listener << "Unexpected desired mode " << ftl::to_underlying(modeId);
-        return false;
-    }
-
-    // VsyncModulator should react to mode switches on the pacesetter display.
-    if (displayId == flinger->scheduler()->pacesetterDisplayId() &&
-        !flinger->scheduler()->vsyncModulator().isVsyncConfigEarly()) {
-        *result_listener << "VsyncModulator did not shift to early phase";
-        return false;
-    }
-
-    return true;
-}
-
-MATCHER_P2(ModeSettledTo, dmc, modeId, "") {
-    const auto displayId = arg->getPhysicalId();
-
-    if (const auto desiredOpt = dmc->getDesiredMode(displayId)) {
-        *result_listener << "Unsettled desired mode "
-                         << ftl::to_underlying(desiredOpt->mode.modePtr->getId());
-        return false;
-    }
-
-    ftl::FakeGuard guard(kMainThreadContext);
-
-    if (dmc->getActiveMode(displayId).modePtr->getId() != modeId) {
-        *result_listener << "Settled to unexpected active mode " << ftl::to_underlying(modeId);
-        return false;
-    }
-
-    return true;
+    EXPECT_THAT(mDisplay, ModeSettledTo(&dmc(), kModeId90_4K));
 }
 
 TEST_F(DisplayModeSwitchingTest, innerXorOuterDisplay) {
     SET_FLAG_FOR_TEST(flags::connected_display, true);
 
-    // For the inner display, this is handled by setupHwcHotplugCallExpectations.
-    EXPECT_CALL(*mComposer, getDisplayConnectionType(kOuterDisplayHwcId, _))
-            .WillOnce(DoAll(SetArgPointee<1>(IComposerClient::DisplayConnectionType::INTERNAL),
-                            Return(hal::V2_4::Error::NONE)));
-
     const auto [innerDisplay, outerDisplay] = injectOuterDisplay();
 
     EXPECT_TRUE(innerDisplay->isPoweredOn());
@@ -381,13 +387,11 @@
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(innerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId90, false,
-                                                                               0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId90, 120_Hz)));
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(outerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId60, false,
-                                                                               0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId60, 120_Hz)));
 
     EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
     EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
@@ -414,8 +418,7 @@
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(innerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId60, false,
-                                                                               0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId60, 120_Hz)));
 
     EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
     EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId60);
@@ -434,10 +437,6 @@
 TEST_F(DisplayModeSwitchingTest, innerAndOuterDisplay) {
     SET_FLAG_FOR_TEST(flags::connected_display, true);
 
-    // For the inner display, this is handled by setupHwcHotplugCallExpectations.
-    EXPECT_CALL(*mComposer, getDisplayConnectionType(kOuterDisplayHwcId, _))
-            .WillOnce(DoAll(SetArgPointee<1>(IComposerClient::DisplayConnectionType::INTERNAL),
-                            Return(hal::V2_4::Error::NONE)));
     const auto [innerDisplay, outerDisplay] = injectOuterDisplay();
 
     EXPECT_TRUE(innerDisplay->isPoweredOn());
@@ -454,13 +453,11 @@
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(innerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId90, false,
-                                                                               0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId90, 120_Hz)));
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(outerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId60, false,
-                                                                               0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId60, 120_Hz)));
 
     EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
     EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
@@ -486,8 +483,7 @@
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId90, false,
-                                                                               0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId90, 120_Hz)));
 
     EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
 
@@ -511,11 +507,6 @@
 TEST_F(DisplayModeSwitchingTest, powerOffDuringConcurrentModeSet) {
     SET_FLAG_FOR_TEST(flags::connected_display, true);
 
-    // For the inner display, this is handled by setupHwcHotplugCallExpectations.
-    EXPECT_CALL(*mComposer, getDisplayConnectionType(kOuterDisplayHwcId, _))
-            .WillOnce(DoAll(SetArgPointee<1>(IComposerClient::DisplayConnectionType::INTERNAL),
-                            Return(hal::V2_4::Error::NONE)));
-
     const auto [innerDisplay, outerDisplay] = injectOuterDisplay();
 
     EXPECT_TRUE(innerDisplay->isPoweredOn());
@@ -532,13 +523,11 @@
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(innerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId90, false,
-                                                                               0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId90, 120_Hz)));
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(outerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId60, false,
-                                                                               0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId60, 120_Hz)));
 
     EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
     EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
@@ -566,8 +555,8 @@
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(outerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId120, false,
-                                                                               0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId120,
+                                                                               120_Hz)));
 
     EXPECT_SET_ACTIVE_CONFIG(kOuterDisplayHwcId, kModeId120);
 
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
index b620830..9bf344c 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
@@ -265,6 +265,13 @@
     processesHotplugConnectCommon<SimpleExternalDisplayCase>();
 }
 
+TEST_F(DisplayTransactionCommitTest, processesHotplugConnectNonSecureExternalDisplay) {
+    // Inject a primary display.
+    PrimaryDisplayVariant::injectHwcDisplay(this);
+
+    processesHotplugConnectCommon<SimpleExternalDisplayNonSecureCase>();
+}
+
 TEST_F(DisplayTransactionCommitTest, ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected) {
     // Inject both a primary and external display.
     PrimaryDisplayVariant::injectHwcDisplay(this);
@@ -273,13 +280,29 @@
     // TODO: This is an unnecessary call.
     EXPECT_CALL(*mComposer,
                 getDisplayIdentificationData(TertiaryDisplayVariant::HWC_DISPLAY_ID, _, _))
-            .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay::PORT),
-                            SetArgPointee<2>(TertiaryDisplay::GET_IDENTIFICATION_DATA()),
+            .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay<kSecure>::PORT),
+                            SetArgPointee<2>(TertiaryDisplay<kSecure>::GET_IDENTIFICATION_DATA()),
                             Return(Error::NONE)));
 
     ignoresHotplugConnectCommon<SimpleTertiaryDisplayCase>();
 }
 
+TEST_F(DisplayTransactionCommitTest,
+       ignoresHotplugConnectNonSecureIfPrimaryAndExternalAlreadyConnected) {
+    // Inject both a primary and external display.
+    PrimaryDisplayVariant::injectHwcDisplay(this);
+    ExternalDisplayVariant::injectHwcDisplay(this);
+
+    // TODO: This is an unnecessary call.
+    EXPECT_CALL(*mComposer,
+                getDisplayIdentificationData(TertiaryDisplayVariant::HWC_DISPLAY_ID, _, _))
+            .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay<kSecure>::PORT),
+                            SetArgPointee<2>(TertiaryDisplay<kSecure>::GET_IDENTIFICATION_DATA()),
+                            Return(Error::NONE)));
+
+    ignoresHotplugConnectCommon<SimpleTertiaryDisplayNonSecureCase>();
+}
+
 TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectPrimaryDisplay) {
     EXPECT_EXIT(processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>(),
                 testing::KilledBySignal(SIGABRT), "Primary display cannot be disconnected.");
@@ -289,6 +312,10 @@
     processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
 }
 
+TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectNonSecureExternalDisplay) {
+    processesHotplugDisconnectCommon<SimpleExternalDisplayNonSecureCase>();
+}
+
 TEST_F(DisplayTransactionCommitTest, processesHotplugConnectThenDisconnectPrimary) {
     EXPECT_EXIT(
             [this] {
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index 198a5de..f063809 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -53,7 +53,7 @@
                       factory, selectorPtr->getActiveMode().fps, timeStats) {
         const auto displayId = selectorPtr->getActiveMode().modePtr->getPhysicalDisplayId();
         registerDisplay(displayId, std::move(selectorPtr), std::move(controller),
-                        std::move(tracker));
+                        std::move(tracker), displayId);
 
         ON_CALL(*this, postMessage).WillByDefault([](sp<MessageHandler>&& handler) {
             // Execute task to prevent broken promise exception on destruction.
@@ -85,14 +85,16 @@
 
     void registerDisplay(
             PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
+            std::optional<PhysicalDisplayId> activeDisplayIdOpt = {},
             std::shared_ptr<VSyncTracker> vsyncTracker = std::make_shared<mock::VSyncTracker>()) {
         registerDisplay(displayId, std::move(selectorPtr),
-                        std::make_unique<mock::VsyncController>(), vsyncTracker);
+                        std::make_unique<mock::VsyncController>(), vsyncTracker,
+                        activeDisplayIdOpt.value_or(displayId));
     }
 
     void registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
                          std::unique_ptr<VsyncController> controller,
-                         std::shared_ptr<VSyncTracker> tracker) {
+                         std::shared_ptr<VSyncTracker> tracker, PhysicalDisplayId activeDisplayId) {
         ftl::FakeGuard guard(kMainThreadContext);
         Scheduler::registerDisplayInternal(displayId, std::move(selectorPtr),
                                            std::shared_ptr<VsyncSchedule>(
@@ -101,16 +103,12 @@
                                                                              mock::VSyncDispatch>(),
                                                                      std::move(controller),
                                                                      mockRequestHardwareVsync
-                                                                             .AsStdFunction())));
+                                                                             .AsStdFunction())),
+                                           activeDisplayId);
     }
 
     testing::MockFunction<void(PhysicalDisplayId, bool)> mockRequestHardwareVsync;
 
-    void unregisterDisplay(PhysicalDisplayId displayId) {
-        ftl::FakeGuard guard(kMainThreadContext);
-        Scheduler::unregisterDisplay(displayId);
-    }
-
     void setDisplayPowerMode(PhysicalDisplayId displayId, hal::PowerMode powerMode) {
         ftl::FakeGuard guard(kMainThreadContext);
         Scheduler::setDisplayPowerMode(displayId, powerMode);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 7d1ec25..5e81b35 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -326,9 +326,13 @@
 
     auto& mutableStateLock() { return mFlinger->mStateLock; }
 
-    static auto findOutputLayerForDisplay(const sp<Layer>& layer,
-                                          const sp<const DisplayDevice>& display) {
-        return layer->findOutputLayerForDisplay(display.get());
+    compositionengine::OutputLayer* findOutputLayerForDisplay(
+            uint32_t layerId, const sp<const DisplayDevice>& display) {
+        ftl::FakeGuard guard(kMainThreadContext);
+        if (mFlinger->mLegacyLayers.find(layerId) == mFlinger->mLegacyLayers.end()) {
+            return nullptr;
+        }
+        return mFlinger->mLegacyLayers[layerId]->findOutputLayerForDisplay(display.get());
     }
 
     static void setLayerSidebandStream(const sp<Layer>& layer,
@@ -340,17 +344,14 @@
 
     void setLayerCompositionType(const sp<Layer>& layer,
                                  aidl::android::hardware::graphics::composer3::Composition type) {
-        auto outputLayer = findOutputLayerForDisplay(layer, mFlinger->getDefaultDisplayDevice());
+        auto outputLayer = findOutputLayerForDisplay(static_cast<uint32_t>(layer->sequence),
+                                                     mFlinger->getDefaultDisplayDevice());
         LOG_ALWAYS_FATAL_IF(!outputLayer);
         auto& state = outputLayer->editState();
         LOG_ALWAYS_FATAL_IF(!outputLayer->getState().hwc);
         (*state.hwc).hwcCompositionType = type;
     }
 
-    static void setLayerPotentialCursor(const sp<Layer>& layer, bool potentialCursor) {
-        layer->mPotentialCursor = potentialCursor;
-    }
-
     static void setLayerDrawingParent(const sp<Layer>& layer, const sp<Layer>& drawingParent) {
         layer->mDrawingParent = drawingParent;
     }
@@ -395,7 +396,7 @@
             targets.try_emplace(id, &frameTargeter.target());
             targeters.try_emplace(id, &frameTargeter);
         }
-
+        mFlinger->setTransactionFlags(eTransactionFlushNeeded);
         mFlinger->commit(displayId, targets);
 
         if (composite) {
@@ -505,10 +506,9 @@
                                           captureResults, displayState, layers, layerFEs);
     }
 
-    auto traverseLayersInLayerStack(ui::LayerStack layerStack, int32_t uid,
-                                    std::unordered_set<uint32_t> excludeLayerIds,
-                                    const LayerVector::Visitor& visitor) {
-        return mFlinger->traverseLayersInLayerStack(layerStack, uid, excludeLayerIds, visitor);
+    auto getLayerSnapshotsForScreenshotsFn(ui::LayerStack layerStack, uint32_t uid) {
+        return mFlinger->getLayerSnapshotsForScreenshots(layerStack, uid,
+                                                         std::unordered_set<uint32_t>{});
     }
 
     auto getDisplayNativePrimaries(const sp<IBinder>& displayToken,
@@ -620,6 +620,18 @@
         mFlinger->mNewLayers.emplace_back(std::move(layer));
     }
 
+    // Used to add a layer before updateLayerSnapshots is called.
+    // Must have transactionsFlushed enabled for the new layer to be updated.
+    void addLayer(uint32_t layerId) {
+        std::scoped_lock<std::mutex> lock(mFlinger->mCreatedLayersLock);
+        LayerCreationArgs args(std::make_optional(layerId));
+        args.flinger = this->mFlinger.get();
+        auto layer = std::make_unique<frontend::RequestedLayerState>(args);
+        auto legacyLayer = sp<Layer>::make(args);
+        injectLegacyLayer(legacyLayer);
+        mFlinger->mNewLayers.emplace_back(std::move(layer));
+    }
+
     /* ------------------------------------------------------------------------
      * Read-only access to private data to assert post-conditions.
      */
@@ -637,12 +649,24 @@
     void injectLegacyLayer(sp<Layer> layer) {
         FTL_FAKE_GUARD(kMainThreadContext,
                        mFlinger->mLegacyLayers[static_cast<uint32_t>(layer->sequence)] = layer);
-    };
+    }
 
     void releaseLegacyLayer(uint32_t sequence) {
         FTL_FAKE_GUARD(kMainThreadContext, mFlinger->mLegacyLayers.erase(sequence));
+    }
+
+    auto getLegacyLayer(uint32_t layerId) {
+        ftl::FakeGuard guard(kMainThreadContext);
+        return mFlinger->mLegacyLayers[layerId];
     };
 
+    void destroyAllLayerHandles() {
+        ftl::FakeGuard guard(kMainThreadContext);
+        for (auto [layerId, legacyLayer] : mFlinger->mLegacyLayers) {
+            mFlinger->onHandleDestroyed(nullptr, legacyLayer, layerId);
+        }
+    }
+
     auto setLayerHistoryDisplayArea(uint32_t displayArea) {
         return mFlinger->mScheduler->onActiveDisplayAreaChanged(displayArea);
     };
@@ -709,10 +733,6 @@
         return mFlinger->initTransactionTraceWriter();
     }
 
-    // Needed since mLayerLifecycleManagerEnabled is false by default and must
-    // be enabled for tests to go through the new front end path.
-    void enableLayerLifecycleManager() { mFlinger->mLayerLifecycleManagerEnabled = true; }
-
     void notifyExpectedPresentIfRequired(PhysicalDisplayId displayId, Period vsyncPeriod,
                                          TimePoint expectedPresentTime, Fps frameInterval,
                                          std::optional<Period> timeoutOpt) {
@@ -1118,8 +1138,8 @@
                 if (mFlinger.scheduler() && mSchedulerRegistration) {
                     mFlinger.scheduler()->registerDisplay(*physicalId,
                                                           mCreationArgs.refreshRateSelector,
-                                                          std::move(controller),
-                                                          std::move(tracker));
+                                                          std::move(controller), std::move(tracker),
+                                                          mFlinger.mutableActiveDisplayId());
                 }
             }
 
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index 7fb9247..e13fe49 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -17,6 +17,7 @@
 #undef LOG_TAG
 #define LOG_TAG "TransactionApplicationTest"
 
+#include <binder/Binder.h>
 #include <common/test/FlagUtils.h>
 #include <compositionengine/Display.h>
 #include <compositionengine/mock/DisplaySurface.h>
@@ -26,10 +27,10 @@
 #include <gui/SurfaceComposerClient.h>
 #include <gui/fake/BufferData.h>
 #include <log/log.h>
+#include <renderengine/mock/RenderEngine.h>
 #include <ui/MockFence.h>
 #include <utils/String8.h>
 #include <vector>
-#include <binder/Binder.h>
 
 #include "FrontEnd/TransactionHandler.h"
 #include "TestableSurfaceFlinger.h"
@@ -55,6 +56,7 @@
 
         mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
         mFlinger.setupMockScheduler();
+        mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
         mFlinger.flinger()->addTransactionReadyFilters();
     }
 
@@ -65,6 +67,7 @@
     }
 
     TestableSurfaceFlinger mFlinger;
+    renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
 
     struct TransactionInfo {
         Vector<ComposerState> states;
@@ -323,15 +326,17 @@
     transaction1.states[0].state.bufferData =
             std::make_shared<fake::BufferData>(/* bufferId */ 1, /* width */ 1, /* height */ 1,
                                                /* pixelFormat */ 0, /* outUsage */ 0);
+    mFlinger.addLayer(1);
+    bool out;
+    mFlinger.updateLayerSnapshots(VsyncId{1}, 0, /* transactionsFlushed */ true, out);
     transaction1.states[0].externalTexture =
             std::make_shared<FakeExternalTexture>(*transaction1.states[0].state.bufferData);
-    transaction1.states[0].state.surface =
-            sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
-                    ->getHandle();
+    transaction1.states[0].state.surface = mFlinger.getLegacyLayer(1)->getHandle();
     auto fence = sp<mock::MockFence>::make();
     EXPECT_CALL(*fence, getStatus()).WillRepeatedly(Return(Fence::Status::Unsignaled));
     transaction1.states[0].state.bufferData->acquireFence = std::move(fence);
     transaction1.states[0].state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
+    transaction1.states[0].layerId = 1;
     transaction1.isAutoTimestamp = true;
 
     // Transaction 2 should be ready to be applied.
@@ -361,8 +366,7 @@
         }
         mFlinger.getPendingTransactionQueue().clear();
         mFlinger.commitTransactionsLocked(eTransactionMask);
-        mFlinger.mutableCurrentState().layersSortedByZ.clear();
-        mFlinger.mutableDrawingState().layersSortedByZ.clear();
+        mFlinger.destroyAllLayerHandles();
     }
 
     static sp<Fence> fence(Fence::Status status) {
@@ -371,8 +375,7 @@
         return fence;
     }
 
-    ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what,
-                                      std::optional<sp<IBinder>> layerHandle = std::nullopt) {
+    ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what) {
         ComposerState state;
         state.state.bufferData =
                 std::make_shared<fake::BufferData>(/* bufferId */ 123L, /* width */ 1,
@@ -380,9 +383,6 @@
                                                    /* outUsage */ 0);
         state.state.bufferData->acquireFence = std::move(fence);
         state.state.layerId = layerId;
-        state.state.surface = layerHandle.value_or(
-                sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
-                        ->getHandle());
         state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
 
         state.state.what = what;
@@ -418,6 +418,19 @@
                               size_t expectedTransactionsPending) {
         EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
         EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
+        std::unordered_set<uint32_t> createdLayers;
+        for (auto transaction : transactions) {
+            for (auto& state : transaction.states) {
+                auto layerId = static_cast<uint32_t>(state.state.layerId);
+                if (createdLayers.find(layerId) == createdLayers.end()) {
+                    mFlinger.addLayer(layerId);
+                    createdLayers.insert(layerId);
+                }
+            }
+        }
+        bool unused;
+        bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0,
+                                                           /*transactionsFlushed=*/true, unused);
 
         for (auto transaction : transactions) {
             std::vector<ResolvedComposerState> resolvedStates;
@@ -427,6 +440,9 @@
                 resolvedState.state = std::move(state.state);
                 resolvedState.externalTexture =
                         std::make_shared<FakeExternalTexture>(*resolvedState.state.bufferData);
+                resolvedState.layerId = static_cast<uint32_t>(state.state.layerId);
+                resolvedState.state.surface =
+                        mFlinger.getLegacyLayer(resolvedState.layerId)->getHandle();
                 resolvedStates.emplace_back(resolvedState);
             }
 
@@ -458,9 +474,8 @@
 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleSignaledFromTheQueue) {
     const sp<IBinder> kApplyToken =
             IInterface::asBinder(TransactionCompletedListener::getIInstance());
-    const auto kLayerId = 1;
+    const auto kLayerId = 10;
     const auto kExpectedTransactionsPending = 0u;
-
     const auto signaledTransaction =
             createTransactionInfo(kApplyToken,
                                   {createComposerState(kLayerId, fence(Fence::Status::Signaled),
@@ -773,7 +788,7 @@
 TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue) {
     const sp<IBinder> kApplyToken =
             IInterface::asBinder(TransactionCompletedListener::getIInstance());
-    const auto kLayerId = 1;
+    const auto kLayerId = 10;
     const auto kExpectedTransactionsPending = 0u;
 
     const auto signaledTransaction =
diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
index 46733b9..0745f87 100644
--- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
@@ -302,58 +302,6 @@
         EXPECT_EQ(PresentState::Presented, bufferSurfaceFrameTX->getPresentState());
     }
 
-    void PendingSurfaceFramesRemovedAfterClassification() {
-        sp<Layer> layer = createLayer();
-
-        sp<Fence> fence1(sp<Fence>::make());
-        auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1);
-        BufferData bufferData;
-        bufferData.acquireFence = fence1;
-        bufferData.frameNumber = 1;
-        bufferData.flags |= BufferData::BufferDataChange::fenceChanged;
-        bufferData.flags |= BufferData::BufferDataChange::frameNumberChanged;
-        std::shared_ptr<renderengine::ExternalTexture> externalTexture1 = std::make_shared<
-                renderengine::mock::FakeExternalTexture>(1U /*width*/, 1U /*height*/,
-                                                         1ULL /* bufferId */,
-                                                         HAL_PIXEL_FORMAT_RGBA_8888,
-                                                         0ULL /*usage*/);
-        FrameTimelineInfo ftInfo;
-        ftInfo.vsyncId = 1;
-        ftInfo.inputEventId = 0;
-        layer->setBuffer(externalTexture1, bufferData, 10, 20, false, ftInfo);
-        ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
-        const auto droppedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
-
-        sp<Fence> fence2(sp<Fence>::make());
-        auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2);
-        bufferData.acquireFence = fence2;
-        bufferData.frameNumber = 1;
-        bufferData.flags |= BufferData::BufferDataChange::fenceChanged;
-        bufferData.flags |= BufferData::BufferDataChange::frameNumberChanged;
-        std::shared_ptr<renderengine::ExternalTexture> externalTexture2 = std::make_shared<
-                renderengine::mock::FakeExternalTexture>(1U /*width*/, 1U /*height*/,
-                                                         1ULL /* bufferId */,
-                                                         HAL_PIXEL_FORMAT_RGBA_8888,
-                                                         0ULL /*usage*/);
-        layer->setBuffer(externalTexture2, bufferData, 10, 20, false, ftInfo);
-        acquireFence2->signalForTest(12);
-
-        ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
-        auto presentedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
-
-        commitTransaction(layer.get());
-        layer->updateTexImage(15);
-
-        // Both the droppedSurfaceFrame and presentedSurfaceFrame should be in
-        // pendingJankClassifications.
-        EXPECT_EQ(2u, layer->mPendingJankClassifications.size());
-        presentedSurfaceFrame->onPresent(20, JankType::None, 90_Hz, 90_Hz,
-                                         /*displayDeadlineDelta*/ 0, /*displayPresentDelta*/ 0);
-        layer->releasePendingBuffer(25);
-
-        EXPECT_EQ(0u, layer->mPendingJankClassifications.size());
-    }
-
     void BufferSurfaceFrame_ReplaceValidTokenBufferWithInvalidTokenBuffer() {
         sp<Layer> layer = createLayer();
 
@@ -445,8 +393,7 @@
 
     void MultipleCommitsBeforeLatch() {
         sp<Layer> layer = createLayer();
-        uint32_t surfaceFramesPendingClassification = 0;
-        std::vector<std::shared_ptr<frametimeline::SurfaceFrame>> bufferlessSurfaceFrames;
+        std::vector<std::shared_ptr<frametimeline::SurfaceFrame>> surfaceFrames;
         for (int i = 0; i < 10; i += 2) {
             sp<Fence> fence(sp<Fence>::make());
             BufferData bufferData;
@@ -469,51 +416,43 @@
             layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo2, 10);
             ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
             EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
-            auto& bufferlessSurfaceFrame =
-                    layer->mDrawingState.bufferlessSurfaceFramesTX.at(/*vsyncId*/ 2);
-            bufferlessSurfaceFrames.push_back(bufferlessSurfaceFrame);
+
+            surfaceFrames.push_back(layer->mDrawingState.bufferSurfaceFrameTX);
+            surfaceFrames.push_back(
+                    layer->mDrawingState.bufferlessSurfaceFramesTX.at(/*vsyncId*/ 2));
 
             commitTransaction(layer.get());
-            surfaceFramesPendingClassification += 2;
-            EXPECT_EQ(surfaceFramesPendingClassification,
-                      layer->mPendingJankClassifications.size());
         }
 
         auto presentedBufferSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
         layer->updateTexImage(15);
         // BufferlessSurfaceFrames are immediately set to presented and added to the DisplayFrame.
         // Since we don't have access to DisplayFrame here, trigger an onPresent directly.
-        for (auto& surfaceFrame : bufferlessSurfaceFrames) {
-            surfaceFrame->onPresent(20, JankType::None, 90_Hz, 90_Hz,
-                                    /*displayDeadlineDelta*/ 0, /*displayPresentDelta*/ 0);
+        // The odd indices are the bufferless frames.
+        for (uint32_t i = 1; i < 10; i += 2) {
+            surfaceFrames[i]->onPresent(20, JankType::None, 90_Hz, 90_Hz,
+                                        /*displayDeadlineDelta*/ 0, /*displayPresentDelta*/ 0);
         }
         presentedBufferSurfaceFrame->onPresent(20, JankType::None, 90_Hz, 90_Hz,
                                                /*displayDeadlineDelta*/ 0,
                                                /*displayPresentDelta*/ 0);
 
-        // There should be 10 bufferlessSurfaceFrames and 1 bufferSurfaceFrame
-        ASSERT_EQ(10u, surfaceFramesPendingClassification);
-        ASSERT_EQ(surfaceFramesPendingClassification, layer->mPendingJankClassifications.size());
-
         // For the frames upto 8, the bufferSurfaceFrame should have been dropped while the
         // bufferlessSurfaceFrame presented
         for (uint32_t i = 0; i < 8; i += 2) {
-            auto& bufferSurfaceFrame = layer->mPendingJankClassifications[i];
-            auto& bufferlessSurfaceFrame = layer->mPendingJankClassifications[i + 1];
+            auto bufferSurfaceFrame = surfaceFrames[i];
+            auto bufferlessSurfaceFrame = surfaceFrames[i + 1];
             EXPECT_EQ(bufferSurfaceFrame->getPresentState(), PresentState::Dropped);
             EXPECT_EQ(bufferlessSurfaceFrame->getPresentState(), PresentState::Presented);
         }
         {
-            auto& bufferSurfaceFrame = layer->mPendingJankClassifications[8u];
-            auto& bufferlessSurfaceFrame = layer->mPendingJankClassifications[9u];
+            auto bufferSurfaceFrame = surfaceFrames[8];
+            auto bufferlessSurfaceFrame = surfaceFrames[9];
             EXPECT_EQ(bufferSurfaceFrame->getPresentState(), PresentState::Presented);
             EXPECT_EQ(bufferlessSurfaceFrame->getPresentState(), PresentState::Presented);
         }
 
         layer->releasePendingBuffer(25);
-
-        // There shouldn't be any pending classifications. Everything should have been cleared.
-        EXPECT_EQ(0u, layer->mPendingJankClassifications.size());
     }
 };
 
@@ -541,10 +480,6 @@
     MultipleSurfaceFramesPresentedTogether();
 }
 
-TEST_F(TransactionSurfaceFrameTest, PendingSurfaceFramesRemovedAfterClassification) {
-    PendingSurfaceFramesRemovedAfterClassification();
-}
-
 TEST_F(TransactionSurfaceFrameTest,
        BufferSurfaceFrame_ReplaceValidTokenBufferWithInvalidTokenBuffer) {
     BufferSurfaceFrame_ReplaceValidTokenBufferWithInvalidTokenBuffer();
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
index 3b09554..b63f299 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
@@ -19,6 +19,7 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
+#include <scheduler/FrameTime.h>
 #include <scheduler/Timer.h>
 
 #include "Scheduler/VSyncDispatchTimerQueue.h"
@@ -51,7 +52,7 @@
     bool isVSyncInPhase(nsecs_t, Fps) final { return false; }
     void setDisplayModePtr(ftl::NonNull<DisplayModePtr>) final {}
     void setRenderRate(Fps, bool) final {}
-    void onFrameBegin(TimePoint, TimePoint) final {}
+    void onFrameBegin(TimePoint, scheduler::FrameTime) final {}
     void onFrameMissed(TimePoint) final {}
     void dump(std::string&) const final {}
     bool isCurrentMode(const ftl::NonNull<DisplayModePtr>&) const final { return false; };
diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
index 5109ea6..8690dba 100644
--- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
@@ -673,6 +673,36 @@
     EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(mNow + 5100), Eq(mNow + 6 * mPeriod));
 }
 
+TEST_F(VSyncPredictorTest, setRenderRateWhenRenderRateGoesDown) {
+    SET_FLAG_FOR_TEST(flags::vrr_config, true);
+    SET_FLAG_FOR_TEST(flags::vrr_bugfix_24q4, true);
+
+    const int32_t kGroup = 0;
+    const auto kResolution = ui::Size(1920, 1080);
+    const auto vsyncRate = Fps::fromPeriodNsecs(500);
+    const auto minFrameRate = Fps::fromPeriodNsecs(1000);
+    hal::VrrConfig vrrConfig;
+    vrrConfig.minFrameIntervalNs = minFrameRate.getPeriodNsecs();
+    const ftl::NonNull<DisplayModePtr> kMode =
+            ftl::as_non_null(createDisplayModeBuilder(DisplayModeId(0), vsyncRate, kGroup,
+                                                      kResolution, DEFAULT_DISPLAY_ID)
+                                     .setVrrConfig(std::move(vrrConfig))
+                                     .build());
+
+    VSyncPredictor vrrTracker{std::make_unique<ClockWrapper>(mClock), kMode, kHistorySize,
+                              kMinimumSamplesForPrediction, kOutlierTolerancePercent};
+
+    Fps frameRate = Fps::fromPeriodNsecs(1000);
+    vrrTracker.setRenderRate(frameRate, /*applyImmediately*/ false);
+    vrrTracker.addVsyncTimestamp(0);
+    EXPECT_EQ(1000, vrrTracker.nextAnticipatedVSyncTimeFrom(700));
+    EXPECT_EQ(2000, vrrTracker.nextAnticipatedVSyncTimeFrom(1000, 1000));
+
+    frameRate = Fps::fromPeriodNsecs(3000);
+    vrrTracker.setRenderRate(frameRate, /*applyImmediately*/ false);
+    EXPECT_TRUE(vrrTracker.isVSyncInPhase(2000, frameRate));
+}
+
 TEST_F(VSyncPredictorTest, setRenderRateHighIsAppliedImmediately) {
     SET_FLAG_FOR_TEST(flags::vrr_config, true);
 
@@ -871,17 +901,20 @@
     EXPECT_EQ(1000, vrrTracker.nextAnticipatedVSyncTimeFrom(700));
     EXPECT_EQ(2000, vrrTracker.nextAnticipatedVSyncTimeFrom(1000));
 
-    vrrTracker.onFrameBegin(TimePoint::fromNs(2000), TimePoint::fromNs(1500));
+    vrrTracker.onFrameBegin(TimePoint::fromNs(2000),
+                            {TimePoint::fromNs(1500), TimePoint::fromNs(1500)});
     EXPECT_EQ(3500, vrrTracker.nextAnticipatedVSyncTimeFrom(2000, 2000));
     EXPECT_EQ(4500, vrrTracker.nextAnticipatedVSyncTimeFrom(3500, 3500));
 
     // Miss when starting 4500 and expect the next vsync will be at 5000 (next one)
-    vrrTracker.onFrameBegin(TimePoint::fromNs(3500), TimePoint::fromNs(2500));
+    vrrTracker.onFrameBegin(TimePoint::fromNs(3500),
+                            {TimePoint::fromNs(2500), TimePoint::fromNs(2500)});
     vrrTracker.onFrameMissed(TimePoint::fromNs(4500));
     EXPECT_EQ(5000, vrrTracker.nextAnticipatedVSyncTimeFrom(4500, 4500));
     EXPECT_EQ(6000, vrrTracker.nextAnticipatedVSyncTimeFrom(5000, 5000));
 
-    vrrTracker.onFrameBegin(TimePoint::fromNs(7000), TimePoint::fromNs(6500));
+    vrrTracker.onFrameBegin(TimePoint::fromNs(7000),
+                            {TimePoint::fromNs(6500), TimePoint::fromNs(6500)});
     EXPECT_EQ(10500, vrrTracker.nextAnticipatedVSyncTimeFrom(9000, 7000));
 }
 
@@ -913,7 +946,7 @@
 
     // SF starts to catch up
     EXPECT_EQ(3000, vrrTracker.nextAnticipatedVSyncTimeFrom(2700));
-    vrrTracker.onFrameBegin(TimePoint::fromNs(3000), TimePoint::fromNs(0));
+    vrrTracker.onFrameBegin(TimePoint::fromNs(3000), {TimePoint::fromNs(0), TimePoint::fromNs(0)});
 
     // SF misses last frame (3000) and observes that when committing (4000)
     EXPECT_EQ(6000, vrrTracker.nextAnticipatedVSyncTimeFrom(5000, 5000));
@@ -922,17 +955,20 @@
 
     // SF wakes up again instead of the (4000) missed frame
     EXPECT_EQ(4500, vrrTracker.nextAnticipatedVSyncTimeFrom(4000, 4000));
-    vrrTracker.onFrameBegin(TimePoint::fromNs(4500), TimePoint::fromNs(4500));
+    vrrTracker.onFrameBegin(TimePoint::fromNs(4500),
+                            {TimePoint::fromNs(4500), TimePoint::fromNs(4500)});
 
     // Timeline shifted. The app needs to get the next frame at (7500) as its last frame (6500) will
     // be presented at (7500)
     EXPECT_EQ(7500, vrrTracker.nextAnticipatedVSyncTimeFrom(6000, 6000));
     EXPECT_EQ(5500, vrrTracker.nextAnticipatedVSyncTimeFrom(4500, 4500));
-    vrrTracker.onFrameBegin(TimePoint::fromNs(5500), TimePoint::fromNs(4500));
+    vrrTracker.onFrameBegin(TimePoint::fromNs(5500),
+                            {TimePoint::fromNs(4500), TimePoint::fromNs(4500)});
 
     EXPECT_EQ(8500, vrrTracker.nextAnticipatedVSyncTimeFrom(7500, 7500));
     EXPECT_EQ(6500, vrrTracker.nextAnticipatedVSyncTimeFrom(5500, 5500));
-    vrrTracker.onFrameBegin(TimePoint::fromNs(6500), TimePoint::fromNs(5500));
+    vrrTracker.onFrameBegin(TimePoint::fromNs(6500),
+                            {TimePoint::fromNs(5500), TimePoint::fromNs(5500)});
 }
 
 TEST_F(VSyncPredictorTest, renderRateIsPreservedForCommittedVsyncs) {
@@ -990,6 +1026,35 @@
     EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(9001), Eq(13000));
 }
 
+TEST_F(VSyncPredictorTest, timelineNotAdjustedForEarlyPresent) {
+    SET_FLAG_FOR_TEST(flags::vrr_config, true);
+
+    const int32_t kGroup = 0;
+    const auto kResolution = ui::Size(1920, 1080);
+    const auto refreshRate = Fps::fromPeriodNsecs(500);
+    const auto minFrameRate = Fps::fromPeriodNsecs(1000);
+    hal::VrrConfig vrrConfig;
+    vrrConfig.minFrameIntervalNs = minFrameRate.getPeriodNsecs();
+    const ftl::NonNull<DisplayModePtr> kMode =
+            ftl::as_non_null(createDisplayModeBuilder(DisplayModeId(0), refreshRate, kGroup,
+                                                      kResolution, DEFAULT_DISPLAY_ID)
+                                     .setVrrConfig(std::move(vrrConfig))
+                                     .build());
+
+    VSyncPredictor vrrTracker{std::make_unique<ClockWrapper>(mClock), kMode, kHistorySize,
+                              kMinimumSamplesForPrediction, kOutlierTolerancePercent};
+
+    vrrTracker.setRenderRate(minFrameRate, /*applyImmediately*/ false);
+    vrrTracker.addVsyncTimestamp(0);
+    EXPECT_EQ(1000, vrrTracker.nextAnticipatedVSyncTimeFrom(700));
+
+    constexpr auto kLastConfirmedExpectedPresentTime = TimePoint::fromNs(1000);
+    constexpr auto kLastActualSignalTime = TimePoint::fromNs(700); // presented early
+    vrrTracker.onFrameBegin(TimePoint::fromNs(1400),
+                            {kLastActualSignalTime, kLastConfirmedExpectedPresentTime});
+    EXPECT_EQ(2000, vrrTracker.nextAnticipatedVSyncTimeFrom(1400, 1000));
+    EXPECT_EQ(3000, vrrTracker.nextAnticipatedVSyncTimeFrom(2000, 1000));
+}
 } // namespace android::scheduler
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/tests/unittests/mock/MockDisplayModeSpecs.h b/services/surfaceflinger/tests/unittests/mock/MockDisplayModeSpecs.h
index 7b18a82..4d35d4d 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockDisplayModeSpecs.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockDisplayModeSpecs.h
@@ -22,14 +22,13 @@
 
 namespace android::mock {
 
-inline gui::DisplayModeSpecs createDisplayModeSpecs(DisplayModeId defaultMode,
-                                                    bool allowGroupSwitching, float minFps,
-                                                    float maxFps) {
+inline gui::DisplayModeSpecs createDisplayModeSpecs(DisplayModeId defaultMode, Fps maxFps,
+                                                    bool allowGroupSwitching = false) {
     gui::DisplayModeSpecs specs;
     specs.defaultMode = ftl::to_underlying(defaultMode);
     specs.allowGroupSwitching = allowGroupSwitching;
-    specs.primaryRanges.physical.min = minFps;
-    specs.primaryRanges.physical.max = maxFps;
+    specs.primaryRanges.physical.min = 0.f;
+    specs.primaryRanges.physical.max = maxFps.getValue();
     specs.primaryRanges.render = specs.primaryRanges.physical;
     specs.appRequestRanges = specs.primaryRanges;
     return specs;
diff --git a/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h b/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h
index dec5fa5..8f21cdb 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h
@@ -31,6 +31,7 @@
     MOCK_METHOD(void, onExpectedPresentTimePosted, (TimePoint, ftl::NonNull<DisplayModePtr>, Fps),
                 (override));
     MOCK_METHOD(void, onCommitNotComposited, (PhysicalDisplayId), (override));
+    MOCK_METHOD(void, vrrDisplayIdle, (bool), (override));
 };
 
 struct NoOpSchedulerCallback final : ISchedulerCallback {
@@ -41,6 +42,7 @@
     void onChoreographerAttached() override {}
     void onExpectedPresentTimePosted(TimePoint, ftl::NonNull<DisplayModePtr>, Fps) override {}
     void onCommitNotComposited(PhysicalDisplayId) override {}
+    void vrrDisplayIdle(bool) override {}
 };
 
 } // namespace android::scheduler::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
index 4f44d1b..8d6d1d3 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
@@ -18,6 +18,8 @@
 
 #include <gmock/gmock.h>
 
+#include <scheduler/FrameTime.h>
+
 #include "Scheduler/VSyncTracker.h"
 
 namespace android::mock {
@@ -37,7 +39,7 @@
     MOCK_METHOD(bool, isVSyncInPhase, (nsecs_t, Fps), (override));
     MOCK_METHOD(void, setDisplayModePtr, (ftl::NonNull<DisplayModePtr>), (override));
     MOCK_METHOD(void, setRenderRate, (Fps, bool), (override));
-    MOCK_METHOD(void, onFrameBegin, (TimePoint, TimePoint), (override));
+    MOCK_METHOD(void, onFrameBegin, (TimePoint, scheduler::FrameTime), (override));
     MOCK_METHOD(void, onFrameMissed, (TimePoint), (override));
     MOCK_METHOD(void, dump, (std::string&), (const, override));
     MOCK_METHOD(bool, isCurrentMode, (const ftl::NonNull<DisplayModePtr>&), (const, override));
diff --git a/services/vibratorservice/Android.bp b/services/vibratorservice/Android.bp
index 2002bdf..4735ae5 100644
--- a/services/vibratorservice/Android.bp
+++ b/services/vibratorservice/Android.bp
@@ -33,19 +33,19 @@
     ],
 
     aidl: {
-       local_include_dirs: ["include"],
-       include_dirs: [
-           "hardware/interfaces/vibrator/aidl/android/hardware/vibrator",
-       ],
-       export_aidl_headers: true
+        local_include_dirs: ["include"],
+        include_dirs: [
+            "hardware/interfaces/vibrator/aidl/android/hardware/vibrator",
+        ],
+        export_aidl_headers: true,
     },
 
     shared_libs: [
-        "libbinder",
+        "libbinder_ndk",
         "libhidlbase",
         "liblog",
         "libutils",
-        "android.hardware.vibrator-V2-cpp",
+        "android.hardware.vibrator-V3-ndk",
         "android.hardware.vibrator@1.0",
         "android.hardware.vibrator@1.1",
         "android.hardware.vibrator@1.2",
diff --git a/services/vibratorservice/VibratorHalController.cpp b/services/vibratorservice/VibratorHalController.cpp
index c1795f5..283a5f0 100644
--- a/services/vibratorservice/VibratorHalController.cpp
+++ b/services/vibratorservice/VibratorHalController.cpp
@@ -16,9 +16,9 @@
 
 #define LOG_TAG "VibratorHalController"
 
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+#include <android/binder_manager.h>
 #include <android/hardware/vibrator/1.3/IVibrator.h>
-#include <android/hardware/vibrator/IVibrator.h>
-#include <binder/IServiceManager.h>
 #include <hardware/vibrator.h>
 
 #include <utils/Log.h>
@@ -27,10 +27,10 @@
 #include <vibratorservice/VibratorHalController.h>
 #include <vibratorservice/VibratorHalWrapper.h>
 
-using android::hardware::vibrator::CompositeEffect;
-using android::hardware::vibrator::CompositePrimitive;
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::CompositeEffect;
+using aidl::android::hardware::vibrator::CompositePrimitive;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
 
 using std::chrono::milliseconds;
 
@@ -38,7 +38,7 @@
 namespace V1_1 = android::hardware::vibrator::V1_1;
 namespace V1_2 = android::hardware::vibrator::V1_2;
 namespace V1_3 = android::hardware::vibrator::V1_3;
-namespace Aidl = android::hardware::vibrator;
+namespace Aidl = aidl::android::hardware::vibrator;
 
 namespace android {
 
@@ -53,10 +53,14 @@
         return nullptr;
     }
 
-    sp<Aidl::IVibrator> aidlHal = waitForVintfService<Aidl::IVibrator>();
-    if (aidlHal) {
-        ALOGV("Successfully connected to Vibrator HAL AIDL service.");
-        return std::make_shared<AidlHalWrapper>(std::move(scheduler), aidlHal);
+    auto serviceName = std::string(Aidl::IVibrator::descriptor) + "/default";
+    if (AServiceManager_isDeclared(serviceName.c_str())) {
+        std::shared_ptr<Aidl::IVibrator> hal = Aidl::IVibrator::fromBinder(
+                ndk::SpAIBinder(AServiceManager_waitForService(serviceName.c_str())));
+        if (hal) {
+            ALOGV("Successfully connected to Vibrator HAL AIDL service.");
+            return std::make_shared<AidlHalWrapper>(std::move(scheduler), std::move(hal));
+        }
     }
 
     sp<V1_0::IVibrator> halV1_0 = V1_0::IVibrator::getService();
diff --git a/services/vibratorservice/VibratorHalWrapper.cpp b/services/vibratorservice/VibratorHalWrapper.cpp
index f10ba44..c97f401 100644
--- a/services/vibratorservice/VibratorHalWrapper.cpp
+++ b/services/vibratorservice/VibratorHalWrapper.cpp
@@ -16,8 +16,8 @@
 
 #define LOG_TAG "VibratorHalWrapper"
 
+#include <aidl/android/hardware/vibrator/IVibrator.h>
 #include <android/hardware/vibrator/1.3/IVibrator.h>
-#include <android/hardware/vibrator/IVibrator.h>
 #include <hardware/vibrator.h>
 #include <cmath>
 
@@ -26,12 +26,13 @@
 #include <vibratorservice/VibratorCallbackScheduler.h>
 #include <vibratorservice/VibratorHalWrapper.h>
 
-using android::hardware::vibrator::Braking;
-using android::hardware::vibrator::CompositeEffect;
-using android::hardware::vibrator::CompositePrimitive;
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
-using android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::Braking;
+using aidl::android::hardware::vibrator::CompositeEffect;
+using aidl::android::hardware::vibrator::CompositePrimitive;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::VendorEffect;
 
 using std::chrono::milliseconds;
 
@@ -39,7 +40,7 @@
 namespace V1_1 = android::hardware::vibrator::V1_1;
 namespace V1_2 = android::hardware::vibrator::V1_2;
 namespace V1_3 = android::hardware::vibrator::V1_3;
-namespace Aidl = android::hardware::vibrator;
+namespace Aidl = aidl::android::hardware::vibrator;
 
 namespace android {
 
@@ -96,6 +97,11 @@
     return mInfoCache.get();
 }
 
+HalResult<void> HalWrapper::performVendorEffect(const VendorEffect&, const std::function<void()>&) {
+    ALOGV("Skipped performVendorEffect because it's not available in Vibrator HAL");
+    return HalResult<void>::unsupported();
+}
+
 HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
                                                           const std::function<void()>&) {
     ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
@@ -200,7 +206,7 @@
 // -------------------------------------------------------------------------------------------------
 
 HalResult<void> AidlHalWrapper::ping() {
-    return HalResultFactory::fromStatus(IInterface::asBinder(getHal())->pingBinder());
+    return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
 }
 
 void AidlHalWrapper::tryReconnect() {
@@ -208,7 +214,7 @@
     if (!result.isOk()) {
         return;
     }
-    sp<Aidl::IVibrator> newHandle = result.value();
+    std::shared_ptr<Aidl::IVibrator> newHandle = result.value();
     if (newHandle) {
         std::lock_guard<std::mutex> lock(mHandleMutex);
         mHandle = std::move(newHandle);
@@ -220,7 +226,8 @@
     HalResult<Capabilities> capabilities = getCapabilities();
     bool supportsCallback = capabilities.isOk() &&
             static_cast<int32_t>(capabilities.value() & Capabilities::ON_CALLBACK);
-    auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
+    auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
+                               : nullptr;
 
     auto ret = HalResultFactory::fromStatus(getHal()->on(timeout.count(), cb));
     if (!supportsCallback && ret.isOk()) {
@@ -255,13 +262,14 @@
     HalResult<Capabilities> capabilities = getCapabilities();
     bool supportsCallback = capabilities.isOk() &&
             static_cast<int32_t>(capabilities.value() & Capabilities::PERFORM_CALLBACK);
-    auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
+    auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
+                               : nullptr;
 
     int32_t lengthMs;
-    auto result = getHal()->perform(effect, strength, cb, &lengthMs);
+    auto status = getHal()->perform(effect, strength, cb, &lengthMs);
     milliseconds length = milliseconds(lengthMs);
 
-    auto ret = HalResultFactory::fromStatus<milliseconds>(result, length);
+    auto ret = HalResultFactory::fromStatus<milliseconds>(std::move(status), length);
     if (!supportsCallback && ret.isOk()) {
         mCallbackScheduler->schedule(completionCallback, length);
     }
@@ -269,11 +277,18 @@
     return ret;
 }
 
+HalResult<void> AidlHalWrapper::performVendorEffect(
+        const VendorEffect& effect, const std::function<void()>& completionCallback) {
+    // This method should always support callbacks, so no need to double check.
+    auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
+    return HalResultFactory::fromStatus(getHal()->performVendorEffect(effect, cb));
+}
+
 HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
         const std::vector<CompositeEffect>& primitives,
         const std::function<void()>& completionCallback) {
     // This method should always support callbacks, so no need to double check.
-    auto cb = new HalCallbackWrapper(completionCallback);
+    auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
 
     auto durations = getPrimitiveDurations().valueOr({});
     milliseconds duration(0);
@@ -294,40 +309,40 @@
 HalResult<void> AidlHalWrapper::performPwleEffect(const std::vector<PrimitivePwle>& primitives,
                                                   const std::function<void()>& completionCallback) {
     // This method should always support callbacks, so no need to double check.
-    auto cb = new HalCallbackWrapper(completionCallback);
+    auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
     return HalResultFactory::fromStatus(getHal()->composePwle(primitives, cb));
 }
 
 HalResult<Capabilities> AidlHalWrapper::getCapabilitiesInternal() {
-    int32_t capabilities = 0;
-    auto result = getHal()->getCapabilities(&capabilities);
-    return HalResultFactory::fromStatus<Capabilities>(result,
-                                                      static_cast<Capabilities>(capabilities));
+    int32_t cap = 0;
+    auto status = getHal()->getCapabilities(&cap);
+    auto capabilities = static_cast<Capabilities>(cap);
+    return HalResultFactory::fromStatus<Capabilities>(std::move(status), capabilities);
 }
 
 HalResult<std::vector<Effect>> AidlHalWrapper::getSupportedEffectsInternal() {
     std::vector<Effect> supportedEffects;
-    auto result = getHal()->getSupportedEffects(&supportedEffects);
-    return HalResultFactory::fromStatus<std::vector<Effect>>(result, supportedEffects);
+    auto status = getHal()->getSupportedEffects(&supportedEffects);
+    return HalResultFactory::fromStatus<std::vector<Effect>>(std::move(status), supportedEffects);
 }
 
 HalResult<std::vector<Braking>> AidlHalWrapper::getSupportedBrakingInternal() {
     std::vector<Braking> supportedBraking;
-    auto result = getHal()->getSupportedBraking(&supportedBraking);
-    return HalResultFactory::fromStatus<std::vector<Braking>>(result, supportedBraking);
+    auto status = getHal()->getSupportedBraking(&supportedBraking);
+    return HalResultFactory::fromStatus<std::vector<Braking>>(std::move(status), supportedBraking);
 }
 
 HalResult<std::vector<CompositePrimitive>> AidlHalWrapper::getSupportedPrimitivesInternal() {
     std::vector<CompositePrimitive> supportedPrimitives;
-    auto result = getHal()->getSupportedPrimitives(&supportedPrimitives);
-    return HalResultFactory::fromStatus<std::vector<CompositePrimitive>>(result,
+    auto status = getHal()->getSupportedPrimitives(&supportedPrimitives);
+    return HalResultFactory::fromStatus<std::vector<CompositePrimitive>>(std::move(status),
                                                                          supportedPrimitives);
 }
 
 HalResult<std::vector<milliseconds>> AidlHalWrapper::getPrimitiveDurationsInternal(
         const std::vector<CompositePrimitive>& supportedPrimitives) {
     std::vector<milliseconds> durations;
-    constexpr auto primitiveRange = enum_range<CompositePrimitive>();
+    constexpr auto primitiveRange = ndk::enum_range<CompositePrimitive>();
     constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
     durations.resize(primitiveCount);
 
@@ -340,8 +355,8 @@
             continue;
         }
         int32_t duration = 0;
-        auto result = getHal()->getPrimitiveDuration(primitive, &duration);
-        auto halResult = HalResultFactory::fromStatus<int32_t>(result, duration);
+        auto status = getHal()->getPrimitiveDuration(primitive, &duration);
+        auto halResult = HalResultFactory::fromStatus<int32_t>(std::move(status), duration);
         if (halResult.isUnsupported()) {
             // Should not happen, supported primitives should always support requesting duration.
             ALOGE("Supported primitive %zu returned unsupported for getPrimitiveDuration",
@@ -349,7 +364,7 @@
         }
         if (halResult.isFailed()) {
             // Fail entire request if one request has failed.
-            return HalResult<std::vector<milliseconds>>::failed(result.toString8().c_str());
+            return HalResult<std::vector<milliseconds>>::failed(halResult.errorMessage());
         }
         durations[primitiveIdx] = milliseconds(duration);
     }
@@ -359,59 +374,59 @@
 
 HalResult<milliseconds> AidlHalWrapper::getPrimitiveDelayMaxInternal() {
     int32_t delay = 0;
-    auto result = getHal()->getCompositionDelayMax(&delay);
-    return HalResultFactory::fromStatus<milliseconds>(result, milliseconds(delay));
+    auto status = getHal()->getCompositionDelayMax(&delay);
+    return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
 }
 
 HalResult<milliseconds> AidlHalWrapper::getPrimitiveDurationMaxInternal() {
     int32_t delay = 0;
-    auto result = getHal()->getPwlePrimitiveDurationMax(&delay);
-    return HalResultFactory::fromStatus<milliseconds>(result, milliseconds(delay));
+    auto status = getHal()->getPwlePrimitiveDurationMax(&delay);
+    return HalResultFactory::fromStatus<milliseconds>(std::move(status), milliseconds(delay));
 }
 
 HalResult<int32_t> AidlHalWrapper::getCompositionSizeMaxInternal() {
     int32_t size = 0;
-    auto result = getHal()->getCompositionSizeMax(&size);
-    return HalResultFactory::fromStatus<int32_t>(result, size);
+    auto status = getHal()->getCompositionSizeMax(&size);
+    return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
 }
 
 HalResult<int32_t> AidlHalWrapper::getPwleSizeMaxInternal() {
     int32_t size = 0;
-    auto result = getHal()->getPwleCompositionSizeMax(&size);
-    return HalResultFactory::fromStatus<int32_t>(result, size);
+    auto status = getHal()->getPwleCompositionSizeMax(&size);
+    return HalResultFactory::fromStatus<int32_t>(std::move(status), size);
 }
 
 HalResult<float> AidlHalWrapper::getMinFrequencyInternal() {
     float minFrequency = 0;
-    auto result = getHal()->getFrequencyMinimum(&minFrequency);
-    return HalResultFactory::fromStatus<float>(result, minFrequency);
+    auto status = getHal()->getFrequencyMinimum(&minFrequency);
+    return HalResultFactory::fromStatus<float>(std::move(status), minFrequency);
 }
 
 HalResult<float> AidlHalWrapper::getResonantFrequencyInternal() {
     float f0 = 0;
-    auto result = getHal()->getResonantFrequency(&f0);
-    return HalResultFactory::fromStatus<float>(result, f0);
+    auto status = getHal()->getResonantFrequency(&f0);
+    return HalResultFactory::fromStatus<float>(std::move(status), f0);
 }
 
 HalResult<float> AidlHalWrapper::getFrequencyResolutionInternal() {
     float frequencyResolution = 0;
-    auto result = getHal()->getFrequencyResolution(&frequencyResolution);
-    return HalResultFactory::fromStatus<float>(result, frequencyResolution);
+    auto status = getHal()->getFrequencyResolution(&frequencyResolution);
+    return HalResultFactory::fromStatus<float>(std::move(status), frequencyResolution);
 }
 
 HalResult<float> AidlHalWrapper::getQFactorInternal() {
     float qFactor = 0;
-    auto result = getHal()->getQFactor(&qFactor);
-    return HalResultFactory::fromStatus<float>(result, qFactor);
+    auto status = getHal()->getQFactor(&qFactor);
+    return HalResultFactory::fromStatus<float>(std::move(status), qFactor);
 }
 
 HalResult<std::vector<float>> AidlHalWrapper::getMaxAmplitudesInternal() {
     std::vector<float> amplitudes;
-    auto result = getHal()->getBandwidthAmplitudeMap(&amplitudes);
-    return HalResultFactory::fromStatus<std::vector<float>>(result, amplitudes);
+    auto status = getHal()->getBandwidthAmplitudeMap(&amplitudes);
+    return HalResultFactory::fromStatus<std::vector<float>>(std::move(status), amplitudes);
 }
 
-sp<Aidl::IVibrator> AidlHalWrapper::getHal() {
+std::shared_ptr<Aidl::IVibrator> AidlHalWrapper::getHal() {
     std::lock_guard<std::mutex> lock(mHandleMutex);
     return mHandle;
 }
@@ -420,8 +435,7 @@
 
 template <typename I>
 HalResult<void> HidlHalWrapper<I>::ping() {
-    auto result = getHal()->ping();
-    return HalResultFactory::fromReturn(result);
+    return HalResultFactory::fromReturn(getHal()->ping());
 }
 
 template <typename I>
@@ -436,8 +450,8 @@
 template <typename I>
 HalResult<void> HidlHalWrapper<I>::on(milliseconds timeout,
                                       const std::function<void()>& completionCallback) {
-    auto result = getHal()->on(timeout.count());
-    auto ret = HalResultFactory::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
+    auto status = getHal()->on(timeout.count());
+    auto ret = HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
     if (ret.isOk()) {
         mCallbackScheduler->schedule(completionCallback, timeout);
     }
@@ -446,15 +460,15 @@
 
 template <typename I>
 HalResult<void> HidlHalWrapper<I>::off() {
-    auto result = getHal()->off();
-    return HalResultFactory::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
+    auto status = getHal()->off();
+    return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
 }
 
 template <typename I>
 HalResult<void> HidlHalWrapper<I>::setAmplitude(float amplitude) {
     uint8_t amp = static_cast<uint8_t>(amplitude * std::numeric_limits<uint8_t>::max());
-    auto result = getHal()->setAmplitude(amp);
-    return HalResultFactory::fromStatus(result.withDefault(V1_0::Status::UNKNOWN_ERROR));
+    auto status = getHal()->setAmplitude(amp);
+    return HalResultFactory::fromStatus(status.withDefault(V1_0::Status::UNKNOWN_ERROR));
 }
 
 template <typename I>
@@ -480,7 +494,7 @@
     hardware::Return<bool> result = getHal()->supportsAmplitudeControl();
     Capabilities capabilities =
             result.withDefault(false) ? Capabilities::AMPLITUDE_CONTROL : Capabilities::NONE;
-    return HalResultFactory::fromReturn<Capabilities>(result, capabilities);
+    return HalResultFactory::fromReturn<Capabilities>(std::move(result), capabilities);
 }
 
 template <typename I>
@@ -499,7 +513,7 @@
     auto result = std::invoke(performFn, handle, effect, effectStrength, effectCallback);
     milliseconds length = milliseconds(lengthMs);
 
-    auto ret = HalResultFactory::fromReturn<milliseconds>(result, status, length);
+    auto ret = HalResultFactory::fromReturn<milliseconds>(std::move(result), status, length);
     if (ret.isOk()) {
         mCallbackScheduler->schedule(completionCallback, length);
     }
@@ -604,7 +618,7 @@
     sp<V1_3::IVibrator> hal = getHal();
     auto amplitudeResult = hal->supportsAmplitudeControl();
     if (!amplitudeResult.isOk()) {
-        return HalResultFactory::fromReturn<Capabilities>(amplitudeResult, capabilities);
+        return HalResultFactory::fromReturn<Capabilities>(std::move(amplitudeResult), capabilities);
     }
 
     auto externalControlResult = hal->supportsExternalControl();
@@ -619,7 +633,8 @@
         }
     }
 
-    return HalResultFactory::fromReturn<Capabilities>(externalControlResult, capabilities);
+    return HalResultFactory::fromReturn<Capabilities>(std::move(externalControlResult),
+                                                      capabilities);
 }
 
 // -------------------------------------------------------------------------------------------------
diff --git a/services/vibratorservice/VibratorManagerHalController.cpp b/services/vibratorservice/VibratorManagerHalController.cpp
index aa5b7fc..ba35d15 100644
--- a/services/vibratorservice/VibratorManagerHalController.cpp
+++ b/services/vibratorservice/VibratorManagerHalController.cpp
@@ -20,7 +20,7 @@
 
 #include <vibratorservice/VibratorManagerHalController.h>
 
-namespace Aidl = android::hardware::vibrator;
+namespace Aidl = aidl::android::hardware::vibrator;
 
 namespace android {
 
@@ -29,10 +29,15 @@
 std::shared_ptr<ManagerHalWrapper> connectManagerHal(std::shared_ptr<CallbackScheduler> scheduler) {
     static bool gHalExists = true;
     if (gHalExists) {
-        sp<Aidl::IVibratorManager> hal = waitForVintfService<Aidl::IVibratorManager>();
-        if (hal) {
-            ALOGV("Successfully connected to VibratorManager HAL AIDL service.");
-            return std::make_shared<AidlManagerHalWrapper>(std::move(scheduler), hal);
+        auto serviceName = std::string(Aidl::IVibratorManager::descriptor) + "/default";
+        if (AServiceManager_isDeclared(serviceName.c_str())) {
+            std::shared_ptr<Aidl::IVibratorManager> hal = Aidl::IVibratorManager::fromBinder(
+                    ndk::SpAIBinder(AServiceManager_checkService(serviceName.c_str())));
+            if (hal) {
+                ALOGV("Successfully connected to VibratorManager HAL AIDL service.");
+                return std::make_shared<AidlManagerHalWrapper>(std::move(scheduler),
+                                                               std::move(hal));
+            }
         }
     }
 
diff --git a/services/vibratorservice/VibratorManagerHalWrapper.cpp b/services/vibratorservice/VibratorManagerHalWrapper.cpp
index 1341266..93ec781 100644
--- a/services/vibratorservice/VibratorManagerHalWrapper.cpp
+++ b/services/vibratorservice/VibratorManagerHalWrapper.cpp
@@ -20,7 +20,7 @@
 
 #include <vibratorservice/VibratorManagerHalWrapper.h>
 
-namespace Aidl = android::hardware::vibrator;
+namespace Aidl = aidl::android::hardware::vibrator;
 
 namespace android {
 
@@ -75,10 +75,11 @@
 
 std::shared_ptr<HalWrapper> AidlManagerHalWrapper::connectToVibrator(
         int32_t vibratorId, std::shared_ptr<CallbackScheduler> callbackScheduler) {
-    std::function<HalResult<sp<Aidl::IVibrator>>()> reconnectFn = [=, this]() {
-        sp<Aidl::IVibrator> vibrator;
-        auto result = this->getHal()->getVibrator(vibratorId, &vibrator);
-        return HalResultFactory::fromStatus<sp<Aidl::IVibrator>>(result, vibrator);
+    std::function<HalResult<std::shared_ptr<Aidl::IVibrator>>()> reconnectFn = [=, this]() {
+        std::shared_ptr<Aidl::IVibrator> vibrator;
+        auto status = this->getHal()->getVibrator(vibratorId, &vibrator);
+        return HalResultFactory::fromStatus<std::shared_ptr<Aidl::IVibrator>>(std::move(status),
+                                                                              vibrator);
     };
     auto result = reconnectFn();
     if (!result.isOk()) {
@@ -93,11 +94,13 @@
 }
 
 HalResult<void> AidlManagerHalWrapper::ping() {
-    return HalResultFactory::fromStatus(IInterface::asBinder(getHal())->pingBinder());
+    return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
 }
 
 void AidlManagerHalWrapper::tryReconnect() {
-    sp<Aidl::IVibratorManager> newHandle = checkVintfService<Aidl::IVibratorManager>();
+    auto aidlServiceName = std::string(Aidl::IVibratorManager::descriptor) + "/default";
+    std::shared_ptr<Aidl::IVibratorManager> newHandle = Aidl::IVibratorManager::fromBinder(
+            ndk::SpAIBinder(AServiceManager_checkService(aidlServiceName.c_str())));
     if (newHandle) {
         std::lock_guard<std::mutex> lock(mHandleMutex);
         mHandle = std::move(newHandle);
@@ -111,9 +114,9 @@
         return HalResult<ManagerCapabilities>::ok(*mCapabilities);
     }
     int32_t cap = 0;
-    auto result = getHal()->getCapabilities(&cap);
+    auto status = getHal()->getCapabilities(&cap);
     auto capabilities = static_cast<ManagerCapabilities>(cap);
-    auto ret = HalResultFactory::fromStatus<ManagerCapabilities>(result, capabilities);
+    auto ret = HalResultFactory::fromStatus<ManagerCapabilities>(std::move(status), capabilities);
     if (ret.isOk()) {
         // Cache copy of returned value.
         mCapabilities.emplace(ret.value());
@@ -128,8 +131,8 @@
         return HalResult<std::vector<int32_t>>::ok(*mVibratorIds);
     }
     std::vector<int32_t> ids;
-    auto result = getHal()->getVibratorIds(&ids);
-    auto ret = HalResultFactory::fromStatus<std::vector<int32_t>>(result, ids);
+    auto status = getHal()->getVibratorIds(&ids);
+    auto ret = HalResultFactory::fromStatus<std::vector<int32_t>>(std::move(status), ids);
     if (ret.isOk()) {
         // Cache copy of returned value and the individual controllers.
         mVibratorIds.emplace(ret.value());
@@ -178,7 +181,8 @@
     HalResult<ManagerCapabilities> capabilities = getCapabilities();
     bool supportsCallback = capabilities.isOk() &&
             static_cast<int32_t>(capabilities.value() & ManagerCapabilities::TRIGGER_CALLBACK);
-    auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
+    auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
+                               : nullptr;
     return HalResultFactory::fromStatus(getHal()->triggerSynced(cb));
 }
 
@@ -196,7 +200,7 @@
     return ret;
 }
 
-sp<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() {
+std::shared_ptr<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() {
     std::lock_guard<std::mutex> lock(mHandleMutex);
     return mHandle;
 }
diff --git a/services/vibratorservice/benchmarks/Android.bp b/services/vibratorservice/benchmarks/Android.bp
index 5437995..915d6c7 100644
--- a/services/vibratorservice/benchmarks/Android.bp
+++ b/services/vibratorservice/benchmarks/Android.bp
@@ -28,12 +28,12 @@
         "VibratorHalControllerBenchmarks.cpp",
     ],
     shared_libs: [
-        "libbinder",
+        "libbinder_ndk",
         "libhidlbase",
         "liblog",
         "libutils",
         "libvibratorservice",
-        "android.hardware.vibrator-V2-cpp",
+        "android.hardware.vibrator-V3-ndk",
         "android.hardware.vibrator@1.0",
         "android.hardware.vibrator@1.1",
         "android.hardware.vibrator@1.2",
diff --git a/services/vibratorservice/benchmarks/VibratorHalControllerBenchmarks.cpp b/services/vibratorservice/benchmarks/VibratorHalControllerBenchmarks.cpp
index 9b30337..5c7c9f4 100644
--- a/services/vibratorservice/benchmarks/VibratorHalControllerBenchmarks.cpp
+++ b/services/vibratorservice/benchmarks/VibratorHalControllerBenchmarks.cpp
@@ -16,16 +16,15 @@
 
 #define LOG_TAG "VibratorHalControllerBenchmarks"
 
+#include <android/binder_process.h>
 #include <benchmark/benchmark.h>
-#include <binder/ProcessState.h>
 #include <vibratorservice/VibratorHalController.h>
 #include <future>
 
-using ::android::enum_range;
-using ::android::hardware::vibrator::CompositeEffect;
-using ::android::hardware::vibrator::CompositePrimitive;
-using ::android::hardware::vibrator::Effect;
-using ::android::hardware::vibrator::EffectStrength;
+using ::aidl::android::hardware::vibrator::CompositeEffect;
+using ::aidl::android::hardware::vibrator::CompositePrimitive;
+using ::aidl::android::hardware::vibrator::Effect;
+using ::aidl::android::hardware::vibrator::EffectStrength;
 using ::benchmark::Counter;
 using ::benchmark::Fixture;
 using ::benchmark::kMicrosecond;
@@ -115,8 +114,8 @@
 class VibratorBench : public Fixture {
 public:
     void SetUp(State& /*state*/) override {
-        android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
-        android::ProcessState::self()->startThreadPool();
+        ABinderProcess_setThreadPoolMaxThreadCount(1);
+        ABinderProcess_startThreadPool();
         mController.init();
     }
 
@@ -388,11 +387,11 @@
             return;
         }
 
-        for (const auto& effect : enum_range<Effect>()) {
+        for (const auto& effect : ndk::enum_range<Effect>()) {
             if (std::find(supported.begin(), supported.end(), effect) == supported.end()) {
                 continue;
             }
-            for (const auto& strength : enum_range<EffectStrength>()) {
+            for (const auto& strength : ndk::enum_range<EffectStrength>()) {
                 b->Args({static_cast<long>(effect), static_cast<long>(strength)});
             }
         }
@@ -533,7 +532,7 @@
             return;
         }
 
-        for (const auto& primitive : enum_range<CompositePrimitive>()) {
+        for (const auto& primitive : ndk::enum_range<CompositePrimitive>()) {
             if (std::find(supported.begin(), supported.end(), primitive) == supported.end()) {
                 continue;
             }
diff --git a/services/vibratorservice/include/vibratorservice/VibratorHalController.h b/services/vibratorservice/include/vibratorservice/VibratorHalController.h
index f97442d..a1cb3fa 100644
--- a/services/vibratorservice/include/vibratorservice/VibratorHalController.h
+++ b/services/vibratorservice/include/vibratorservice/VibratorHalController.h
@@ -17,8 +17,8 @@
 #ifndef ANDROID_OS_VIBRATORHALCONTROLLER_H
 #define ANDROID_OS_VIBRATORHALCONTROLLER_H
 
+#include <aidl/android/hardware/vibrator/IVibrator.h>
 #include <android-base/thread_annotations.h>
-#include <android/hardware/vibrator/IVibrator.h>
 
 #include <vibratorservice/VibratorCallbackScheduler.h>
 #include <vibratorservice/VibratorHalWrapper.h>
diff --git a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
index 39c4eb4..20979bd 100644
--- a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
+++ b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
@@ -17,10 +17,12 @@
 #ifndef ANDROID_OS_VIBRATORHALWRAPPER_H
 #define ANDROID_OS_VIBRATORHALWRAPPER_H
 
+#include <aidl/android/hardware/vibrator/BnVibratorCallback.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+
 #include <android-base/thread_annotations.h>
+#include <android/binder_manager.h>
 #include <android/hardware/vibrator/1.3/IVibrator.h>
-#include <android/hardware/vibrator/BnVibratorCallback.h>
-#include <android/hardware/vibrator/IVibrator.h>
 #include <binder/IServiceManager.h>
 
 #include <vibratorservice/VibratorCallbackScheduler.h>
@@ -98,43 +100,49 @@
 class HalResultFactory {
 public:
     template <typename T>
-    static HalResult<T> fromStatus(binder::Status status, T data) {
-        return status.isOk() ? HalResult<T>::ok(data) : fromFailedStatus<T>(status);
+    static HalResult<T> fromStatus(ndk::ScopedAStatus&& status, T data) {
+        return status.isOk() ? HalResult<T>::ok(std::move(data))
+                             : fromFailedStatus<T>(std::move(status));
     }
 
     template <typename T>
-    static HalResult<T> fromStatus(hardware::vibrator::V1_0::Status status, T data) {
-        return (status == hardware::vibrator::V1_0::Status::OK) ? HalResult<T>::ok(data)
-                                                                : fromFailedStatus<T>(status);
+    static HalResult<T> fromStatus(hardware::vibrator::V1_0::Status&& status, T data) {
+        return (status == hardware::vibrator::V1_0::Status::OK)
+                ? HalResult<T>::ok(std::move(data))
+                : fromFailedStatus<T>(std::move(status));
     }
 
     template <typename T, typename R>
-    static HalResult<T> fromReturn(hardware::Return<R>& ret, T data) {
-        return ret.isOk() ? HalResult<T>::ok(data) : fromFailedReturn<T, R>(ret);
+    static HalResult<T> fromReturn(hardware::Return<R>&& ret, T data) {
+        return ret.isOk() ? HalResult<T>::ok(std::move(data))
+                          : fromFailedReturn<T, R>(std::move(ret));
     }
 
     template <typename T, typename R>
-    static HalResult<T> fromReturn(hardware::Return<R>& ret,
+    static HalResult<T> fromReturn(hardware::Return<R>&& ret,
                                    hardware::vibrator::V1_0::Status status, T data) {
-        return ret.isOk() ? fromStatus<T>(status, data) : fromFailedReturn<T, R>(ret);
+        return ret.isOk() ? fromStatus<T>(std::move(status), std::move(data))
+                          : fromFailedReturn<T, R>(std::move(ret));
     }
 
     static HalResult<void> fromStatus(status_t status) {
-        return (status == android::OK) ? HalResult<void>::ok() : fromFailedStatus<void>(status);
+        return (status == android::OK) ? HalResult<void>::ok()
+                                       : fromFailedStatus<void>(std::move(status));
     }
 
-    static HalResult<void> fromStatus(binder::Status status) {
-        return status.isOk() ? HalResult<void>::ok() : fromFailedStatus<void>(status);
+    static HalResult<void> fromStatus(ndk::ScopedAStatus&& status) {
+        return status.isOk() ? HalResult<void>::ok() : fromFailedStatus<void>(std::move(status));
     }
 
-    static HalResult<void> fromStatus(hardware::vibrator::V1_0::Status status) {
-        return (status == hardware::vibrator::V1_0::Status::OK) ? HalResult<void>::ok()
-                                                                : fromFailedStatus<void>(status);
+    static HalResult<void> fromStatus(hardware::vibrator::V1_0::Status&& status) {
+        return (status == hardware::vibrator::V1_0::Status::OK)
+                ? HalResult<void>::ok()
+                : fromFailedStatus<void>(std::move(status));
     }
 
     template <typename R>
-    static HalResult<void> fromReturn(hardware::Return<R>& ret) {
-        return ret.isOk() ? HalResult<void>::ok() : fromFailedReturn<void, R>(ret);
+    static HalResult<void> fromReturn(hardware::Return<R>&& ret) {
+        return ret.isOk() ? HalResult<void>::ok() : fromFailedReturn<void, R>(std::move(ret));
     }
 
 private:
@@ -146,21 +154,21 @@
     }
 
     template <typename T>
-    static HalResult<T> fromFailedStatus(binder::Status status) {
-        if (status.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION ||
-            status.transactionError() == android::UNKNOWN_TRANSACTION) {
-            // UNKNOWN_TRANSACTION means the HAL implementation is an older version, so this is
-            // the same as the operation being unsupported by this HAL. Should not retry.
+    static HalResult<T> fromFailedStatus(ndk::ScopedAStatus&& status) {
+        if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION ||
+            status.getStatus() == STATUS_UNKNOWN_TRANSACTION) {
+            // STATUS_UNKNOWN_TRANSACTION means the HAL implementation is an older version, so this
+            // is the same as the operation being unsupported by this HAL. Should not retry.
             return HalResult<T>::unsupported();
         }
-        if (status.exceptionCode() == binder::Status::EX_TRANSACTION_FAILED) {
-            return HalResult<T>::transactionFailed(status.toString8().c_str());
+        if (status.getExceptionCode() == EX_TRANSACTION_FAILED) {
+            return HalResult<T>::transactionFailed(status.getMessage());
         }
-        return HalResult<T>::failed(status.toString8().c_str());
+        return HalResult<T>::failed(status.getMessage());
     }
 
     template <typename T>
-    static HalResult<T> fromFailedStatus(hardware::vibrator::V1_0::Status status) {
+    static HalResult<T> fromFailedStatus(hardware::vibrator::V1_0::Status&& status) {
         switch (status) {
             case hardware::vibrator::V1_0::Status::UNSUPPORTED_OPERATION:
                 return HalResult<T>::unsupported();
@@ -171,7 +179,7 @@
     }
 
     template <typename T, typename R>
-    static HalResult<T> fromFailedReturn(hardware::Return<R>& ret) {
+    static HalResult<T> fromFailedReturn(hardware::Return<R>&& ret) {
         return ret.isDeadObject() ? HalResult<T>::transactionFailed(ret.description().c_str())
                                   : HalResult<T>::failed(ret.description().c_str());
     }
@@ -179,14 +187,14 @@
 
 // -------------------------------------------------------------------------------------------------
 
-class HalCallbackWrapper : public hardware::vibrator::BnVibratorCallback {
+class HalCallbackWrapper : public aidl::android::hardware::vibrator::BnVibratorCallback {
 public:
     HalCallbackWrapper(std::function<void()> completionCallback)
           : mCompletionCallback(completionCallback) {}
 
-    binder::Status onComplete() override {
+    ndk::ScopedAStatus onComplete() override {
         mCompletionCallback();
-        return binder::Status::ok();
+        return ndk::ScopedAStatus::ok();
     }
 
 private:
@@ -198,14 +206,15 @@
 // Vibrator HAL capabilities.
 enum class Capabilities : int32_t {
     NONE = 0,
-    ON_CALLBACK = hardware::vibrator::IVibrator::CAP_ON_CALLBACK,
-    PERFORM_CALLBACK = hardware::vibrator::IVibrator::CAP_PERFORM_CALLBACK,
-    AMPLITUDE_CONTROL = hardware::vibrator::IVibrator::CAP_AMPLITUDE_CONTROL,
-    EXTERNAL_CONTROL = hardware::vibrator::IVibrator::CAP_EXTERNAL_CONTROL,
-    EXTERNAL_AMPLITUDE_CONTROL = hardware::vibrator::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL,
-    COMPOSE_EFFECTS = hardware::vibrator::IVibrator::CAP_COMPOSE_EFFECTS,
-    COMPOSE_PWLE_EFFECTS = hardware::vibrator::IVibrator::CAP_COMPOSE_PWLE_EFFECTS,
-    ALWAYS_ON_CONTROL = hardware::vibrator::IVibrator::CAP_ALWAYS_ON_CONTROL,
+    ON_CALLBACK = aidl::android::hardware::vibrator::IVibrator::CAP_ON_CALLBACK,
+    PERFORM_CALLBACK = aidl::android::hardware::vibrator::IVibrator::CAP_PERFORM_CALLBACK,
+    AMPLITUDE_CONTROL = aidl::android::hardware::vibrator::IVibrator::CAP_AMPLITUDE_CONTROL,
+    EXTERNAL_CONTROL = aidl::android::hardware::vibrator::IVibrator::CAP_EXTERNAL_CONTROL,
+    EXTERNAL_AMPLITUDE_CONTROL =
+            aidl::android::hardware::vibrator::IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL,
+    COMPOSE_EFFECTS = aidl::android::hardware::vibrator::IVibrator::CAP_COMPOSE_EFFECTS,
+    COMPOSE_PWLE_EFFECTS = aidl::android::hardware::vibrator::IVibrator::CAP_COMPOSE_PWLE_EFFECTS,
+    ALWAYS_ON_CONTROL = aidl::android::hardware::vibrator::IVibrator::CAP_ALWAYS_ON_CONTROL,
 };
 
 inline Capabilities operator|(Capabilities lhs, Capabilities rhs) {
@@ -230,10 +239,15 @@
 
 class Info {
 public:
+    using Effect = aidl::android::hardware::vibrator::Effect;
+    using EffectStrength = aidl::android::hardware::vibrator::EffectStrength;
+    using CompositePrimitive = aidl::android::hardware::vibrator::CompositePrimitive;
+    using Braking = aidl::android::hardware::vibrator::Braking;
+
     const HalResult<Capabilities> capabilities;
-    const HalResult<std::vector<hardware::vibrator::Effect>> supportedEffects;
-    const HalResult<std::vector<hardware::vibrator::Braking>> supportedBraking;
-    const HalResult<std::vector<hardware::vibrator::CompositePrimitive>> supportedPrimitives;
+    const HalResult<std::vector<Effect>> supportedEffects;
+    const HalResult<std::vector<Braking>> supportedBraking;
+    const HalResult<std::vector<CompositePrimitive>> supportedPrimitives;
     const HalResult<std::vector<std::chrono::milliseconds>> primitiveDurations;
     const HalResult<std::chrono::milliseconds> primitiveDelayMax;
     const HalResult<std::chrono::milliseconds> pwlePrimitiveDurationMax;
@@ -247,12 +261,9 @@
 
     void logFailures() const {
         logFailure<Capabilities>(capabilities, "getCapabilities");
-        logFailure<std::vector<hardware::vibrator::Effect>>(supportedEffects,
-                                                            "getSupportedEffects");
-        logFailure<std::vector<hardware::vibrator::Braking>>(supportedBraking,
-                                                             "getSupportedBraking");
-        logFailure<std::vector<hardware::vibrator::CompositePrimitive>>(supportedPrimitives,
-                                                                        "getSupportedPrimitives");
+        logFailure<std::vector<Effect>>(supportedEffects, "getSupportedEffects");
+        logFailure<std::vector<Braking>>(supportedBraking, "getSupportedBraking");
+        logFailure<std::vector<CompositePrimitive>>(supportedPrimitives, "getSupportedPrimitives");
         logFailure<std::vector<std::chrono::milliseconds>>(primitiveDurations,
                                                            "getPrimitiveDuration");
         logFailure<std::chrono::milliseconds>(primitiveDelayMax, "getPrimitiveDelayMax");
@@ -309,12 +320,12 @@
     // Create a transaction failed results as default so we can retry on the first time we get them.
     static const constexpr char* MSG = "never loaded";
     HalResult<Capabilities> mCapabilities = HalResult<Capabilities>::transactionFailed(MSG);
-    HalResult<std::vector<hardware::vibrator::Effect>> mSupportedEffects =
-            HalResult<std::vector<hardware::vibrator::Effect>>::transactionFailed(MSG);
-    HalResult<std::vector<hardware::vibrator::Braking>> mSupportedBraking =
-            HalResult<std::vector<hardware::vibrator::Braking>>::transactionFailed(MSG);
-    HalResult<std::vector<hardware::vibrator::CompositePrimitive>> mSupportedPrimitives =
-            HalResult<std::vector<hardware::vibrator::CompositePrimitive>>::transactionFailed(MSG);
+    HalResult<std::vector<Info::Effect>> mSupportedEffects =
+            HalResult<std::vector<Info::Effect>>::transactionFailed(MSG);
+    HalResult<std::vector<Info::Braking>> mSupportedBraking =
+            HalResult<std::vector<Info::Braking>>::transactionFailed(MSG);
+    HalResult<std::vector<Info::CompositePrimitive>> mSupportedPrimitives =
+            HalResult<std::vector<Info::CompositePrimitive>>::transactionFailed(MSG);
     HalResult<std::vector<std::chrono::milliseconds>> mPrimitiveDurations =
             HalResult<std::vector<std::chrono::milliseconds>>::transactionFailed(MSG);
     HalResult<std::chrono::milliseconds> mPrimitiveDelayMax =
@@ -336,6 +347,14 @@
 // Wrapper for Vibrator HAL handlers.
 class HalWrapper {
 public:
+    using Effect = aidl::android::hardware::vibrator::Effect;
+    using EffectStrength = aidl::android::hardware::vibrator::EffectStrength;
+    using VendorEffect = aidl::android::hardware::vibrator::VendorEffect;
+    using CompositePrimitive = aidl::android::hardware::vibrator::CompositePrimitive;
+    using CompositeEffect = aidl::android::hardware::vibrator::CompositeEffect;
+    using Braking = aidl::android::hardware::vibrator::Braking;
+    using PrimitivePwle = aidl::android::hardware::vibrator::PrimitivePwle;
+
     explicit HalWrapper(std::shared_ptr<CallbackScheduler> scheduler)
           : mCallbackScheduler(std::move(scheduler)) {}
     virtual ~HalWrapper() = default;
@@ -355,21 +374,22 @@
     virtual HalResult<void> setAmplitude(float amplitude) = 0;
     virtual HalResult<void> setExternalControl(bool enabled) = 0;
 
-    virtual HalResult<void> alwaysOnEnable(int32_t id, hardware::vibrator::Effect effect,
-                                           hardware::vibrator::EffectStrength strength) = 0;
+    virtual HalResult<void> alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) = 0;
     virtual HalResult<void> alwaysOnDisable(int32_t id) = 0;
 
     virtual HalResult<std::chrono::milliseconds> performEffect(
-            hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
+            Effect effect, EffectStrength strength,
             const std::function<void()>& completionCallback) = 0;
 
+    virtual HalResult<void> performVendorEffect(const VendorEffect& effect,
+                                                const std::function<void()>& completionCallback);
+
     virtual HalResult<std::chrono::milliseconds> performComposedEffect(
-            const std::vector<hardware::vibrator::CompositeEffect>& primitives,
+            const std::vector<CompositeEffect>& primitives,
             const std::function<void()>& completionCallback);
 
-    virtual HalResult<void> performPwleEffect(
-            const std::vector<hardware::vibrator::PrimitivePwle>& primitives,
-            const std::function<void()>& completionCallback);
+    virtual HalResult<void> performPwleEffect(const std::vector<PrimitivePwle>& primitives,
+                                              const std::function<void()>& completionCallback);
 
 protected:
     // Shared pointer to allow CallbackScheduler to outlive this wrapper.
@@ -381,12 +401,11 @@
 
     // Request vibrator info to HAL skipping cache.
     virtual HalResult<Capabilities> getCapabilitiesInternal() = 0;
-    virtual HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffectsInternal();
-    virtual HalResult<std::vector<hardware::vibrator::Braking>> getSupportedBrakingInternal();
-    virtual HalResult<std::vector<hardware::vibrator::CompositePrimitive>>
-    getSupportedPrimitivesInternal();
+    virtual HalResult<std::vector<Effect>> getSupportedEffectsInternal();
+    virtual HalResult<std::vector<Braking>> getSupportedBrakingInternal();
+    virtual HalResult<std::vector<CompositePrimitive>> getSupportedPrimitivesInternal();
     virtual HalResult<std::vector<std::chrono::milliseconds>> getPrimitiveDurationsInternal(
-            const std::vector<hardware::vibrator::CompositePrimitive>& supportedPrimitives);
+            const std::vector<CompositePrimitive>& supportedPrimitives);
     virtual HalResult<std::chrono::milliseconds> getPrimitiveDelayMaxInternal();
     virtual HalResult<std::chrono::milliseconds> getPrimitiveDurationMaxInternal();
     virtual HalResult<int32_t> getCompositionSizeMaxInternal();
@@ -405,12 +424,17 @@
 // Wrapper for the AIDL Vibrator HAL.
 class AidlHalWrapper : public HalWrapper {
 public:
+    using IVibrator = aidl::android::hardware::vibrator::IVibrator;
+    using reconnect_fn = std::function<HalResult<std::shared_ptr<IVibrator>>()>;
+
     AidlHalWrapper(
-            std::shared_ptr<CallbackScheduler> scheduler, sp<hardware::vibrator::IVibrator> handle,
-            std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> reconnectFn =
+            std::shared_ptr<CallbackScheduler> scheduler, std::shared_ptr<IVibrator> handle,
+            reconnect_fn reconnectFn =
                     []() {
-                        return HalResult<sp<hardware::vibrator::IVibrator>>::ok(
-                                checkVintfService<hardware::vibrator::IVibrator>());
+                        auto serviceName = std::string(IVibrator::descriptor) + "/default";
+                        auto hal = IVibrator::fromBinder(
+                                ndk::SpAIBinder(AServiceManager_checkService(serviceName.c_str())));
+                        return HalResult<std::shared_ptr<IVibrator>>::ok(std::move(hal));
                     })
           : HalWrapper(std::move(scheduler)),
             mReconnectFn(reconnectFn),
@@ -427,32 +451,33 @@
     HalResult<void> setAmplitude(float amplitude) override final;
     HalResult<void> setExternalControl(bool enabled) override final;
 
-    HalResult<void> alwaysOnEnable(int32_t id, hardware::vibrator::Effect effect,
-                                   hardware::vibrator::EffectStrength strength) override final;
+    HalResult<void> alwaysOnEnable(int32_t id, Effect effect,
+                                   EffectStrength strength) override final;
     HalResult<void> alwaysOnDisable(int32_t id) override final;
 
     HalResult<std::chrono::milliseconds> performEffect(
-            hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
+            Effect effect, EffectStrength strength,
+            const std::function<void()>& completionCallback) override final;
+
+    HalResult<void> performVendorEffect(
+            const VendorEffect& effect,
             const std::function<void()>& completionCallback) override final;
 
     HalResult<std::chrono::milliseconds> performComposedEffect(
-            const std::vector<hardware::vibrator::CompositeEffect>& primitives,
+            const std::vector<CompositeEffect>& primitives,
             const std::function<void()>& completionCallback) override final;
 
     HalResult<void> performPwleEffect(
-            const std::vector<hardware::vibrator::PrimitivePwle>& primitives,
+            const std::vector<PrimitivePwle>& primitives,
             const std::function<void()>& completionCallback) override final;
 
 protected:
     HalResult<Capabilities> getCapabilitiesInternal() override final;
-    HalResult<std::vector<hardware::vibrator::Effect>> getSupportedEffectsInternal() override final;
-    HalResult<std::vector<hardware::vibrator::Braking>> getSupportedBrakingInternal()
-            override final;
-    HalResult<std::vector<hardware::vibrator::CompositePrimitive>> getSupportedPrimitivesInternal()
-            override final;
+    HalResult<std::vector<Effect>> getSupportedEffectsInternal() override final;
+    HalResult<std::vector<Braking>> getSupportedBrakingInternal() override final;
+    HalResult<std::vector<CompositePrimitive>> getSupportedPrimitivesInternal() override final;
     HalResult<std::vector<std::chrono::milliseconds>> getPrimitiveDurationsInternal(
-            const std::vector<hardware::vibrator::CompositePrimitive>& supportedPrimitives)
-            override final;
+            const std::vector<CompositePrimitive>& supportedPrimitives) override final;
     HalResult<std::chrono::milliseconds> getPrimitiveDelayMaxInternal() override final;
     HalResult<std::chrono::milliseconds> getPrimitiveDurationMaxInternal() override final;
     HalResult<int32_t> getCompositionSizeMaxInternal() override final;
@@ -464,11 +489,11 @@
     HalResult<std::vector<float>> getMaxAmplitudesInternal() override final;
 
 private:
-    const std::function<HalResult<sp<hardware::vibrator::IVibrator>>()> mReconnectFn;
+    const reconnect_fn mReconnectFn;
     std::mutex mHandleMutex;
-    sp<hardware::vibrator::IVibrator> mHandle GUARDED_BY(mHandleMutex);
+    std::shared_ptr<IVibrator> mHandle GUARDED_BY(mHandleMutex);
 
-    sp<hardware::vibrator::IVibrator> getHal();
+    std::shared_ptr<IVibrator> getHal();
 };
 
 // Wrapper for the HDIL Vibrator HALs.
@@ -489,8 +514,8 @@
     HalResult<void> setAmplitude(float amplitude) override final;
     virtual HalResult<void> setExternalControl(bool enabled) override;
 
-    HalResult<void> alwaysOnEnable(int32_t id, hardware::vibrator::Effect effect,
-                                   hardware::vibrator::EffectStrength strength) override final;
+    HalResult<void> alwaysOnEnable(int32_t id, HalWrapper::Effect effect,
+                                   HalWrapper::EffectStrength strength) override final;
     HalResult<void> alwaysOnDisable(int32_t id) override final;
 
 protected:
@@ -506,8 +531,7 @@
 
     template <class T>
     HalResult<std::chrono::milliseconds> performInternal(
-            perform_fn<T> performFn, sp<I> handle, T effect,
-            hardware::vibrator::EffectStrength strength,
+            perform_fn<T> performFn, sp<I> handle, T effect, HalWrapper::EffectStrength strength,
             const std::function<void()>& completionCallback);
 
     sp<I> getHal();
@@ -523,7 +547,7 @@
     virtual ~HidlHalWrapperV1_0() = default;
 
     HalResult<std::chrono::milliseconds> performEffect(
-            hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
+            HalWrapper::Effect effect, HalWrapper::EffectStrength strength,
             const std::function<void()>& completionCallback) override final;
 };
 
@@ -537,7 +561,7 @@
     virtual ~HidlHalWrapperV1_1() = default;
 
     HalResult<std::chrono::milliseconds> performEffect(
-            hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
+            HalWrapper::Effect effect, HalWrapper::EffectStrength strength,
             const std::function<void()>& completionCallback) override final;
 };
 
@@ -551,7 +575,7 @@
     virtual ~HidlHalWrapperV1_2() = default;
 
     HalResult<std::chrono::milliseconds> performEffect(
-            hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
+            HalWrapper::Effect effect, HalWrapper::EffectStrength strength,
             const std::function<void()>& completionCallback) override final;
 };
 
@@ -567,7 +591,7 @@
     HalResult<void> setExternalControl(bool enabled) override final;
 
     HalResult<std::chrono::milliseconds> performEffect(
-            hardware::vibrator::Effect effect, hardware::vibrator::EffectStrength strength,
+            HalWrapper::Effect effect, HalWrapper::EffectStrength strength,
             const std::function<void()>& completionCallback) override final;
 
 protected:
diff --git a/services/vibratorservice/include/vibratorservice/VibratorManagerHalController.h b/services/vibratorservice/include/vibratorservice/VibratorManagerHalController.h
index 9168565..70c846b 100644
--- a/services/vibratorservice/include/vibratorservice/VibratorManagerHalController.h
+++ b/services/vibratorservice/include/vibratorservice/VibratorManagerHalController.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_OS_VIBRATOR_MANAGER_HAL_CONTROLLER_H
 #define ANDROID_OS_VIBRATOR_MANAGER_HAL_CONTROLLER_H
 
-#include <android/hardware/vibrator/IVibratorManager.h>
+#include <aidl/android/hardware/vibrator/IVibratorManager.h>
 #include <vibratorservice/VibratorHalController.h>
 #include <vibratorservice/VibratorManagerHalWrapper.h>
 #include <unordered_map>
diff --git a/services/vibratorservice/include/vibratorservice/VibratorManagerHalWrapper.h b/services/vibratorservice/include/vibratorservice/VibratorManagerHalWrapper.h
index 563f55e..9e3f221 100644
--- a/services/vibratorservice/include/vibratorservice/VibratorManagerHalWrapper.h
+++ b/services/vibratorservice/include/vibratorservice/VibratorManagerHalWrapper.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_OS_VIBRATOR_MANAGER_HAL_WRAPPER_H
 #define ANDROID_OS_VIBRATOR_MANAGER_HAL_WRAPPER_H
 
-#include <android/hardware/vibrator/IVibratorManager.h>
+#include <aidl/android/hardware/vibrator/IVibratorManager.h>
 #include <vibratorservice/VibratorHalController.h>
 #include <unordered_map>
 
@@ -28,14 +28,17 @@
 // VibratorManager HAL capabilities.
 enum class ManagerCapabilities : int32_t {
     NONE = 0,
-    SYNC = hardware::vibrator::IVibratorManager::CAP_SYNC,
-    PREPARE_ON = hardware::vibrator::IVibratorManager::CAP_PREPARE_ON,
-    PREPARE_PERFORM = hardware::vibrator::IVibratorManager::CAP_PREPARE_PERFORM,
-    PREPARE_COMPOSE = hardware::vibrator::IVibratorManager::CAP_PREPARE_COMPOSE,
-    MIXED_TRIGGER_ON = hardware::vibrator::IVibratorManager::IVibratorManager::CAP_MIXED_TRIGGER_ON,
-    MIXED_TRIGGER_PERFORM = hardware::vibrator::IVibratorManager::CAP_MIXED_TRIGGER_PERFORM,
-    MIXED_TRIGGER_COMPOSE = hardware::vibrator::IVibratorManager::CAP_MIXED_TRIGGER_COMPOSE,
-    TRIGGER_CALLBACK = hardware::vibrator::IVibratorManager::CAP_TRIGGER_CALLBACK
+    SYNC = aidl::android::hardware::vibrator::IVibratorManager::CAP_SYNC,
+    PREPARE_ON = aidl::android::hardware::vibrator::IVibratorManager::CAP_PREPARE_ON,
+    PREPARE_PERFORM = aidl::android::hardware::vibrator::IVibratorManager::CAP_PREPARE_PERFORM,
+    PREPARE_COMPOSE = aidl::android::hardware::vibrator::IVibratorManager::CAP_PREPARE_COMPOSE,
+    MIXED_TRIGGER_ON = aidl::android::hardware::vibrator::IVibratorManager::IVibratorManager::
+            CAP_MIXED_TRIGGER_ON,
+    MIXED_TRIGGER_PERFORM =
+            aidl::android::hardware::vibrator::IVibratorManager::CAP_MIXED_TRIGGER_PERFORM,
+    MIXED_TRIGGER_COMPOSE =
+            aidl::android::hardware::vibrator::IVibratorManager::CAP_MIXED_TRIGGER_COMPOSE,
+    TRIGGER_CALLBACK = aidl::android::hardware::vibrator::IVibratorManager::CAP_TRIGGER_CALLBACK
 };
 
 inline ManagerCapabilities operator|(ManagerCapabilities lhs, ManagerCapabilities rhs) {
@@ -106,8 +109,10 @@
 // Wrapper for the AIDL VibratorManager HAL.
 class AidlManagerHalWrapper : public ManagerHalWrapper {
 public:
+    using VibratorManager = aidl::android::hardware::vibrator::IVibratorManager;
+
     explicit AidlManagerHalWrapper(std::shared_ptr<CallbackScheduler> callbackScheduler,
-                                   sp<hardware::vibrator::IVibratorManager> handle)
+                                   std::shared_ptr<VibratorManager> handle)
           : mHandle(std::move(handle)), mCallbackScheduler(callbackScheduler) {}
     virtual ~AidlManagerHalWrapper() = default;
 
@@ -126,14 +131,14 @@
     std::mutex mHandleMutex;
     std::mutex mCapabilitiesMutex;
     std::mutex mVibratorsMutex;
-    sp<hardware::vibrator::IVibratorManager> mHandle GUARDED_BY(mHandleMutex);
+    std::shared_ptr<VibratorManager> mHandle GUARDED_BY(mHandleMutex);
     std::optional<ManagerCapabilities> mCapabilities GUARDED_BY(mCapabilitiesMutex);
     std::optional<std::vector<int32_t>> mVibratorIds GUARDED_BY(mVibratorsMutex);
     std::unordered_map<int32_t, std::shared_ptr<HalController>> mVibrators
             GUARDED_BY(mVibratorsMutex);
     std::shared_ptr<CallbackScheduler> mCallbackScheduler;
 
-    sp<hardware::vibrator::IVibratorManager> getHal();
+    std::shared_ptr<VibratorManager> getHal();
     std::shared_ptr<HalWrapper> connectToVibrator(int32_t vibratorId,
                                                   std::shared_ptr<CallbackScheduler> scheduler);
 };
diff --git a/services/vibratorservice/test/Android.bp b/services/vibratorservice/test/Android.bp
index be71dc2..92527eb 100644
--- a/services/vibratorservice/test/Android.bp
+++ b/services/vibratorservice/test/Android.bp
@@ -44,12 +44,12 @@
     ],
     shared_libs: [
         "libbase",
-        "libbinder",
+        "libbinder_ndk",
         "libhidlbase",
         "liblog",
         "libvibratorservice",
         "libutils",
-        "android.hardware.vibrator-V2-cpp",
+        "android.hardware.vibrator-V3-ndk",
         "android.hardware.vibrator@1.0",
         "android.hardware.vibrator@1.1",
         "android.hardware.vibrator@1.2",
diff --git a/services/vibratorservice/test/VibratorHalControllerTest.cpp b/services/vibratorservice/test/VibratorHalControllerTest.cpp
index 15fde91..f4c2898 100644
--- a/services/vibratorservice/test/VibratorHalControllerTest.cpp
+++ b/services/vibratorservice/test/VibratorHalControllerTest.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "VibratorHalControllerTest"
 
-#include <android/hardware/vibrator/IVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
 #include <cutils/atomic.h>
 
 #include <gmock/gmock.h>
@@ -29,10 +29,11 @@
 #include <vibratorservice/VibratorHalController.h>
 #include <vibratorservice/VibratorHalWrapper.h>
 
+#include "test_mocks.h"
 #include "test_utils.h"
 
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
 
 using std::chrono::milliseconds;
 
@@ -46,41 +47,12 @@
 
 // -------------------------------------------------------------------------------------------------
 
-class MockHalWrapper : public vibrator::HalWrapper {
-public:
-    MockHalWrapper(std::shared_ptr<vibrator::CallbackScheduler> scheduler)
-          : HalWrapper(scheduler) {}
-    virtual ~MockHalWrapper() = default;
-
-    MOCK_METHOD(vibrator::HalResult<void>, ping, (), (override));
-    MOCK_METHOD(void, tryReconnect, (), (override));
-    MOCK_METHOD(vibrator::HalResult<void>, on,
-                (milliseconds timeout, const std::function<void()>& completionCallback),
-                (override));
-    MOCK_METHOD(vibrator::HalResult<void>, off, (), (override));
-    MOCK_METHOD(vibrator::HalResult<void>, setAmplitude, (float amplitude), (override));
-    MOCK_METHOD(vibrator::HalResult<void>, setExternalControl, (bool enabled), (override));
-    MOCK_METHOD(vibrator::HalResult<void>, alwaysOnEnable,
-                (int32_t id, Effect effect, EffectStrength strength), (override));
-    MOCK_METHOD(vibrator::HalResult<void>, alwaysOnDisable, (int32_t id), (override));
-    MOCK_METHOD(vibrator::HalResult<milliseconds>, performEffect,
-                (Effect effect, EffectStrength strength,
-                 const std::function<void()>& completionCallback),
-                (override));
-    MOCK_METHOD(vibrator::HalResult<vibrator::Capabilities>, getCapabilitiesInternal, (),
-                (override));
-
-    vibrator::CallbackScheduler* getCallbackScheduler() { return mCallbackScheduler.get(); }
-};
-
-// -------------------------------------------------------------------------------------------------
-
 class VibratorHalControllerTest : public Test {
 public:
     void SetUp() override {
         mConnectCounter = 0;
         auto callbackScheduler = std::make_shared<vibrator::CallbackScheduler>();
-        mMockHal = std::make_shared<StrictMock<MockHalWrapper>>(callbackScheduler);
+        mMockHal = std::make_shared<StrictMock<vibrator::MockHalWrapper>>(callbackScheduler);
         mController = std::make_unique<
                 vibrator::HalController>(std::move(callbackScheduler),
                                          [&](std::shared_ptr<vibrator::CallbackScheduler>) {
@@ -92,7 +64,7 @@
 
 protected:
     int32_t mConnectCounter;
-    std::shared_ptr<MockHalWrapper> mMockHal;
+    std::shared_ptr<vibrator::MockHalWrapper> mMockHal;
     std::unique_ptr<vibrator::HalController> mController;
 };
 
diff --git a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
index 03c9e77..7bcc59a 100644
--- a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
@@ -16,7 +16,8 @@
 
 #define LOG_TAG "VibratorHalWrapperAidlTest"
 
-#include <android/hardware/vibrator/IVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+#include <android/persistable_bundle_aidl.h>
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -27,18 +28,19 @@
 #include <vibratorservice/VibratorCallbackScheduler.h>
 #include <vibratorservice/VibratorHalWrapper.h>
 
+#include "test_mocks.h"
 #include "test_utils.h"
 
-using android::binder::Status;
-
-using android::hardware::vibrator::Braking;
-using android::hardware::vibrator::CompositeEffect;
-using android::hardware::vibrator::CompositePrimitive;
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
-using android::hardware::vibrator::IVibrator;
-using android::hardware::vibrator::IVibratorCallback;
-using android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::Braking;
+using aidl::android::hardware::vibrator::CompositeEffect;
+using aidl::android::hardware::vibrator::CompositePrimitive;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::IVibrator;
+using aidl::android::hardware::vibrator::IVibratorCallback;
+using aidl::android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::VendorEffect;
+using aidl::android::os::PersistableBundle;
 
 using namespace android;
 using namespace std::chrono_literals;
@@ -46,61 +48,10 @@
 
 // -------------------------------------------------------------------------------------------------
 
-class MockBinder : public BBinder {
-public:
-    MOCK_METHOD(status_t, linkToDeath,
-                (const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags), (override));
-    MOCK_METHOD(status_t, unlinkToDeath,
-                (const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
-                 wp<DeathRecipient>* outRecipient),
-                (override));
-    MOCK_METHOD(status_t, pingBinder, (), (override));
-};
-
-class MockIVibrator : public IVibrator {
-public:
-    MOCK_METHOD(Status, getCapabilities, (int32_t * ret), (override));
-    MOCK_METHOD(Status, off, (), (override));
-    MOCK_METHOD(Status, on, (int32_t timeout, const sp<IVibratorCallback>& cb), (override));
-    MOCK_METHOD(Status, perform,
-                (Effect e, EffectStrength s, const sp<IVibratorCallback>& cb, int32_t* ret),
-                (override));
-    MOCK_METHOD(Status, getSupportedEffects, (std::vector<Effect> * ret), (override));
-    MOCK_METHOD(Status, setAmplitude, (float amplitude), (override));
-    MOCK_METHOD(Status, setExternalControl, (bool enabled), (override));
-    MOCK_METHOD(Status, getCompositionDelayMax, (int32_t * ret), (override));
-    MOCK_METHOD(Status, getCompositionSizeMax, (int32_t * ret), (override));
-    MOCK_METHOD(Status, getSupportedPrimitives, (std::vector<CompositePrimitive> * ret),
-                (override));
-    MOCK_METHOD(Status, getPrimitiveDuration, (CompositePrimitive p, int32_t* ret), (override));
-    MOCK_METHOD(Status, compose,
-                (const std::vector<CompositeEffect>& e, const sp<IVibratorCallback>& cb),
-                (override));
-    MOCK_METHOD(Status, composePwle,
-                (const std::vector<PrimitivePwle>& e, const sp<IVibratorCallback>& cb), (override));
-    MOCK_METHOD(Status, getSupportedAlwaysOnEffects, (std::vector<Effect> * ret), (override));
-    MOCK_METHOD(Status, alwaysOnEnable, (int32_t id, Effect e, EffectStrength s), (override));
-    MOCK_METHOD(Status, alwaysOnDisable, (int32_t id), (override));
-    MOCK_METHOD(Status, getQFactor, (float * ret), (override));
-    MOCK_METHOD(Status, getResonantFrequency, (float * ret), (override));
-    MOCK_METHOD(Status, getFrequencyResolution, (float* ret), (override));
-    MOCK_METHOD(Status, getFrequencyMinimum, (float* ret), (override));
-    MOCK_METHOD(Status, getBandwidthAmplitudeMap, (std::vector<float> * ret), (override));
-    MOCK_METHOD(Status, getPwlePrimitiveDurationMax, (int32_t * ret), (override));
-    MOCK_METHOD(Status, getPwleCompositionSizeMax, (int32_t * ret), (override));
-    MOCK_METHOD(Status, getSupportedBraking, (std::vector<Braking> * ret), (override));
-    MOCK_METHOD(int32_t, getInterfaceVersion, (), (override));
-    MOCK_METHOD(std::string, getInterfaceHash, (), (override));
-    MOCK_METHOD(IBinder*, onAsBinder, (), (override));
-};
-
-// -------------------------------------------------------------------------------------------------
-
 class VibratorHalWrapperAidlTest : public Test {
 public:
     void SetUp() override {
-        mMockBinder = new StrictMock<MockBinder>();
-        mMockHal = new StrictMock<MockIVibrator>();
+        mMockHal = ndk::SharedRefBase::make<StrictMock<vibrator::MockIVibrator>>();
         mMockScheduler = std::make_shared<StrictMock<vibrator::MockCallbackScheduler>>();
         mWrapper = std::make_unique<vibrator::AidlHalWrapper>(mMockScheduler, mMockHal);
         ASSERT_NE(mWrapper, nullptr);
@@ -109,54 +60,28 @@
 protected:
     std::shared_ptr<StrictMock<vibrator::MockCallbackScheduler>> mMockScheduler = nullptr;
     std::unique_ptr<vibrator::HalWrapper> mWrapper = nullptr;
-    sp<StrictMock<MockIVibrator>> mMockHal = nullptr;
-    sp<StrictMock<MockBinder>> mMockBinder = nullptr;
+    std::shared_ptr<StrictMock<vibrator::MockIVibrator>> mMockHal = nullptr;
 };
 
 // -------------------------------------------------------------------------------------------------
 
-ACTION(TriggerCallbackInArg1) {
-    if (arg1 != nullptr) {
-        arg1->onComplete();
-    }
-}
-
-ACTION(TriggerCallbackInArg2) {
-    if (arg2 != nullptr) {
-        arg2->onComplete();
-    }
-}
-
-TEST_F(VibratorHalWrapperAidlTest, TestPing) {
-    EXPECT_CALL(*mMockHal.get(), onAsBinder())
-            .Times(Exactly(2))
-            .WillRepeatedly(Return(mMockBinder.get()));
-    EXPECT_CALL(*mMockBinder.get(), pingBinder())
-            .Times(Exactly(2))
-            .WillOnce(Return(android::OK))
-            .WillRepeatedly(Return(android::DEAD_OBJECT));
-
-    ASSERT_TRUE(mWrapper->ping().isOk());
-    ASSERT_TRUE(mWrapper->ping().isFailed());
-}
-
 TEST_F(VibratorHalWrapperAidlTest, TestOnWithCallbackSupport) {
     {
         InSequence seq;
         EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
                 .Times(Exactly(1))
-                .WillRepeatedly(
-                        DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK),
+                                Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), on(Eq(10), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
+                .WillOnce(DoAll(WithArg<1>(vibrator::TriggerCallback()),
+                                Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), on(Eq(100), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(
-                        Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)));
         EXPECT_CALL(*mMockHal.get(), on(Eq(1000), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)));
     }
 
     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
@@ -179,20 +104,20 @@
         InSequence seq;
         EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
                 .Times(Exactly(1))
-                .WillRepeatedly(
-                        DoAll(SetArgPointee<0>(IVibrator::CAP_COMPOSE_EFFECTS), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<0>(IVibrator::CAP_COMPOSE_EFFECTS),
+                                Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), on(Eq(10), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status()));
+                .WillOnce(Return(ndk::ScopedAStatus::ok()));
         EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms)))
                 .Times(Exactly(1))
-                .WillRepeatedly(vibrator::TriggerSchedulerCallback());
+                .WillOnce(vibrator::TriggerSchedulerCallback());
         EXPECT_CALL(*mMockHal.get(), on(Eq(11), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)));
         EXPECT_CALL(*mMockHal.get(), on(Eq(12), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)));
     }
 
     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
@@ -211,10 +136,9 @@
 TEST_F(VibratorHalWrapperAidlTest, TestOff) {
     EXPECT_CALL(*mMockHal.get(), off())
             .Times(Exactly(3))
-            .WillOnce(Return(Status()))
-            .WillOnce(
-                    Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)))
-            .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
+            .WillOnce(Return(ndk::ScopedAStatus::ok()))
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)))
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)));
 
     ASSERT_TRUE(mWrapper->off().isOk());
     ASSERT_TRUE(mWrapper->off().isUnsupported());
@@ -224,13 +148,15 @@
 TEST_F(VibratorHalWrapperAidlTest, TestSetAmplitude) {
     {
         InSequence seq;
-        EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(0.1f))).Times(Exactly(1));
+        EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(0.1f)))
+                .Times(Exactly(1))
+                .WillOnce(Return(ndk::ScopedAStatus::ok()));
         EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(0.2f)))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)));
         EXPECT_CALL(*mMockHal.get(), setAmplitude(Eq(0.5f)))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)));
     }
 
     ASSERT_TRUE(mWrapper->setAmplitude(0.1f).isOk());
@@ -241,12 +167,13 @@
 TEST_F(VibratorHalWrapperAidlTest, TestSetExternalControl) {
     {
         InSequence seq;
-        EXPECT_CALL(*mMockHal.get(), setExternalControl(Eq(true))).Times(Exactly(1));
+        EXPECT_CALL(*mMockHal.get(), setExternalControl(Eq(true)))
+                .Times(Exactly(1))
+                .WillOnce(Return(ndk::ScopedAStatus::ok()));
         EXPECT_CALL(*mMockHal.get(), setExternalControl(Eq(false)))
                 .Times(Exactly(2))
-                .WillOnce(Return(
-                        Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)))
-                .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)))
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)));
     }
 
     ASSERT_TRUE(mWrapper->setExternalControl(true).isOk());
@@ -259,15 +186,16 @@
         InSequence seq;
         EXPECT_CALL(*mMockHal.get(),
                     alwaysOnEnable(Eq(1), Eq(Effect::CLICK), Eq(EffectStrength::LIGHT)))
-                .Times(Exactly(1));
+                .Times(Exactly(1))
+                .WillOnce(Return(ndk::ScopedAStatus::ok()));
         EXPECT_CALL(*mMockHal.get(),
                     alwaysOnEnable(Eq(2), Eq(Effect::TICK), Eq(EffectStrength::MEDIUM)))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)));
         EXPECT_CALL(*mMockHal.get(),
                     alwaysOnEnable(Eq(3), Eq(Effect::POP), Eq(EffectStrength::STRONG)))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)));
     }
 
     auto result = mWrapper->alwaysOnEnable(1, Effect::CLICK, EffectStrength::LIGHT);
@@ -281,14 +209,15 @@
 TEST_F(VibratorHalWrapperAidlTest, TestAlwaysOnDisable) {
     {
         InSequence seq;
-        EXPECT_CALL(*mMockHal.get(), alwaysOnDisable(Eq(1))).Times(Exactly(1));
+        EXPECT_CALL(*mMockHal.get(), alwaysOnDisable(Eq(1)))
+                .Times(Exactly(1))
+                .WillOnce(Return(ndk::ScopedAStatus::ok()));
         EXPECT_CALL(*mMockHal.get(), alwaysOnDisable(Eq(2)))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(
-                        Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)));
         EXPECT_CALL(*mMockHal.get(), alwaysOnDisable(Eq(3)))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)));
     }
 
     ASSERT_TRUE(mWrapper->alwaysOnDisable(1).isOk());
@@ -311,66 +240,70 @@
     std::vector<float> amplitudes = {0.f, 1.f, 0.f};
 
     std::vector<std::chrono::milliseconds> primitiveDurations;
-    constexpr auto primitiveRange = enum_range<CompositePrimitive>();
+    constexpr auto primitiveRange = ndk::enum_range<CompositePrimitive>();
     constexpr auto primitiveCount = std::distance(primitiveRange.begin(), primitiveRange.end());
     primitiveDurations.resize(primitiveCount);
     primitiveDurations[static_cast<size_t>(CompositePrimitive::CLICK)] = 10ms;
 
     EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK),
+                            Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getSupportedEffects(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(supportedEffects), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(supportedEffects), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getSupportedBraking(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(supportedBraking), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(supportedBraking), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(supportedPrimitives), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(
+                    DoAll(SetArgPointee<0>(supportedPrimitives), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::CLICK), _))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<1>(10), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<1>(10), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getCompositionSizeMax(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(COMPOSITION_SIZE_MAX), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(COMPOSITION_SIZE_MAX),
+                            Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getCompositionDelayMax(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(PRIMITIVE_DELAY_MAX), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(
+                    DoAll(SetArgPointee<0>(PRIMITIVE_DELAY_MAX), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getPwlePrimitiveDurationMax(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_DURATION_MAX), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(PWLE_DURATION_MAX), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getPwleCompositionSizeMax(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_SIZE_MAX), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(PWLE_SIZE_MAX), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getFrequencyMinimum(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(F_MIN), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(F_MIN), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getResonantFrequency(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(F0), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(F0), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getFrequencyResolution(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(F_RESOLUTION), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(F_RESOLUTION), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getQFactor(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(Q_FACTOR), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(Q_FACTOR), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getBandwidthAmplitudeMap(_))
             .Times(Exactly(2))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(amplitudes), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(amplitudes), Return(ndk::ScopedAStatus::ok())));
 
     vibrator::Info failed = mWrapper->getInfo();
     ASSERT_TRUE(failed.capabilities.isFailed());
@@ -417,46 +350,46 @@
 
     EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK),
+                            Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getSupportedEffects(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(supportedEffects), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(supportedEffects), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getQFactor(_))
             .Times(Exactly(1))
-            .WillRepeatedly(
-                    Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)));
     EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
             .Times(Exactly(1))
-            .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
+            .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)));
     EXPECT_CALL(*mMockHal.get(), getCompositionSizeMax(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(COMPOSITION_SIZE_MAX), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(COMPOSITION_SIZE_MAX),
+                            Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getCompositionDelayMax(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(PRIMITIVE_DELAY_MAX), Return(Status())));
+            .WillOnce(
+                    DoAll(SetArgPointee<0>(PRIMITIVE_DELAY_MAX), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getPwlePrimitiveDurationMax(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_DURATION_MAX), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(PWLE_DURATION_MAX), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getPwleCompositionSizeMax(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(PWLE_SIZE_MAX), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(PWLE_SIZE_MAX), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getFrequencyMinimum(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(F_MIN), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(F_MIN), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getResonantFrequency(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(F0), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(F0), Return(ndk::ScopedAStatus::ok())));
     EXPECT_CALL(*mMockHal.get(), getFrequencyResolution(_))
             .Times(Exactly(1))
-            .WillRepeatedly(
-                    Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)));
     EXPECT_CALL(*mMockHal.get(), getBandwidthAmplitudeMap(_))
             .Times(Exactly(1))
-            .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
+            .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)));
     EXPECT_CALL(*mMockHal.get(), getSupportedBraking(_))
             .Times(Exactly(1))
-            .WillRepeatedly(
-                    Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)));
 
     std::vector<std::thread> threads;
     for (int i = 0; i < 10; i++) {
@@ -487,18 +420,18 @@
         InSequence seq;
         EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
                 .Times(Exactly(1))
-                .WillRepeatedly(
-                        DoAll(SetArgPointee<0>(IVibrator::CAP_PERFORM_CALLBACK), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<0>(IVibrator::CAP_PERFORM_CALLBACK),
+                                Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::CLICK), Eq(EffectStrength::LIGHT), _, _))
                 .Times(Exactly(1))
-                .WillRepeatedly(
-                        DoAll(SetArgPointee<3>(1000), TriggerCallbackInArg2(), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<3>(1000), WithArg<2>(vibrator::TriggerCallback()),
+                                Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::POP), Eq(EffectStrength::MEDIUM), _, _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)));
         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::THUD), Eq(EffectStrength::STRONG), _, _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)));
     }
 
     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
@@ -525,21 +458,20 @@
         InSequence seq;
         EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
                 .Times(Exactly(1))
-                .WillRepeatedly(
-                        DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<0>(IVibrator::CAP_ON_CALLBACK),
+                                Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::CLICK), Eq(EffectStrength::LIGHT), _, _))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<3>(10), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<3>(10), Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockScheduler.get(), schedule(_, Eq(10ms)))
                 .Times(Exactly(1))
-                .WillRepeatedly(vibrator::TriggerSchedulerCallback());
+                .WillOnce(vibrator::TriggerSchedulerCallback());
         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::POP), Eq(EffectStrength::MEDIUM), _, _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(
-                        Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)));
         EXPECT_CALL(*mMockHal.get(), perform(Eq(Effect::THUD), Eq(EffectStrength::STRONG), _, _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)));
     }
 
     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
@@ -560,6 +492,42 @@
     ASSERT_EQ(1, *callbackCounter.get());
 }
 
+TEST_F(VibratorHalWrapperAidlTest, TestPerformVendorEffect) {
+    PersistableBundle vendorData;
+    vendorData.putInt("key", 1);
+    VendorEffect vendorEffect;
+    vendorEffect.vendorData = vendorData;
+    vendorEffect.strength = EffectStrength::MEDIUM;
+    vendorEffect.scale = 0.5f;
+
+    {
+        InSequence seq;
+        EXPECT_CALL(*mMockHal.get(), performVendorEffect(_, _))
+                .Times(Exactly(3))
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)))
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+                .WillOnce(DoAll(WithArg<1>(vibrator::TriggerCallback()),
+                                Return(ndk::ScopedAStatus::ok())));
+    }
+
+    std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
+    auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
+
+    auto result = mWrapper->performVendorEffect(vendorEffect, callback);
+    ASSERT_TRUE(result.isUnsupported());
+    // Callback not triggered on failure
+    ASSERT_EQ(0, *callbackCounter.get());
+
+    result = mWrapper->performVendorEffect(vendorEffect, callback);
+    ASSERT_TRUE(result.isFailed());
+    // Callback not triggered for unsupported
+    ASSERT_EQ(0, *callbackCounter.get());
+
+    result = mWrapper->performVendorEffect(vendorEffect, callback);
+    ASSERT_TRUE(result.isOk());
+    ASSERT_EQ(1, *callbackCounter.get());
+}
+
 TEST_F(VibratorHalWrapperAidlTest, TestPerformComposedEffect) {
     std::vector<CompositePrimitive> supportedPrimitives = {CompositePrimitive::CLICK,
                                                            CompositePrimitive::SPIN,
@@ -576,26 +544,28 @@
         InSequence seq;
         EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<0>(supportedPrimitives), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<0>(supportedPrimitives),
+                                Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::CLICK), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<1>(1), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<1>(1), Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::SPIN), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<1>(2), Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::THUD), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<1>(3), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<1>(3), Return(ndk::ScopedAStatus::ok())));
 
         EXPECT_CALL(*mMockHal.get(), compose(Eq(emptyEffects), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
+                .WillOnce(DoAll(WithArg<1>(vibrator::TriggerCallback()),
+                                Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), compose(Eq(singleEffect), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)));
         EXPECT_CALL(*mMockHal.get(), compose(Eq(multipleEffects), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)));
     }
 
     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
@@ -630,26 +600,32 @@
         InSequence seq;
         EXPECT_CALL(*mMockHal.get(), getSupportedPrimitives(_))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<0>(supportedPrimitives), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<0>(supportedPrimitives),
+                                Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::SPIN), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<1>(2), Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::THUD), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)));
         EXPECT_CALL(*mMockHal.get(), compose(Eq(multipleEffects), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
+                .WillOnce(DoAll(WithArg<1>(vibrator::TriggerCallback()),
+                                Return(ndk::ScopedAStatus::ok())));
 
         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::SPIN), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<1>(2), Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), getPrimitiveDuration(Eq(CompositePrimitive::THUD), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<1>(2), Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), compose(Eq(multipleEffects), _))
                 .Times(Exactly(2))
-                .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
+                // ndk::ScopedAStatus::ok() cannot be copy-constructed so can't use WillRepeatedly
+                .WillOnce(DoAll(WithArg<1>(vibrator::TriggerCallback()),
+                                Return(ndk::ScopedAStatus::ok())))
+                .WillOnce(DoAll(WithArg<1>(vibrator::TriggerCallback()),
+                                Return(ndk::ScopedAStatus::ok())));
     }
 
     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
@@ -680,12 +656,12 @@
         InSequence seq;
         EXPECT_CALL(*mMockHal.get(), composePwle(Eq(emptyPrimitives), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(
-                        Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)));
         EXPECT_CALL(*mMockHal.get(), composePwle(Eq(multiplePrimitives), _))
                 .Times(Exactly(2))
-                .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-                .WillRepeatedly(DoAll(TriggerCallbackInArg1(), Return(Status())));
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+                .WillOnce(DoAll(WithArg<1>(vibrator::TriggerCallback()),
+                                Return(ndk::ScopedAStatus::ok())));
     }
 
     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
index 0c27fc7..9a7c69d 100644
--- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
@@ -16,7 +16,8 @@
 
 #define LOG_TAG "VibratorHalWrapperHidlV1_0Test"
 
-#include <android/hardware/vibrator/IVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+#include <android/persistable_bundle_aidl.h>
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -27,17 +28,20 @@
 #include <vibratorservice/VibratorCallbackScheduler.h>
 #include <vibratorservice/VibratorHalWrapper.h>
 
+#include "test_mocks.h"
 #include "test_utils.h"
 
 namespace V1_0 = android::hardware::vibrator::V1_0;
 
-using android::hardware::vibrator::Braking;
-using android::hardware::vibrator::CompositeEffect;
-using android::hardware::vibrator::CompositePrimitive;
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
-using android::hardware::vibrator::IVibrator;
-using android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::Braking;
+using aidl::android::hardware::vibrator::CompositeEffect;
+using aidl::android::hardware::vibrator::CompositePrimitive;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::IVibrator;
+using aidl::android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::VendorEffect;
+using aidl::android::os::PersistableBundle;
 
 using namespace android;
 using namespace std::chrono_literals;
@@ -316,6 +320,22 @@
     ASSERT_EQ(0, *callbackCounter.get());
 }
 
+TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformVendorEffectUnsupported) {
+    PersistableBundle vendorData; // empty
+    VendorEffect vendorEffect;
+    vendorEffect.vendorData = vendorData;
+    vendorEffect.strength = EffectStrength::LIGHT;
+    vendorEffect.scale = 1.0f;
+
+    std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
+    auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
+
+    ASSERT_TRUE(mWrapper->performVendorEffect(vendorEffect, callback).isUnsupported());
+
+    // No callback is triggered.
+    ASSERT_EQ(0, *callbackCounter.get());
+}
+
 TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformComposedEffectUnsupported) {
     std::vector<CompositeEffect> emptyEffects, singleEffect, multipleEffects;
     singleEffect.push_back(
diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_1Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_1Test.cpp
index d887efc..b0a6537 100644
--- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_1Test.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperHidlV1_1Test.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "VibratorHalWrapperHidlV1_1Test"
 
-#include <android/hardware/vibrator/IVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -26,13 +26,14 @@
 #include <vibratorservice/VibratorCallbackScheduler.h>
 #include <vibratorservice/VibratorHalWrapper.h>
 
+#include "test_mocks.h"
 #include "test_utils.h"
 
 namespace V1_0 = android::hardware::vibrator::V1_0;
 namespace V1_1 = android::hardware::vibrator::V1_1;
 
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
 
 using namespace android;
 using namespace std::chrono_literals;
diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_2Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_2Test.cpp
index 26d9350..dfe3fa0 100644
--- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_2Test.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperHidlV1_2Test.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "VibratorHalWrapperHidlV1_2Test"
 
-#include <android/hardware/vibrator/IVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -26,14 +26,15 @@
 #include <vibratorservice/VibratorCallbackScheduler.h>
 #include <vibratorservice/VibratorHalWrapper.h>
 
+#include "test_mocks.h"
 #include "test_utils.h"
 
 namespace V1_0 = android::hardware::vibrator::V1_0;
 namespace V1_1 = android::hardware::vibrator::V1_1;
 namespace V1_2 = android::hardware::vibrator::V1_2;
 
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
 
 using namespace android;
 using namespace std::chrono_literals;
diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_3Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_3Test.cpp
index a6f1a74..8624332 100644
--- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_3Test.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperHidlV1_3Test.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "VibratorHalWrapperHidlV1_3Test"
 
-#include <android/hardware/vibrator/IVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -27,6 +27,7 @@
 #include <vibratorservice/VibratorCallbackScheduler.h>
 #include <vibratorservice/VibratorHalWrapper.h>
 
+#include "test_mocks.h"
 #include "test_utils.h"
 
 namespace V1_0 = android::hardware::vibrator::V1_0;
@@ -34,9 +35,9 @@
 namespace V1_2 = android::hardware::vibrator::V1_2;
 namespace V1_3 = android::hardware::vibrator::V1_3;
 
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
-using android::hardware::vibrator::IVibrator;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::IVibrator;
 
 using namespace android;
 using namespace std::chrono_literals;
diff --git a/services/vibratorservice/test/VibratorManagerHalControllerTest.cpp b/services/vibratorservice/test/VibratorManagerHalControllerTest.cpp
index 11a8b66..c7214e0 100644
--- a/services/vibratorservice/test/VibratorManagerHalControllerTest.cpp
+++ b/services/vibratorservice/test/VibratorManagerHalControllerTest.cpp
@@ -24,6 +24,7 @@
 
 #include <vibratorservice/VibratorManagerHalController.h>
 
+#include "test_mocks.h"
 #include "test_utils.h"
 
 using android::vibrator::HalController;
@@ -35,6 +36,8 @@
 static const std::vector<int32_t> VIBRATOR_IDS = {1, 2};
 static constexpr int VIBRATOR_ID = 1;
 
+// -------------------------------------------------------------------------------------------------
+
 class MockManagerHalWrapper : public vibrator::ManagerHalWrapper {
 public:
     MOCK_METHOD(void, tryReconnect, (), (override));
@@ -51,6 +54,8 @@
     MOCK_METHOD(vibrator::HalResult<void>, cancelSynced, (), (override));
 };
 
+// -------------------------------------------------------------------------------------------------
+
 class VibratorManagerHalControllerTest : public Test {
 public:
     void SetUp() override {
@@ -106,6 +111,8 @@
     }
 };
 
+// -------------------------------------------------------------------------------------------------
+
 TEST_F(VibratorManagerHalControllerTest, TestInit) {
     mController->init();
     ASSERT_EQ(1, mConnectCounter);
diff --git a/services/vibratorservice/test/VibratorManagerHalWrapperAidlTest.cpp b/services/vibratorservice/test/VibratorManagerHalWrapperAidlTest.cpp
index dffc281..764d9be 100644
--- a/services/vibratorservice/test/VibratorManagerHalWrapperAidlTest.cpp
+++ b/services/vibratorservice/test/VibratorManagerHalWrapperAidlTest.cpp
@@ -23,84 +23,42 @@
 
 #include <vibratorservice/VibratorManagerHalWrapper.h>
 
+#include "test_mocks.h"
 #include "test_utils.h"
 
-using android::binder::Status;
-
-using android::hardware::vibrator::Braking;
-using android::hardware::vibrator::CompositeEffect;
-using android::hardware::vibrator::CompositePrimitive;
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
-using android::hardware::vibrator::IVibrator;
-using android::hardware::vibrator::IVibratorCallback;
-using android::hardware::vibrator::IVibratorManager;
-using android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::Braking;
+using aidl::android::hardware::vibrator::CompositeEffect;
+using aidl::android::hardware::vibrator::CompositePrimitive;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::IVibrator;
+using aidl::android::hardware::vibrator::IVibratorCallback;
+using aidl::android::hardware::vibrator::IVibratorManager;
+using aidl::android::hardware::vibrator::PrimitivePwle;
 
 using namespace android;
 using namespace testing;
 
 static const auto OFF_FN = [](vibrator::HalWrapper* hal) { return hal->off(); };
 
-class MockBinder : public BBinder {
-public:
-    MOCK_METHOD(status_t, linkToDeath,
-                (const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags), (override));
-    MOCK_METHOD(status_t, unlinkToDeath,
-                (const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
-                 wp<DeathRecipient>* outRecipient),
-                (override));
-    MOCK_METHOD(status_t, pingBinder, (), (override));
-};
-
-class MockIVibrator : public IVibrator {
-public:
-    MOCK_METHOD(Status, getCapabilities, (int32_t * ret), (override));
-    MOCK_METHOD(Status, off, (), (override));
-    MOCK_METHOD(Status, on, (int32_t timeout, const sp<IVibratorCallback>& cb), (override));
-    MOCK_METHOD(Status, perform,
-                (Effect e, EffectStrength s, const sp<IVibratorCallback>& cb, int32_t* ret),
-                (override));
-    MOCK_METHOD(Status, getSupportedEffects, (std::vector<Effect> * ret), (override));
-    MOCK_METHOD(Status, setAmplitude, (float amplitude), (override));
-    MOCK_METHOD(Status, setExternalControl, (bool enabled), (override));
-    MOCK_METHOD(Status, getCompositionDelayMax, (int32_t * ret), (override));
-    MOCK_METHOD(Status, getCompositionSizeMax, (int32_t * ret), (override));
-    MOCK_METHOD(Status, getSupportedPrimitives, (std::vector<CompositePrimitive> * ret),
-                (override));
-    MOCK_METHOD(Status, getPrimitiveDuration, (CompositePrimitive p, int32_t* ret), (override));
-    MOCK_METHOD(Status, compose,
-                (const std::vector<CompositeEffect>& e, const sp<IVibratorCallback>& cb),
-                (override));
-    MOCK_METHOD(Status, composePwle,
-                (const std::vector<PrimitivePwle>& e, const sp<IVibratorCallback>& cb), (override));
-    MOCK_METHOD(Status, getSupportedAlwaysOnEffects, (std::vector<Effect> * ret), (override));
-    MOCK_METHOD(Status, alwaysOnEnable, (int32_t id, Effect e, EffectStrength s), (override));
-    MOCK_METHOD(Status, alwaysOnDisable, (int32_t id), (override));
-    MOCK_METHOD(Status, getQFactor, (float * ret), (override));
-    MOCK_METHOD(Status, getResonantFrequency, (float * ret), (override));
-    MOCK_METHOD(Status, getFrequencyResolution, (float* ret), (override));
-    MOCK_METHOD(Status, getFrequencyMinimum, (float* ret), (override));
-    MOCK_METHOD(Status, getBandwidthAmplitudeMap, (std::vector<float> * ret), (override));
-    MOCK_METHOD(Status, getPwlePrimitiveDurationMax, (int32_t * ret), (override));
-    MOCK_METHOD(Status, getPwleCompositionSizeMax, (int32_t * ret), (override));
-    MOCK_METHOD(Status, getSupportedBraking, (std::vector<Braking> * ret), (override));
-    MOCK_METHOD(int32_t, getInterfaceVersion, (), (override));
-    MOCK_METHOD(std::string, getInterfaceHash, (), (override));
-    MOCK_METHOD(IBinder*, onAsBinder, (), (override));
-};
+// -------------------------------------------------------------------------------------------------
 
 class MockIVibratorManager : public IVibratorManager {
 public:
-    MOCK_METHOD(Status, getCapabilities, (int32_t * ret), (override));
-    MOCK_METHOD(Status, getVibratorIds, (std::vector<int32_t> * ret), (override));
-    MOCK_METHOD(Status, getVibrator, (int32_t id, sp<IVibrator>* ret), (override));
-    MOCK_METHOD(Status, prepareSynced, (const std::vector<int32_t>& ids), (override));
-    MOCK_METHOD(Status, triggerSynced, (const sp<IVibratorCallback>& cb), (override));
-    MOCK_METHOD(Status, cancelSynced, (), (override));
-    MOCK_METHOD(int32_t, getInterfaceVersion, (), (override));
-    MOCK_METHOD(std::string, getInterfaceHash, (), (override));
-    MOCK_METHOD(IBinder*, onAsBinder, (), (override));
+    MockIVibratorManager() = default;
+
+    MOCK_METHOD(ndk::ScopedAStatus, getCapabilities, (int32_t * ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getVibratorIds, (std::vector<int32_t> * ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getVibrator, (int32_t id, std::shared_ptr<IVibrator>* ret),
+                (override));
+    MOCK_METHOD(ndk::ScopedAStatus, prepareSynced, (const std::vector<int32_t>& ids), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, triggerSynced, (const std::shared_ptr<IVibratorCallback>& cb),
+                (override));
+    MOCK_METHOD(ndk::ScopedAStatus, cancelSynced, (), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getInterfaceVersion, (int32_t*), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getInterfaceHash, (std::string*), (override));
+    MOCK_METHOD(ndk::SpAIBinder, asBinder, (), (override));
+    MOCK_METHOD(bool, isRemote, (), (override));
 };
 
 // -------------------------------------------------------------------------------------------------
@@ -108,9 +66,8 @@
 class VibratorManagerHalWrapperAidlTest : public Test {
 public:
     void SetUp() override {
-        mMockBinder = new StrictMock<MockBinder>();
-        mMockVibrator = new StrictMock<MockIVibrator>();
-        mMockHal = new StrictMock<MockIVibratorManager>();
+        mMockVibrator = ndk::SharedRefBase::make<StrictMock<vibrator::MockIVibrator>>();
+        mMockHal = ndk::SharedRefBase::make<StrictMock<MockIVibratorManager>>();
         mMockScheduler = std::make_shared<StrictMock<vibrator::MockCallbackScheduler>>();
         mWrapper = std::make_unique<vibrator::AidlManagerHalWrapper>(mMockScheduler, mMockHal);
         ASSERT_NE(mWrapper, nullptr);
@@ -119,9 +76,8 @@
 protected:
     std::shared_ptr<StrictMock<vibrator::MockCallbackScheduler>> mMockScheduler = nullptr;
     std::unique_ptr<vibrator::ManagerHalWrapper> mWrapper = nullptr;
-    sp<StrictMock<MockIVibratorManager>> mMockHal = nullptr;
-    sp<StrictMock<MockIVibrator>> mMockVibrator = nullptr;
-    sp<StrictMock<MockBinder>> mMockBinder = nullptr;
+    std::shared_ptr<StrictMock<MockIVibratorManager>> mMockHal = nullptr;
+    std::shared_ptr<StrictMock<vibrator::MockIVibrator>> mMockVibrator = nullptr;
 };
 
 // -------------------------------------------------------------------------------------------------
@@ -129,32 +85,13 @@
 static const std::vector<int32_t> kVibratorIds = {1, 2};
 static constexpr int kVibratorId = 1;
 
-ACTION(TriggerCallback) {
-    if (arg0 != nullptr) {
-        arg0->onComplete();
-    }
-}
-
-TEST_F(VibratorManagerHalWrapperAidlTest, TestPing) {
-    EXPECT_CALL(*mMockHal.get(), onAsBinder())
-            .Times(Exactly(2))
-            .WillRepeatedly(Return(mMockBinder.get()));
-    EXPECT_CALL(*mMockBinder.get(), pingBinder())
-            .Times(Exactly(2))
-            .WillOnce(Return(android::OK))
-            .WillRepeatedly(Return(android::DEAD_OBJECT));
-
-    ASSERT_TRUE(mWrapper->ping().isOk());
-    ASSERT_TRUE(mWrapper->ping().isFailed());
-}
-
 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetCapabilitiesDoesNotCacheFailedResult) {
     EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
             .Times(Exactly(3))
-            .WillOnce(
-                    Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(IVibratorManager::CAP_SYNC), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)))
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(IVibratorManager::CAP_SYNC),
+                            Return(ndk::ScopedAStatus::ok())));
 
     ASSERT_TRUE(mWrapper->getCapabilities().isUnsupported());
     ASSERT_TRUE(mWrapper->getCapabilities().isFailed());
@@ -167,7 +104,8 @@
 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetCapabilitiesCachesResult) {
     EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(IVibratorManager::CAP_SYNC), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(IVibratorManager::CAP_SYNC),
+                            Return(ndk::ScopedAStatus::ok())));
 
     std::vector<std::thread> threads;
     for (int i = 0; i < 10; i++) {
@@ -187,10 +125,9 @@
 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetVibratorIdsDoesNotCacheFailedResult) {
     EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
             .Times(Exactly(3))
-            .WillOnce(
-                    Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(kVibratorIds), Return(Status())));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)))
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
 
     ASSERT_TRUE(mWrapper->getVibratorIds().isUnsupported());
     ASSERT_TRUE(mWrapper->getVibratorIds().isFailed());
@@ -203,7 +140,7 @@
 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetVibratorIdsCachesResult) {
     EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(kVibratorIds), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
 
     std::vector<std::thread> threads;
     for (int i = 0; i < 10; i++) {
@@ -225,11 +162,11 @@
         InSequence seq;
         EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<0>(kVibratorIds), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
 
         EXPECT_CALL(*mMockHal.get(), getVibrator(Eq(kVibratorId), _))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<1>(mMockVibrator), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())));
     }
 
     auto result = mWrapper->getVibrator(kVibratorId);
@@ -241,7 +178,7 @@
 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetVibratorWithInvalidIdFails) {
     EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(kVibratorIds), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
 
     ASSERT_TRUE(mWrapper->getVibrator(0).isFailed());
 }
@@ -249,20 +186,21 @@
 TEST_F(VibratorManagerHalWrapperAidlTest, TestGetVibratorRecoversVibratorPointer) {
     EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(kVibratorIds), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
 
     EXPECT_CALL(*mMockHal.get(), getVibrator(Eq(kVibratorId), _))
             .Times(Exactly(3))
             .WillOnce(DoAll(SetArgPointee<1>(nullptr),
-                            Return(Status::fromExceptionCode(
-                                    Status::Exception::EX_TRANSACTION_FAILED))))
-            .WillRepeatedly(DoAll(SetArgPointee<1>(mMockVibrator), Return(Status())));
+                            Return(ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED))))
+            // ndk::ScopedAStatus::ok() cannot be copy-constructed so can't use WillRepeatedly
+            .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())))
+            .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())));
 
     EXPECT_CALL(*mMockVibrator.get(), off())
             .Times(Exactly(3))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_TRANSACTION_FAILED)))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_TRANSACTION_FAILED)))
-            .WillRepeatedly(Return(Status()));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED)))
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_TRANSACTION_FAILED)))
+            .WillOnce(Return(ndk::ScopedAStatus::ok()));
 
     // Get vibrator controller is successful even if first getVibrator.
     auto result = mWrapper->getVibrator(kVibratorId);
@@ -281,18 +219,19 @@
 TEST_F(VibratorManagerHalWrapperAidlTest, TestPrepareSynced) {
     EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(kVibratorIds), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
 
     EXPECT_CALL(*mMockHal.get(), getVibrator(_, _))
             .Times(Exactly(2))
-            .WillRepeatedly(DoAll(SetArgPointee<1>(mMockVibrator), Return(Status())));
+            // ndk::ScopedAStatus::ok() cannot be copy-constructed so can't use WillRepeatedly
+            .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())))
+            .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())));
 
     EXPECT_CALL(*mMockHal.get(), prepareSynced(Eq(kVibratorIds)))
             .Times(Exactly(3))
-            .WillOnce(
-                    Return(Status::fromExceptionCode(Status::Exception::EX_UNSUPPORTED_OPERATION)))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(Return(Status()));
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)))
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(Return(ndk::ScopedAStatus::ok()));
 
     ASSERT_TRUE(mWrapper->getVibratorIds().isOk());
     ASSERT_TRUE(mWrapper->prepareSynced(kVibratorIds).isUnsupported());
@@ -305,13 +244,13 @@
         InSequence seq;
         EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
                 .Times(Exactly(1))
-                .WillRepeatedly(DoAll(SetArgPointee<0>(IVibratorManager::CAP_TRIGGER_CALLBACK),
-                                      Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<0>(IVibratorManager::CAP_TRIGGER_CALLBACK),
+                                Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), triggerSynced(_))
                 .Times(Exactly(3))
-                .WillOnce(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)))
-                .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-                .WillRepeatedly(DoAll(TriggerCallback(), Return(Status())));
+                .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)))
+                .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+                .WillOnce(DoAll(vibrator::TriggerCallback(), Return(ndk::ScopedAStatus::ok())));
     }
 
     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
@@ -328,11 +267,11 @@
         InSequence seq;
         EXPECT_CALL(*mMockHal.get(), getCapabilities(_))
                 .Times(Exactly(1))
-                .WillRepeatedly(
-                        DoAll(SetArgPointee<0>(IVibratorManager::CAP_SYNC), Return(Status())));
+                .WillOnce(DoAll(SetArgPointee<0>(IVibratorManager::CAP_SYNC),
+                                Return(ndk::ScopedAStatus::ok())));
         EXPECT_CALL(*mMockHal.get(), triggerSynced(Eq(nullptr)))
                 .Times(Exactly(1))
-                .WillRepeatedly(Return(Status()));
+                .WillOnce(Return(ndk::ScopedAStatus::ok()));
     }
 
     std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
@@ -345,9 +284,9 @@
 TEST_F(VibratorManagerHalWrapperAidlTest, TestCancelSynced) {
     EXPECT_CALL(*mMockHal.get(), cancelSynced())
             .Times(Exactly(3))
-            .WillOnce(Return(Status::fromStatusT(UNKNOWN_TRANSACTION)))
-            .WillOnce(Return(Status::fromExceptionCode(Status::Exception::EX_SECURITY)))
-            .WillRepeatedly(Return(Status()));
+            .WillOnce(Return(ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_TRANSACTION)))
+            .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+            .WillOnce(Return(ndk::ScopedAStatus::ok()));
 
     ASSERT_TRUE(mWrapper->cancelSynced().isUnsupported());
     ASSERT_TRUE(mWrapper->cancelSynced().isFailed());
@@ -357,13 +296,17 @@
 TEST_F(VibratorManagerHalWrapperAidlTest, TestCancelSyncedReloadsAllControllers) {
     EXPECT_CALL(*mMockHal.get(), getVibratorIds(_))
             .Times(Exactly(1))
-            .WillRepeatedly(DoAll(SetArgPointee<0>(kVibratorIds), Return(Status())));
+            .WillOnce(DoAll(SetArgPointee<0>(kVibratorIds), Return(ndk::ScopedAStatus::ok())));
 
     EXPECT_CALL(*mMockHal.get(), getVibrator(_, _))
             .Times(Exactly(2))
-            .WillRepeatedly(DoAll(SetArgPointee<1>(mMockVibrator), Return(Status())));
+            // ndk::ScopedAStatus::ok() cannot be copy-constructed so can't use WillRepeatedly
+            .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())))
+            .WillOnce(DoAll(SetArgPointee<1>(mMockVibrator), Return(ndk::ScopedAStatus::ok())));
 
-    EXPECT_CALL(*mMockHal.get(), cancelSynced()).Times(Exactly(1)).WillRepeatedly(Return(Status()));
+    EXPECT_CALL(*mMockHal.get(), cancelSynced())
+            .Times(Exactly(1))
+            .WillOnce(Return(ndk::ScopedAStatus::ok()));
 
     ASSERT_TRUE(mWrapper->getVibratorIds().isOk());
     ASSERT_TRUE(mWrapper->cancelSynced().isOk());
diff --git a/services/vibratorservice/test/VibratorManagerHalWrapperLegacyTest.cpp b/services/vibratorservice/test/VibratorManagerHalWrapperLegacyTest.cpp
index 0850ef3..7877236 100644
--- a/services/vibratorservice/test/VibratorManagerHalWrapperLegacyTest.cpp
+++ b/services/vibratorservice/test/VibratorManagerHalWrapperLegacyTest.cpp
@@ -23,10 +23,12 @@
 
 #include <vibratorservice/VibratorManagerHalWrapper.h>
 
-using android::hardware::vibrator::CompositeEffect;
-using android::hardware::vibrator::CompositePrimitive;
-using android::hardware::vibrator::Effect;
-using android::hardware::vibrator::EffectStrength;
+#include "test_mocks.h"
+
+using aidl::android::hardware::vibrator::CompositeEffect;
+using aidl::android::hardware::vibrator::CompositePrimitive;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
 
 using std::chrono::milliseconds;
 
@@ -35,27 +37,16 @@
 
 // -------------------------------------------------------------------------------------------------
 
-class MockHalController : public vibrator::HalController {
-public:
-    MockHalController() = default;
-    virtual ~MockHalController() = default;
-
-    MOCK_METHOD(bool, init, (), (override));
-    MOCK_METHOD(void, tryReconnect, (), (override));
-};
-
-// -------------------------------------------------------------------------------------------------
-
 class VibratorManagerHalWrapperLegacyTest : public Test {
 public:
     void SetUp() override {
-        mMockController = std::make_shared<StrictMock<MockHalController>>();
+        mMockController = std::make_shared<StrictMock<vibrator::MockHalController>>();
         mWrapper = std::make_unique<vibrator::LegacyManagerHalWrapper>(mMockController);
         ASSERT_NE(mWrapper, nullptr);
     }
 
 protected:
-    std::shared_ptr<StrictMock<MockHalController>> mMockController = nullptr;
+    std::shared_ptr<StrictMock<vibrator::MockHalController>> mMockController = nullptr;
     std::unique_ptr<vibrator::ManagerHalWrapper> mWrapper = nullptr;
 };
 
diff --git a/services/vibratorservice/test/test_mocks.h b/services/vibratorservice/test/test_mocks.h
new file mode 100644
index 0000000..2f9451e
--- /dev/null
+++ b/services/vibratorservice/test/test_mocks.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *            http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VIBRATORSERVICE_UNITTEST_MOCKS_H_
+#define VIBRATORSERVICE_UNITTEST_MOCKS_H_
+
+#include <gmock/gmock.h>
+
+#include <aidl/android/hardware/vibrator/IVibrator.h>
+
+#include <vibratorservice/VibratorCallbackScheduler.h>
+#include <vibratorservice/VibratorHalController.h>
+#include <vibratorservice/VibratorHalWrapper.h>
+
+namespace android {
+
+namespace vibrator {
+
+using std::chrono::milliseconds;
+
+using namespace testing;
+
+using aidl::android::hardware::vibrator::Braking;
+using aidl::android::hardware::vibrator::CompositeEffect;
+using aidl::android::hardware::vibrator::CompositePrimitive;
+using aidl::android::hardware::vibrator::Effect;
+using aidl::android::hardware::vibrator::EffectStrength;
+using aidl::android::hardware::vibrator::IVibrator;
+using aidl::android::hardware::vibrator::IVibratorCallback;
+using aidl::android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::VendorEffect;
+
+// -------------------------------------------------------------------------------------------------
+
+class MockIVibrator : public IVibrator {
+public:
+    MockIVibrator() = default;
+
+    MOCK_METHOD(ndk::ScopedAStatus, getCapabilities, (int32_t * ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, off, (), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, on,
+                (int32_t timeout, const std::shared_ptr<IVibratorCallback>& cb), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, perform,
+                (Effect e, EffectStrength s, const std::shared_ptr<IVibratorCallback>& cb,
+                 int32_t* ret),
+                (override));
+    MOCK_METHOD(ndk::ScopedAStatus, performVendorEffect,
+                (const VendorEffect& e, const std::shared_ptr<IVibratorCallback>& cb), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getSupportedEffects, (std::vector<Effect> * ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, setAmplitude, (float amplitude), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, setExternalControl, (bool enabled), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getCompositionDelayMax, (int32_t * ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getCompositionSizeMax, (int32_t * ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getSupportedPrimitives, (std::vector<CompositePrimitive> * ret),
+                (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getPrimitiveDuration, (CompositePrimitive p, int32_t* ret),
+                (override));
+    MOCK_METHOD(ndk::ScopedAStatus, compose,
+                (const std::vector<CompositeEffect>& e,
+                 const std::shared_ptr<IVibratorCallback>& cb),
+                (override));
+    MOCK_METHOD(ndk::ScopedAStatus, composePwle,
+                (const std::vector<PrimitivePwle>& e, const std::shared_ptr<IVibratorCallback>& cb),
+                (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getSupportedAlwaysOnEffects, (std::vector<Effect> * ret),
+                (override));
+    MOCK_METHOD(ndk::ScopedAStatus, alwaysOnEnable, (int32_t id, Effect e, EffectStrength s),
+                (override));
+    MOCK_METHOD(ndk::ScopedAStatus, alwaysOnDisable, (int32_t id), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getQFactor, (float* ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getResonantFrequency, (float* ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getFrequencyResolution, (float* ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getFrequencyMinimum, (float* ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getBandwidthAmplitudeMap, (std::vector<float> * ret),
+                (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getPwlePrimitiveDurationMax, (int32_t * ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getPwleCompositionSizeMax, (int32_t * ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getSupportedBraking, (std::vector<Braking> * ret), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getInterfaceVersion, (int32_t*), (override));
+    MOCK_METHOD(ndk::ScopedAStatus, getInterfaceHash, (std::string*), (override));
+    MOCK_METHOD(ndk::SpAIBinder, asBinder, (), (override));
+    MOCK_METHOD(bool, isRemote, (), (override));
+};
+
+// gmock requirement to provide a WithArg<0>(TriggerCallback()) matcher
+typedef void TriggerCallbackFunction(const std::shared_ptr<IVibratorCallback>&);
+
+class TriggerCallbackAction : public ActionInterface<TriggerCallbackFunction> {
+public:
+    explicit TriggerCallbackAction() {}
+
+    virtual Result Perform(const ArgumentTuple& args) {
+        const std::shared_ptr<IVibratorCallback>& callback = get<0>(args);
+        if (callback) {
+            callback->onComplete();
+        }
+    }
+};
+
+inline Action<TriggerCallbackFunction> TriggerCallback() {
+    return MakeAction(new TriggerCallbackAction());
+}
+
+// -------------------------------------------------------------------------------------------------
+
+class MockCallbackScheduler : public CallbackScheduler {
+public:
+    MOCK_METHOD(void, schedule, (std::function<void()> callback, std::chrono::milliseconds delay),
+                (override));
+};
+
+ACTION(TriggerSchedulerCallback) {
+    arg0();
+}
+
+// -------------------------------------------------------------------------------------------------
+
+class MockHalWrapper : public HalWrapper {
+public:
+    MockHalWrapper(std::shared_ptr<CallbackScheduler> scheduler) : HalWrapper(scheduler) {}
+    virtual ~MockHalWrapper() = default;
+
+    MOCK_METHOD(vibrator::HalResult<void>, ping, (), (override));
+    MOCK_METHOD(void, tryReconnect, (), (override));
+    MOCK_METHOD(vibrator::HalResult<void>, on,
+                (milliseconds timeout, const std::function<void()>& completionCallback),
+                (override));
+    MOCK_METHOD(vibrator::HalResult<void>, off, (), (override));
+    MOCK_METHOD(vibrator::HalResult<void>, setAmplitude, (float amplitude), (override));
+    MOCK_METHOD(vibrator::HalResult<void>, setExternalControl, (bool enabled), (override));
+    MOCK_METHOD(vibrator::HalResult<void>, alwaysOnEnable,
+                (int32_t id, Effect effect, EffectStrength strength), (override));
+    MOCK_METHOD(vibrator::HalResult<void>, alwaysOnDisable, (int32_t id), (override));
+    MOCK_METHOD(vibrator::HalResult<milliseconds>, performEffect,
+                (Effect effect, EffectStrength strength,
+                 const std::function<void()>& completionCallback),
+                (override));
+    MOCK_METHOD(vibrator::HalResult<vibrator::Capabilities>, getCapabilitiesInternal, (),
+                (override));
+
+    CallbackScheduler* getCallbackScheduler() { return mCallbackScheduler.get(); }
+};
+
+class MockHalController : public vibrator::HalController {
+public:
+    MockHalController() = default;
+    virtual ~MockHalController() = default;
+
+    MOCK_METHOD(bool, init, (), (override));
+    MOCK_METHOD(void, tryReconnect, (), (override));
+};
+
+// -------------------------------------------------------------------------------------------------
+
+} // namespace vibrator
+
+} // namespace android
+
+#endif // VIBRATORSERVICE_UNITTEST_MOCKS_H_
diff --git a/services/vibratorservice/test/test_utils.h b/services/vibratorservice/test/test_utils.h
index 715c221..e99965c 100644
--- a/services/vibratorservice/test/test_utils.h
+++ b/services/vibratorservice/test/test_utils.h
@@ -17,7 +17,7 @@
 #ifndef VIBRATORSERVICE_UNITTEST_UTIL_H_
 #define VIBRATORSERVICE_UNITTEST_UTIL_H_
 
-#include <android/hardware/vibrator/IVibrator.h>
+#include <aidl/android/hardware/vibrator/IVibrator.h>
 
 #include <vibratorservice/VibratorHalWrapper.h>
 
@@ -25,24 +25,12 @@
 
 namespace vibrator {
 
-using ::android::hardware::vibrator::ActivePwle;
-using ::android::hardware::vibrator::Braking;
-using ::android::hardware::vibrator::BrakingPwle;
-using ::android::hardware::vibrator::CompositeEffect;
-using ::android::hardware::vibrator::CompositePrimitive;
-using ::android::hardware::vibrator::PrimitivePwle;
-
-// -------------------------------------------------------------------------------------------------
-
-class MockCallbackScheduler : public vibrator::CallbackScheduler {
-public:
-    MOCK_METHOD(void, schedule, (std::function<void()> callback, std::chrono::milliseconds delay),
-                (override));
-};
-
-ACTION(TriggerSchedulerCallback) {
-    arg0();
-}
+using aidl::android::hardware::vibrator::ActivePwle;
+using aidl::android::hardware::vibrator::Braking;
+using aidl::android::hardware::vibrator::BrakingPwle;
+using aidl::android::hardware::vibrator::CompositeEffect;
+using aidl::android::hardware::vibrator::CompositePrimitive;
+using aidl::android::hardware::vibrator::PrimitivePwle;
 
 // -------------------------------------------------------------------------------------------------
 
diff --git a/services/vr/.clang-format b/services/vr/.clang-format
deleted file mode 100644
index 04d7970..0000000
--- a/services/vr/.clang-format
+++ /dev/null
@@ -1,5 +0,0 @@
-BasedOnStyle: Google
-DerivePointerAlignment: false
-PointerAlignment: Left
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
diff --git a/services/vr/Android.bp b/services/vr/Android.bp
deleted file mode 100644
index 980dcf4..0000000
--- a/services/vr/Android.bp
+++ /dev/null
@@ -1,13 +0,0 @@
-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
-    //   SPDX-license-identifier-MIT
-    default_applicable_licenses: ["frameworks_native_license"],
-}
-
-subdirs = [
-  "*",
-]
diff --git a/services/vr/bufferhubd/Android.bp b/services/vr/bufferhubd/Android.bp
deleted file mode 100644
index f5491cf..0000000
--- a/services/vr/bufferhubd/Android.bp
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (C) 2016 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"],
-}
-
-sharedLibraries = [
-    "libbase",
-    "libcutils",
-    "libgui",
-    "liblog",
-    "libpdx_default_transport",
-    "libsync",
-    "libui",
-    "libutils",
-]
-
-cc_library_static {
-    name: "libbufferhubd",
-    srcs: [
-        "buffer_hub.cpp",
-        "consumer_channel.cpp",
-        "consumer_queue_channel.cpp",
-        "producer_channel.cpp",
-        "producer_queue_channel.cpp",
-    ],
-    cflags: [
-        "-DLOG_TAG=\"libbufferhubd\"",
-        "-DTRACE=0",
-        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
-    ],
-    export_include_dirs: ["include"],
-    header_libs: ["libdvr_headers"],
-    shared_libs: sharedLibraries,
-    static_libs: [
-        "libbufferhub",
-    ],
-}
-
-cc_binary {
-    srcs: ["bufferhubd.cpp"],
-    system_ext_specific: true,
-    cflags: [
-        "-DLOG_TAG=\"bufferhubd\"",
-        "-DTRACE=0",
-        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
-    ],
-    header_libs: ["libdvr_headers"],
-    shared_libs: sharedLibraries,
-    static_libs: [
-        "libbufferhub",
-        "libbufferhubd",
-        "libperformance",
-    ],
-    name: "bufferhubd",
-    init_rc: ["bufferhubd.rc"],
-}
diff --git a/services/vr/bufferhubd/buffer_hub.cpp b/services/vr/bufferhubd/buffer_hub.cpp
deleted file mode 100644
index 6409265..0000000
--- a/services/vr/bufferhubd/buffer_hub.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-#include <inttypes.h>
-#include <poll.h>
-
-#include <iomanip>
-#include <memory>
-#include <sstream>
-#include <string>
-#include <thread>
-
-#include <log/log.h>
-#include <pdx/default_transport/service_endpoint.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/buffer_hub.h>
-#include <private/dvr/consumer_channel.h>
-#include <private/dvr/producer_channel.h>
-#include <private/dvr/producer_queue_channel.h>
-#include <utils/Trace.h>
-
-using android::pdx::Channel;
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::Status;
-using android::pdx::default_transport::Endpoint;
-using android::pdx::rpc::DispatchRemoteMethod;
-
-namespace android {
-namespace dvr {
-
-BufferHubService::BufferHubService()
-    : BASE("BufferHub", Endpoint::Create(BufferHubRPC::kClientPath)) {}
-
-BufferHubService::~BufferHubService() {}
-
-bool BufferHubService::IsInitialized() const { return BASE::IsInitialized(); }
-
-std::string BufferHubService::DumpState(size_t /*max_length*/) {
-  std::ostringstream stream;
-  auto channels = GetChannels<BufferHubChannel>();
-
-  std::sort(channels.begin(), channels.end(),
-            [](const std::shared_ptr<BufferHubChannel>& a,
-               const std::shared_ptr<BufferHubChannel>& b) {
-              return a->buffer_id() < b->buffer_id();
-            });
-
-  stream << "Active Producer Buffers:\n";
-  stream << std::right;
-  stream << std::setw(6) << "Id";
-  stream << " ";
-  stream << std::setw(9) << "Consumers";
-  stream << " ";
-  stream << std::setw(14) << "Geometry";
-  stream << " ";
-  stream << std::setw(6) << "Format";
-  stream << " ";
-  stream << std::setw(10) << "Usage";
-  stream << " ";
-  stream << std::setw(18) << "State";
-  stream << " ";
-  stream << std::setw(18) << "Signaled";
-  stream << " ";
-  stream << std::setw(10) << "Index";
-  stream << std::endl;
-
-  for (const auto& channel : channels) {
-    if (channel->channel_type() == BufferHubChannel::kProducerType) {
-      BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
-
-      stream << std::right;
-      stream << std::setw(6) << info.id;
-      stream << " ";
-      stream << std::setw(9) << info.consumer_count;
-      stream << " ";
-      if (info.format == HAL_PIXEL_FORMAT_BLOB) {
-        std::string size = std::to_string(info.width) + " B";
-        stream << std::setw(14) << size;
-      } else {
-        std::string dimensions = std::to_string(info.width) + "x" +
-                                 std::to_string(info.height) + "x" +
-                                 std::to_string(info.layer_count);
-        stream << std::setw(14) << dimensions;
-      }
-      stream << " ";
-      stream << std::setw(6) << info.format;
-      stream << " ";
-      stream << "0x" << std::hex << std::setfill('0');
-      stream << std::setw(8) << info.usage;
-      stream << std::dec << std::setfill(' ');
-      stream << " ";
-      stream << "0x" << std::hex << std::setfill('0');
-      stream << std::setw(16) << info.state;
-      stream << " ";
-      stream << "0x" << std::setw(16) << info.signaled_mask;
-      stream << std::dec << std::setfill(' ');
-      stream << " ";
-      stream << std::setw(8) << info.index;
-      stream << std::endl;
-    }
-
-    if (channel->channel_type() == BufferHubChannel::kDetachedBufferType) {
-      BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
-
-      stream << std::right;
-      stream << std::setw(6) << info.id;
-      stream << " ";
-      stream << std::setw(9) << "N/A";
-      stream << " ";
-      if (info.format == HAL_PIXEL_FORMAT_BLOB) {
-        std::string size = std::to_string(info.width) + " B";
-        stream << std::setw(14) << size;
-      } else {
-        std::string dimensions = std::to_string(info.width) + "x" +
-                                 std::to_string(info.height) + "x" +
-                                 std::to_string(info.layer_count);
-        stream << std::setw(14) << dimensions;
-      }
-      stream << " ";
-      stream << std::setw(6) << info.format;
-      stream << " ";
-      stream << "0x" << std::hex << std::setfill('0');
-      stream << std::setw(8) << info.usage;
-      stream << std::dec << std::setfill(' ');
-      stream << " ";
-      stream << std::setw(9) << "N/A";
-      stream << " ";
-      stream << std::hex << std::setfill(' ');
-      stream << std::setw(18) << "Detached";
-      stream << " ";
-      stream << std::setw(18) << "N/A";
-      stream << " ";
-      stream << std::setw(10) << "N/A";
-      stream << std::endl;
-    }
-  }
-
-  stream << std::endl;
-  stream << "Active Producer Queues:\n";
-  stream << std::right << std::setw(6) << "Id";
-  stream << std::right << std::setw(12) << " Capacity";
-  stream << std::right << std::setw(12) << " Consumers";
-  stream << " UsageSetMask";
-  stream << " UsageClearMask";
-  stream << " UsageDenySetMask";
-  stream << " UsageDenyClearMask";
-  stream << " ";
-  stream << std::endl;
-
-  for (const auto& channel : channels) {
-    if (channel->channel_type() == BufferHubChannel::kProducerQueueType) {
-      BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
-
-      stream << std::dec << std::setfill(' ');
-      stream << std::right << std::setw(6) << info.id;
-      stream << std::right << std::setw(12) << info.capacity;
-      stream << std::right << std::setw(12) << info.consumer_count;
-      stream << std::setw(5) << std::setfill(' ') << "0x";
-      stream << std::hex << std::setfill('0');
-      stream << std::setw(8) << info.usage_policy.usage_set_mask;
-      stream << std::setw(7) << std::setfill(' ') << "0x";
-      stream << std::hex << std::setfill('0');
-      stream << std::setw(8) << info.usage_policy.usage_clear_mask;
-      stream << std::setw(9) << std::setfill(' ') << "0x";
-      stream << std::hex << std::setfill('0');
-      stream << std::setw(8) << info.usage_policy.usage_deny_set_mask;
-      stream << std::setw(11) << std::setfill(' ') << "0x";
-      stream << std::hex << std::setfill('0');
-      stream << std::setw(8) << info.usage_policy.usage_deny_clear_mask;
-      stream << std::hex << std::setfill('0');
-      stream << std::endl;
-    }
-  }
-
-  stream << std::endl;
-  stream << "Active Consumer Queues:\n";
-  stream << std::dec << std::setfill(' ');
-  stream << std::right << std::setw(6) << "Id";
-  stream << std::right << std::setw(12) << " Imported";
-  stream << " ";
-  stream << std::endl;
-
-  for (const auto& channel : channels) {
-    if (channel->channel_type() == BufferHubChannel::kConsumerQueueType) {
-      BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
-
-      stream << std::right << std::setw(6) << info.id;
-      stream << std::right << std::setw(12) << info.capacity;
-      stream << std::endl;
-    }
-  }
-
-  stream << std::endl;
-  stream << "Orphaned Consumer Buffers:\n";
-  stream << std::right;
-  stream << std::setw(6) << "Id";
-  stream << " ";
-  stream << std::setw(14) << "Info";
-  stream << std::endl;
-
-  for (const auto& channel : channels) {
-    BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
-    // consumer_count is tracked by producer. When it's zero, producer must have
-    // already hung up and the consumer is orphaned.
-    if (channel->channel_type() == BufferHubChannel::kConsumerType &&
-        info.consumer_count == 0) {
-      stream << std::right;
-      stream << std::setw(6) << info.id;
-      stream << " ";
-
-      stream << std::setw(14) << "Orphaned.";
-      stream << (" channel_id=" + std::to_string(channel->channel_id()));
-      stream << std::endl;
-    }
-  }
-
-  return stream.str();
-}
-
-void BufferHubService::HandleImpulse(Message& message) {
-  ATRACE_NAME("BufferHubService::HandleImpulse");
-  if (auto channel = message.GetChannel<BufferHubChannel>())
-    channel->HandleImpulse(message);
-}
-
-pdx::Status<void> BufferHubService::HandleMessage(Message& message) {
-  ATRACE_NAME("BufferHubService::HandleMessage");
-  auto channel = message.GetChannel<BufferHubChannel>();
-
-  ALOGD_IF(
-      TRACE,
-      "BufferHubService::HandleMessage: channel=%p channel_id=%d opcode=%d",
-      channel.get(), message.GetChannelId(), message.GetOp());
-
-  // If the channel is already set up, let it handle the message.
-  if (channel && !channel->HandleMessage(message))
-    return DefaultHandleMessage(message);
-
-  // This channel has not been set up yet, the following are valid operations.
-  switch (message.GetOp()) {
-    case BufferHubRPC::CreateBuffer::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::CreateBuffer>(
-          *this, &BufferHubService::OnCreateBuffer, message);
-      return {};
-
-    case BufferHubRPC::CreateProducerQueue::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::CreateProducerQueue>(
-          *this, &BufferHubService::OnCreateProducerQueue, message);
-      return {};
-
-    default:
-      return DefaultHandleMessage(message);
-  }
-}
-
-Status<void> BufferHubService::OnCreateBuffer(Message& message, uint32_t width,
-                                              uint32_t height, uint32_t format,
-                                              uint64_t usage,
-                                              size_t meta_size_bytes) {
-  // Use the producer channel id as the global buffer id.
-  const int buffer_id = message.GetChannelId();
-  ALOGD_IF(TRACE,
-           "BufferHubService::OnCreateBuffer: buffer_id=%d width=%u height=%u "
-           "format=%u usage=%" PRIx64 " meta_size_bytes=%zu",
-           buffer_id, width, height, format, usage, meta_size_bytes);
-
-  // See if this channel is already attached to a buffer.
-  if (const auto channel = message.GetChannel<BufferHubChannel>()) {
-    ALOGE("BufferHubService::OnCreateBuffer: Buffer already created: buffer=%d",
-          buffer_id);
-    return ErrorStatus(EALREADY);
-  }
-  const uint32_t kDefaultLayerCount = 1;
-  auto status = ProducerChannel::Create(this, buffer_id, width, height,
-                                        kDefaultLayerCount, format, usage,
-                                        meta_size_bytes);
-  if (status) {
-    message.SetChannel(status.take());
-    return {};
-  } else {
-    ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer: %s",
-          status.GetErrorMessage().c_str());
-    return status.error_status();
-  }
-}
-
-Status<QueueInfo> BufferHubService::OnCreateProducerQueue(
-    pdx::Message& message, const ProducerQueueConfig& producer_config,
-    const UsagePolicy& usage_policy) {
-  // Use the producer channel id as the global queue id.
-  const int queue_id = message.GetChannelId();
-  ALOGD_IF(TRACE, "BufferHubService::OnCreateProducerQueue: queue_id=%d",
-           queue_id);
-
-  // See if this channel is already attached to another object.
-  if (const auto channel = message.GetChannel<BufferHubChannel>()) {
-    ALOGE("BufferHubService::OnCreateProducerQueue: already created: queue=%d",
-          queue_id);
-    return ErrorStatus(EALREADY);
-  }
-
-  auto status = ProducerQueueChannel::Create(this, queue_id, producer_config,
-                                             usage_policy);
-  if (status) {
-    message.SetChannel(status.take());
-    return {{producer_config, queue_id}};
-  } else {
-    ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
-    return status.error_status();
-  }
-}
-
-void BufferHubChannel::SignalAvailable() {
-  ATRACE_NAME("BufferHubChannel::SignalAvailable");
-  ALOGD_IF(TRACE,
-           "BufferHubChannel::SignalAvailable: channel_id=%d buffer_id=%d",
-           channel_id(), buffer_id());
-  signaled_ = true;
-  const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLIN);
-  ALOGE_IF(!status,
-           "BufferHubChannel::SignalAvailable: failed to signal availability "
-           "channel_id=%d: %s",
-           channel_id_, status.GetErrorMessage().c_str());
-}
-
-void BufferHubChannel::ClearAvailable() {
-  ATRACE_NAME("BufferHubChannel::ClearAvailable");
-  ALOGD_IF(TRACE,
-           "BufferHubChannel::ClearAvailable: channel_id=%d buffer_id=%d",
-           channel_id(), buffer_id());
-  signaled_ = false;
-  const auto status = service_->ModifyChannelEvents(channel_id_, POLLIN, 0);
-  ALOGE_IF(!status,
-           "BufferHubChannel::ClearAvailable: failed to clear availability "
-           "channel_id=%d: %s",
-           channel_id_, status.GetErrorMessage().c_str());
-}
-
-void BufferHubChannel::Hangup() {
-  ATRACE_NAME("BufferHubChannel::Hangup");
-  ALOGD_IF(TRACE, "BufferHubChannel::Hangup: channel_id=%d buffer_id=%d",
-           channel_id(), buffer_id());
-  const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLHUP);
-  ALOGE_IF(
-      !status,
-      "BufferHubChannel::Hangup: failed to signal hangup channel_id=%d: %s",
-      channel_id_, status.GetErrorMessage().c_str());
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/bufferhubd/bufferhubd.cpp b/services/vr/bufferhubd/bufferhubd.cpp
deleted file mode 100644
index 50cb3b7..0000000
--- a/services/vr/bufferhubd/bufferhubd.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <sched.h>
-#include <sys/resource.h>
-#include <unistd.h>
-
-#include <dvr/performance_client_api.h>
-#include <log/log.h>
-#include <pdx/service_dispatcher.h>
-#include <private/dvr/buffer_hub.h>
-
-int main(int, char**) {
-  int ret = -1;
-  std::shared_ptr<android::dvr::BufferHubService> pdx_service;
-  std::unique_ptr<android::pdx::ServiceDispatcher> dispatcher;
-
-  // We need to be able to create endpoints with full perms.
-  umask(0000);
-
-  // Bump up the soft limit of open fd to the hard limit.
-  struct rlimit64 rlim;
-  ret = getrlimit64(RLIMIT_NOFILE, &rlim);
-  LOG_ALWAYS_FATAL_IF(ret != 0, "Failed to get nofile limit.");
-
-  ALOGI("Current nofile limit is %llu/%llu.", rlim.rlim_cur, rlim.rlim_max);
-  rlim.rlim_cur = rlim.rlim_max;
-  ret = setrlimit64(RLIMIT_NOFILE, &rlim);
-  ALOGE_IF(ret < 0, "Failed to set nofile limit, error=%s", strerror(errno));
-
-  rlim.rlim_cur = -1;
-  rlim.rlim_max = -1;
-  if (getrlimit64(RLIMIT_NOFILE, &rlim) < 0)
-    ALOGE("Failed to get nofile limit.");
-  else
-    ALOGI("New nofile limit is %llu/%llu.", rlim.rlim_cur, rlim.rlim_max);
-
-  dispatcher = android::pdx::ServiceDispatcher::Create();
-  CHECK_ERROR(!dispatcher, error, "Failed to create service dispatcher\n");
-
-  pdx_service = android::dvr::BufferHubService::Create();
-  CHECK_ERROR(!pdx_service, error, "Failed to create bufferhub pdx service\n");
-  dispatcher->AddService(pdx_service);
-
-  ret = dvrSetSchedulerClass(0, "graphics");
-  CHECK_ERROR(ret < 0, error, "Failed to set thread priority");
-
-  ALOGI("Entering message loop.");
-
-  ret = dispatcher->EnterDispatchLoop();
-  CHECK_ERROR(ret < 0, error, "Dispatch loop exited because: %s\n",
-              strerror(-ret));
-
-error:
-  return -ret;
-}
diff --git a/services/vr/bufferhubd/bufferhubd.rc b/services/vr/bufferhubd/bufferhubd.rc
deleted file mode 100644
index c470de5..0000000
--- a/services/vr/bufferhubd/bufferhubd.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service bufferhubd /system/bin/bufferhubd
-  class core
-  user system
-  group system
-  socket pdx/system/buffer_hub/client stream 0660 system system u:object_r:pdx_bufferhub_client_endpoint_socket:s0
diff --git a/services/vr/bufferhubd/consumer_channel.cpp b/services/vr/bufferhubd/consumer_channel.cpp
deleted file mode 100644
index c7695bc..0000000
--- a/services/vr/bufferhubd/consumer_channel.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-#include <thread>
-
-#include <log/log.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/consumer_channel.h>
-#include <private/dvr/producer_channel.h>
-#include <utils/Trace.h>
-
-using android::pdx::BorrowedHandle;
-using android::pdx::Channel;
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::Status;
-using android::pdx::rpc::DispatchRemoteMethod;
-
-namespace android {
-namespace dvr {
-
-ConsumerChannel::ConsumerChannel(BufferHubService* service, int buffer_id,
-                                 int channel_id, uint32_t client_state_mask,
-                                 const std::shared_ptr<Channel> producer)
-    : BufferHubChannel(service, buffer_id, channel_id, kConsumerType),
-      client_state_mask_(client_state_mask),
-      producer_(producer) {
-  GetProducer()->AddConsumer(this);
-}
-
-ConsumerChannel::~ConsumerChannel() {
-  ALOGD_IF(TRACE,
-           "ConsumerChannel::~ConsumerChannel: channel_id=%d buffer_id=%d",
-           channel_id(), buffer_id());
-
-  if (auto producer = GetProducer()) {
-    producer->RemoveConsumer(this);
-  }
-}
-
-BufferHubChannel::BufferInfo ConsumerChannel::GetBufferInfo() const {
-  BufferHubChannel::BufferInfo info;
-  if (auto producer = GetProducer()) {
-    // If producer has not hung up, copy most buffer info from the producer.
-    info = producer->GetBufferInfo();
-  } else {
-    info.signaled_mask = client_state_mask();
-  }
-  info.id = buffer_id();
-  return info;
-}
-
-std::shared_ptr<ProducerChannel> ConsumerChannel::GetProducer() const {
-  return std::static_pointer_cast<ProducerChannel>(producer_.lock());
-}
-
-void ConsumerChannel::HandleImpulse(Message& message) {
-  ATRACE_NAME("ConsumerChannel::HandleImpulse");
-  switch (message.GetOp()) {
-    case BufferHubRPC::ConsumerAcquire::Opcode:
-      OnConsumerAcquire(message);
-      break;
-    case BufferHubRPC::ConsumerRelease::Opcode:
-      OnConsumerRelease(message, {});
-      break;
-  }
-}
-
-bool ConsumerChannel::HandleMessage(Message& message) {
-  ATRACE_NAME("ConsumerChannel::HandleMessage");
-  auto producer = GetProducer();
-  if (!producer)
-    REPLY_ERROR_RETURN(message, EPIPE, true);
-
-  switch (message.GetOp()) {
-    case BufferHubRPC::GetBuffer::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::GetBuffer>(
-          *this, &ConsumerChannel::OnGetBuffer, message);
-      return true;
-
-    case BufferHubRPC::NewConsumer::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::NewConsumer>(
-          *producer, &ProducerChannel::OnNewConsumer, message);
-      return true;
-
-    case BufferHubRPC::ConsumerAcquire::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::ConsumerAcquire>(
-          *this, &ConsumerChannel::OnConsumerAcquire, message);
-      return true;
-
-    case BufferHubRPC::ConsumerRelease::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::ConsumerRelease>(
-          *this, &ConsumerChannel::OnConsumerRelease, message);
-      return true;
-
-    default:
-      return false;
-  }
-}
-
-Status<BufferDescription<BorrowedHandle>> ConsumerChannel::OnGetBuffer(
-    Message& /*message*/) {
-  ATRACE_NAME("ConsumerChannel::OnGetBuffer");
-  ALOGD_IF(TRACE, "ConsumerChannel::OnGetBuffer: buffer=%d", buffer_id());
-  if (auto producer = GetProducer()) {
-    return {producer->GetBuffer(client_state_mask_)};
-  } else {
-    return ErrorStatus(EPIPE);
-  }
-}
-
-Status<LocalFence> ConsumerChannel::OnConsumerAcquire(Message& message) {
-  ATRACE_NAME("ConsumerChannel::OnConsumerAcquire");
-  auto producer = GetProducer();
-  if (!producer)
-    return ErrorStatus(EPIPE);
-
-  if (acquired_ || released_) {
-    ALOGE(
-        "ConsumerChannel::OnConsumerAcquire: Acquire when not posted: "
-        "acquired=%d released=%d channel_id=%d buffer_id=%d",
-        acquired_, released_, message.GetChannelId(), producer->buffer_id());
-    return ErrorStatus(EBUSY);
-  } else {
-    auto status = producer->OnConsumerAcquire(message);
-    if (status) {
-      ClearAvailable();
-      acquired_ = true;
-    }
-    return status;
-  }
-}
-
-Status<void> ConsumerChannel::OnConsumerRelease(Message& message,
-                                                LocalFence release_fence) {
-  ATRACE_NAME("ConsumerChannel::OnConsumerRelease");
-  auto producer = GetProducer();
-  if (!producer)
-    return ErrorStatus(EPIPE);
-
-  if (!acquired_ || released_) {
-    ALOGE(
-        "ConsumerChannel::OnConsumerRelease: Release when not acquired: "
-        "acquired=%d released=%d channel_id=%d buffer_id=%d",
-        acquired_, released_, message.GetChannelId(), producer->buffer_id());
-    return ErrorStatus(EBUSY);
-  } else {
-    auto status =
-        producer->OnConsumerRelease(message, std::move(release_fence));
-    if (status) {
-      ClearAvailable();
-      acquired_ = false;
-      released_ = true;
-    }
-    return status;
-  }
-}
-
-void ConsumerChannel::OnProducerGained() {
-  // Clear the signal if exist. There is a possiblity that the signal still
-  // exist in consumer client when producer gains the buffer, e.g. newly added
-  // consumer fail to acquire the previous posted buffer in time. Then, when
-  // producer gains back the buffer, posts the buffer again and signal the
-  // consumer later, there won't be an signal change in eventfd, and thus,
-  // consumer will miss the posted buffer later. Thus, we need to clear the
-  // signal in consumer clients if the signal exist.
-  ClearAvailable();
-}
-
-void ConsumerChannel::OnProducerPosted() {
-  acquired_ = false;
-  released_ = false;
-  SignalAvailable();
-}
-
-void ConsumerChannel::OnProducerClosed() {
-  producer_.reset();
-  Hangup();
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/bufferhubd/consumer_queue_channel.cpp b/services/vr/bufferhubd/consumer_queue_channel.cpp
deleted file mode 100644
index 5d7d4e9..0000000
--- a/services/vr/bufferhubd/consumer_queue_channel.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-#include <pdx/channel_handle.h>
-#include <private/dvr/consumer_queue_channel.h>
-#include <private/dvr/producer_channel.h>
-
-using android::pdx::ErrorStatus;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::Status;
-using android::pdx::rpc::DispatchRemoteMethod;
-using android::pdx::rpc::RemoteMethodError;
-
-namespace android {
-namespace dvr {
-
-ConsumerQueueChannel::ConsumerQueueChannel(
-    BufferHubService* service, int buffer_id, int channel_id,
-    const std::shared_ptr<Channel>& producer, bool silent)
-    : BufferHubChannel(service, buffer_id, channel_id, kConsumerQueueType),
-      producer_(producer),
-      capacity_(0),
-      silent_(silent) {
-  GetProducer()->AddConsumer(this);
-}
-
-ConsumerQueueChannel::~ConsumerQueueChannel() {
-  ALOGD_IF(TRACE, "ConsumerQueueChannel::~ConsumerQueueChannel: channel_id=%d",
-           channel_id());
-
-  if (auto producer = GetProducer()) {
-    producer->RemoveConsumer(this);
-  }
-}
-
-bool ConsumerQueueChannel::HandleMessage(Message& message) {
-  ATRACE_NAME("ConsumerQueueChannel::HandleMessage");
-  auto producer = GetProducer();
-  if (!producer) {
-    RemoteMethodError(message, EPIPE);
-    return true;
-  }
-
-  switch (message.GetOp()) {
-    case BufferHubRPC::CreateConsumerQueue::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::CreateConsumerQueue>(
-          *producer, &ProducerQueueChannel::OnCreateConsumerQueue, message);
-      return true;
-
-    case BufferHubRPC::GetQueueInfo::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::GetQueueInfo>(
-          *producer, &ProducerQueueChannel::OnGetQueueInfo, message);
-      return true;
-
-    case BufferHubRPC::ConsumerQueueImportBuffers::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::ConsumerQueueImportBuffers>(
-          *this, &ConsumerQueueChannel::OnConsumerQueueImportBuffers, message);
-      return true;
-
-    default:
-      return false;
-  }
-}
-
-std::shared_ptr<ProducerQueueChannel> ConsumerQueueChannel::GetProducer()
-    const {
-  return std::static_pointer_cast<ProducerQueueChannel>(producer_.lock());
-}
-
-void ConsumerQueueChannel::HandleImpulse(Message& /* message */) {
-  ATRACE_NAME("ConsumerQueueChannel::HandleImpulse");
-}
-
-BufferHubChannel::BufferInfo ConsumerQueueChannel::GetBufferInfo() const {
-  BufferHubChannel::BufferInfo info;
-  if (auto producer = GetProducer()) {
-    // If producer has not hung up, copy most buffer info from the producer.
-    info = producer->GetBufferInfo();
-  }
-  info.id = buffer_id();
-  info.capacity = capacity_;
-  return info;
-}
-
-void ConsumerQueueChannel::RegisterNewBuffer(
-    const std::shared_ptr<ProducerChannel>& producer_channel,
-    size_t producer_slot) {
-  ALOGD_IF(TRACE, "%s: queue_id=%d buffer_id=%d slot=%zu silent=%d",
-           __FUNCTION__, buffer_id(), producer_channel->buffer_id(),
-           producer_slot, silent_);
-  // Only register buffers if the queue is not silent.
-  if (silent_) {
-    return;
-  }
-
-  auto status = producer_channel->CreateConsumerStateMask();
-  if (!status.ok()) {
-    ALOGE("%s: Failed to create consumer state mask: %s", __FUNCTION__,
-          status.GetErrorMessage().c_str());
-    return;
-  }
-  uint64_t consumer_state_mask = status.get();
-
-  pending_buffer_slots_.emplace(producer_channel, producer_slot,
-                                consumer_state_mask);
-  // Signal the client that there is new buffer available.
-  SignalAvailable();
-}
-
-Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
-ConsumerQueueChannel::OnConsumerQueueImportBuffers(Message& message) {
-  std::vector<std::pair<RemoteChannelHandle, size_t>> buffer_handles;
-  ATRACE_NAME(__FUNCTION__);
-  ALOGD_IF(TRACE, "%s: pending_buffer_slots=%zu", __FUNCTION__,
-           pending_buffer_slots_.size());
-
-  // Indicate this is a silent queue that will not import buffers.
-  if (silent_)
-    return ErrorStatus(EBADR);
-
-  while (!pending_buffer_slots_.empty()) {
-    auto producer_channel =
-        pending_buffer_slots_.front().producer_channel.lock();
-    size_t producer_slot = pending_buffer_slots_.front().producer_slot;
-    uint64_t consumer_state_mask =
-        pending_buffer_slots_.front().consumer_state_mask;
-    pending_buffer_slots_.pop();
-
-    // It's possible that the producer channel has expired. When this occurs,
-    // ignore the producer channel.
-    if (producer_channel == nullptr) {
-      ALOGW("%s: producer channel has already been expired.", __FUNCTION__);
-      continue;
-    }
-
-    auto status =
-        producer_channel->CreateConsumer(message, consumer_state_mask);
-
-    // If no buffers are imported successfully, clear available and return an
-    // error. Otherwise, return all consumer handles already imported
-    // successfully, but keep available bits on, so that the client can retry
-    // importing remaining consumer buffers.
-    if (!status) {
-      ALOGE("%s: Failed create consumer: %s", __FUNCTION__,
-            status.GetErrorMessage().c_str());
-      if (buffer_handles.empty()) {
-        ClearAvailable();
-        return status.error_status();
-      } else {
-        return {std::move(buffer_handles)};
-      }
-    }
-
-    buffer_handles.emplace_back(status.take(), producer_slot);
-  }
-
-  ClearAvailable();
-  return {std::move(buffer_handles)};
-}
-
-void ConsumerQueueChannel::OnProducerClosed() {
-  ALOGD_IF(TRACE, "ConsumerQueueChannel::OnProducerClosed: queue_id=%d",
-           buffer_id());
-  producer_.reset();
-  Hangup();
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_hub.h b/services/vr/bufferhubd/include/private/dvr/buffer_hub.h
deleted file mode 100644
index 909d69b..0000000
--- a/services/vr/bufferhubd/include/private/dvr/buffer_hub.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
-#define ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
-
-#include <memory>
-#include <string>
-#include <unordered_map>
-
-#include <hardware/gralloc.h>
-#include <pdx/service.h>
-#include <private/dvr/bufferhub_rpc.h>
-
-namespace android {
-namespace dvr {
-
-class BufferHubService;
-class ConsumerChannel;
-class ProducerChannel;
-class ConsumerQueueChannel;
-class ProducerQueueChannel;
-
-class BufferHubChannel : public pdx::Channel {
- public:
-  enum ChannelType {
-    kProducerType,
-    kConsumerType,
-    kDetachedBufferType,
-    kProducerQueueType,
-    kConsumerQueueType,
-  };
-
-  BufferHubChannel(BufferHubService* service, int buffer_id, int channel_id,
-                   ChannelType channel_type)
-      : service_(service),
-        buffer_id_(buffer_id),
-        channel_id_(channel_id),
-        channel_type_(channel_type) {}
-  virtual ~BufferHubChannel() {}
-
-  virtual bool HandleMessage(pdx::Message& message) = 0;
-  virtual void HandleImpulse(pdx::Message& message) = 0;
-
-  // Captures buffer info for use by BufferHubService::DumpState().
-  struct BufferInfo {
-    // Common data field shared by ProducerBuffer and ProducerQueue.
-    int id = -1;
-    int type = -1;
-    size_t consumer_count = 0;
-
-    // Data field for producer buffer.
-    uint32_t width = 0;
-    uint32_t height = 0;
-    uint32_t layer_count = 0;
-    uint32_t format = 0;
-    uint64_t usage = 0;
-    uint64_t state = 0;
-    uint64_t signaled_mask = 0;
-    uint64_t index = 0;
-
-    // Data filed for producer queue.
-    size_t capacity = 0;
-    UsagePolicy usage_policy{0, 0, 0, 0};
-
-    BufferInfo(int id, size_t consumer_count, uint32_t width, uint32_t height,
-               uint32_t layer_count, uint32_t format, uint64_t usage,
-               uint64_t state, uint64_t signaled_mask, uint64_t index)
-        : id(id),
-          type(kProducerType),
-          consumer_count(consumer_count),
-          width(width),
-          height(height),
-          layer_count(layer_count),
-          format(format),
-          usage(usage),
-          state(state),
-          signaled_mask(signaled_mask),
-          index(index) {}
-
-    BufferInfo(int id, size_t consumer_count, size_t capacity,
-               const UsagePolicy& usage_policy)
-        : id(id),
-          type(kProducerQueueType),
-          consumer_count(consumer_count),
-          capacity(capacity),
-          usage_policy(usage_policy) {}
-
-    BufferInfo() {}
-  };
-
-  // Returns the buffer info for this buffer.
-  virtual BufferInfo GetBufferInfo() const = 0;
-
-  // Signal the client fd that an ownership change occurred using POLLIN.
-  void SignalAvailable();
-
-  // Clear the ownership change event.
-  void ClearAvailable();
-
-  // Signal hangup event.
-  void Hangup();
-
-  BufferHubService* service() const { return service_; }
-  ChannelType channel_type() const { return channel_type_; }
-  int buffer_id() const { return buffer_id_; }
-
-  int channel_id() const { return channel_id_; }
-
-  bool signaled() const { return signaled_; }
-
- private:
-  BufferHubService* service_;
-
-  // Static id of the buffer for logging and informational purposes. This id
-  // does not change for the life of the buffer.
-  // TODO(eieio): Consider using an id allocator instead of the originating
-  // channel id; channel ids wrap after 2^31 ids, but this is not a problem in
-  // general because channel ids are not used for any lookup in this service.
-  int buffer_id_;
-
-  // The channel id of the buffer.
-  int channel_id_;
-
-  bool signaled_;
-
-  ChannelType channel_type_;
-
-  BufferHubChannel(const BufferHubChannel&) = delete;
-  void operator=(const BufferHubChannel&) = delete;
-};
-
-class BufferHubService : public pdx::ServiceBase<BufferHubService> {
- public:
-  BufferHubService();
-  ~BufferHubService() override;
-
-  pdx::Status<void> HandleMessage(pdx::Message& message) override;
-  void HandleImpulse(pdx::Message& message) override;
-
-  bool IsInitialized() const override;
-  std::string DumpState(size_t max_length) override;
-
- private:
-  friend BASE;
-
-  pdx::Status<void> OnCreateBuffer(pdx::Message& message, uint32_t width,
-                                   uint32_t height, uint32_t format,
-                                   uint64_t usage, size_t meta_size_bytes);
-  pdx::Status<QueueInfo> OnCreateProducerQueue(
-      pdx::Message& message, const ProducerQueueConfig& producer_config,
-      const UsagePolicy& usage_policy);
-
-  BufferHubService(const BufferHubService&) = delete;
-  void operator=(const BufferHubService&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
diff --git a/services/vr/bufferhubd/include/private/dvr/consumer_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
deleted file mode 100644
index 5ee551f..0000000
--- a/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
-#define ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
-
-#include <pdx/rpc/buffer_wrapper.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/buffer_hub.h>
-
-namespace android {
-namespace dvr {
-
-// Consumer channels are attached to a Producer channel
-class ConsumerChannel : public BufferHubChannel {
- public:
-  using BorrowedHandle = pdx::BorrowedHandle;
-  using Channel = pdx::Channel;
-  using Message = pdx::Message;
-
-  ConsumerChannel(BufferHubService* service, int buffer_id, int channel_id,
-                  uint32_t client_state_mask,
-                  const std::shared_ptr<Channel> producer);
-  ~ConsumerChannel() override;
-
-  bool HandleMessage(Message& message) override;
-  void HandleImpulse(Message& message) override;
-
-  uint32_t client_state_mask() const { return client_state_mask_; }
-  BufferInfo GetBufferInfo() const override;
-
-  void OnProducerGained();
-  void OnProducerPosted();
-  void OnProducerClosed();
-
- private:
-  std::shared_ptr<ProducerChannel> GetProducer() const;
-
-  pdx::Status<BufferDescription<BorrowedHandle>> OnGetBuffer(Message& message);
-
-  pdx::Status<LocalFence> OnConsumerAcquire(Message& message);
-  pdx::Status<void> OnConsumerRelease(Message& message,
-                                      LocalFence release_fence);
-
-  uint32_t client_state_mask_{0U};
-  bool acquired_{false};
-  bool released_{true};
-  std::weak_ptr<Channel> producer_;
-
-  ConsumerChannel(const ConsumerChannel&) = delete;
-  void operator=(const ConsumerChannel&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
diff --git a/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
deleted file mode 100644
index 3a81b03..0000000
--- a/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
-#define ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
-
-#include <queue>
-
-#include <private/dvr/buffer_hub.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/consumer_channel.h>
-#include <private/dvr/producer_queue_channel.h>
-
-namespace android {
-namespace dvr {
-
-class ConsumerQueueChannel : public BufferHubChannel {
- public:
-  using Message = pdx::Message;
-  using RemoteChannelHandle = pdx::RemoteChannelHandle;
-
-  ConsumerQueueChannel(BufferHubService* service, int buffer_id, int channel_id,
-                       const std::shared_ptr<Channel>& producer, bool silent);
-  ~ConsumerQueueChannel() override;
-
-  bool HandleMessage(Message& message) override;
-  void HandleImpulse(Message& message) override;
-
-  BufferInfo GetBufferInfo() const override;
-
-  // Called by ProdcuerQueueChannel to notify consumer queue that a new
-  // buffer has been allocated.
-  void RegisterNewBuffer(
-      const std::shared_ptr<ProducerChannel>& producer_channel,
-      size_t producer_slot);
-
-  // Called after clients been signaled by service that new buffer has been
-  // allocated. Clients uses kOpConsumerQueueImportBuffers to import new
-  // consumer buffers and this handler returns a vector of fd representing
-  // BufferConsumers that clients can import.
-  pdx::Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
-  OnConsumerQueueImportBuffers(Message& message);
-
-  void OnProducerClosed();
-
- private:
-  // Data structure to store relavant info of a newly allocated producer buffer
-  // so that consumer channel and buffer can be created later.
-  struct PendingBuffer {
-    PendingBuffer(std::shared_ptr<ProducerChannel> channel, size_t slot,
-                  uint64_t mask) {
-      producer_channel = channel;
-      producer_slot = slot;
-      consumer_state_mask = mask;
-    }
-    PendingBuffer() = delete;
-
-    std::weak_ptr<ProducerChannel> producer_channel;
-    size_t producer_slot;
-    uint64_t consumer_state_mask;
-  };
-
-  std::shared_ptr<ProducerQueueChannel> GetProducer() const;
-
-  // Pointer to the producer channel.
-  std::weak_ptr<Channel> producer_;
-
-  // Tracks newly allocated buffer producers along with it's slot number.
-  std::queue<PendingBuffer> pending_buffer_slots_;
-
-  // Tracks how many buffers have this queue imported.
-  size_t capacity_;
-
-  // A silent queue does not signal or export buffers. It is only used to spawn
-  // another consumer queue.
-  bool silent_;
-
-  ConsumerQueueChannel(const ConsumerQueueChannel&) = delete;
-  void operator=(const ConsumerQueueChannel&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
diff --git a/services/vr/bufferhubd/include/private/dvr/producer_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
deleted file mode 100644
index 45593ad..0000000
--- a/services/vr/bufferhubd/include/private/dvr/producer_channel.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
-#define ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
-
-#include <functional>
-#include <memory>
-#include <vector>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/rpc/buffer_wrapper.h>
-#include <private/dvr/buffer_hub.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/ion_buffer.h>
-
-namespace android {
-namespace dvr {
-
-// The buffer changes ownership according to the following sequence:
-// POST -> ACQUIRE/RELEASE (all consumers) -> GAIN (producer acquires) -> POST
-
-// The producer channel is owned by a single app that writes into buffers and
-// calls POST when drawing is complete. This channel has a set of consumer
-// channels associated with it that are waiting for notifications.
-class ProducerChannel : public BufferHubChannel {
- public:
-  using Message = pdx::Message;
-  using BorrowedHandle = pdx::BorrowedHandle;
-  using RemoteChannelHandle = pdx::RemoteChannelHandle;
-  template <typename T>
-  using BufferWrapper = pdx::rpc::BufferWrapper<T>;
-
-  static std::unique_ptr<ProducerChannel> Create(BufferHubService* service,
-                                                 int buffer_id, int channel_id,
-                                                 IonBuffer buffer,
-                                                 IonBuffer metadata_buffer,
-                                                 size_t user_metadata_size);
-
-  static pdx::Status<std::shared_ptr<ProducerChannel>> Create(
-      BufferHubService* service, int channel_id, uint32_t width,
-      uint32_t height, uint32_t layer_count, uint32_t format, uint64_t usage,
-      size_t user_metadata_size);
-
-  ~ProducerChannel() override;
-
-  uint32_t buffer_state() const {
-    return buffer_state_->load(std::memory_order_acquire);
-  }
-
-  bool HandleMessage(Message& message) override;
-  void HandleImpulse(Message& message) override;
-
-  BufferInfo GetBufferInfo() const override;
-
-  BufferDescription<BorrowedHandle> GetBuffer(uint32_t client_state_mask);
-
-  pdx::Status<RemoteChannelHandle> CreateConsumer(Message& message,
-                                                  uint32_t consumer_state_mask);
-  pdx::Status<uint32_t> CreateConsumerStateMask();
-  pdx::Status<RemoteChannelHandle> OnNewConsumer(Message& message);
-
-  pdx::Status<LocalFence> OnConsumerAcquire(Message& message);
-  pdx::Status<void> OnConsumerRelease(Message& message,
-                                      LocalFence release_fence);
-
-  void OnConsumerOrphaned(const uint32_t& consumer_state_mask);
-
-  void AddConsumer(ConsumerChannel* channel);
-  void RemoveConsumer(ConsumerChannel* channel);
-
-  bool CheckParameters(uint32_t width, uint32_t height, uint32_t layer_count,
-                       uint32_t format, uint64_t usage,
-                       size_t user_metadata_size) const;
-
- private:
-  std::vector<ConsumerChannel*> consumer_channels_;
-
-  IonBuffer buffer_;
-
-  // IonBuffer that is shared between bufferhubd, producer, and consumers.
-  IonBuffer metadata_buffer_;
-  BufferHubDefs::MetadataHeader* metadata_header_ = nullptr;
-  std::atomic<uint32_t>* buffer_state_ = nullptr;
-  std::atomic<uint32_t>* fence_state_ = nullptr;
-  std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
-
-  // All orphaned consumer bits. Valid bits are the lower 63 bits, while the
-  // highest bit is reserved for the producer and should not be set.
-  uint32_t orphaned_consumer_bit_mask_{0U};
-
-  LocalFence post_fence_;
-  LocalFence returned_fence_;
-  size_t user_metadata_size_;  // size of user requested buffer buffer size.
-  size_t metadata_buf_size_;   // size of the ion buffer that holds metadata.
-
-  pdx::LocalHandle acquire_fence_fd_;
-  pdx::LocalHandle release_fence_fd_;
-  pdx::LocalHandle dummy_fence_fd_;
-
-  ProducerChannel(BufferHubService* service, int buffer_id, int channel_id,
-                  IonBuffer buffer, IonBuffer metadata_buffer,
-                  size_t user_metadata_size, int* error);
-  ProducerChannel(BufferHubService* service, int channel, uint32_t width,
-                  uint32_t height, uint32_t layer_count, uint32_t format,
-                  uint64_t usage, size_t user_metadata_size, int* error);
-
-  int InitializeBuffer();
-  pdx::Status<BufferDescription<BorrowedHandle>> OnGetBuffer(Message& message);
-  pdx::Status<void> OnProducerPost(Message& message, LocalFence acquire_fence);
-  pdx::Status<LocalFence> OnProducerGain(Message& message);
-
-  // Remove consumer from atomics in shared memory based on consumer_state_mask.
-  // This function is used for clean up for failures in CreateConsumer method.
-  void RemoveConsumerClientMask(uint32_t consumer_state_mask);
-
-  // Checks whether the buffer is released by all active clients, excluding
-  // orphaned consumers.
-  bool IsBufferReleasedByAllActiveClientsExceptForOrphans() const;
-
-  ProducerChannel(const ProducerChannel&) = delete;
-  void operator=(const ProducerChannel&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
diff --git a/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
deleted file mode 100644
index 0456ad8..0000000
--- a/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
+++ /dev/null
@@ -1,94 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
-#define ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
-
-#include <pdx/status.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/buffer_hub.h>
-
-namespace android {
-namespace dvr {
-
-class ProducerQueueChannel : public BufferHubChannel {
- public:
-  static pdx::Status<std::shared_ptr<ProducerQueueChannel>> Create(
-      BufferHubService* service, int channel_id,
-      const ProducerQueueConfig& config, const UsagePolicy& usage_policy);
-  ~ProducerQueueChannel() override;
-
-  bool HandleMessage(pdx::Message& message) override;
-  void HandleImpulse(pdx::Message& message) override;
-
-  BufferInfo GetBufferInfo() const override;
-
-  // Handles client request to create a new consumer queue attached to current
-  // producer queue.
-  // Returns a handle for the service channel, as well as the size of the
-  // metadata associated with the queue.
-  pdx::Status<pdx::RemoteChannelHandle> OnCreateConsumerQueue(
-      pdx::Message& message, bool silent);
-
-  pdx::Status<QueueInfo> OnGetQueueInfo(pdx::Message& message);
-
-  // Allocate a new BufferHubProducer according to the input spec. Client may
-  // handle this as if a new producer is created through kOpCreateBuffer.
-  pdx::Status<std::vector<std::pair<pdx::RemoteChannelHandle, size_t>>>
-  OnProducerQueueAllocateBuffers(pdx::Message& message, uint32_t width,
-                                 uint32_t height, uint32_t layer_count,
-                                 uint32_t format, uint64_t usage,
-                                 size_t buffer_count);
-
-  // Inserts a ProducerBuffer into the queue. Note that the buffer must be in
-  // Gain'ed state for the operation to succeed.
-  pdx::Status<size_t> OnProducerQueueInsertBuffer(pdx::Message& message, int buffer_cid);
-
-  // Removes a ProducerBuffer indicated by |slot|. Note that the buffer must be
-  // in Gain'ed state for the operation to succeed.
-  pdx::Status<void> OnProducerQueueRemoveBuffer(pdx::Message& message,
-                                                size_t slot);
-
-  void AddConsumer(ConsumerQueueChannel* channel);
-  void RemoveConsumer(ConsumerQueueChannel* channel);
-
- private:
-  ProducerQueueChannel(BufferHubService* service, int channel_id,
-                       const ProducerQueueConfig& config,
-                       const UsagePolicy& usage_policy, int* error);
-
-  // Allocate one single producer buffer by |OnProducerQueueAllocateBuffers|.
-  // Note that the newly created buffer's file handle will be pushed to client
-  // and our return type is a RemoteChannelHandle.
-  // Returns the remote channel handle and the slot number for the newly
-  // allocated buffer.
-  pdx::Status<std::pair<pdx::RemoteChannelHandle, size_t>> AllocateBuffer(
-      pdx::Message& message, uint32_t width, uint32_t height,
-      uint32_t layer_count, uint32_t format, uint64_t usage);
-
-  // The producer queue's configuration. Now we assume the configuration is
-  // immutable once the queue is created.
-  ProducerQueueConfig config_;
-
-  // A set of variables to control what |usage| bits can this ProducerQueue
-  // allocate.
-  UsagePolicy usage_policy_;
-
-  // Provides access to the |channel_id| of all consumer channels associated
-  // with this producer.
-  std::vector<ConsumerQueueChannel*> consumer_channels_;
-
-  // Tracks how many buffers have this queue allocated.
-  size_t capacity_;
-
-  // Tracks of all buffer producer allocated through this buffer queue. Once
-  // a buffer get allocated, it will take a logical slot in the |buffers_| array
-  // and the slot number will stay unchanged during the entire life cycle of the
-  // queue.
-  std::weak_ptr<ProducerChannel> buffers_[BufferHubRPC::kMaxQueueCapacity];
-
-  ProducerQueueChannel(const ProducerQueueChannel&) = delete;
-  void operator=(const ProducerQueueChannel&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
deleted file mode 100644
index b71964b..0000000
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ /dev/null
@@ -1,673 +0,0 @@
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-#include <sys/poll.h>
-
-#include <algorithm>
-#include <atomic>
-#include <thread>
-
-#include <log/log.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/consumer_channel.h>
-#include <private/dvr/producer_channel.h>
-#include <sync/sync.h>
-#include <utils/Trace.h>
-
-using android::pdx::BorrowedHandle;
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::Status;
-using android::pdx::rpc::BufferWrapper;
-using android::pdx::rpc::DispatchRemoteMethod;
-using android::pdx::rpc::WrapBuffer;
-
-namespace android {
-namespace dvr {
-
-ProducerChannel::ProducerChannel(BufferHubService* service, int buffer_id,
-                                 int channel_id, IonBuffer buffer,
-                                 IonBuffer metadata_buffer,
-                                 size_t user_metadata_size, int* error)
-    : BufferHubChannel(service, buffer_id, channel_id, kProducerType),
-      buffer_(std::move(buffer)),
-      metadata_buffer_(std::move(metadata_buffer)),
-      user_metadata_size_(user_metadata_size),
-      metadata_buf_size_(BufferHubDefs::kMetadataHeaderSize +
-                         user_metadata_size) {
-  if (!buffer_.IsValid()) {
-    ALOGE("ProducerChannel::ProducerChannel: Invalid buffer.");
-    *error = -EINVAL;
-    return;
-  }
-  if (!metadata_buffer_.IsValid()) {
-    ALOGE("ProducerChannel::ProducerChannel: Invalid metadata buffer.");
-    *error = -EINVAL;
-    return;
-  }
-
-  *error = InitializeBuffer();
-}
-
-ProducerChannel::ProducerChannel(BufferHubService* service, int channel_id,
-                                 uint32_t width, uint32_t height,
-                                 uint32_t layer_count, uint32_t format,
-                                 uint64_t usage, size_t user_metadata_size,
-                                 int* error)
-    : BufferHubChannel(service, channel_id, channel_id, kProducerType),
-      user_metadata_size_(user_metadata_size),
-      metadata_buf_size_(BufferHubDefs::kMetadataHeaderSize +
-                         user_metadata_size) {
-  if (int ret = buffer_.Alloc(width, height, layer_count, format, usage)) {
-    ALOGE("ProducerChannel::ProducerChannel: Failed to allocate buffer: %s",
-          strerror(-ret));
-    *error = ret;
-    return;
-  }
-
-  if (int ret = metadata_buffer_.Alloc(metadata_buf_size_, /*height=*/1,
-                                       /*layer_count=*/1,
-                                       BufferHubDefs::kMetadataFormat,
-                                       BufferHubDefs::kMetadataUsage)) {
-    ALOGE("ProducerChannel::ProducerChannel: Failed to allocate metadata: %s",
-          strerror(-ret));
-    *error = ret;
-    return;
-  }
-
-  *error = InitializeBuffer();
-}
-
-int ProducerChannel::InitializeBuffer() {
-  void* metadata_ptr = nullptr;
-  if (int ret = metadata_buffer_.Lock(BufferHubDefs::kMetadataUsage, /*x=*/0,
-                                      /*y=*/0, metadata_buf_size_,
-                                      /*height=*/1, &metadata_ptr)) {
-    ALOGE("ProducerChannel::ProducerChannel: Failed to lock metadata.");
-    return ret;
-  }
-  metadata_header_ =
-      reinterpret_cast<BufferHubDefs::MetadataHeader*>(metadata_ptr);
-
-  // Using placement new here to reuse shared memory instead of new allocation
-  // and also initialize the value to zero.
-  buffer_state_ = new (&metadata_header_->bufferState) std::atomic<uint32_t>(0);
-  fence_state_ = new (&metadata_header_->fenceState) std::atomic<uint32_t>(0);
-  active_clients_bit_mask_ =
-      new (&metadata_header_->activeClientsBitMask) std::atomic<uint32_t>(0);
-
-  // Producer channel is never created after consumer channel, and one buffer
-  // only have one fixed producer for now. Thus, it is correct to assume
-  // producer state bit is kFirstClientBitMask for now.
-  active_clients_bit_mask_->store(BufferHubDefs::kFirstClientBitMask,
-                                  std::memory_order_release);
-
-  acquire_fence_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
-  release_fence_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
-  if (!acquire_fence_fd_ || !release_fence_fd_) {
-    ALOGE("ProducerChannel::ProducerChannel: Failed to create shared fences.");
-    return -EIO;
-  }
-
-  dummy_fence_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-  if (!dummy_fence_fd_) {
-    ALOGE("ProducerChannel::ProducerChannel: Failed to create dummy fences.");
-    return EIO;
-  }
-
-  epoll_event event;
-  event.events = 0;
-  event.data.u32 = 0U;
-  if (epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_ADD, dummy_fence_fd_.Get(),
-                &event) < 0) {
-    ALOGE(
-        "ProducerChannel::ProducerChannel: Failed to modify the shared "
-        "release fence to include the dummy fence: %s",
-        strerror(errno));
-    return -EIO;
-  }
-
-  // Success.
-  return 0;
-}
-
-std::unique_ptr<ProducerChannel> ProducerChannel::Create(
-    BufferHubService* service, int buffer_id, int channel_id, IonBuffer buffer,
-    IonBuffer metadata_buffer, size_t user_metadata_size) {
-  int error = 0;
-  std::unique_ptr<ProducerChannel> producer(new ProducerChannel(
-      service, buffer_id, channel_id, std::move(buffer),
-      std::move(metadata_buffer), user_metadata_size, &error));
-
-  if (error < 0)
-    return nullptr;
-  else
-    return producer;
-}
-
-Status<std::shared_ptr<ProducerChannel>> ProducerChannel::Create(
-    BufferHubService* service, int channel_id, uint32_t width, uint32_t height,
-    uint32_t layer_count, uint32_t format, uint64_t usage,
-    size_t user_metadata_size) {
-  int error;
-  std::shared_ptr<ProducerChannel> producer(
-      new ProducerChannel(service, channel_id, width, height, layer_count,
-                          format, usage, user_metadata_size, &error));
-  if (error < 0)
-    return ErrorStatus(-error);
-  else
-    return {std::move(producer)};
-}
-
-ProducerChannel::~ProducerChannel() {
-  ALOGD_IF(TRACE,
-           "ProducerChannel::~ProducerChannel: channel_id=%d buffer_id=%d "
-           "state=%" PRIx32 ".",
-           channel_id(), buffer_id(),
-           buffer_state_->load(std::memory_order_acquire));
-  for (auto consumer : consumer_channels_) {
-    consumer->OnProducerClosed();
-  }
-  Hangup();
-}
-
-BufferHubChannel::BufferInfo ProducerChannel::GetBufferInfo() const {
-  // Derive the mask of signaled buffers in this producer / consumer set.
-  uint32_t signaled_mask = signaled() ? BufferHubDefs::kFirstClientBitMask : 0;
-  for (const ConsumerChannel* consumer : consumer_channels_) {
-    signaled_mask |= consumer->signaled() ? consumer->client_state_mask() : 0;
-  }
-
-  return BufferInfo(buffer_id(), consumer_channels_.size(), buffer_.width(),
-                    buffer_.height(), buffer_.layer_count(), buffer_.format(),
-                    buffer_.usage(),
-                    buffer_state_->load(std::memory_order_acquire),
-                    signaled_mask, metadata_header_->queueIndex);
-}
-
-void ProducerChannel::HandleImpulse(Message& message) {
-  ATRACE_NAME("ProducerChannel::HandleImpulse");
-  switch (message.GetOp()) {
-    case BufferHubRPC::ProducerGain::Opcode:
-      OnProducerGain(message);
-      break;
-    case BufferHubRPC::ProducerPost::Opcode:
-      OnProducerPost(message, {});
-      break;
-  }
-}
-
-bool ProducerChannel::HandleMessage(Message& message) {
-  ATRACE_NAME("ProducerChannel::HandleMessage");
-  switch (message.GetOp()) {
-    case BufferHubRPC::GetBuffer::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::GetBuffer>(
-          *this, &ProducerChannel::OnGetBuffer, message);
-      return true;
-
-    case BufferHubRPC::NewConsumer::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::NewConsumer>(
-          *this, &ProducerChannel::OnNewConsumer, message);
-      return true;
-
-    case BufferHubRPC::ProducerPost::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::ProducerPost>(
-          *this, &ProducerChannel::OnProducerPost, message);
-      return true;
-
-    case BufferHubRPC::ProducerGain::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::ProducerGain>(
-          *this, &ProducerChannel::OnProducerGain, message);
-      return true;
-
-    default:
-      return false;
-  }
-}
-
-BufferDescription<BorrowedHandle> ProducerChannel::GetBuffer(
-    uint32_t client_state_mask) {
-  return {buffer_,
-          metadata_buffer_,
-          buffer_id(),
-          channel_id(),
-          client_state_mask,
-          acquire_fence_fd_.Borrow(),
-          release_fence_fd_.Borrow()};
-}
-
-Status<BufferDescription<BorrowedHandle>> ProducerChannel::OnGetBuffer(
-    Message& /*message*/) {
-  ATRACE_NAME("ProducerChannel::OnGetBuffer");
-  ALOGD_IF(TRACE, "ProducerChannel::OnGetBuffer: buffer=%d, state=%" PRIx32 ".",
-           buffer_id(), buffer_state_->load(std::memory_order_acquire));
-  return {GetBuffer(BufferHubDefs::kFirstClientBitMask)};
-}
-
-Status<uint32_t> ProducerChannel::CreateConsumerStateMask() {
-  // Try find the next consumer state bit which has not been claimed by any
-  // consumer yet.
-  // memory_order_acquire is chosen here because all writes in other threads
-  // that release active_clients_bit_mask_ need to be visible here.
-  uint32_t current_active_clients_bit_mask =
-      active_clients_bit_mask_->load(std::memory_order_acquire);
-  uint32_t consumer_state_mask =
-      BufferHubDefs::findNextAvailableClientStateMask(
-          current_active_clients_bit_mask | orphaned_consumer_bit_mask_);
-  if (consumer_state_mask == 0U) {
-    ALOGE("%s: reached the maximum mumber of consumers per producer: 63.",
-          __FUNCTION__);
-    return ErrorStatus(E2BIG);
-  }
-  uint32_t updated_active_clients_bit_mask =
-      current_active_clients_bit_mask | consumer_state_mask;
-  // Set the updated value only if the current value stays the same as what was
-  // read before. If the comparison succeeds, update the value without
-  // reordering anything before or after this read-modify-write in the current
-  // thread, and the modification will be visible in other threads that acquire
-  // active_clients_bit_mask_. If the comparison fails, load the result of
-  // all writes from all threads to updated_active_clients_bit_mask.
-  // Keep on finding the next available slient state mask until succeed or out
-  // of memory.
-  while (!active_clients_bit_mask_->compare_exchange_weak(
-      current_active_clients_bit_mask, updated_active_clients_bit_mask,
-      std::memory_order_acq_rel, std::memory_order_acquire)) {
-    ALOGE("%s: Current active clients bit mask is changed to %" PRIx32
-          ", which was expected to be %" PRIx32
-          ". Trying to generate a new client state mask to resolve race "
-          "condition.",
-          __FUNCTION__, updated_active_clients_bit_mask,
-          current_active_clients_bit_mask);
-    consumer_state_mask = BufferHubDefs::findNextAvailableClientStateMask(
-        current_active_clients_bit_mask | orphaned_consumer_bit_mask_);
-    if (consumer_state_mask == 0U) {
-      ALOGE("%s: reached the maximum mumber of consumers per producer: %d.",
-            __FUNCTION__, (BufferHubDefs::kMaxNumberOfClients - 1));
-      return ErrorStatus(E2BIG);
-    }
-    updated_active_clients_bit_mask =
-        current_active_clients_bit_mask | consumer_state_mask;
-  }
-
-  return {consumer_state_mask};
-}
-
-void ProducerChannel::RemoveConsumerClientMask(uint32_t consumer_state_mask) {
-  // Clear up the buffer state and fence state in case there is already
-  // something there due to possible race condition between producer post and
-  // consumer failed to create channel.
-  buffer_state_->fetch_and(~consumer_state_mask, std::memory_order_release);
-  fence_state_->fetch_and(~consumer_state_mask, std::memory_order_release);
-
-  // Restore the consumer state bit and make it visible in other threads that
-  // acquire the active_clients_bit_mask_.
-  active_clients_bit_mask_->fetch_and(~consumer_state_mask,
-                                      std::memory_order_release);
-}
-
-Status<RemoteChannelHandle> ProducerChannel::CreateConsumer(
-    Message& message, uint32_t consumer_state_mask) {
-  ATRACE_NAME(__FUNCTION__);
-  ALOGD("%s: buffer_id=%d", __FUNCTION__, buffer_id());
-
-  int channel_id;
-  auto status = message.PushChannel(0, nullptr, &channel_id);
-  if (!status) {
-    ALOGE("%s: Failed to push consumer channel: %s", __FUNCTION__,
-          status.GetErrorMessage().c_str());
-    RemoveConsumerClientMask(consumer_state_mask);
-    return ErrorStatus(ENOMEM);
-  }
-
-  auto consumer = std::make_shared<ConsumerChannel>(
-      service(), buffer_id(), channel_id, consumer_state_mask,
-      shared_from_this());
-  const auto channel_status = service()->SetChannel(channel_id, consumer);
-  if (!channel_status) {
-    ALOGE("%s: failed to set new consumer channel: %s.", __FUNCTION__,
-          channel_status.GetErrorMessage().c_str());
-    RemoveConsumerClientMask(consumer_state_mask);
-    return ErrorStatus(ENOMEM);
-  }
-
-  uint32_t current_buffer_state =
-      buffer_state_->load(std::memory_order_acquire);
-  // Return the consumer channel handle without signal when adding the new
-  // consumer to a buffer that is available to producer (a.k.a a fully-released
-  // buffer) or a gained buffer.
-  if (current_buffer_state == 0U ||
-      BufferHubDefs::isAnyClientGained(current_buffer_state)) {
-    return {status.take()};
-  }
-
-  // Signal the new consumer when adding it to a posted producer.
-  bool update_buffer_state = true;
-  if (!BufferHubDefs::isClientPosted(current_buffer_state,
-                                     consumer_state_mask)) {
-    uint32_t updated_buffer_state =
-        current_buffer_state ^
-        (consumer_state_mask & BufferHubDefs::kHighBitsMask);
-    while (!buffer_state_->compare_exchange_weak(
-        current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
-        std::memory_order_acquire)) {
-      ALOGV(
-          "%s: Failed to post to the new consumer. "
-          "Current buffer state was changed to %" PRIx32
-          " when trying to acquire the buffer and modify the buffer state to "
-          "%" PRIx32
-          ". About to try again if the buffer is still not gained nor fully "
-          "released.",
-          __FUNCTION__, current_buffer_state, updated_buffer_state);
-      if (current_buffer_state == 0U ||
-          BufferHubDefs::isAnyClientGained(current_buffer_state)) {
-        ALOGI("%s: buffer is gained or fully released, state=%" PRIx32 ".",
-              __FUNCTION__, current_buffer_state);
-        update_buffer_state = false;
-        break;
-      }
-      updated_buffer_state =
-          current_buffer_state ^
-          (consumer_state_mask & BufferHubDefs::kHighBitsMask);
-    }
-  }
-  if (update_buffer_state || BufferHubDefs::isClientPosted(
-                                 buffer_state_->load(std::memory_order_acquire),
-                                 consumer_state_mask)) {
-    consumer->OnProducerPosted();
-  }
-
-  return {status.take()};
-}
-
-Status<RemoteChannelHandle> ProducerChannel::OnNewConsumer(Message& message) {
-  ATRACE_NAME("ProducerChannel::OnNewConsumer");
-  ALOGD_IF(TRACE, "ProducerChannel::OnNewConsumer: buffer_id=%d", buffer_id());
-  auto status = CreateConsumerStateMask();
-  if (!status.ok()) {
-    return status.error_status();
-  }
-  return CreateConsumer(message, /*consumer_state_mask=*/status.get());
-}
-
-Status<void> ProducerChannel::OnProducerPost(Message&,
-                                             LocalFence acquire_fence) {
-  ATRACE_NAME("ProducerChannel::OnProducerPost");
-  ALOGD_IF(TRACE, "%s: buffer_id=%d, state=0x%x", __FUNCTION__, buffer_id(),
-           buffer_state_->load(std::memory_order_acquire));
-
-  epoll_event event;
-  event.events = 0;
-  event.data.u32 = 0U;
-  int ret = epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_MOD,
-                      dummy_fence_fd_.Get(), &event);
-  ALOGE_IF(ret < 0,
-           "ProducerChannel::OnProducerPost: Failed to modify the shared "
-           "release fence to include the dummy fence: %s",
-           strerror(errno));
-
-  eventfd_t dummy_fence_count = 0U;
-  if (eventfd_read(dummy_fence_fd_.Get(), &dummy_fence_count) < 0) {
-    const int error = errno;
-    if (error != EAGAIN) {
-      ALOGE(
-          "ProducerChannel::ProducerChannel: Failed to read dummy fence, "
-          "error: %s",
-          strerror(error));
-      return ErrorStatus(error);
-    }
-  }
-
-  ALOGW_IF(dummy_fence_count > 0,
-           "ProducerChannel::ProducerChannel: %" PRIu64
-           " dummy fence(s) was signaled during last release/gain cycle "
-           "buffer_id=%d.",
-           dummy_fence_count, buffer_id());
-
-  post_fence_ = std::move(acquire_fence);
-
-  // Signal any interested consumers. If there are none, the buffer will stay
-  // in posted state until a consumer comes online. This behavior guarantees
-  // that no frame is silently dropped.
-  for (auto& consumer : consumer_channels_) {
-    consumer->OnProducerPosted();
-  }
-
-  return {};
-}
-
-Status<LocalFence> ProducerChannel::OnProducerGain(Message& /*message*/) {
-  ATRACE_NAME("ProducerChannel::OnGain");
-  ALOGD_IF(TRACE, "%s: buffer_id=%d", __FUNCTION__, buffer_id());
-
-  ClearAvailable();
-  post_fence_.close();
-  for (auto& consumer : consumer_channels_) {
-    consumer->OnProducerGained();
-  }
-  return {std::move(returned_fence_)};
-}
-
-// TODO(b/112338294) Keep here for reference. Remove it after new logic is
-// written.
-/* Status<RemoteChannelHandle> ProducerChannel::OnProducerDetach(
-    Message& message) {
-  ATRACE_NAME("ProducerChannel::OnProducerDetach");
-  ALOGD_IF(TRACE, "ProducerChannel::OnProducerDetach: buffer_id=%d",
-           buffer_id());
-
-  uint32_t buffer_state = buffer_state_->load(std::memory_order_acquire);
-  if (!BufferHubDefs::isClientGained(
-      buffer_state, BufferHubDefs::kFirstClientStateMask)) {
-    // Can only detach a ProducerBuffer when it's in gained state.
-    ALOGW(
-        "ProducerChannel::OnProducerDetach: The buffer (id=%d, state=%"
-        PRIx32
-        ") is not in gained state.",
-        buffer_id(), buffer_state);
-    return {};
-  }
-
-  int channel_id;
-  auto status = message.PushChannel(0, nullptr, &channel_id);
-  if (!status) {
-    ALOGE(
-        "ProducerChannel::OnProducerDetach: Failed to push detached buffer "
-        "channel: %s",
-        status.GetErrorMessage().c_str());
-    return ErrorStatus(ENOMEM);
-  }
-
-  // Make sure we unlock the buffer.
-  if (int ret = metadata_buffer_.Unlock()) {
-    ALOGE("ProducerChannel::OnProducerDetach: Failed to unlock metadata.");
-    return ErrorStatus(-ret);
-  };
-
-  std::unique_ptr<BufferChannel> channel =
-      BufferChannel::Create(service(), buffer_id(), channel_id,
-                            std::move(buffer_), user_metadata_size_);
-  if (!channel) {
-    ALOGE("ProducerChannel::OnProducerDetach: Invalid buffer.");
-    return ErrorStatus(EINVAL);
-  }
-
-  const auto channel_status =
-      service()->SetChannel(channel_id, std::move(channel));
-  if (!channel_status) {
-    // Technically, this should never fail, as we just pushed the channel.
-    // Note that LOG_FATAL will be stripped out in non-debug build.
-    LOG_FATAL(
-        "ProducerChannel::OnProducerDetach: Failed to set new detached "
-        "buffer channel: %s.", channel_status.GetErrorMessage().c_str());
-  }
-
-  return status;
-} */
-
-Status<LocalFence> ProducerChannel::OnConsumerAcquire(Message& /*message*/) {
-  ATRACE_NAME("ProducerChannel::OnConsumerAcquire");
-  ALOGD_IF(TRACE, "ProducerChannel::OnConsumerAcquire: buffer_id=%d",
-           buffer_id());
-
-  // Return a borrowed fd to avoid unnecessary duplication of the underlying
-  // fd. Serialization just needs to read the handle.
-  return {std::move(post_fence_)};
-}
-
-Status<void> ProducerChannel::OnConsumerRelease(Message&,
-                                                LocalFence release_fence) {
-  ATRACE_NAME("ProducerChannel::OnConsumerRelease");
-  ALOGD_IF(TRACE, "ProducerChannel::OnConsumerRelease: buffer_id=%d",
-           buffer_id());
-
-  // Attempt to merge the fences if necessary.
-  if (release_fence) {
-    if (returned_fence_) {
-      LocalFence merged_fence(sync_merge("bufferhub_merged",
-                                         returned_fence_.get_fd(),
-                                         release_fence.get_fd()));
-      const int error = errno;
-      if (!merged_fence) {
-        ALOGE("ProducerChannel::OnConsumerRelease: Failed to merge fences: %s",
-              strerror(error));
-        return ErrorStatus(error);
-      }
-      returned_fence_ = std::move(merged_fence);
-    } else {
-      returned_fence_ = std::move(release_fence);
-    }
-  }
-
-  if (IsBufferReleasedByAllActiveClientsExceptForOrphans()) {
-    buffer_state_->store(0U);
-    SignalAvailable();
-    if (orphaned_consumer_bit_mask_) {
-      ALOGW(
-          "%s: orphaned buffer detected during the this acquire/release cycle: "
-          "id=%d orphaned=0x%" PRIx32 " queue_index=%" PRId64 ".",
-          __FUNCTION__, buffer_id(), orphaned_consumer_bit_mask_,
-          metadata_header_->queueIndex);
-      orphaned_consumer_bit_mask_ = 0;
-    }
-  }
-
-  return {};
-}
-
-void ProducerChannel::OnConsumerOrphaned(const uint32_t& consumer_state_mask) {
-  // Remember the ignored consumer so that newly added consumer won't be
-  // taking the same state mask as this orphaned consumer.
-  ALOGE_IF(orphaned_consumer_bit_mask_ & consumer_state_mask,
-           "%s: Consumer (consumer_state_mask=%" PRIx32
-           ") is already orphaned.",
-           __FUNCTION__, consumer_state_mask);
-  orphaned_consumer_bit_mask_ |= consumer_state_mask;
-
-  if (IsBufferReleasedByAllActiveClientsExceptForOrphans()) {
-    buffer_state_->store(0U);
-    SignalAvailable();
-  }
-
-  // Atomically clear the fence state bit as an orphaned consumer will never
-  // signal a release fence.
-  fence_state_->fetch_and(~consumer_state_mask, std::memory_order_release);
-
-  // Atomically set the buffer state of this consumer to released state.
-  buffer_state_->fetch_and(~consumer_state_mask, std::memory_order_release);
-
-  ALOGW(
-      "%s: detected new orphaned consumer buffer_id=%d "
-      "consumer_state_mask=%" PRIx32 " queue_index=%" PRId64
-      " buffer_state=%" PRIx32 " fence_state=%" PRIx32 ".",
-      __FUNCTION__, buffer_id(), consumer_state_mask,
-      metadata_header_->queueIndex,
-      buffer_state_->load(std::memory_order_acquire),
-      fence_state_->load(std::memory_order_acquire));
-}
-
-void ProducerChannel::AddConsumer(ConsumerChannel* channel) {
-  consumer_channels_.push_back(channel);
-}
-
-void ProducerChannel::RemoveConsumer(ConsumerChannel* channel) {
-  consumer_channels_.erase(
-      std::find(consumer_channels_.begin(), consumer_channels_.end(), channel));
-  // Restore the consumer state bit and make it visible in other threads that
-  // acquire the active_clients_bit_mask_.
-  uint32_t consumer_state_mask = channel->client_state_mask();
-  uint32_t current_active_clients_bit_mask =
-      active_clients_bit_mask_->load(std::memory_order_acquire);
-  uint32_t updated_active_clients_bit_mask =
-      current_active_clients_bit_mask & (~consumer_state_mask);
-  while (!active_clients_bit_mask_->compare_exchange_weak(
-      current_active_clients_bit_mask, updated_active_clients_bit_mask,
-      std::memory_order_acq_rel, std::memory_order_acquire)) {
-    ALOGI(
-        "%s: Failed to remove consumer state mask. Current active clients bit "
-        "mask is changed to %" PRIx32
-        " when trying to acquire and modify it to %" PRIx32
-        ". About to try again.",
-        __FUNCTION__, current_active_clients_bit_mask,
-        updated_active_clients_bit_mask);
-    updated_active_clients_bit_mask =
-        current_active_clients_bit_mask & (~consumer_state_mask);
-  }
-
-  const uint32_t current_buffer_state =
-      buffer_state_->load(std::memory_order_acquire);
-  if (BufferHubDefs::isClientPosted(current_buffer_state,
-                                    consumer_state_mask) ||
-      BufferHubDefs::isClientAcquired(current_buffer_state,
-                                      consumer_state_mask)) {
-    // The consumer client is being destoryed without releasing. This could
-    // happen in corner cases when the consumer crashes. Here we mark it
-    // orphaned before remove it from producer.
-    OnConsumerOrphaned(consumer_state_mask);
-    return;
-  }
-
-  if (BufferHubDefs::isClientReleased(current_buffer_state,
-                                      consumer_state_mask) ||
-      BufferHubDefs::isAnyClientGained(current_buffer_state)) {
-    // The consumer is being close while it is suppose to signal a release
-    // fence. Signal the dummy fence here.
-    if (fence_state_->load(std::memory_order_acquire) & consumer_state_mask) {
-      epoll_event event;
-      event.events = EPOLLIN;
-      event.data.u32 = consumer_state_mask;
-      if (epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_MOD,
-                    dummy_fence_fd_.Get(), &event) < 0) {
-        ALOGE(
-            "%s: Failed to modify the shared release fence to include the "
-            "dummy fence: %s",
-            __FUNCTION__, strerror(errno));
-        return;
-      }
-      ALOGW("%s: signal dummy release fence buffer_id=%d", __FUNCTION__,
-            buffer_id());
-      eventfd_write(dummy_fence_fd_.Get(), 1);
-    }
-  }
-}
-
-// Returns true if the given parameters match the underlying buffer
-// parameters.
-bool ProducerChannel::CheckParameters(uint32_t width, uint32_t height,
-                                      uint32_t layer_count, uint32_t format,
-                                      uint64_t usage,
-                                      size_t user_metadata_size) const {
-  return user_metadata_size == user_metadata_size_ &&
-         buffer_.width() == width && buffer_.height() == height &&
-         buffer_.layer_count() == layer_count && buffer_.format() == format &&
-         buffer_.usage() == usage;
-}
-
-bool ProducerChannel::IsBufferReleasedByAllActiveClientsExceptForOrphans()
-    const {
-  return (buffer_state_->load(std::memory_order_acquire) &
-          ~orphaned_consumer_bit_mask_ &
-          active_clients_bit_mask_->load(std::memory_order_acquire)) == 0U;
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/bufferhubd/producer_queue_channel.cpp b/services/vr/bufferhubd/producer_queue_channel.cpp
deleted file mode 100644
index 004dc7c..0000000
--- a/services/vr/bufferhubd/producer_queue_channel.cpp
+++ /dev/null
@@ -1,397 +0,0 @@
-#include <inttypes.h>
-
-#include <private/dvr/consumer_queue_channel.h>
-#include <private/dvr/producer_channel.h>
-#include <private/dvr/producer_queue_channel.h>
-
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::Status;
-using android::pdx::rpc::DispatchRemoteMethod;
-
-namespace android {
-namespace dvr {
-
-ProducerQueueChannel::ProducerQueueChannel(BufferHubService* service,
-                                           int channel_id,
-                                           const ProducerQueueConfig& config,
-                                           const UsagePolicy& usage_policy,
-                                           int* error)
-    : BufferHubChannel(service, channel_id, channel_id, kProducerQueueType),
-      config_(config),
-      usage_policy_(usage_policy),
-      capacity_(0) {
-  *error = 0;
-}
-
-ProducerQueueChannel::~ProducerQueueChannel() {
-  ALOGD_IF(TRACE, "ProducerQueueChannel::~ProducerQueueChannel: queue_id=%d",
-           buffer_id());
-  for (auto* consumer : consumer_channels_)
-    consumer->OnProducerClosed();
-}
-
-/* static */
-Status<std::shared_ptr<ProducerQueueChannel>> ProducerQueueChannel::Create(
-    BufferHubService* service, int channel_id,
-    const ProducerQueueConfig& config, const UsagePolicy& usage_policy) {
-  // Configuration between |usage_deny_set_mask| and |usage_deny_clear_mask|
-  // should be mutually exclusive.
-  if ((usage_policy.usage_deny_set_mask & usage_policy.usage_deny_clear_mask)) {
-    ALOGE(
-        "BufferHubService::OnCreateProducerQueue: illegal usage mask "
-        "configuration: usage_deny_set_mask=%" PRIx64
-        " usage_deny_clear_mask=%" PRIx64,
-        usage_policy.usage_deny_set_mask, usage_policy.usage_deny_clear_mask);
-    return ErrorStatus(EINVAL);
-  }
-
-  int error = 0;
-  std::shared_ptr<ProducerQueueChannel> producer(new ProducerQueueChannel(
-      service, channel_id, config, usage_policy, &error));
-  if (error < 0)
-    return ErrorStatus(-error);
-  else
-    return {std::move(producer)};
-}
-
-bool ProducerQueueChannel::HandleMessage(Message& message) {
-  ATRACE_NAME("ProducerQueueChannel::HandleMessage");
-  switch (message.GetOp()) {
-    case BufferHubRPC::CreateConsumerQueue::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::CreateConsumerQueue>(
-          *this, &ProducerQueueChannel::OnCreateConsumerQueue, message);
-      return true;
-
-    case BufferHubRPC::GetQueueInfo::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::GetQueueInfo>(
-          *this, &ProducerQueueChannel::OnGetQueueInfo, message);
-      return true;
-
-    case BufferHubRPC::ProducerQueueAllocateBuffers::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::ProducerQueueAllocateBuffers>(
-          *this, &ProducerQueueChannel::OnProducerQueueAllocateBuffers,
-          message);
-      return true;
-
-    case BufferHubRPC::ProducerQueueInsertBuffer::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::ProducerQueueInsertBuffer>(
-          *this, &ProducerQueueChannel::OnProducerQueueInsertBuffer, message);
-      return true;
-
-    case BufferHubRPC::ProducerQueueRemoveBuffer::Opcode:
-      DispatchRemoteMethod<BufferHubRPC::ProducerQueueRemoveBuffer>(
-          *this, &ProducerQueueChannel::OnProducerQueueRemoveBuffer, message);
-      return true;
-
-    default:
-      return false;
-  }
-}
-
-void ProducerQueueChannel::HandleImpulse(Message& /* message */) {
-  ATRACE_NAME("ProducerQueueChannel::HandleImpulse");
-}
-
-BufferHubChannel::BufferInfo ProducerQueueChannel::GetBufferInfo() const {
-  return BufferInfo(channel_id(), consumer_channels_.size(), capacity_,
-                    usage_policy_);
-}
-
-Status<RemoteChannelHandle> ProducerQueueChannel::OnCreateConsumerQueue(
-    Message& message, bool silent) {
-  ATRACE_NAME("ProducerQueueChannel::OnCreateConsumerQueue");
-  ALOGD_IF(
-      TRACE,
-      "ProducerQueueChannel::OnCreateConsumerQueue: channel_id=%d slient=%d",
-      channel_id(), silent);
-
-  int channel_id;
-  auto status = message.PushChannel(0, nullptr, &channel_id);
-  if (!status) {
-    ALOGE(
-        "ProducerQueueChannel::OnCreateConsumerQueue: failed to push consumer "
-        "channel: %s",
-        status.GetErrorMessage().c_str());
-    return ErrorStatus(ENOMEM);
-  }
-
-  auto consumer_queue_channel = std::make_shared<ConsumerQueueChannel>(
-      service(), buffer_id(), channel_id, shared_from_this(), silent);
-
-  // Register the existing buffers with the new consumer queue.
-  for (size_t slot = 0; slot < BufferHubRPC::kMaxQueueCapacity; slot++) {
-    if (auto buffer = buffers_[slot].lock())
-      consumer_queue_channel->RegisterNewBuffer(buffer, slot);
-  }
-
-  const auto channel_status =
-      service()->SetChannel(channel_id, consumer_queue_channel);
-  if (!channel_status) {
-    ALOGE(
-        "ProducerQueueChannel::OnCreateConsumerQueue: Failed to set channel: "
-        "%s",
-        channel_status.GetErrorMessage().c_str());
-    return ErrorStatus(ENOMEM);
-  }
-
-  return {status.take()};
-}
-
-Status<QueueInfo> ProducerQueueChannel::OnGetQueueInfo(Message&) {
-  return {{config_, buffer_id()}};
-}
-
-Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
-ProducerQueueChannel::OnProducerQueueAllocateBuffers(
-    Message& message, uint32_t width, uint32_t height, uint32_t layer_count,
-    uint32_t format, uint64_t usage, size_t buffer_count) {
-  ATRACE_NAME("ProducerQueueChannel::OnProducerQueueAllocateBuffers");
-  ALOGD_IF(TRACE,
-           "ProducerQueueChannel::OnProducerQueueAllocateBuffers: "
-           "producer_channel_id=%d",
-           channel_id());
-
-  std::vector<std::pair<RemoteChannelHandle, size_t>> buffer_handles;
-
-  // Deny buffer allocation violating preset rules.
-  if (usage & usage_policy_.usage_deny_set_mask) {
-    ALOGE(
-        "ProducerQueueChannel::OnProducerQueueAllocateBuffers: usage: %" PRIx64
-        " is not permitted. Violating usage_deny_set_mask, the following  bits "
-        "shall not be set: %" PRIx64 ".",
-        usage, usage_policy_.usage_deny_set_mask);
-    return ErrorStatus(EINVAL);
-  }
-
-  if (~usage & usage_policy_.usage_deny_clear_mask) {
-    ALOGE(
-        "ProducerQueueChannel::OnProducerQueueAllocateBuffers: usage: %" PRIx64
-        " is not permitted. Violating usage_deny_clear_mask, the following "
-        "bits must be set: %" PRIx64 ".",
-        usage, usage_policy_.usage_deny_clear_mask);
-    return ErrorStatus(EINVAL);
-  }
-
-  // Force set mask and clear mask. Note that |usage_policy_.usage_set_mask_|
-  // takes precedence and will overwrite |usage_policy_.usage_clear_mask|.
-  uint64_t effective_usage =
-      (usage & ~usage_policy_.usage_clear_mask) | usage_policy_.usage_set_mask;
-
-  for (size_t i = 0; i < buffer_count; i++) {
-    auto status = AllocateBuffer(message, width, height, layer_count, format,
-                                 effective_usage);
-    if (!status) {
-      ALOGE(
-          "ProducerQueueChannel::OnProducerQueueAllocateBuffers: Failed to "
-          "allocate new buffer.");
-      return ErrorStatus(status.error());
-    }
-    buffer_handles.push_back(status.take());
-  }
-
-  return {std::move(buffer_handles)};
-}
-
-Status<std::pair<RemoteChannelHandle, size_t>>
-ProducerQueueChannel::AllocateBuffer(Message& message, uint32_t width,
-                                     uint32_t height, uint32_t layer_count,
-                                     uint32_t format, uint64_t usage) {
-  ATRACE_NAME("ProducerQueueChannel::AllocateBuffer");
-  ALOGD_IF(TRACE,
-           "ProducerQueueChannel::AllocateBuffer: producer_channel_id=%d",
-           channel_id());
-
-  if (capacity_ >= BufferHubRPC::kMaxQueueCapacity) {
-    ALOGE("ProducerQueueChannel::AllocateBuffer: reaches kMaxQueueCapacity.");
-    return ErrorStatus(E2BIG);
-  }
-
-  // Here we are creating a new BufferHubBuffer, initialize the producer
-  // channel, and returning its file handle back to the client.
-  // buffer_id is the id of the producer channel of BufferHubBuffer.
-  int buffer_id;
-  auto status = message.PushChannel(0, nullptr, &buffer_id);
-
-  if (!status) {
-    ALOGE("ProducerQueueChannel::AllocateBuffer: failed to push channel: %s",
-          status.GetErrorMessage().c_str());
-    return ErrorStatus(status.error());
-  }
-
-  ALOGD_IF(TRACE,
-           "ProducerQueueChannel::AllocateBuffer: buffer_id=%d width=%u "
-           "height=%u layer_count=%u format=%u usage=%" PRIx64,
-           buffer_id, width, height, layer_count, format, usage);
-  auto buffer_handle = status.take();
-
-  auto producer_channel_status =
-      ProducerChannel::Create(service(), buffer_id, width, height, layer_count,
-                              format, usage, config_.user_metadata_size);
-  if (!producer_channel_status) {
-    ALOGE(
-        "ProducerQueueChannel::AllocateBuffer: Failed to create producer "
-        "buffer: %s",
-        producer_channel_status.GetErrorMessage().c_str());
-    return ErrorStatus(ENOMEM);
-  }
-  auto producer_channel = producer_channel_status.take();
-
-  ALOGD_IF(
-      TRACE,
-      "ProducerQueueChannel::AllocateBuffer: buffer_id=%d, buffer_handle=%d",
-      buffer_id, buffer_handle.value());
-
-  const auto channel_status =
-      service()->SetChannel(buffer_id, producer_channel);
-  if (!channel_status) {
-    ALOGE(
-        "ProducerQueueChannel::AllocateBuffer: failed to set producer channel "
-        "for new BufferHubBuffer: %s",
-        channel_status.GetErrorMessage().c_str());
-    return ErrorStatus(ENOMEM);
-  }
-
-  // Register the newly allocated buffer's channel_id into the first empty
-  // buffer slot.
-  size_t slot = 0;
-  for (; slot < BufferHubRPC::kMaxQueueCapacity; slot++) {
-    if (buffers_[slot].expired())
-      break;
-  }
-  if (slot == BufferHubRPC::kMaxQueueCapacity) {
-    ALOGE(
-        "ProducerQueueChannel::AllocateBuffer: Cannot find empty slot for new "
-        "buffer allocation.");
-    return ErrorStatus(E2BIG);
-  }
-
-  buffers_[slot] = producer_channel;
-  capacity_++;
-
-  // Notify each consumer channel about the new buffer.
-  for (auto* consumer_channel : consumer_channels_) {
-    ALOGD(
-        "ProducerQueueChannel::AllocateBuffer: Notified consumer with new "
-        "buffer, buffer_id=%d",
-        buffer_id);
-    consumer_channel->RegisterNewBuffer(producer_channel, slot);
-  }
-
-  return {{std::move(buffer_handle), slot}};
-}
-
-Status<size_t> ProducerQueueChannel::OnProducerQueueInsertBuffer(
-    pdx::Message& message, int buffer_cid) {
-  ATRACE_NAME("ProducerQueueChannel::InsertBuffer");
-  ALOGD_IF(TRACE,
-           "ProducerQueueChannel::InsertBuffer: channel_id=%d, buffer_cid=%d",
-           channel_id(), buffer_cid);
-
-  if (capacity_ >= BufferHubRPC::kMaxQueueCapacity) {
-    ALOGE("ProducerQueueChannel::InsertBuffer: reaches kMaxQueueCapacity.");
-    return ErrorStatus(E2BIG);
-  }
-  auto producer_channel = std::static_pointer_cast<ProducerChannel>(
-      service()->GetChannel(buffer_cid));
-  if (producer_channel == nullptr ||
-      producer_channel->channel_type() != BufferHubChannel::kProducerType) {
-    // Rejects the request if the requested buffer channel is invalid and/or
-    // it's not a ProducerChannel.
-    ALOGE(
-        "ProducerQueueChannel::InsertBuffer: Invalid buffer_cid=%d, "
-        "producer_buffer=0x%p, channel_type=%d.",
-        buffer_cid, producer_channel.get(),
-        producer_channel == nullptr ? -1 : producer_channel->channel_type());
-    return ErrorStatus(EINVAL);
-  }
-  if (producer_channel->GetActiveProcessId() != message.GetProcessId()) {
-    // Rejects the request if the requested buffer channel is not currently
-    // connected to the caller this is IPC request. This effectively prevents
-    // fake buffer_cid from being injected.
-    ALOGE(
-        "ProducerQueueChannel::InsertBuffer: Requested buffer channel "
-        "(buffer_cid=%d) is not connected to the calling process (pid=%d). "
-        "It's connected to a different process (pid=%d).",
-        buffer_cid, message.GetProcessId(),
-        producer_channel->GetActiveProcessId());
-    return ErrorStatus(EINVAL);
-  }
-  uint64_t buffer_state = producer_channel->buffer_state();
-  // TODO(b/112007999) add an atomic variable in metadata header in shared
-  // memory to indicate which client is the last producer of the buffer.
-  // Currently, the first client is the only producer to the buffer.
-  // Thus, it checks whether the first client gains the buffer below.
-  if (!BufferHubDefs::isClientGained(buffer_state,
-                                     BufferHubDefs::kFirstClientBitMask)) {
-    // Rejects the request if the requested buffer is not in Gained state.
-    ALOGE(
-        "ProducerQueueChannel::InsertBuffer: The buffer (cid=%d, "
-        "state=0x%" PRIx64 ") is not in gained state.",
-        buffer_cid, buffer_state);
-    return ErrorStatus(EINVAL);
-  }
-
-  // Register the to-be-inserted buffer's channel_id into the first empty
-  // buffer slot.
-  size_t slot = 0;
-  for (; slot < BufferHubRPC::kMaxQueueCapacity; slot++) {
-    if (buffers_[slot].expired())
-      break;
-  }
-  if (slot == BufferHubRPC::kMaxQueueCapacity) {
-    ALOGE(
-        "ProducerQueueChannel::AllocateBuffer: Cannot find empty slot for new "
-        "buffer allocation.");
-    return ErrorStatus(E2BIG);
-  }
-
-  buffers_[slot] = producer_channel;
-  capacity_++;
-
-  // Notify each consumer channel about the new buffer.
-  for (auto* consumer_channel : consumer_channels_) {
-    ALOGD(
-        "ProducerQueueChannel::AllocateBuffer: Notified consumer with new "
-        "buffer, buffer_cid=%d",
-        buffer_cid);
-    consumer_channel->RegisterNewBuffer(producer_channel, slot);
-  }
-
-  return {slot};
-}
-
-Status<void> ProducerQueueChannel::OnProducerQueueRemoveBuffer(
-    Message& /*message*/, size_t slot) {
-  if (buffers_[slot].expired()) {
-    ALOGE(
-        "ProducerQueueChannel::OnProducerQueueRemoveBuffer: trying to remove "
-        "an invalid buffer producer at slot %zu",
-        slot);
-    return ErrorStatus(EINVAL);
-  }
-
-  if (capacity_ == 0) {
-    ALOGE(
-        "ProducerQueueChannel::OnProducerQueueRemoveBuffer: trying to remove a "
-        "buffer producer while the queue's capacity is already zero.");
-    return ErrorStatus(EINVAL);
-  }
-
-  buffers_[slot].reset();
-  capacity_--;
-  return {};
-}
-
-void ProducerQueueChannel::AddConsumer(ConsumerQueueChannel* channel) {
-  consumer_channels_.push_back(channel);
-}
-
-void ProducerQueueChannel::RemoveConsumer(ConsumerQueueChannel* channel) {
-  consumer_channels_.erase(
-      std::find(consumer_channels_.begin(), consumer_channels_.end(), channel));
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/performanced/Android.bp b/services/vr/performanced/Android.bp
deleted file mode 100644
index 5eca88b..0000000
--- a/services/vr/performanced/Android.bp
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2016 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-MIT
-    default_applicable_licenses: ["frameworks_native_license"],
-}
-
-cc_defaults {
-    name: "performanced_defaults",
-    static_libs: [
-        "libperformance",
-        "libvr_manager",
-    ],
-    shared_libs: [
-        "libbinder",
-        "libbase",
-        "libcutils",
-        "liblog",
-        "libutils",
-        "libpdx_default_transport",
-    ],
-}
-
-cc_binary {
-    name: "performanced",
-    system_ext_specific: true,
-    defaults: ["performanced_defaults"],
-    srcs: [
-        "cpu_set.cpp",
-        "main.cpp",
-        "performance_service.cpp",
-        "task.cpp",
-    ],
-    cflags: [
-        "-DLOG_TAG=\"performanced\"",
-        "-DTRACE=0",
-        "-Wall",
-        "-Werror",
-    ],
-    init_rc: ["performanced.rc"],
-}
-
-cc_test {
-    name: "performance_service_tests",
-    defaults: ["performanced_defaults"],
-    srcs: ["performance_service_tests.cpp"],
-}
diff --git a/services/vr/performanced/CPPLINT.cfg b/services/vr/performanced/CPPLINT.cfg
deleted file mode 100644
index fd379da..0000000
--- a/services/vr/performanced/CPPLINT.cfg
+++ /dev/null
@@ -1 +0,0 @@
-filter=-runtime/int
diff --git a/services/vr/performanced/cpu_set.cpp b/services/vr/performanced/cpu_set.cpp
deleted file mode 100644
index d940b79..0000000
--- a/services/vr/performanced/cpu_set.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-#include "cpu_set.h"
-
-#include <log/log.h>
-
-#include <algorithm>
-#include <iomanip>
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include <android-base/file.h>
-
-#include "directory_reader.h"
-#include "stdio_filebuf.h"
-#include "task.h"
-#include "unique_file.h"
-
-using android::pdx::ErrorStatus;
-using android::pdx::Status;
-
-namespace {
-
-constexpr int kDirectoryFlags = O_RDONLY | O_DIRECTORY | O_CLOEXEC;
-constexpr pid_t kKernelThreadDaemonPid = 2;
-
-}  // anonymous namespace
-
-namespace android {
-namespace dvr {
-
-bool CpuSet::prefix_enabled_ = false;
-
-void CpuSetManager::Load(const std::string& cpuset_root) {
-  if (!root_set_)
-    root_set_ = Create(cpuset_root);
-}
-
-std::unique_ptr<CpuSet> CpuSetManager::Create(const std::string& path) {
-  base::unique_fd root_cpuset_fd(open(path.c_str(), kDirectoryFlags));
-  if (root_cpuset_fd.get() < 0) {
-    ALOGE("CpuSet::Create: Failed to open \"%s\": %s", path.c_str(),
-          strerror(errno));
-    return nullptr;
-  }
-
-  return Create(std::move(root_cpuset_fd), "/", nullptr);
-}
-
-std::unique_ptr<CpuSet> CpuSetManager::Create(base::unique_fd base_fd,
-                                              const std::string& name,
-                                              CpuSet* parent) {
-  DirectoryReader directory(base::unique_fd(dup(base_fd)));
-  if (!directory) {
-    ALOGE("CpuSet::Create: Failed to opendir %s cpuset: %s", name.c_str(),
-          strerror(directory.GetError()));
-    return nullptr;
-  }
-
-  std::unique_ptr<CpuSet> group(
-      new CpuSet(parent, name, base::unique_fd(dup(base_fd))));
-  path_map_.insert(std::make_pair(group->path(), group.get()));
-
-  while (dirent* entry = directory.Next()) {
-    if (entry->d_type == DT_DIR) {
-      std::string directory_name(entry->d_name);
-
-      if (directory_name == "." || directory_name == "..")
-        continue;
-
-      base::unique_fd entry_fd(
-          openat(base_fd.get(), directory_name.c_str(), kDirectoryFlags));
-      if (entry_fd.get() >= 0) {
-        auto child =
-            Create(std::move(entry_fd), directory_name.c_str(), group.get());
-
-        if (child)
-          group->AddChild(std::move(child));
-        else
-          return nullptr;
-      } else {
-        ALOGE("CpuSet::Create: Failed to openat \"%s\": %s", entry->d_name,
-              strerror(errno));
-        return nullptr;
-      }
-    }
-  }
-
-  return group;
-}
-
-CpuSet* CpuSetManager::Lookup(const std::string& path) {
-  auto search = path_map_.find(path);
-  if (search != path_map_.end())
-    return search->second;
-  else
-    return nullptr;
-}
-
-std::vector<CpuSet*> CpuSetManager::GetCpuSets() {
-  std::vector<CpuSet*> sets(path_map_.size());
-
-  for (const auto& pair : path_map_) {
-    sets.push_back(pair.second);
-  }
-
-  return sets;
-}
-
-void CpuSetManager::DumpState(std::ostringstream& stream) const {
-  size_t max_path = 0;
-  std::vector<CpuSet*> sets;
-
-  for (const auto& pair : path_map_) {
-    max_path = std::max(max_path, pair.second->path().length());
-    sets.push_back(pair.second);
-  }
-
-  std::sort(sets.begin(), sets.end(), [](const CpuSet* a, const CpuSet* b) {
-    return a->path() < b->path();
-  });
-
-  stream << std::left;
-  stream << std::setw(max_path) << "Path";
-  stream << " ";
-  stream << std::setw(6) << "CPUs";
-  stream << " ";
-  stream << std::setw(6) << "Tasks";
-  stream << std::endl;
-
-  stream << std::string(max_path, '_');
-  stream << " ";
-  stream << std::string(6, '_');
-  stream << " ";
-  stream << std::string(6, '_');
-  stream << std::endl;
-
-  for (const auto set : sets) {
-    stream << std::left;
-    stream << std::setw(max_path) << set->path();
-    stream << " ";
-    stream << std::right;
-    stream << std::setw(6) << set->GetCpuList();
-    stream << " ";
-    stream << std::setw(6) << set->GetTasks().size();
-    stream << std::endl;
-  }
-}
-
-void CpuSetManager::MoveUnboundTasks(const std::string& target_set) {
-  auto root = Lookup("/");
-  if (!root) {
-    ALOGE("CpuSetManager::MoveUnboundTasks: Failed to find root cpuset!");
-    return;
-  }
-
-  auto target = Lookup(target_set);
-  if (!target) {
-    ALOGE(
-        "CpuSetManager::MoveUnboundTasks: Failed to find target cpuset \"%s\"!",
-        target_set.c_str());
-    return;
-  }
-
-  auto cpu_list = root->GetCpuList();
-
-  for (auto task_id : root->GetTasks()) {
-    Task task(task_id);
-
-    // Move only unbound kernel threads to the target cpuset.
-    if (task.cpus_allowed_list() == cpu_list &&
-        task.parent_process_id() == kKernelThreadDaemonPid) {
-      ALOGD_IF(TRACE,
-               "CpuSetManager::MoveUnboundTasks: Moving task_id=%d name=%s to "
-               "target_set=%s tgid=%d ppid=%d.",
-               task_id, task.name().c_str(), target_set.c_str(),
-               task.thread_group_id(), task.parent_process_id());
-
-      auto status = target->AttachTask(task_id);
-      ALOGW_IF(!status && status.error() != EINVAL,
-               "CpuSetManager::MoveUnboundTasks: Failed to attach task_id=%d "
-               "to cpuset=%s: %s",
-               task_id, target_set.c_str(), status.GetErrorMessage().c_str());
-    } else {
-      ALOGD_IF(TRACE,
-               "CpuSet::MoveUnboundTasks: Skipping task_id=%d name=%s cpus=%s.",
-               task_id, task.name().c_str(), task.cpus_allowed_list().c_str());
-    }
-  }
-}
-
-CpuSet::CpuSet(CpuSet* parent, const std::string& name,
-               base::unique_fd&& cpuset_fd)
-    : parent_(parent), name_(name), cpuset_fd_(std::move(cpuset_fd)) {
-  if (parent_ == nullptr)
-    path_ = name_;
-  else if (parent_->IsRoot())
-    path_ = parent_->name() + name_;
-  else
-    path_ = parent_->path() + "/" + name_;
-
-  ALOGI("CpuSet::CpuSet: path=%s", path().c_str());
-}
-
-base::unique_fd CpuSet::OpenPropertyFile(const std::string& name) const {
-  return OpenFile(prefix_enabled_ ? "cpuset." + name : name);
-}
-
-UniqueFile CpuSet::OpenPropertyFilePointer(const std::string& name) const {
-  return OpenFilePointer(prefix_enabled_ ? "cpuset." + name : name);
-}
-
-base::unique_fd CpuSet::OpenFile(const std::string& name, int flags) const {
-  const std::string relative_path = "./" + name;
-  return base::unique_fd(
-      openat(cpuset_fd_.get(), relative_path.c_str(), flags));
-}
-
-UniqueFile CpuSet::OpenFilePointer(const std::string& name, int flags) const {
-  const std::string relative_path = "./" + name;
-  base::unique_fd fd(openat(cpuset_fd_.get(), relative_path.c_str(), flags));
-  if (fd.get() < 0) {
-    ALOGE("CpuSet::OpenPropertyFilePointer: Failed to open %s/%s: %s",
-          path_.c_str(), name.c_str(), strerror(errno));
-    return nullptr;
-  }
-
-  UniqueFile fp(fdopen(fd.release(), "r"));
-  if (!fp)
-    ALOGE("CpuSet::OpenPropertyFilePointer: Failed to fdopen %s/%s: %s",
-          path_.c_str(), name.c_str(), strerror(errno));
-
-  return fp;
-}
-
-Status<void> CpuSet::AttachTask(pid_t task_id) const {
-  auto file = OpenFile("tasks", O_RDWR);
-  if (file.get() >= 0) {
-    std::ostringstream stream;
-    stream << task_id;
-    std::string value = stream.str();
-
-    const bool ret = base::WriteStringToFd(value, file.get());
-    if (!ret)
-      return ErrorStatus(errno);
-    else
-      return {};
-  } else {
-    const int error = errno;
-    ALOGE("CpuSet::AttachTask: Failed to open %s/tasks: %s", path_.c_str(),
-          strerror(error));
-    return ErrorStatus(error);
-  }
-}
-
-std::vector<pid_t> CpuSet::GetTasks() const {
-  std::vector<pid_t> tasks;
-
-  if (auto file = OpenFilePointer("tasks")) {
-    stdio_filebuf<char> filebuf(file.get());
-    std::istream file_stream(&filebuf);
-
-    for (std::string line; std::getline(file_stream, line);) {
-      pid_t task_id = std::strtol(line.c_str(), nullptr, 10);
-      tasks.push_back(task_id);
-    }
-  }
-
-  return tasks;
-}
-
-std::string CpuSet::GetCpuList() const {
-  if (auto file = OpenPropertyFilePointer("cpus")) {
-    stdio_filebuf<char> filebuf(file.get());
-    std::istream file_stream(&filebuf);
-
-    std::string line;
-    if (std::getline(file_stream, line))
-      return line;
-  }
-
-  ALOGE("CpuSet::GetCpuList: Failed to read cpu list!!!");
-  return "";
-}
-
-void CpuSet::AddChild(std::unique_ptr<CpuSet> child) {
-  children_.push_back(std::move(child));
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/performanced/cpu_set.h b/services/vr/performanced/cpu_set.h
deleted file mode 100644
index 4c25e9e..0000000
--- a/services/vr/performanced/cpu_set.h
+++ /dev/null
@@ -1,108 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCED_CPU_SET_H_
-#define ANDROID_DVR_PERFORMANCED_CPU_SET_H_
-
-#include <fcntl.h>
-
-#include <memory>
-#include <mutex>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include <android-base/unique_fd.h>
-
-#include <pdx/status.h>
-
-#include "unique_file.h"
-
-namespace android {
-namespace dvr {
-
-class CpuSet {
- public:
-  // Returns the parent group for this group, if any. This pointer is owned by
-  // the group hierarchy and is only valid as long as the hierarchy is valid.
-  CpuSet* parent() const { return parent_; }
-  std::string name() const { return name_; }
-  std::string path() const { return path_; }
-
-  bool IsRoot() const { return parent_ == nullptr; }
-
-  std::string GetCpuList() const;
-
-  pdx::Status<void> AttachTask(pid_t task_id) const;
-  std::vector<pid_t> GetTasks() const;
-
- private:
-  friend class CpuSetManager;
-
-  CpuSet(CpuSet* parent, const std::string& name, base::unique_fd&& cpuset_fd);
-
-  void AddChild(std::unique_ptr<CpuSet> child);
-
-  base::unique_fd OpenPropertyFile(const std::string& name) const;
-  UniqueFile OpenPropertyFilePointer(const std::string& name) const;
-
-  base::unique_fd OpenFile(const std::string& name, int flags = O_RDONLY) const;
-  UniqueFile OpenFilePointer(const std::string& name,
-                             int flags = O_RDONLY) const;
-
-  CpuSet* parent_;
-  std::string name_;
-  std::string path_;
-  base::unique_fd cpuset_fd_;
-  std::vector<std::unique_ptr<CpuSet>> children_;
-
-  static void SetPrefixEnabled(bool enabled) { prefix_enabled_ = enabled; }
-  static bool prefix_enabled_;
-
-  CpuSet(const CpuSet&) = delete;
-  void operator=(const CpuSet&) = delete;
-};
-
-class CpuSetManager {
- public:
-  CpuSetManager() {}
-
-  // Creats a CpuSet hierarchy by walking the directory tree starting at
-  // |cpuset_root|. This argument must be the path to the root cpuset for the
-  // system, which is usually /dev/cpuset.
-  void Load(const std::string& cpuset_root);
-
-  // Lookup and return a CpuSet from a cpuset path. Ownership of the pointer
-  // DOES NOT pass to the caller; the pointer remains valid as long as the
-  // CpuSet hierarchy is valid.
-  CpuSet* Lookup(const std::string& path);
-
-  // Returns a vector of all the cpusets found at initializaiton. Ownership of
-  // the pointers to CpuSets DOES NOT pass to the caller; the pointers remain
-  // valid as long as the CpuSet hierarchy is valid.
-  std::vector<CpuSet*> GetCpuSets();
-
-  // Moves all unbound tasks from the root set into the target set. This is used
-  // to shield the system from interference from unbound kernel threads.
-  void MoveUnboundTasks(const std::string& target_set);
-
-  void DumpState(std::ostringstream& stream) const;
-
-  operator bool() const { return root_set_ != nullptr; }
-
- private:
-  // Creates a CpuSet from a path to a cpuset cgroup directory. Recursively
-  // creates child groups for each directory found under |path|.
-  std::unique_ptr<CpuSet> Create(const std::string& path);
-  std::unique_ptr<CpuSet> Create(base::unique_fd base_fd,
-                                 const std::string& name, CpuSet* parent);
-
-  std::unique_ptr<CpuSet> root_set_;
-  std::unordered_map<std::string, CpuSet*> path_map_;
-
-  CpuSetManager(const CpuSetManager&) = delete;
-  void operator=(const CpuSetManager&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_PERFORMANCED_CPU_SET_H_
diff --git a/services/vr/performanced/directory_reader.h b/services/vr/performanced/directory_reader.h
deleted file mode 100644
index f8359c4..0000000
--- a/services/vr/performanced/directory_reader.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCED_DIRECTORY_READER_H_
-#define ANDROID_DVR_PERFORMANCED_DIRECTORY_READER_H_
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <android-base/unique_fd.h>
-
-namespace android {
-namespace dvr {
-
-// Utility class around readdir() that handles automatic cleanup.
-class DirectoryReader {
- public:
-  explicit DirectoryReader(base::unique_fd directory_fd) {
-    int fd = directory_fd.release();
-    directory_ = fdopendir(fd);
-    error_ = errno;
-    if (directory_ == nullptr)
-      close(fd);
-  }
-
-  ~DirectoryReader() {
-    if (directory_)
-      closedir(directory_);
-  }
-
-  bool IsValid() const { return directory_ != nullptr; }
-  explicit operator bool() const { return IsValid(); }
-  int GetError() const { return error_; }
-
-  // Returns a pointer to a dirent describing the next directory entry. The
-  // pointer is only valid unitl the next call to Next() or the DirectoryReader
-  // is destroyed. Returns nullptr when the end of the directory is reached.
-  dirent* Next() {
-    if (directory_)
-      return readdir(directory_);
-    else
-      return nullptr;
-  }
-
- private:
-  DIR* directory_;
-  int error_;
-
-  DirectoryReader(const DirectoryReader&) = delete;
-  void operator=(const DirectoryReader&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_PERFORMANCED_DIRECTORY_READER_H_
diff --git a/services/vr/performanced/main.cpp b/services/vr/performanced/main.cpp
deleted file mode 100644
index d7dc8f6..0000000
--- a/services/vr/performanced/main.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <errno.h>
-#include <sys/capability.h>
-#include <sys/prctl.h>
-#include <sys/stat.h>
-
-#include <cutils/properties.h>
-#include <cutils/sched_policy.h>
-#include <log/log.h>
-#include <sys/resource.h>
-#include <utils/threads.h>
-
-#include <pdx/service_dispatcher.h>
-#include <private/android_filesystem_config.h>
-
-#include "performance_service.h"
-
-namespace {
-
-// Annoying that sys/capability.h doesn't define this directly.
-constexpr int kMaxCapNumber = (CAP_TO_INDEX(CAP_LAST_CAP) + 1);
-
-}  // anonymous namespace
-
-int main(int /*argc*/, char** /*argv*/) {
-  int ret = -1;
-
-  struct __user_cap_header_struct capheader;
-  struct __user_cap_data_struct capdata[kMaxCapNumber];
-
-  std::shared_ptr<android::pdx::Service> service;
-  std::unique_ptr<android::pdx::ServiceDispatcher> dispatcher;
-
-  ALOGI("Starting up...");
-
-  // We need to be able to create endpoints with full perms.
-  umask(0000);
-
-  // Keep capabilities when switching UID to AID_SYSTEM.
-  ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
-  CHECK_ERROR(ret < 0, error, "Failed to set KEEPCAPS: %s", strerror(errno));
-
-  // Set UID and GID to system.
-  ret = setresgid(AID_SYSTEM, AID_SYSTEM, AID_SYSTEM);
-  CHECK_ERROR(ret < 0, error, "Failed to set GID: %s", strerror(errno));
-  ret = setresuid(AID_SYSTEM, AID_SYSTEM, AID_SYSTEM);
-  CHECK_ERROR(ret < 0, error, "Failed to set UID: %s", strerror(errno));
-
-  // Keep CAP_SYS_NICE, allowing control of scheduler class, priority, and
-  // cpuset for other tasks in the system.
-  memset(&capheader, 0, sizeof(capheader));
-  memset(&capdata, 0, sizeof(capdata));
-  capheader.version = _LINUX_CAPABILITY_VERSION_3;
-  capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_NICE);
-  capdata[CAP_TO_INDEX(CAP_SYS_NICE)].permitted |= CAP_TO_MASK(CAP_SYS_NICE);
-
-  // Drop all caps but the ones configured above.
-  ret = capset(&capheader, capdata);
-  CHECK_ERROR(ret < 0, error, "Could not set capabilities: %s",
-              strerror(errno));
-
-  dispatcher = android::pdx::ServiceDispatcher::Create();
-  CHECK_ERROR(!dispatcher, error, "Failed to create service dispatcher.");
-
-  service = android::dvr::PerformanceService::Create();
-  CHECK_ERROR(!service, error, "Failed to create performance service service.");
-  dispatcher->AddService(service);
-
-  ALOGI("Entering message loop.");
-
-  ret = dispatcher->EnterDispatchLoop();
-  CHECK_ERROR(ret < 0, error, "Dispatch loop exited because: %s\n",
-              strerror(-ret));
-
-error:
-  return ret;
-}
diff --git a/services/vr/performanced/performance_service.cpp b/services/vr/performanced/performance_service.cpp
deleted file mode 100644
index 73dcf76..0000000
--- a/services/vr/performanced/performance_service.cpp
+++ /dev/null
@@ -1,461 +0,0 @@
-#include "performance_service.h"
-
-#include <sstream>
-
-#include <sched.h>
-#include <sys/prctl.h>
-#include <unistd.h>
-
-#include <pdx/default_transport/service_endpoint.h>
-#include <pdx/rpc/argument_encoder.h>
-#include <pdx/rpc/message_buffer.h>
-#include <pdx/rpc/remote_method.h>
-#include <private/android_filesystem_config.h>
-#include <private/dvr/performance_rpc.h>
-#include <private/dvr/trusted_uids.h>
-
-#include "task.h"
-
-// This prctl is only available in Android kernels.
-#define PR_SET_TIMERSLACK_PID 41
-
-using android::dvr::IsTrustedUid;
-using android::dvr::Task;
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::Status;
-using android::pdx::default_transport::Endpoint;
-using android::pdx::rpc::DispatchRemoteMethod;
-
-namespace {
-
-const char kCpuSetBasePath[] = "/dev/cpuset";
-
-const char kRootCpuSet[] = "/";
-
-const char kVrAppRenderPolicy[] = "vr:app:render";
-
-const bool kAllowAppsToRequestVrAppRenderPolicy = false;
-
-constexpr unsigned long kTimerSlackForegroundNs = 50000;
-constexpr unsigned long kTimerSlackBackgroundNs = 40000000;
-
-// Expands the given parameter pack expression using an initializer list to
-// guarantee ordering and a comma expression to guarantee even void expressions
-// are valid elements of the initializer list.
-#define EXPAND_PACK(...) \
-  std::initializer_list<int> { (__VA_ARGS__, 0)... }
-
-// Returns true if the sender's euid matches any of the uids in |UIDs|.
-template <uid_t... UIDs>
-struct UserId {
-  static bool Check(const Message& sender, const Task&) {
-    const uid_t uid = sender.GetEffectiveUserId();
-    bool allow = false;
-    EXPAND_PACK(allow |= (uid == UIDs));
-    return allow;
-  }
-};
-
-// Returns true if the sender's egid matches any of the gids in |GIDs|.
-template <gid_t... GIDs>
-struct GroupId {
-  static bool Check(const Message& sender, const Task&) {
-    const gid_t gid = sender.GetEffectiveGroupId();
-    bool allow = false;
-    EXPAND_PACK(allow |= (gid == GIDs));
-    return allow;
-  }
-};
-
-// Returns true if the sender's euid is trusted according to VR manager service.
-struct Trusted {
-  static bool Check(const Message& sender, const Task&) {
-    return IsTrustedUid(sender.GetEffectiveUserId());
-  }
-};
-
-// Returns returns true if the task belongs to the sending process.
-struct SameProcess {
-  static bool Check(const Message& sender, const Task& task) {
-    return sender.GetProcessId() == task.thread_group_id();
-  }
-};
-
-// Returns true if any of the checks in |Allows| pass, false otherwise.
-template <typename... Allows>
-struct CheckOr {
-  static bool Check(const Message& sender, const Task& task) {
-    bool allow = false;
-    EXPAND_PACK(allow |= Allows::Check(sender, task));
-    return allow;
-  }
-};
-
-// Returns true if all of the checks in |Allows| pass, false otherwise.
-template <typename... Allows>
-struct CheckAnd {
-  static bool Check(const Message& sender, const Task& task) {
-    bool allow = true;
-    EXPAND_PACK(allow &= Allows::Check(sender, task));
-    return allow;
-  }
-};
-
-}  // anonymous namespace
-
-namespace android {
-namespace dvr {
-
-PerformanceService::PerformanceService()
-    : BASE("PerformanceService",
-           Endpoint::Create(PerformanceRPC::kClientPath)) {
-  cpuset_.Load(kCpuSetBasePath);
-
-  Task task(getpid());
-  ALOGI("Running in cpuset=%s uid=%d gid=%d", task.GetCpuSetPath().c_str(),
-        task.user_id()[Task::kUidReal], task.group_id()[Task::kUidReal]);
-
-  // Errors here are checked in IsInitialized().
-  sched_fifo_min_priority_ = sched_get_priority_min(SCHED_FIFO);
-  sched_fifo_max_priority_ = sched_get_priority_max(SCHED_FIFO);
-
-  const int fifo_range = sched_fifo_max_priority_ - sched_fifo_min_priority_;
-  const int fifo_low = sched_fifo_min_priority_;
-  const int fifo_medium = sched_fifo_min_priority_ + fifo_range / 5;
-
-  // TODO(eieio): Make this configurable on the command line or config file.
-  cpuset_.MoveUnboundTasks("/kernel");
-
-  // TODO(eieio): Replace this witha device-specific config file. This is just a
-  // hack for now to put some form of permission logic in place while a longer
-  // term solution is developed.
-  using AllowRootSystemGraphics =
-      CheckAnd<SameProcess, CheckOr<UserId<AID_ROOT, AID_SYSTEM, AID_GRAPHICS>,
-                                    GroupId<AID_SYSTEM, AID_GRAPHICS>>>;
-  using AllowRootSystemAudio =
-      CheckAnd<SameProcess, CheckOr<UserId<AID_ROOT, AID_SYSTEM, AID_AUDIO>,
-                                    GroupId<AID_SYSTEM, AID_AUDIO>>>;
-  using AllowRootSystemTrusted =
-      CheckOr<Trusted, UserId<AID_ROOT, AID_SYSTEM>, GroupId<AID_SYSTEM>>;
-
-  auto vr_app_render_permission_check = [](
-      const pdx::Message& sender, const Task& task) {
-          // For vr:app:render, in addition to system/root apps and VrCore, we
-          // also allow apps to request vr:app:render if
-          // kAllowAppsToRequestVrAppRenderPolicy == true, but not for other
-          // apps, only for themselves.
-          return (task && task.thread_group_id() == sender.GetProcessId() &&
-                  kAllowAppsToRequestVrAppRenderPolicy)
-              || AllowRootSystemTrusted::Check(sender, task);
-      };
-
-  partition_permission_check_ = AllowRootSystemTrusted::Check;
-
-  // Setup the scheduler classes.
-  // TODO(eieio): Replace this with a device-specific config file.
-  scheduler_policies_ = {
-      {"audio:low",
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
-        .priority = fifo_medium,
-        .permission_check = AllowRootSystemAudio::Check}},
-      {"audio:high",
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
-        .priority = fifo_medium + 3,
-        .permission_check = AllowRootSystemAudio::Check}},
-      {"graphics",
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
-        .priority = fifo_medium,
-        .permission_check = AllowRootSystemGraphics::Check}},
-      {"graphics:low",
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
-        .priority = fifo_medium,
-        .permission_check = AllowRootSystemGraphics::Check}},
-      {"graphics:high",
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
-        .priority = fifo_medium + 2,
-        .permission_check = AllowRootSystemGraphics::Check}},
-      {"sensors",
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
-        .priority = fifo_low,
-        .permission_check = AllowRootSystemTrusted::Check}},
-      {"sensors:low",
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
-        .priority = fifo_low,
-        .permission_check = AllowRootSystemTrusted::Check}},
-      {"sensors:high",
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
-        .priority = fifo_low + 1,
-        .permission_check = AllowRootSystemTrusted::Check}},
-      {"vr:system:arp",
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
-        .priority = fifo_medium + 2,
-        .permission_check = AllowRootSystemTrusted::Check,
-        "/system/performance"}},
-      {kVrAppRenderPolicy,
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
-        .priority = fifo_medium + 1,
-        .permission_check = vr_app_render_permission_check,
-        "/application/performance"}},
-      {"normal",
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_NORMAL,
-        .priority = 0}},
-      {"foreground",
-       {.timer_slack = kTimerSlackForegroundNs,
-        .scheduler_policy = SCHED_NORMAL,
-        .priority = 0}},
-      {"background",
-       {.timer_slack = kTimerSlackBackgroundNs,
-        .scheduler_policy = SCHED_BATCH,
-        .priority = 0}},
-      {"batch",
-       {.timer_slack = kTimerSlackBackgroundNs,
-        .scheduler_policy = SCHED_BATCH,
-        .priority = 0}},
-  };
-}
-
-bool PerformanceService::IsInitialized() const {
-  return BASE::IsInitialized() && cpuset_ && sched_fifo_min_priority_ >= 0 &&
-         sched_fifo_max_priority_ >= 0;
-}
-
-std::string PerformanceService::DumpState(size_t /*max_length*/) {
-  std::ostringstream stream;
-  stream << "vr_app_render_thread: " << vr_app_render_thread_ << std::endl;
-  cpuset_.DumpState(stream);
-  return stream.str();
-}
-
-Status<void> PerformanceService::OnSetSchedulerPolicy(
-    Message& message, pid_t task_id, const std::string& scheduler_policy) {
-  ALOGI(
-      "PerformanceService::OnSetSchedulerPolicy: task_id=%d "
-      "scheduler_policy=%s",
-      task_id, scheduler_policy.c_str());
-
-  Task task(task_id);
-  if (!task) {
-    ALOGE(
-        "PerformanceService::OnSetSchedulerPolicy: Unable to access /proc/%d "
-        "to gather task information.",
-        task_id);
-    return ErrorStatus(EINVAL);
-  }
-
-  auto search = scheduler_policies_.find(scheduler_policy);
-  if (search != scheduler_policies_.end()) {
-    auto config = search->second;
-
-    // Make sure the sending process is allowed to make the requested change to
-    // this task.
-    if (!config.IsAllowed(message, task))
-      return ErrorStatus(EPERM);
-
-    if (scheduler_policy == kVrAppRenderPolicy) {
-      // We only allow one vr:app:render thread at a time
-      SetVrAppRenderThread(task_id);
-    }
-
-    // Get the thread group's cpu set. Policies that do not specify a cpuset
-    // should default to this cpuset.
-    std::string thread_group_cpuset;
-    Task thread_group{task.thread_group_id()};
-    if (thread_group) {
-      thread_group_cpuset = thread_group.GetCpuSetPath();
-    } else {
-      ALOGE(
-          "PerformanceService::OnSetSchedulerPolicy: Failed to get thread "
-          "group tgid=%d for task_id=%d",
-          task.thread_group_id(), task_id);
-      thread_group_cpuset = kRootCpuSet;
-    }
-
-    std::string target_cpuset;
-    if (config.cpuset.empty()) {
-      target_cpuset = thread_group_cpuset;
-    } else {
-      target_cpuset = config.cpuset;
-    }
-    ALOGI("PerformanceService::OnSetSchedulerPolicy: Using cpuset=%s",
-          target_cpuset.c_str());
-
-    auto target_set = cpuset_.Lookup(target_cpuset);
-    if (target_set) {
-      auto attach_status = target_set->AttachTask(task_id);
-      ALOGW_IF(!attach_status,
-               "PerformanceService::OnSetSchedulerPolicy: Failed to attach "
-               "task=%d to cpuset=%s: %s",
-               task_id, target_cpuset.c_str(),
-               attach_status.GetErrorMessage().c_str());
-    } else {
-      ALOGW(
-          "PerformanceService::OnSetSchedulerPolicy: Failed to lookup "
-          "cpuset=%s",
-          target_cpuset.c_str());
-    }
-
-    struct sched_param param;
-    param.sched_priority = config.priority;
-
-    sched_setscheduler(task_id, config.scheduler_policy, &param);
-    prctl(PR_SET_TIMERSLACK_PID, config.timer_slack, task_id);
-    return {};
-  } else {
-    ALOGE(
-        "PerformanceService::OnSetSchedulerPolicy: Invalid scheduler_policy=%s "
-        "requested by task=%d.",
-        scheduler_policy.c_str(), task_id);
-    return ErrorStatus(EINVAL);
-  }
-}
-
-Status<void> PerformanceService::OnSetCpuPartition(
-    Message& message, pid_t task_id, const std::string& partition) {
-  Task task(task_id);
-  if (!task)
-    return ErrorStatus(EINVAL);
-  if (task.thread_group_id() != message.GetProcessId())
-    return ErrorStatus(EPERM);
-
-  // Temporary permission check.
-  // TODO(eieio): Replace this with a configuration file.
-  if (partition_permission_check_ &&
-      !partition_permission_check_(message, task)) {
-    return ErrorStatus(EPERM);
-  }
-
-  auto target_set = cpuset_.Lookup(partition);
-  if (!target_set)
-    return ErrorStatus(ENOENT);
-
-  auto attach_status = target_set->AttachTask(task_id);
-  if (!attach_status)
-    return attach_status;
-
-  return {};
-}
-
-Status<void> PerformanceService::OnSetSchedulerClass(
-    Message& message, pid_t task_id, const std::string& scheduler_class) {
-  Task task(task_id);
-  if (!task)
-    return ErrorStatus(EINVAL);
-
-  auto search = scheduler_policies_.find(scheduler_class);
-  if (search != scheduler_policies_.end()) {
-    auto config = search->second;
-
-    // Make sure the sending process is allowed to make the requested change to
-    // this task.
-    if (!config.IsAllowed(message, task))
-      return ErrorStatus(EPERM);
-
-    if (scheduler_class == kVrAppRenderPolicy) {
-      // We only allow one vr:app:render thread at a time
-      SetVrAppRenderThread(task_id);
-    }
-
-    struct sched_param param;
-    param.sched_priority = config.priority;
-
-    sched_setscheduler(task_id, config.scheduler_policy, &param);
-    prctl(PR_SET_TIMERSLACK_PID, config.timer_slack, task_id);
-    ALOGI("PerformanceService::OnSetSchedulerClass: Set task=%d to class=%s.",
-          task_id, scheduler_class.c_str());
-    return {};
-  } else {
-    ALOGE(
-        "PerformanceService::OnSetSchedulerClass: Invalid class=%s requested "
-        "by task=%d.",
-        scheduler_class.c_str(), task_id);
-    return ErrorStatus(EINVAL);
-  }
-}
-
-Status<std::string> PerformanceService::OnGetCpuPartition(Message& message,
-                                                          pid_t task_id) {
-  // Make sure the task id is valid and belongs to the sending process.
-  Task task(task_id);
-  if (!task)
-    return ErrorStatus(EINVAL);
-  if (task.thread_group_id() != message.GetProcessId())
-    return ErrorStatus(EPERM);
-
-  return task.GetCpuSetPath();
-}
-
-Status<void> PerformanceService::HandleMessage(Message& message) {
-  ALOGD_IF(TRACE, "PerformanceService::HandleMessage: op=%d", message.GetOp());
-  switch (message.GetOp()) {
-    case PerformanceRPC::SetSchedulerPolicy::Opcode:
-      DispatchRemoteMethod<PerformanceRPC::SetSchedulerPolicy>(
-          *this, &PerformanceService::OnSetSchedulerPolicy, message);
-      return {};
-
-    case PerformanceRPC::SetCpuPartition::Opcode:
-      DispatchRemoteMethod<PerformanceRPC::SetCpuPartition>(
-          *this, &PerformanceService::OnSetCpuPartition, message);
-      return {};
-
-    case PerformanceRPC::SetSchedulerClass::Opcode:
-      DispatchRemoteMethod<PerformanceRPC::SetSchedulerClass>(
-          *this, &PerformanceService::OnSetSchedulerClass, message);
-      return {};
-
-    case PerformanceRPC::GetCpuPartition::Opcode:
-      DispatchRemoteMethod<PerformanceRPC::GetCpuPartition>(
-          *this, &PerformanceService::OnGetCpuPartition, message);
-      return {};
-
-    default:
-      return Service::HandleMessage(message);
-  }
-}
-
-void PerformanceService::SetVrAppRenderThread(pid_t new_vr_app_render_thread) {
-  ALOGI("SetVrAppRenderThread old=%d new=%d",
-      vr_app_render_thread_, new_vr_app_render_thread);
-
-  if (vr_app_render_thread_ >= 0 &&
-      vr_app_render_thread_ != new_vr_app_render_thread) {
-    // Restore the default scheduler policy and priority on the previous
-    // vr:app:render thread.
-    struct sched_param param;
-    param.sched_priority = 0;
-    if (sched_setscheduler(vr_app_render_thread_, SCHED_NORMAL, &param) < 0) {
-      if (errno == ESRCH) {
-        ALOGI("Failed to revert %s scheduler policy. Couldn't find thread %d."
-            " Was the app killed?", kVrAppRenderPolicy, vr_app_render_thread_);
-      } else {
-        ALOGE("Failed to revert %s scheduler policy: %s",
-            kVrAppRenderPolicy, strerror(errno));
-      }
-    }
-
-    // Restore the default timer slack on the previous vr:app:render thread.
-    prctl(PR_SET_TIMERSLACK_PID, kTimerSlackForegroundNs,
-        vr_app_render_thread_);
-  }
-
-  // We could also reset the thread's cpuset here, but the cpuset is already
-  // managed by Android. Better to let Android adjust the cpuset as the app
-  // moves to the background, rather than adjust it ourselves here, and risk
-  // stomping on the value set by Android.
-
-  vr_app_render_thread_ = new_vr_app_render_thread;
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/performanced/performance_service.h b/services/vr/performanced/performance_service.h
deleted file mode 100644
index fe63756..0000000
--- a/services/vr/performanced/performance_service.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCED_PERFORMANCE_SERVICE_H_
-#define ANDROID_DVR_PERFORMANCED_PERFORMANCE_SERVICE_H_
-
-#include <functional>
-#include <string>
-#include <unordered_map>
-
-#include <pdx/service.h>
-
-#include "cpu_set.h"
-#include "task.h"
-
-namespace android {
-namespace dvr {
-
-// PerformanceService manages compute partitions usings cpusets. Different
-// cpusets are assigned specific purposes and performance characteristics;
-// clients may request for threads to be moved into these cpusets to help
-// achieve system performance goals.
-class PerformanceService : public pdx::ServiceBase<PerformanceService> {
- public:
-  pdx::Status<void> HandleMessage(pdx::Message& message) override;
-  bool IsInitialized() const override;
-
-  std::string DumpState(size_t max_length) override;
-
- private:
-  friend BASE;
-
-  PerformanceService();
-
-  pdx::Status<void> OnSetSchedulerPolicy(pdx::Message& message, pid_t task_id,
-                                         const std::string& scheduler_class);
-
-  pdx::Status<void> OnSetCpuPartition(pdx::Message& message, pid_t task_id,
-                                      const std::string& partition);
-  pdx::Status<void> OnSetSchedulerClass(pdx::Message& message, pid_t task_id,
-                                        const std::string& scheduler_class);
-  pdx::Status<std::string> OnGetCpuPartition(pdx::Message& message,
-                                             pid_t task_id);
-
-  // Set which thread gets the vr:app:render policy. Only one thread at a time
-  // is allowed to have vr:app:render. If multiple threads are allowed
-  // vr:app:render, and those threads busy loop, the system can freeze. When
-  // SetVrAppRenderThread() is called, the thread which we had previously
-  // assigned vr:app:render will have its scheduling policy reset to default
-  // values.
-  void SetVrAppRenderThread(pid_t new_vr_app_render_thread);
-
-  CpuSetManager cpuset_;
-
-  int sched_fifo_min_priority_;
-  int sched_fifo_max_priority_;
-
-  struct SchedulerPolicyConfig {
-    unsigned long timer_slack;
-    int scheduler_policy;
-    int priority;
-    std::function<bool(const pdx::Message& message, const Task& task)>
-        permission_check;
-    std::string cpuset;
-
-    // Check the permisison of the given task to use this scheduler class. If a
-    // permission check function is not set then operations are only allowed on
-    // tasks in the sender's process.
-    bool IsAllowed(const pdx::Message& sender, const Task& task) const {
-      if (permission_check)
-        return permission_check(sender, task);
-      else if (!task || task.thread_group_id() != sender.GetProcessId())
-        return false;
-      else
-        return true;
-    }
-  };
-
-  std::unordered_map<std::string, SchedulerPolicyConfig> scheduler_policies_;
-
-  std::function<bool(const pdx::Message& message, const Task& task)>
-      partition_permission_check_;
-
-  pid_t vr_app_render_thread_ = -1;
-
-  PerformanceService(const PerformanceService&) = delete;
-  void operator=(const PerformanceService&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_PERFORMANCED_PERFORMANCE_SERVICE_H_
diff --git a/services/vr/performanced/performance_service_tests.cpp b/services/vr/performanced/performance_service_tests.cpp
deleted file mode 100644
index a24c889..0000000
--- a/services/vr/performanced/performance_service_tests.cpp
+++ /dev/null
@@ -1,529 +0,0 @@
-#include <errno.h>
-#include <sched.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <condition_variable>
-#include <cstdlib>
-#include <iostream>
-#include <mutex>
-#include <sstream>
-#include <thread>
-#include <utility>
-
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-#include <dvr/performance_client_api.h>
-#include <gtest/gtest.h>
-#include <private/android_filesystem_config.h>
-
-#include "stdio_filebuf.h"
-#include "unique_file.h"
-
-using android::base::Trim;
-using android::dvr::UniqueFile;
-using android::dvr::stdio_filebuf;
-
-namespace {
-
-const char kTrustedUidEnvironmentVariable[] = "GTEST_TRUSTED_UID";
-
-const char kProcBase[] = "/proc";
-
-std::pair<UniqueFile, int> OpenTaskFile(pid_t task_id,
-                                        const std::string& name) {
-  std::ostringstream stream;
-  stream << kProcBase << "/" << task_id << "/" << name;
-
-  UniqueFile file{fopen(stream.str().c_str(), "r")};
-  const int error = file ? 0 : errno;
-  return {std::move(file), error};
-}
-
-std::string GetTaskCpuSet(pid_t task_id) {
-  int error;
-  UniqueFile file;
-
-  std::tie(file, error) = OpenTaskFile(task_id, "cpuset");
-  if (!file)
-    return std::string("errno:") + strerror(error);
-
-  stdio_filebuf<char> filebuf(file.get());
-  std::istream file_stream(&filebuf);
-
-  std::string line;
-  std::getline(file_stream, line);
-  return Trim(line);
-}
-
-}  // anonymous namespace
-
-TEST(PerformanceTest, SetCpuPartition) {
-  int error;
-
-  // Test setting the the partition for the current task.
-  error = dvrSetCpuPartition(0, "/application/background");
-  EXPECT_EQ(0, error);
-
-  error = dvrSetCpuPartition(0, "/application/performance");
-  EXPECT_EQ(0, error);
-
-  // Test setting the partition for one of our tasks.
-  bool done = false;
-  pid_t task_id = 0;
-  std::mutex mutex;
-  std::condition_variable done_condition, id_condition;
-
-  std::thread thread([&] {
-    std::unique_lock<std::mutex> lock(mutex);
-
-    task_id = gettid();
-    id_condition.notify_one();
-
-    done_condition.wait(lock, [&done] { return done; });
-  });
-
-  {
-    std::unique_lock<std::mutex> lock(mutex);
-    id_condition.wait(lock, [&task_id] { return task_id != 0; });
-  }
-  EXPECT_NE(0, task_id);
-
-  error = dvrSetCpuPartition(task_id, "/application");
-  EXPECT_EQ(0, error);
-
-  {
-    std::lock_guard<std::mutex> lock(mutex);
-    done = true;
-    done_condition.notify_one();
-  }
-  thread.join();
-
-  // Test setting the partition for a task that doesn't belong to us.
-  error = dvrSetCpuPartition(1, "/application");
-  EXPECT_EQ(-EINVAL, error);
-
-  // Test setting the partition to one that doesn't exist.
-  error = dvrSetCpuPartition(0, "/foobar");
-  EXPECT_EQ(-ENOENT, error);
-
-  // Set the test back to the root partition.
-  error = dvrSetCpuPartition(0, "/");
-  EXPECT_EQ(0, error);
-}
-
-TEST(PerformanceTest, SetSchedulerClass) {
-  int error;
-
-  // TODO(eieio): Test all supported scheduler classes and priority levels.
-
-  error = dvrSetSchedulerClass(0, "background");
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(SCHED_BATCH, sched_getscheduler(0));
-
-  error = dvrSetSchedulerClass(0, "audio:low");
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0));
-
-  error = dvrSetSchedulerClass(0, "normal");
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(SCHED_NORMAL, sched_getscheduler(0));
-
-  error = dvrSetSchedulerClass(0, "foobar");
-  EXPECT_EQ(-EINVAL, error);
-}
-
-TEST(PerformanceTest, SetSchedulerPolicy) {
-  int error;
-
-  error = dvrSetSchedulerPolicy(0, "background");
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(SCHED_BATCH, sched_getscheduler(0));
-
-  error = dvrSetSchedulerPolicy(0, "audio:low");
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0));
-
-  error = dvrSetSchedulerPolicy(0, "normal");
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(SCHED_NORMAL, sched_getscheduler(0));
-
-  error = dvrSetSchedulerPolicy(0, "foobar");
-  EXPECT_EQ(-EINVAL, error);
-
-  // Set the test back to the root partition.
-  error = dvrSetCpuPartition(0, "/");
-  EXPECT_EQ(0, error);
-
-  const std::string original_cpuset = GetTaskCpuSet(gettid());
-  EXPECT_EQ("/", original_cpuset);
-
-  error = dvrSetSchedulerPolicy(0, "vr:system:arp");
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0));
-
-  const std::string new_cpuset = GetTaskCpuSet(gettid());
-  EXPECT_NE(original_cpuset, new_cpuset);
-
-  // The cpuset for the thread group is now new_cpuset. Scheduler profiles that
-  // do not specify a cpuset should not change the cpuset of a thread, except to
-  // restore it to the thread group cpuset.
-  std::string thread_original_cpuset;
-  std::string thread_new_cpuset;
-  std::string thread_final_cpuset;
-
-  std::thread thread{
-      [&thread_original_cpuset, &thread_new_cpuset, &thread_final_cpuset]() {
-        thread_original_cpuset = GetTaskCpuSet(gettid());
-
-        int error = dvrSetSchedulerPolicy(0, "vr:app:render");
-        EXPECT_EQ(0, error);
-
-        thread_new_cpuset = GetTaskCpuSet(gettid());
-
-        error = dvrSetSchedulerPolicy(0, "normal");
-        EXPECT_EQ(0, error);
-
-        thread_final_cpuset = GetTaskCpuSet(gettid());
-      }};
-  thread.join();
-
-  EXPECT_EQ(new_cpuset, thread_original_cpuset);
-  EXPECT_NE(new_cpuset, thread_new_cpuset);
-  EXPECT_EQ(new_cpuset, thread_final_cpuset);
-
-  error = dvrSetCpuPartition(0, original_cpuset.c_str());
-  EXPECT_EQ(0, error);
-}
-
-TEST(PerformanceTest, SchedulerClassResetOnFork) {
-  int error;
-
-  error = dvrSetSchedulerClass(0, "graphics:high");
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0));
-
-  int scheduler = -1;
-  std::thread thread([&]() { scheduler = sched_getscheduler(0); });
-  thread.join();
-
-  EXPECT_EQ(SCHED_NORMAL, scheduler);
-
-  // Return to SCHED_NORMAL.
-  error = dvrSetSchedulerClass(0, "normal");
-  EXPECT_EQ(0, error);
-  EXPECT_EQ(SCHED_NORMAL, sched_getscheduler(0));
-}
-
-TEST(PerformanceTest, GetCpuPartition) {
-  int error;
-  char partition[PATH_MAX + 1];
-
-  error = dvrSetCpuPartition(0, "/");
-  ASSERT_EQ(0, error);
-
-  error = dvrGetCpuPartition(0, partition, sizeof(partition));
-  EXPECT_EQ(0, error);
-  EXPECT_EQ("/", std::string(partition));
-
-  error = dvrSetCpuPartition(0, "/application");
-  EXPECT_EQ(0, error);
-
-  error = dvrGetCpuPartition(0, partition, sizeof(partition));
-  EXPECT_EQ(0, error);
-  EXPECT_EQ("/application", std::string(partition));
-
-  // Test passing a buffer that is too short.
-  error = dvrGetCpuPartition(0, partition, 5);
-  EXPECT_EQ(-ENOBUFS, error);
-
-  // Test getting the partition for a task that doesn't belong to us.
-  error = dvrGetCpuPartition(1, partition, sizeof(partition));
-  EXPECT_EQ(-EINVAL, error);
-
-  // Test passing a nullptr value for partition buffer.
-  error = dvrGetCpuPartition(0, nullptr, sizeof(partition));
-  EXPECT_EQ(-EINVAL, error);
-}
-
-TEST(PerformanceTest, Permissions) {
-  int error;
-
-  const int original_uid = getuid();
-  const int original_gid = getgid();
-  int trusted_uid = -1;
-
-  // See if the environment variable GTEST_TRUSTED_UID is set. If it is enable
-  // testing the ActivityManager trusted uid permission checks using that uid.
-  const char* trusted_uid_env = std::getenv(kTrustedUidEnvironmentVariable);
-  if (trusted_uid_env)
-    trusted_uid = std::atoi(trusted_uid_env);
-
-  ASSERT_EQ(AID_ROOT, original_uid)
-      << "This test must run as root to function correctly!";
-
-  // Test unprivileged policies on a task that does not belong to this process.
-  // Use the init process (task_id=1) as the target.
-  error = dvrSetSchedulerPolicy(1, "batch");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(1, "background");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(1, "foreground");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(1, "normal");
-  EXPECT_EQ(-EINVAL, error);
-
-  // Switch the uid/gid to an id that should not have permission to access any
-  // privileged actions.
-  ASSERT_EQ(0, setresgid(AID_NOBODY, AID_NOBODY, -1))
-      << "Failed to set gid: " << strerror(errno);
-  ASSERT_EQ(0, setresuid(AID_NOBODY, AID_NOBODY, -1))
-      << "Failed to set uid: " << strerror(errno);
-
-  // Unprivileged policies.
-  error = dvrSetSchedulerPolicy(0, "batch");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "background");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "foreground");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "normal");
-  EXPECT_EQ(0, error);
-
-  // Privileged policies.
-  error = dvrSetSchedulerPolicy(0, "audio:low");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "audio:high");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "graphics");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "graphics:low");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "graphics:high");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "sensors");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "sensors:low");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "sensors:high");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "vr:system:arp");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "vr:app:render");
-  EXPECT_EQ(-EINVAL, error);
-
-  // uid=AID_SYSTEM / gid=AID_NOBODY
-  ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
-      << "Failed to restore uid: " << strerror(errno);
-  ASSERT_EQ(0, setresuid(AID_SYSTEM, AID_SYSTEM, -1))
-      << "Failed to set uid: " << strerror(errno);
-
-  // Unprivileged policies.
-  error = dvrSetSchedulerPolicy(0, "batch");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "background");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "foreground");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "normal");
-  EXPECT_EQ(0, error);
-
-  // Privileged policies.
-  error = dvrSetSchedulerPolicy(0, "audio:low");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "audio:high");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "graphics");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "graphics:low");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "graphics:high");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "sensors");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "sensors:low");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "sensors:high");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "vr:system:arp");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "vr:app:render");
-  EXPECT_EQ(0, error);
-
-  // uid=AID_NOBODY / gid=AID_SYSTEM
-  ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
-      << "Failed to restore uid: " << strerror(errno);
-  ASSERT_EQ(0, setresgid(original_gid, original_gid, -1))
-      << "Failed to restore gid: " << strerror(errno);
-  ASSERT_EQ(0, setresgid(AID_SYSTEM, AID_SYSTEM, -1))
-      << "Failed to set gid: " << strerror(errno);
-  ASSERT_EQ(0, setresuid(AID_SYSTEM, AID_NOBODY, -1))
-      << "Failed to set uid: " << strerror(errno);
-
-  // Unprivileged policies.
-  error = dvrSetSchedulerPolicy(0, "batch");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "background");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "foreground");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "normal");
-  EXPECT_EQ(0, error);
-
-  // Privileged policies.
-  error = dvrSetSchedulerPolicy(0, "audio:low");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "audio:high");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "graphics");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "graphics:low");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "graphics:high");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "sensors");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "sensors:low");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "sensors:high");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "vr:system:arp");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "vr:app:render");
-  EXPECT_EQ(0, error);
-
-  // uid=AID_GRAPHICS / gid=AID_NOBODY
-  ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
-      << "Failed to restore uid: " << strerror(errno);
-  ASSERT_EQ(0, setresgid(original_gid, original_gid, -1))
-      << "Failed to restore gid: " << strerror(errno);
-  ASSERT_EQ(0, setresgid(AID_NOBODY, AID_NOBODY, -1))
-      << "Failed to set gid: " << strerror(errno);
-  ASSERT_EQ(0, setresuid(AID_GRAPHICS, AID_GRAPHICS, -1))
-      << "Failed to set uid: " << strerror(errno);
-
-  // Unprivileged policies.
-  error = dvrSetSchedulerPolicy(0, "batch");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "background");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "foreground");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "normal");
-  EXPECT_EQ(0, error);
-
-  // Privileged policies.
-  error = dvrSetSchedulerPolicy(0, "audio:low");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "audio:high");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "graphics");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "graphics:low");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "graphics:high");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "sensors");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "sensors:low");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "sensors:high");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "vr:system:arp");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "vr:app:render");
-  EXPECT_EQ(-EINVAL, error);
-
-  // uid=AID_NOBODY / gid=AID_GRAPHICS
-  ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
-      << "Failed to restore uid: " << strerror(errno);
-  ASSERT_EQ(0, setresgid(original_gid, original_gid, -1))
-      << "Failed to restore gid: " << strerror(errno);
-  ASSERT_EQ(0, setresgid(AID_GRAPHICS, AID_GRAPHICS, -1))
-      << "Failed to set gid: " << strerror(errno);
-  ASSERT_EQ(0, setresuid(AID_NOBODY, AID_NOBODY, -1))
-      << "Failed to set uid: " << strerror(errno);
-
-  // Unprivileged policies.
-  error = dvrSetSchedulerPolicy(0, "batch");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "background");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "foreground");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "normal");
-  EXPECT_EQ(0, error);
-
-  // Privileged policies.
-  error = dvrSetSchedulerPolicy(0, "audio:low");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "audio:high");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "graphics");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "graphics:low");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "graphics:high");
-  EXPECT_EQ(0, error);
-  error = dvrSetSchedulerPolicy(0, "sensors");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "sensors:low");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "sensors:high");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "vr:system:arp");
-  EXPECT_EQ(-EINVAL, error);
-  error = dvrSetSchedulerPolicy(0, "vr:app:render");
-  EXPECT_EQ(-EINVAL, error);
-
-  if (trusted_uid != -1) {
-    // uid=<trusted uid> / gid=AID_NOBODY
-    ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
-        << "Failed to restore uid: " << strerror(errno);
-    ASSERT_EQ(0, setresgid(original_gid, original_gid, -1))
-        << "Failed to restore gid: " << strerror(errno);
-    ASSERT_EQ(0, setresgid(AID_NOBODY, AID_NOBODY, -1))
-        << "Failed to set gid: " << strerror(errno);
-    ASSERT_EQ(0, setresuid(trusted_uid, trusted_uid, -1))
-        << "Failed to set uid: " << strerror(errno);
-
-    // Unprivileged policies.
-    error = dvrSetSchedulerPolicy(0, "batch");
-    EXPECT_EQ(0, error);
-    error = dvrSetSchedulerPolicy(0, "background");
-    EXPECT_EQ(0, error);
-    error = dvrSetSchedulerPolicy(0, "foreground");
-    EXPECT_EQ(0, error);
-    error = dvrSetSchedulerPolicy(0, "normal");
-    EXPECT_EQ(0, error);
-
-    // Privileged policies.
-    error = dvrSetSchedulerPolicy(0, "audio:low");
-    EXPECT_EQ(-EINVAL, error);
-    error = dvrSetSchedulerPolicy(0, "audio:high");
-    EXPECT_EQ(-EINVAL, error);
-    error = dvrSetSchedulerPolicy(0, "graphics");
-    EXPECT_EQ(-EINVAL, error);
-    error = dvrSetSchedulerPolicy(0, "graphics:low");
-    EXPECT_EQ(-EINVAL, error);
-    error = dvrSetSchedulerPolicy(0, "graphics:high");
-    EXPECT_EQ(-EINVAL, error);
-    error = dvrSetSchedulerPolicy(0, "sensors");
-    EXPECT_EQ(-EINVAL, error);
-    error = dvrSetSchedulerPolicy(0, "sensors:low");
-    EXPECT_EQ(-EINVAL, error);
-    error = dvrSetSchedulerPolicy(0, "sensors:high");
-    EXPECT_EQ(-EINVAL, error);
-    error = dvrSetSchedulerPolicy(0, "vr:system:arp");
-    EXPECT_EQ(0, error);
-    error = dvrSetSchedulerPolicy(0, "vr:app:render");
-    EXPECT_EQ(0, error);
-  }
-
-  // Restore original effective uid/gid.
-  ASSERT_EQ(0, setresgid(original_gid, original_gid, -1))
-      << "Failed to restore gid: " << strerror(errno);
-  ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
-      << "Failed to restore uid: " << strerror(errno);
-}
diff --git a/services/vr/performanced/performanced.rc b/services/vr/performanced/performanced.rc
deleted file mode 100644
index af9760e..0000000
--- a/services/vr/performanced/performanced.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service performanced /system/bin/performanced
-  class core
-  user root
-  group system readproc
-  socket pdx/system/performance/client stream 0666 system system u:object_r:pdx_performance_client_endpoint_socket:s0
diff --git a/services/vr/performanced/stdio_filebuf.h b/services/vr/performanced/stdio_filebuf.h
deleted file mode 100644
index 5988aa8..0000000
--- a/services/vr/performanced/stdio_filebuf.h
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
-// Copyright (c) 2016 Google, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#ifndef ANDROID_DVR_PERFORMANCED_STDIO_FILEBUF_H_
-#define ANDROID_DVR_PERFORMANCED_STDIO_FILEBUF_H_
-
-#include <cstdio>
-#include <istream>
-#include <locale>
-#include <streambuf>
-
-namespace android {
-namespace dvr {
-
-// An implementation of std::basic_streambuf backed by a FILE pointer. This is
-// ported from the internal llvm-libc++ support for std::cin. It's really
-// unfortunate that we have to do this, but the C++11 standard is too pendantic
-// to support creating streams from file descriptors or FILE pointers. This
-// implementation uses all standard interfaces, except for the call to
-// std::__throw_runtime_error(), which is only needed to deal with exceeding
-// locale encoding limits. This class is meant to be used for reading system
-// files, which don't require exotic locale support, so this call could be
-// removed in the future, if necessary.
-//
-// Original source file: llvm-libcxx/llvm-libc++/include/__std_stream
-// Original class name: __stdinbuf
-//
-template <class _CharT>
-class stdio_filebuf
-    : public std::basic_streambuf<_CharT, std::char_traits<_CharT> > {
- public:
-  typedef _CharT char_type;
-  typedef std::char_traits<char_type> traits_type;
-  typedef typename traits_type::int_type int_type;
-  typedef typename traits_type::pos_type pos_type;
-  typedef typename traits_type::off_type off_type;
-  typedef typename traits_type::state_type state_type;
-
-  explicit stdio_filebuf(FILE* __fp);
-  ~stdio_filebuf() override;
-
- protected:
-  virtual int_type underflow() override;
-  virtual int_type uflow() override;
-  virtual int_type pbackfail(int_type __c = traits_type::eof()) override;
-  virtual void imbue(const std::locale& __loc) override;
-
- private:
-  FILE* __file_;
-  const std::codecvt<char_type, char, state_type>* __cv_;
-  state_type __st_;
-  int __encoding_;
-  int_type __last_consumed_;
-  bool __last_consumed_is_next_;
-  bool __always_noconv_;
-
-  stdio_filebuf(const stdio_filebuf&);
-  stdio_filebuf& operator=(const stdio_filebuf&);
-
-  int_type __getchar(bool __consume);
-
-  static const int __limit = 8;
-};
-
-template <class _CharT>
-stdio_filebuf<_CharT>::stdio_filebuf(FILE* __fp)
-    : __file_(__fp),
-      __last_consumed_(traits_type::eof()),
-      __last_consumed_is_next_(false) {
-  imbue(this->getloc());
-}
-
-template <class _CharT>
-stdio_filebuf<_CharT>::~stdio_filebuf() {
-  if (__file_)
-    fclose(__file_);
-}
-
-template <class _CharT>
-void stdio_filebuf<_CharT>::imbue(const std::locale& __loc) {
-  __cv_ = &std::use_facet<std::codecvt<char_type, char, state_type> >(__loc);
-  __encoding_ = __cv_->encoding();
-  __always_noconv_ = __cv_->always_noconv();
-  if (__encoding_ > __limit)
-    std::__throw_runtime_error("unsupported locale for standard io");
-}
-
-template <class _CharT>
-typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::underflow() {
-  return __getchar(false);
-}
-
-template <class _CharT>
-typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::uflow() {
-  return __getchar(true);
-}
-
-template <class _CharT>
-typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::__getchar(
-    bool __consume) {
-  if (__last_consumed_is_next_) {
-    int_type __result = __last_consumed_;
-    if (__consume) {
-      __last_consumed_ = traits_type::eof();
-      __last_consumed_is_next_ = false;
-    }
-    return __result;
-  }
-  char __extbuf[__limit];
-  int __nread = std::max(1, __encoding_);
-  for (int __i = 0; __i < __nread; ++__i) {
-    int __c = getc(__file_);
-    if (__c == EOF)
-      return traits_type::eof();
-    __extbuf[__i] = static_cast<char>(__c);
-  }
-  char_type __1buf;
-  if (__always_noconv_)
-    __1buf = static_cast<char_type>(__extbuf[0]);
-  else {
-    const char* __enxt;
-    char_type* __inxt;
-    std::codecvt_base::result __r;
-    do {
-      state_type __sv_st = __st_;
-      __r = __cv_->in(__st_, __extbuf, __extbuf + __nread, __enxt, &__1buf,
-                      &__1buf + 1, __inxt);
-      switch (__r) {
-        case std::codecvt_base::ok:
-          break;
-        case std::codecvt_base::partial:
-          __st_ = __sv_st;
-          if (__nread == sizeof(__extbuf))
-            return traits_type::eof();
-          {
-            int __c = getc(__file_);
-            if (__c == EOF)
-              return traits_type::eof();
-            __extbuf[__nread] = static_cast<char>(__c);
-          }
-          ++__nread;
-          break;
-        case std::codecvt_base::error:
-          return traits_type::eof();
-        case std::codecvt_base::noconv:
-          __1buf = static_cast<char_type>(__extbuf[0]);
-          break;
-      }
-    } while (__r == std::codecvt_base::partial);
-  }
-  if (!__consume) {
-    for (int __i = __nread; __i > 0;) {
-      if (ungetc(traits_type::to_int_type(__extbuf[--__i]), __file_) == EOF)
-        return traits_type::eof();
-    }
-  } else
-    __last_consumed_ = traits_type::to_int_type(__1buf);
-  return traits_type::to_int_type(__1buf);
-}
-
-template <class _CharT>
-typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::pbackfail(
-    int_type __c) {
-  if (traits_type::eq_int_type(__c, traits_type::eof())) {
-    if (!__last_consumed_is_next_) {
-      __c = __last_consumed_;
-      __last_consumed_is_next_ =
-          !traits_type::eq_int_type(__last_consumed_, traits_type::eof());
-    }
-    return __c;
-  }
-  if (__last_consumed_is_next_) {
-    char __extbuf[__limit];
-    char* __enxt;
-    const char_type __ci = traits_type::to_char_type(__last_consumed_);
-    const char_type* __inxt;
-    switch (__cv_->out(__st_, &__ci, &__ci + 1, __inxt, __extbuf,
-                       __extbuf + sizeof(__extbuf), __enxt)) {
-      case std::codecvt_base::ok:
-        break;
-      case std::codecvt_base::noconv:
-        __extbuf[0] = static_cast<char>(__last_consumed_);
-        __enxt = __extbuf + 1;
-        break;
-      case std::codecvt_base::partial:
-      case std::codecvt_base::error:
-        return traits_type::eof();
-    }
-    while (__enxt > __extbuf)
-      if (ungetc(*--__enxt, __file_) == EOF)
-        return traits_type::eof();
-  }
-  __last_consumed_ = __c;
-  __last_consumed_is_next_ = true;
-  return __c;
-}
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_PERFORMANCED_STDIO_FILEBUF_H_
diff --git a/services/vr/performanced/task.cpp b/services/vr/performanced/task.cpp
deleted file mode 100644
index 2fc96bf..0000000
--- a/services/vr/performanced/task.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-#include "task.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <log/log.h>
-#include <stdio.h>
-
-#include <cctype>
-#include <cstdlib>
-#include <memory>
-#include <sstream>
-
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-
-#include "stdio_filebuf.h"
-
-namespace {
-
-const char kProcBase[] = "/proc";
-
-android::base::unique_fd OpenTaskDirectory(pid_t task_id) {
-  std::ostringstream stream;
-  stream << kProcBase << "/" << task_id;
-
-  return android::base::unique_fd(
-      open(stream.str().c_str(), O_RDONLY | O_DIRECTORY));
-}
-
-void ParseUidStatusField(const std::string& value, std::array<int, 4>& ids) {
-  const char* start = value.c_str();
-
-  ids[0] = std::strtol(start, const_cast<char**>(&start), 10);
-  ids[1] = std::strtol(start, const_cast<char**>(&start), 10);
-  ids[2] = std::strtol(start, const_cast<char**>(&start), 10);
-  ids[3] = std::strtol(start, const_cast<char**>(&start), 10);
-}
-
-}  // anonymous namespace
-
-namespace android {
-namespace dvr {
-
-Task::Task(pid_t task_id)
-    : task_id_(task_id),
-      thread_group_id_(-1),
-      parent_process_id_(-1),
-      thread_count_(0),
-      cpus_allowed_mask_(0) {
-  task_fd_ = OpenTaskDirectory(task_id_);
-  const int error = errno;
-  ALOGE_IF(task_fd_.get() < 0 && error != EACCES,
-           "Task::Task: Failed to open task directory for task_id=%d: %s",
-           task_id, strerror(error));
-
-  if (IsValid()) {
-    ReadStatusFields();
-    ALOGD_IF(TRACE,
-             "Task::Task: task_id=%d name=%s tgid=%d ppid=%d cpu_mask=%x",
-             task_id_, name_.c_str(), thread_group_id_, parent_process_id_,
-             cpus_allowed_mask_);
-  }
-}
-
-base::unique_fd Task::OpenTaskFile(const std::string& name) const {
-  const std::string relative_path = "./" + name;
-  return base::unique_fd(
-      openat(task_fd_.get(), relative_path.c_str(), O_RDONLY));
-}
-
-UniqueFile Task::OpenTaskFilePointer(const std::string& name) const {
-  const std::string relative_path = "./" + name;
-  base::unique_fd fd(openat(task_fd_.get(), relative_path.c_str(), O_RDONLY));
-  if (fd.get() < 0) {
-    ALOGE("Task::OpenTaskFilePointer: Failed to open /proc/%d/%s: %s", task_id_,
-          name.c_str(), strerror(errno));
-    return nullptr;
-  }
-
-  UniqueFile fp(fdopen(fd.release(), "r"));
-  if (!fp)
-    ALOGE("Task::OpenTaskFilePointer: Failed to fdopen /proc/%d/%s: %s",
-          task_id_, name.c_str(), strerror(errno));
-
-  return fp;
-}
-
-std::string Task::GetStatusField(const std::string& field) const {
-  if (auto file = OpenTaskFilePointer("status")) {
-    stdio_filebuf<char> filebuf(file.get());
-    std::istream file_stream(&filebuf);
-
-    for (std::string line; std::getline(file_stream, line);) {
-      auto offset = line.find(field);
-
-      ALOGD_IF(TRACE,
-               "Task::GetStatusField: field=\"%s\" line=\"%s\" offset=%zd",
-               field.c_str(), line.c_str(), offset);
-
-      if (offset == std::string::npos)
-        continue;
-
-      // The status file has lines with the format <field>:<value>. Extract the
-      // value after the colon.
-      return android::base::Trim(line.substr(offset + field.size() + 1));
-    }
-  }
-
-  return "[unknown]";
-}
-
-void Task::ReadStatusFields() {
-  if (auto file = OpenTaskFilePointer("status")) {
-    stdio_filebuf<char> filebuf(file.get());
-    std::istream file_stream(&filebuf);
-
-    for (std::string line; std::getline(file_stream, line);) {
-      auto offset = line.find(':');
-      if (offset == std::string::npos) {
-        ALOGW("ReadStatusFields: Failed to find delimiter \":\" in line=\"%s\"",
-              line.c_str());
-        continue;
-      }
-
-      std::string key = line.substr(0, offset);
-      std::string value = android::base::Trim(line.substr(offset + 1));
-
-      ALOGD_IF(TRACE, "Task::ReadStatusFields: key=\"%s\" value=\"%s\"",
-               key.c_str(), value.c_str());
-
-      if (key == "Name")
-        name_ = value;
-      else if (key == "Tgid")
-        thread_group_id_ = std::strtol(value.c_str(), nullptr, 10);
-      else if (key == "PPid")
-        parent_process_id_ = std::strtol(value.c_str(), nullptr, 10);
-      else if (key == "Uid")
-        ParseUidStatusField(value, user_id_);
-      else if (key == "Gid")
-        ParseUidStatusField(value, group_id_);
-      else if (key == "Threads")
-        thread_count_ = std::strtoul(value.c_str(), nullptr, 10);
-      else if (key == "Cpus_allowed")
-        cpus_allowed_mask_ = std::strtoul(value.c_str(), nullptr, 16);
-      else if (key == "Cpus_allowed_list")
-        cpus_allowed_list_ = value;
-    }
-  }
-}
-
-std::string Task::GetCpuSetPath() const {
-  if (auto file = OpenTaskFilePointer("cpuset")) {
-    stdio_filebuf<char> filebuf(file.get());
-    std::istream file_stream(&filebuf);
-
-    std::string line = "";
-    std::getline(file_stream, line);
-
-    return android::base::Trim(line);
-  } else {
-    return "";
-  }
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/performanced/task.h b/services/vr/performanced/task.h
deleted file mode 100644
index 4a3b7f2..0000000
--- a/services/vr/performanced/task.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCED_TASK_H_
-#define ANDROID_DVR_PERFORMANCED_TASK_H_
-
-#include <sys/types.h>
-
-#include <array>
-#include <cstdio>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include <android-base/unique_fd.h>
-
-#include "unique_file.h"
-
-namespace android {
-namespace dvr {
-
-// Task provides access to task-related information from the procfs
-// pseudo-filesystem.
-class Task {
- public:
-  explicit Task(pid_t task_id);
-
-  bool IsValid() const { return task_fd_.get() >= 0; }
-  explicit operator bool() const { return IsValid(); }
-
-  pid_t task_id() const { return task_id_; }
-  std::string name() const { return name_; }
-  pid_t thread_group_id() const { return thread_group_id_; }
-  pid_t parent_process_id() const { return parent_process_id_; }
-  size_t thread_count() const { return thread_count_; }
-  uint32_t cpus_allowed_mask() const { return cpus_allowed_mask_; }
-  const std::string& cpus_allowed_list() const { return cpus_allowed_list_; }
-  const std::array<int, 4>& user_id() const { return user_id_; }
-  const std::array<int, 4>& group_id() const { return group_id_; }
-
-  // Indices into user and group id arrays.
-  enum {
-    kUidReal = 0,
-    kUidEffective,
-    kUidSavedSet,
-    kUidFilesystem,
-  };
-
-  std::string GetCpuSetPath() const;
-
- private:
-  pid_t task_id_;
-  base::unique_fd task_fd_;
-
-  // Fields read from /proc/<task_id_>/status.
-  std::string name_;
-  pid_t thread_group_id_;
-  pid_t parent_process_id_;
-  std::array<int, 4> user_id_;
-  std::array<int, 4> group_id_;
-  size_t thread_count_;
-  uint32_t cpus_allowed_mask_;
-  std::string cpus_allowed_list_;
-
-  // Opens the file /proc/<task_id_>/|name| and returns the open file
-  // descriptor.
-  base::unique_fd OpenTaskFile(const std::string& name) const;
-
-  // Similar to OpenTaskFile() but returns a file pointer.
-  UniqueFile OpenTaskFilePointer(const std::string& name) const;
-
-  // Reads the field named |field| from /proc/<task_id_>/status.
-  std::string GetStatusField(const std::string& field) const;
-
-  // Reads a subset of the fields in /proc/<task_id_>/status.
-  void ReadStatusFields();
-
-  Task(const Task&) = delete;
-  void operator=(const Task&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_PERFORMANCED_TASK_H_
diff --git a/services/vr/performanced/unique_file.h b/services/vr/performanced/unique_file.h
deleted file mode 100644
index 86e487a..0000000
--- a/services/vr/performanced/unique_file.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCED_UNIQUE_FILE_H_
-#define ANDROID_DVR_PERFORMANCED_UNIQUE_FILE_H_
-
-#include <stdio.h>
-
-#include <memory>
-
-namespace android {
-namespace dvr {
-
-// Utility to manage the lifetime of a file pointer.
-struct FileDeleter {
-  void operator()(FILE* fp) { fclose(fp); }
-};
-using UniqueFile = std::unique_ptr<FILE, FileDeleter>;
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_PERFORMANCED_UNIQUE_FILE_H_
diff --git a/services/vr/virtual_touchpad/Android.bp b/services/vr/virtual_touchpad/Android.bp
deleted file mode 100644
index f2ec5a4..0000000
--- a/services/vr/virtual_touchpad/Android.bp
+++ /dev/null
@@ -1,140 +0,0 @@
-
-
-// Touchpad implementation.
-
-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"],
-}
-
-src = [
-    "EvdevInjector.cpp",
-    "VirtualTouchpadEvdev.cpp",
-]
-
-shared_libs = [
-    "libbase",
-    "liblog",
-    "libutils",
-]
-
-header_libraries = [
-    "jni_headers",
-    "libdvr_headers",
-]
-
-cc_library {
-    srcs: src,
-    export_include_dirs: ["include"],
-    shared_libs: shared_libs,
-    header_libs: header_libraries,
-    cflags: [
-        "-DLOG_TAG=\"VrVirtualTouchpad\"",
-        "-Wall",
-        "-Werror",
-    ],
-    name: "libvirtualtouchpad",
-}
-
-// Touchpad unit tests.
-
-test_static_libs = [
-    "libcutils",
-    "libvirtualtouchpad",
-    "libbase",
-    "liblog",
-    "libutils",
-]
-
-test_src_files = ["tests/VirtualTouchpad_test.cpp"]
-
-cc_test {
-    srcs: test_src_files,
-    static_libs: test_static_libs,
-    header_libs: header_libraries,
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-    host_ldlibs: [
-        "-llog",
-    ],
-    name: "VirtualTouchpad_test",
-    stl: "libc++_static",
-}
-
-// Service.
-
-service_src = [
-    "main.cpp",
-    "VirtualTouchpadService.cpp",
-    ":virtualtouchpad_aidl",
-]
-
-service_static_libs = [
-    "libcutils",
-    "libvirtualtouchpad",
-]
-
-service_shared_libs = [
-    "libbase",
-    "libbinder",
-    "liblog",
-    "libutils",
-]
-
-cc_binary {
-    srcs: service_src,
-    static_libs: service_static_libs,
-    shared_libs: service_shared_libs,
-    header_libs: header_libraries,
-    cflags: [
-        "-DLOG_TAG=\"VrVirtualTouchpad\"",
-        "-Wall",
-        "-Werror",
-    ],
-    host_ldlibs: ["-llog"],
-    name: "virtual_touchpad",
-    init_rc: ["virtual_touchpad.rc"],
-    compile_multilib: "64",
-    stl: "libc++_static",
-}
-
-// Touchpad client library.
-
-client_src = [
-    "VirtualTouchpadClient.cpp",
-    "DvrVirtualTouchpadClient.cpp",
-    ":virtualtouchpad_aidl",
-]
-
-client_shared_libs = [
-    "libbase",
-    "libbinder",
-    "liblog",
-    "libutils",
-]
-
-cc_library {
-    srcs: client_src,
-    shared_libs: client_shared_libs,
-    header_libs: header_libraries,
-    cflags: [
-        "-DLOG_TAG=\"VirtualTouchpadClient\"",
-        "-Wall",
-        "-Werror",
-    ],
-    host_ldlibs: ["-llog"],
-    name: "libvirtualtouchpadclient",
-    export_include_dirs: ["include"],
-}
-
-filegroup {
-    name: "virtualtouchpad_aidl",
-    srcs: ["aidl/android/dvr/IVirtualTouchpadService.aidl"],
-    path: "aidl",
-}
diff --git a/services/vr/virtual_touchpad/DvrVirtualTouchpadClient.cpp b/services/vr/virtual_touchpad/DvrVirtualTouchpadClient.cpp
deleted file mode 100644
index 3ab77a7..0000000
--- a/services/vr/virtual_touchpad/DvrVirtualTouchpadClient.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#include "VirtualTouchpadClient.h"
-#include "dvr/virtual_touchpad_client.h"
-
-struct DvrVirtualTouchpad {};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-namespace {
-android::dvr::VirtualTouchpad* FromC(DvrVirtualTouchpad* client) {
-  return reinterpret_cast<android::dvr::VirtualTouchpad*>(client);
-}
-}  // namespace
-
-DvrVirtualTouchpad* dvrVirtualTouchpadCreate() {
-  return reinterpret_cast<DvrVirtualTouchpad*>(
-      android::dvr::VirtualTouchpadClient::Create().release());
-}
-
-void dvrVirtualTouchpadDestroy(DvrVirtualTouchpad* client) {
-  delete FromC(client);
-}
-
-int dvrVirtualTouchpadAttach(DvrVirtualTouchpad* client) {
-  return FromC(client)->Attach();
-}
-
-int dvrVirtualTouchpadDetach(DvrVirtualTouchpad* client) {
-  return FromC(client)->Detach();
-}
-
-int dvrVirtualTouchpadTouch(DvrVirtualTouchpad* client, int touchpad, float x,
-                            float y, float pressure) {
-  return FromC(client)->Touch(touchpad, x, y, pressure);
-}
-
-int dvrVirtualTouchpadButtonState(DvrVirtualTouchpad* client, int touchpad,
-                                  int buttons) {
-  return FromC(client)->ButtonState(touchpad, buttons);
-}
-
-int dvrVirtualTouchpadScroll(DvrVirtualTouchpad* client, int touchpad, float x,
-                             float y) {
-  return FromC(client)->Scroll(touchpad, x, y);
-}
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
diff --git a/services/vr/virtual_touchpad/EvdevInjector.cpp b/services/vr/virtual_touchpad/EvdevInjector.cpp
deleted file mode 100644
index 7fad379..0000000
--- a/services/vr/virtual_touchpad/EvdevInjector.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-#include "EvdevInjector.h"
-
-#include <errno.h>
-#include <inttypes.h>
-#include <linux/input.h>
-#include <log/log.h>
-#include <string.h>
-#include <sys/fcntl.h>
-#include <unistd.h>
-
-namespace android {
-namespace dvr {
-
-int EvdevInjector::UInput::Open() {
-  errno = 0;
-  fd_.reset(open("/dev/uinput", O_WRONLY | O_NONBLOCK));
-  if (fd_.get() < 0) {
-    ALOGE("couldn't open uinput (r=%d errno=%d)", fd_.get(), errno);
-  }
-  return errno;
-}
-
-int EvdevInjector::UInput::Close() {
-  errno = 0;
-  fd_.reset();
-  return errno;
-}
-
-int EvdevInjector::UInput::Write(const void* buf, size_t count) {
-  ALOGV("UInput::Write(%zu, %02X...)", count, *static_cast<const char*>(buf));
-  errno = 0;
-  ssize_t r = write(fd_.get(), buf, count);
-  if (r != static_cast<ssize_t>(count)) {
-    ALOGE("write(%zu) failed (r=%zd errno=%d)", count, r, errno);
-  }
-  return errno;
-}
-
-int EvdevInjector::UInput::IoctlSetInt(int request, int value) {
-  ALOGV("UInput::IoctlSetInt(0x%X, 0x%X)", request, value);
-  errno = 0;
-  if (const int status = ioctl(fd_.get(), request, value)) {
-    ALOGE("ioctl(%d, 0x%X, 0x%X) failed (r=%d errno=%d)", fd_.get(), request,
-          value, status, errno);
-  }
-  return errno;
-}
-
-int EvdevInjector::UInput::IoctlVoid(int request) {
-  ALOGV("UInput::IoctlVoid(0x%X)", request);
-  errno = 0;
-  if (const int status = ioctl(fd_.get(), request)) {
-    ALOGE("ioctl(%d, 0x%X) failed (r=%d errno=%d)", fd_.get(), request, status,
-          errno);
-  }
-  return errno;
-}
-
-void EvdevInjector::Close() {
-  uinput_->Close();
-  state_ = State::CLOSED;
-}
-
-int EvdevInjector::ConfigureBegin(const char* device_name, int16_t bustype,
-                                  int16_t vendor, int16_t product,
-                                  int16_t version) {
-  ALOGV("ConfigureBegin %s 0x%04" PRIX16 " 0x%04" PRIX16 " 0x%04" PRIX16
-        " 0x%04" PRIX16 "",
-        device_name, bustype, vendor, product, version);
-  if (!device_name || strlen(device_name) >= UINPUT_MAX_NAME_SIZE) {
-    return Error(ERROR_DEVICE_NAME);
-  }
-  if (const int status = RequireState(State::NEW)) {
-    return status;
-  }
-  if (!uinput_) {
-    owned_uinput_.reset(new EvdevInjector::UInput());
-    uinput_ = owned_uinput_.get();
-  }
-  if (const int status = uinput_->Open()) {
-    // Without uinput we're dead in the water.
-    state_ = State::CLOSED;
-    return Error(status);
-  }
-  state_ = State::CONFIGURING;
-  // Initialize device setting structure.
-  memset(&uidev_, 0, sizeof(uidev_));
-  strncpy(uidev_.name, device_name, UINPUT_MAX_NAME_SIZE);
-  uidev_.id.bustype = bustype;
-  uidev_.id.vendor = vendor;
-  uidev_.id.product = product;
-  uidev_.id.version = version;
-  return 0;
-}
-
-int EvdevInjector::ConfigureInputProperty(int property) {
-  ALOGV("ConfigureInputProperty %d", property);
-  if (property < 0 || property >= INPUT_PROP_CNT) {
-    ALOGE("property 0x%X out of range [0,0x%X)", property, INPUT_PROP_CNT);
-    return Error(ERROR_PROPERTY_RANGE);
-  }
-  if (const int status = RequireState(State::CONFIGURING)) {
-    return status;
-  }
-  if (const int status = uinput_->IoctlSetInt(UI_SET_PROPBIT, property)) {
-    ALOGE("failed to set property %d", property);
-    return Error(status);
-  }
-  return 0;
-}
-
-int EvdevInjector::ConfigureKey(uint16_t key) {
-  ALOGV("ConfigureKey 0x%02" PRIX16 "", key);
-  if (key < 0 || key >= KEY_CNT) {
-    ALOGE("key 0x%X out of range [0,0x%X)", key, KEY_CNT);
-    return Error(ERROR_KEY_RANGE);
-  }
-  if (const int status = RequireState(State::CONFIGURING)) {
-    return status;
-  }
-  if (const int status = EnableEventType(EV_KEY)) {
-    return status;
-  }
-  if (const int status = uinput_->IoctlSetInt(UI_SET_KEYBIT, key)) {
-    ALOGE("failed to enable EV_KEY 0x%02" PRIX16 "", key);
-    return Error(status);
-  }
-  return 0;
-}
-
-int EvdevInjector::ConfigureAbs(uint16_t abs_type, int32_t min, int32_t max,
-                                int32_t fuzz, int32_t flat) {
-  ALOGV("ConfigureAbs 0x%" PRIX16 " %" PRId32 " %" PRId32 " %" PRId32
-        " %" PRId32 "",
-        abs_type, min, max, fuzz, flat);
-  if (abs_type < 0 || abs_type >= ABS_CNT) {
-    ALOGE("EV_ABS type 0x%" PRIX16 " out of range [0,0x%X)", abs_type, ABS_CNT);
-    return Error(ERROR_ABS_RANGE);
-  }
-  if (const int status = RequireState(State::CONFIGURING)) {
-    return status;
-  }
-  if (const int status = EnableEventType(EV_ABS)) {
-    return status;
-  }
-  if (const int status = uinput_->IoctlSetInt(UI_SET_ABSBIT, abs_type)) {
-    ALOGE("failed to enable EV_ABS 0x%" PRIX16 "", abs_type);
-    return Error(status);
-  }
-  uidev_.absmin[abs_type] = min;
-  uidev_.absmax[abs_type] = max;
-  uidev_.absfuzz[abs_type] = fuzz;
-  uidev_.absflat[abs_type] = flat;
-  return 0;
-}
-
-int EvdevInjector::ConfigureMultiTouchXY(int x0, int y0, int x1, int y1) {
-  if (const int status = ConfigureAbs(ABS_MT_POSITION_X, x0, x1, 0, 0)) {
-    return status;
-  }
-  if (const int status = ConfigureAbs(ABS_MT_POSITION_Y, y0, y1, 0, 0)) {
-    return status;
-  }
-  return 0;
-}
-
-int EvdevInjector::ConfigureAbsSlots(int slots) {
-  return ConfigureAbs(ABS_MT_SLOT, 0, slots, 0, 0);
-}
-
-int EvdevInjector::ConfigureRel(uint16_t rel_type) {
-  ALOGV("ConfigureRel 0x%" PRIX16 "", rel_type);
-  if (rel_type < 0 || rel_type >= REL_CNT) {
-    ALOGE("EV_REL type 0x%" PRIX16 " out of range [0,0x%X)", rel_type, REL_CNT);
-    return Error(ERROR_REL_RANGE);
-  }
-  if (const int status = RequireState(State::CONFIGURING)) {
-    return status;
-  }
-  if (const int status = EnableEventType(EV_REL)) {
-    return status;
-  }
-  if (const int status = uinput_->IoctlSetInt(UI_SET_RELBIT, rel_type)) {
-    ALOGE("failed to enable EV_REL 0x%" PRIX16 "", rel_type);
-    return Error(status);
-  }
-  return 0;
-}
-
-int EvdevInjector::ConfigureEnd() {
-  ALOGV("ConfigureEnd:");
-  ALOGV("  name=\"%s\"", uidev_.name);
-  ALOGV("  id.bustype=0x%04" PRIX16, uidev_.id.bustype);
-  ALOGV("  id.vendor=0x%04" PRIX16, uidev_.id.vendor);
-  ALOGV("  id.product=0x%04" PRIX16, uidev_.id.product);
-  ALOGV("  id.version=0x%04" PRIX16, uidev_.id.version);
-  ALOGV("  ff_effects_max=%" PRIu32, uidev_.ff_effects_max);
-  for (int i = 0; i < ABS_CNT; ++i) {
-    if (uidev_.absmin[i]) {
-      ALOGV("  absmin[%d]=%" PRId32, i, uidev_.absmin[i]);
-    }
-    if (uidev_.absmax[i]) {
-      ALOGV("  absmax[%d]=%" PRId32, i, uidev_.absmax[i]);
-    }
-    if (uidev_.absfuzz[i]) {
-      ALOGV("  absfuzz[%d]=%" PRId32, i, uidev_.absfuzz[i]);
-    }
-    if (uidev_.absflat[i]) {
-      ALOGV("  absflat[%d]=%" PRId32, i, uidev_.absflat[i]);
-    }
-  }
-
-  if (const int status = RequireState(State::CONFIGURING)) {
-    return status;
-  }
-  // Write out device settings.
-  if (const int status = uinput_->Write(&uidev_, sizeof uidev_)) {
-    ALOGE("failed to write device settings");
-    return Error(status);
-  }
-  // Create device node.
-  if (const int status = uinput_->IoctlVoid(UI_DEV_CREATE)) {
-    ALOGE("failed to create device node");
-    return Error(status);
-  }
-  state_ = State::READY;
-  return 0;
-}
-
-int EvdevInjector::Send(uint16_t type, uint16_t code, int32_t value) {
-  ALOGV("Send(0x%" PRIX16 ", 0x%" PRIX16 ", 0x%" PRIX32 ")", type, code, value);
-  if (const int status = RequireState(State::READY)) {
-    return status;
-  }
-  struct input_event event;
-  memset(&event, 0, sizeof(event));
-  event.type = type;
-  event.code = code;
-  event.value = value;
-  if (const int status = uinput_->Write(&event, sizeof(event))) {
-    ALOGE("failed to write event 0x%" PRIX16 ", 0x%" PRIX16 ", 0x%" PRIX32,
-          type, code, value);
-    return Error(status);
-  }
-  return 0;
-}
-
-int EvdevInjector::SendSynReport() { return Send(EV_SYN, SYN_REPORT, 0); }
-
-int EvdevInjector::SendKey(uint16_t code, int32_t value) {
-  return Send(EV_KEY, code, value);
-}
-
-int EvdevInjector::SendAbs(uint16_t code, int32_t value) {
-  return Send(EV_ABS, code, value);
-}
-
-int EvdevInjector::SendRel(uint16_t code, int32_t value) {
-  return Send(EV_REL, code, value);
-}
-
-int EvdevInjector::SendMultiTouchSlot(int32_t slot) {
-  if (latest_slot_ != slot) {
-    if (const int status = SendAbs(ABS_MT_SLOT, slot)) {
-      return status;
-    }
-    latest_slot_ = slot;
-  }
-  return 0;
-}
-
-int EvdevInjector::SendMultiTouchXY(int32_t slot, int32_t id, int32_t x,
-                                    int32_t y) {
-  if (const int status = SendMultiTouchSlot(slot)) {
-    return status;
-  }
-  if (const int status = SendAbs(ABS_MT_TRACKING_ID, id)) {
-    return status;
-  }
-  if (const int status = SendAbs(ABS_MT_POSITION_X, x)) {
-    return status;
-  }
-  if (const int status = SendAbs(ABS_MT_POSITION_Y, y)) {
-    return status;
-  }
-  return 0;
-}
-
-int EvdevInjector::SendMultiTouchLift(int32_t slot) {
-  if (const int status = SendMultiTouchSlot(slot)) {
-    return status;
-  }
-  if (const int status = SendAbs(ABS_MT_TRACKING_ID, -1)) {
-    return status;
-  }
-  return 0;
-}
-
-int EvdevInjector::Error(int code) {
-  if (!error_) {
-    error_ = code;
-  }
-  return code;
-}
-
-int EvdevInjector::RequireState(State required_state) {
-  if (error_) {
-    return error_;
-  }
-  if (state_ != required_state) {
-    ALOGE("in state %d but require state %d", static_cast<int>(state_),
-          static_cast<int>(required_state));
-    return Error(ERROR_SEQUENCING);
-  }
-  return 0;
-}
-
-int EvdevInjector::EnableEventType(uint16_t type) {
-  if (const int status = RequireState(State::CONFIGURING)) {
-    return status;
-  }
-  if (enabled_event_types_.count(type) > 0) {
-    return 0;
-  }
-  if (const int status = uinput_->IoctlSetInt(UI_SET_EVBIT, type)) {
-    ALOGE("failed to enable event type 0x%X", type);
-    return Error(status);
-  }
-  enabled_event_types_.insert(type);
-  return 0;
-}
-
-void EvdevInjector::dumpInternal(String8& result) {
-  result.appendFormat("injector_state = %d\n", static_cast<int>(state_));
-  result.appendFormat("injector_error = %d\n", error_);
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/virtual_touchpad/EvdevInjector.h b/services/vr/virtual_touchpad/EvdevInjector.h
deleted file mode 100644
index e87c959..0000000
--- a/services/vr/virtual_touchpad/EvdevInjector.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef ANDROID_DVR_EVDEV_INJECTOR_H
-#define ANDROID_DVR_EVDEV_INJECTOR_H
-
-#include <android-base/unique_fd.h>
-#include <linux/uinput.h>
-#include <utils/String8.h>
-
-#include <cstdint>
-#include <memory>
-#include <unordered_set>
-
-namespace android {
-namespace dvr {
-
-// Simulated evdev input device.
-//
-class EvdevInjector {
- public:
-  // EvdevInjector-specific error codes are negative integers; other non-zero
-  // values returned from public routines are |errno| codes from underlying I/O.
-  // EvdevInjector maintains a 'sticky' error state, similar to |errno|, so that
-  // a caller can perform a sequence of operations and check for errors at the
-  // end using |GetError()|. In general, the first such error will be recorded
-  // and will suppress effects of further device operations until |ResetError()|
-  // is called.
-  //
-  enum : int {
-    ERROR_DEVICE_NAME = -1,     // Invalid device name.
-    ERROR_PROPERTY_RANGE = -2,  // |INPUT_PROP_*| code out of range.
-    ERROR_KEY_RANGE = -3,       // |KEY_*|/|BTN_*| code out of range.
-    ERROR_ABS_RANGE = -4,       // |ABS_*| code out of range.
-    ERROR_SEQUENCING = -5,      // Configure/Send out of order.
-    ERROR_REL_RANGE = -6,       // |REL_*| code out of range.
-  };
-
-  // Key event |value| is not defined in <linux/input.h>.
-  enum : int32_t { KEY_RELEASE = 0, KEY_PRESS = 1, KEY_REPEAT = 2 };
-
-  // UInput provides a shim to intercept /dev/uinput operations
-  // just above the system call level, for testing.
-  //
-  class UInput {
-   public:
-    UInput() {}
-    virtual ~UInput() {}
-    virtual int Open();
-    virtual int Close();
-    virtual int Write(const void* buf, size_t count);
-    virtual int IoctlVoid(int request);
-    virtual int IoctlSetInt(int request, int value);
-
-   private:
-    base::unique_fd fd_;
-  };
-
-  EvdevInjector() {}
-  ~EvdevInjector() { Close(); }
-  void Close();
-
-  int GetError() const { return error_; }
-  void ResetError() { error_ = 0; }
-
-  // Configuration must be performed before sending any events.
-  // |ConfigureBegin()| must be called first, and |ConfigureEnd()| last,
-  // with zero or more other |Configure...()| calls in between in any order.
-
-  // Configure the basic evdev device properties; must be called first.
-  int ConfigureBegin(const char* device_name, int16_t bustype, int16_t vendor,
-                     int16_t product, int16_t version);
-
-  // Configure an optional input device property.
-  // @param property  One of the |INPUT_PROP_*| constants from <linux/input.h>.
-  int ConfigureInputProperty(int property);
-
-  // Configure an input key.
-  // @param key One of the |KEY_*| or |BTN_*| constants from <linux/input.h>.
-  int ConfigureKey(uint16_t key);
-
-  // Configure an absolute axis.
-  // @param abs_type One of the |KEY_*| or |BTN_*| constants from
-  // <linux/input.h>.
-  int ConfigureAbs(uint16_t abs_type, int32_t min, int32_t max, int32_t fuzz,
-                   int32_t flat);
-
-  // Configure the number of multitouch slots.
-  int ConfigureAbsSlots(int slots);
-
-  // Configure multitouch coordinate range.
-  int ConfigureMultiTouchXY(int32_t x0, int32_t y0, int32_t x1, int32_t y1);
-
-  // Configure a relative axis.
-  // @param rel_type One of the |REL_*| constants from <linux/input.h>.
-  int ConfigureRel(uint16_t rel_type);
-
-  // Complete configuration and create the input device.
-  int ConfigureEnd();
-
-  // Send various events.
-  //
-  int Send(uint16_t type, uint16_t code, int32_t value);
-  int SendSynReport();
-  int SendKey(uint16_t code, int32_t value);
-  int SendAbs(uint16_t code, int32_t value);
-  int SendRel(uint16_t code, int32_t value);
-  int SendMultiTouchSlot(int32_t slot);
-  int SendMultiTouchXY(int32_t slot, int32_t id, int32_t x, int32_t y);
-  int SendMultiTouchLift(int32_t slot);
-
-  void dumpInternal(String8& result);
-
- protected:
-  // Must be called only between construction and ConfigureBegin().
-  inline void SetUInputForTesting(UInput* uinput) { uinput_ = uinput; }
-  // Caller must not retain pointer longer than EvdevInjector.
-  inline const uinput_user_dev* GetUiDevForTesting() const { return &uidev_; }
-
- private:
-  // Phase to enforce that configuration is complete before events are sent.
-  enum class State { NEW, CONFIGURING, READY, CLOSED };
-
-  // Sets |error_| if it is not already set; returns |code|.
-  int Error(int code);
-
-  // Returns a nonzero error if the injector is not in the required |state|.
-  int RequireState(State state);
-
-  // Configures an event type if necessary.
-  // @param type One of the |EV_*| constants from <linux/input.h>.
-  int EnableEventType(uint16_t type);
-
-  // Active pointer to owned or testing UInput.
-  UInput* uinput_ = nullptr;
-  std::unique_ptr<UInput> owned_uinput_;
-
-  State state_ = State::NEW;
-  int error_ = 0;
-  uinput_user_dev uidev_;
-  std::unordered_set<uint16_t> enabled_event_types_;
-  int32_t latest_slot_ = -1;
-
-  EvdevInjector(const EvdevInjector&) = delete;
-  void operator=(const EvdevInjector&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_EVDEV_INJECTOR_H
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp b/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
deleted file mode 100644
index 00e4ce6..0000000
--- a/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "VirtualTouchpadClient.h"
-
-#include <android/dvr/IVirtualTouchpadService.h>
-#include <binder/IServiceManager.h>
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-class VirtualTouchpadClientImpl : public VirtualTouchpadClient {
- public:
-  VirtualTouchpadClientImpl() {}
-  ~VirtualTouchpadClientImpl() override {
-    if (service_ != nullptr) {
-      Detach();
-    }
-  }
-
-  status_t Attach() {
-    if (service_ != nullptr) {
-      return ALREADY_EXISTS;
-    }
-    sp<IServiceManager> sm = defaultServiceManager();
-    if (sm == nullptr) {
-      ALOGE("no service manager");
-      return NO_INIT;
-    }
-    sp<IVirtualTouchpadService> service =
-        interface_cast<IVirtualTouchpadService>(
-            sm->getService(IVirtualTouchpadService::SERVICE_NAME()));
-    if (service == nullptr) {
-      ALOGE("failed to get service");
-      return NAME_NOT_FOUND;
-    }
-    service_ = service;
-    return service_->attach().transactionError();
-  }
-
-  status_t Detach() {
-    if (service_ == nullptr) {
-      return NO_INIT;
-    }
-    status_t status = service_->detach().transactionError();
-    service_ = nullptr;
-    return status;
-  }
-
-  status_t Touch(int touchpad, float x, float y, float pressure) override {
-    if (service_ == nullptr) {
-      return NO_INIT;
-    }
-    return service_->touch(touchpad, x, y, pressure).transactionError();
-  }
-
-  status_t ButtonState(int touchpad, int buttons) override {
-    if (service_ == nullptr) {
-      return NO_INIT;
-    }
-    return service_->buttonState(touchpad, buttons).transactionError();
-  }
-
-  status_t Scroll(int touchpad, float x, float y) override {
-    if (service_ == nullptr) {
-      return NO_INIT;
-    }
-    return service_->scroll(touchpad, x, y).transactionError();
-  }
-
-  void dumpInternal(String8& result) override {
-    result.append("[virtual touchpad]\n");
-    result.appendFormat("connected = %s\n\n",
-                        service_ != nullptr ? "true" : "false");
-  }
-
- private:
-  sp<IVirtualTouchpadService> service_;
-};
-
-}  // anonymous namespace
-
-std::unique_ptr<VirtualTouchpad> VirtualTouchpadClient::Create() {
-  return std::unique_ptr<VirtualTouchpad>(new VirtualTouchpadClientImpl());
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
deleted file mode 100644
index bcfdad3..0000000
--- a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-#include "VirtualTouchpadEvdev.h"
-
-#include <android/input.h>
-#include <inttypes.h>
-#include <linux/input.h>
-#include <log/log.h>
-
-// References:
-//  [0] Multi-touch (MT) Protocol,
-//      https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-// Virtual evdev device properties. The name is arbitrary, but Android can
-// use it to look up device configuration, so it must be unique. Vendor and
-// product values must be 0 to indicate an internal device and prevent a
-// similar lookup that could conflict with a physical device.
-static const char* const kDeviceNameFormat = "vr-virtual-touchpad-%d";
-static constexpr int16_t kDeviceBusType = BUS_VIRTUAL;
-static constexpr int16_t kDeviceVendor = 0;
-static constexpr int16_t kDeviceProduct = 0;
-static constexpr int16_t kDeviceVersion = 0x0001;
-
-static constexpr int32_t kWidth = 0x10000;
-static constexpr int32_t kHeight = 0x10000;
-static constexpr int32_t kSlots = 2;
-
-static constexpr float kScrollScale = 100.0f;
-
-int32_t scale_relative_scroll(float x) {
-  return kScrollScale * x;
-}
-
-}  // anonymous namespace
-
-std::unique_ptr<VirtualTouchpad> VirtualTouchpadEvdev::Create() {
-  std::unique_ptr<VirtualTouchpadEvdev> touchpad(new VirtualTouchpadEvdev());
-  touchpad->Reset();
-  return touchpad;
-}
-
-void VirtualTouchpadEvdev::Reset() {
-  for (auto& touchpad : touchpad_) {
-    if (touchpad.injector) {
-      touchpad.injector->Close();
-    }
-    touchpad.injector = nullptr;
-    touchpad.owned_injector.reset();
-    touchpad.last_device_x = INT32_MIN;
-    touchpad.last_device_y = INT32_MIN;
-    touchpad.touches = 0;
-    touchpad.last_motion_event_buttons = 0;
-  }
-}
-
-status_t VirtualTouchpadEvdev::Attach() {
-  status_t status = OK;
-  for (int i = 0; i < kTouchpads; ++i) {
-    Touchpad& touchpad = touchpad_[i];
-    if (!touchpad.injector) {
-      touchpad.owned_injector.reset(new EvdevInjector());
-      touchpad.injector = touchpad.owned_injector.get();
-    }
-    String8 DeviceName;
-    DeviceName.appendFormat(kDeviceNameFormat, i);
-    touchpad.injector->ConfigureBegin(DeviceName, kDeviceBusType,
-                                      kDeviceVendor, kDeviceProduct,
-                                      kDeviceVersion);
-    touchpad.injector->ConfigureInputProperty(INPUT_PROP_DIRECT);
-    touchpad.injector->ConfigureMultiTouchXY(0, 0, kWidth - 1, kHeight - 1);
-    touchpad.injector->ConfigureAbsSlots(kSlots);
-    touchpad.injector->ConfigureRel(REL_WHEEL);
-    touchpad.injector->ConfigureRel(REL_HWHEEL);
-    touchpad.injector->ConfigureKey(BTN_TOUCH);
-    touchpad.injector->ConfigureKey(BTN_BACK);
-    touchpad.injector->ConfigureEnd();
-    if (const status_t configuration_status =  touchpad.injector->GetError()) {
-      status = configuration_status;
-    }
-  }
-  return status;
-}
-
-status_t VirtualTouchpadEvdev::Detach() {
-  Reset();
-  return OK;
-}
-
-int VirtualTouchpadEvdev::Touch(int touchpad_id, float x, float y,
-                                float pressure) {
-  if (touchpad_id < 0 || touchpad_id >= kTouchpads) {
-    return EINVAL;
-  }
-  int32_t device_x = x * kWidth;
-  int32_t device_y = y * kHeight;
-  Touchpad& touchpad = touchpad_[touchpad_id];
-  touchpad.touches = ((touchpad.touches & 1) << 1) | (pressure > 0);
-  ALOGV("(%f,%f) %f -> (%" PRId32 ",%" PRId32 ") %d", x, y, pressure, device_x,
-        device_y, touchpad.touches);
-
-  if (!touchpad.injector) {
-    return EvdevInjector::ERROR_SEQUENCING;
-  }
-  touchpad.injector->ResetError();
-  switch (touchpad.touches) {
-    case 0b00:  // Hover continues.
-      if (device_x != touchpad.last_device_x ||
-          device_y != touchpad.last_device_y) {
-        touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y);
-        touchpad.injector->SendSynReport();
-      }
-      break;
-    case 0b01:  // Touch begins.
-      // Press.
-      touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y);
-      touchpad.injector->SendKey(BTN_TOUCH, EvdevInjector::KEY_PRESS);
-      touchpad.injector->SendSynReport();
-      break;
-    case 0b10:  // Touch ends.
-      touchpad.injector->SendKey(BTN_TOUCH, EvdevInjector::KEY_RELEASE);
-      touchpad.injector->SendMultiTouchLift(0);
-      touchpad.injector->SendSynReport();
-      break;
-    case 0b11:  // Touch continues.
-      if (device_x != touchpad.last_device_x ||
-          device_y != touchpad.last_device_y) {
-        touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y);
-        touchpad.injector->SendSynReport();
-      }
-      break;
-  }
-  touchpad.last_device_x = device_x;
-  touchpad.last_device_y = device_y;
-
-  return touchpad.injector->GetError();
-}
-
-int VirtualTouchpadEvdev::ButtonState(int touchpad_id, int buttons) {
-  if (touchpad_id < 0 || touchpad_id >= kTouchpads) {
-    return EINVAL;
-  }
-  Touchpad& touchpad = touchpad_[touchpad_id];
-  const int changes = touchpad.last_motion_event_buttons ^ buttons;
-  if (!changes) {
-    return 0;
-  }
-  if (buttons & ~AMOTION_EVENT_BUTTON_BACK) {
-    return ENOTSUP;
-  }
-  ALOGV("change %X from %X to %X", changes, touchpad.last_motion_event_buttons,
-        buttons);
-
-  if (!touchpad.injector) {
-    return EvdevInjector::ERROR_SEQUENCING;
-  }
-  touchpad.injector->ResetError();
-  if (changes & AMOTION_EVENT_BUTTON_BACK) {
-    touchpad.injector->SendKey(BTN_BACK, (buttons & AMOTION_EVENT_BUTTON_BACK)
-                                             ? EvdevInjector::KEY_PRESS
-                                             : EvdevInjector::KEY_RELEASE);
-    touchpad.injector->SendSynReport();
-  }
-  touchpad.last_motion_event_buttons = buttons;
-  return touchpad.injector->GetError();
-}
-
-int VirtualTouchpadEvdev::Scroll(int touchpad_id, float x, float y) {
-  if (touchpad_id < 0 || touchpad_id >= kTouchpads) {
-    return EINVAL;
-  }
-  if ((x < -1.0f) || (x > 1.0f) || (y < -1.0f) || (y > 1.0f)) {
-    return EINVAL;
-  }
-  Touchpad& touchpad = touchpad_[touchpad_id];
-  if (!touchpad.injector) {
-    return EvdevInjector::ERROR_SEQUENCING;
-  }
-  touchpad.injector->ResetError();
-  const int32_t scaled_x = scale_relative_scroll(x);
-  const int32_t scaled_y = scale_relative_scroll(y);
-  ALOGV("(%f,%f) -> (%" PRId32 ",%" PRId32 ")", x, y, scaled_x, scaled_y);
-  if (scaled_x) {
-    touchpad.injector->SendRel(REL_HWHEEL, scaled_x);
-  }
-  if (scaled_y) {
-    touchpad.injector->SendRel(REL_WHEEL, scaled_y);
-  }
-  if (scaled_x || scaled_y) {
-    touchpad.injector->SendSynReport();
-  }
-  return touchpad.injector->GetError();
-}
-
-void VirtualTouchpadEvdev::dumpInternal(String8& result) {
-  for (int i = 0; i < kTouchpads; ++i) {
-    const auto& touchpad = touchpad_[i];
-    result.appendFormat("[virtual touchpad %d]\n", i);
-    if (!touchpad.injector) {
-      result.append("injector = none\n");
-      return;
-    }
-    result.appendFormat("injector = %s\n",
-                        touchpad.owned_injector ? "normal" : "test");
-    result.appendFormat("touches = %d\n", touchpad.touches);
-    result.appendFormat("last_position = (%" PRId32 ", %" PRId32 ")\n",
-                        touchpad.last_device_x, touchpad.last_device_y);
-    result.appendFormat("last_buttons = 0x%" PRIX32 "\n",
-                        touchpad.last_motion_event_buttons);
-    touchpad.injector->dumpInternal(result);
-    result.append("\n");
-  }
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
deleted file mode 100644
index c9578bf..0000000
--- a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_EVDEV_H
-#define ANDROID_DVR_VIRTUAL_TOUCHPAD_EVDEV_H
-
-#include "EvdevInjector.h"
-#include "VirtualTouchpad.h"
-
-namespace android {
-namespace dvr {
-
-class EvdevInjector;
-
-// VirtualTouchpadEvdev implements a VirtualTouchpad by injecting evdev events.
-//
-class VirtualTouchpadEvdev : public VirtualTouchpad {
- public:
-  static std::unique_ptr<VirtualTouchpad> Create();
-  ~VirtualTouchpadEvdev() override {}
-
-  // VirtualTouchpad implementation:
-  status_t Attach() override;
-  status_t Detach() override;
-  status_t Touch(int touchpad, float x, float y, float pressure) override;
-  status_t ButtonState(int touchpad, int buttons) override;
-  status_t Scroll(int touchpad, float x, float y) override;
-  void dumpInternal(String8& result) override;
-
- protected:
-  static constexpr int kTouchpads = 2;
-
-  VirtualTouchpadEvdev() {}
-  void Reset();
-
-  // Must be called only between construction (or Detach()) and Attach().
-  inline void SetEvdevInjectorForTesting(int touchpad,
-                                         EvdevInjector* injector) {
-    touchpad_[touchpad].injector = injector;
-  }
-
- private:
-  // Per-touchpad state.
-  struct Touchpad {
-    // Except for testing, the |EvdevInjector| used to inject evdev events.
-    std::unique_ptr<EvdevInjector> owned_injector;
-
-    // Active pointer to |owned_injector_| or to a testing injector.
-    EvdevInjector* injector = nullptr;
-
-    // Previous (x, y) position in device space, to suppress redundant events.
-    int32_t last_device_x;
-    int32_t last_device_y;
-
-    // Records current touch state (0=up 1=down) in bit 0, and previous state
-    // in bit 1, to track transitions.
-    int touches;
-
-    // Previous injected button state, to detect changes.
-    int32_t last_motion_event_buttons;
-  };
-  Touchpad touchpad_[kTouchpads];
-
-  VirtualTouchpadEvdev(const VirtualTouchpadEvdev&) = delete;
-  void operator=(const VirtualTouchpadEvdev&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_VIRTUAL_TOUCHPAD_EVDEV_H
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.cpp b/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
deleted file mode 100644
index d0a9da1..0000000
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-#include "VirtualTouchpadService.h"
-
-#include <inttypes.h>
-
-#include <binder/IPCThreadState.h>
-#include <binder/PermissionCache.h>
-#include <binder/Status.h>
-#include <cutils/log.h>
-#include <linux/input.h>
-#include <private/android_filesystem_config.h>
-#include <utils/Errors.h>
-
-namespace android {
-namespace dvr {
-
-namespace {
-const String16 kDumpPermission("android.permission.DUMP");
-const String16 kTouchPermission("android.permission.RESTRICTED_VR_ACCESS");
-}  // anonymous namespace
-
-VirtualTouchpadService::~VirtualTouchpadService() {
-  if (client_pid_) {
-    client_pid_ = 0;
-    touchpad_->Detach();
-  }
-}
-
-binder::Status VirtualTouchpadService::attach() {
-  pid_t pid;
-  if (!CheckTouchPermission(&pid)) {
-    return binder::Status::fromStatusT(PERMISSION_DENIED);
-  }
-  if (client_pid_ == pid) {
-    // The same client has called attach() twice with no intervening detach().
-    // This indicates a problem with the client, so return an error.
-    // However, since the client is already attached, any touchpad actions
-    // it takes will still work.
-    ALOGE("pid=%ld attached twice", static_cast<long>(pid));
-    return binder::Status::fromStatusT(ALREADY_EXISTS);
-  }
-  if (client_pid_ != 0) {
-    // Attach while another client is attached. This can happen if the client
-    // dies without cleaning up after itself, so move ownership to the current
-    // caller. If two actual clients have connected, the problem will be
-    // reported when the previous client performs any touchpad action.
-    ALOGE("pid=%ld replaces %ld", static_cast<long>(pid),
-          static_cast<long>(client_pid_));
-    client_pid_ = pid;
-    return binder::Status::ok();
-  }
-  client_pid_ = pid;
-  if (const status_t error = touchpad_->Attach()) {
-    return binder::Status::fromStatusT(error);
-  }
-  return binder::Status::ok();
-}
-
-binder::Status VirtualTouchpadService::detach() {
-  if (!CheckPermissions()) {
-    return binder::Status::fromStatusT(PERMISSION_DENIED);
-  }
-  client_pid_ = 0;
-  if (const status_t error = touchpad_->Detach()) {
-    return binder::Status::fromStatusT(error);
-  }
-  return binder::Status::ok();
-}
-
-binder::Status VirtualTouchpadService::touch(int touchpad, float x, float y,
-                                             float pressure) {
-  if (!CheckPermissions()) {
-    return binder::Status::fromStatusT(PERMISSION_DENIED);
-  }
-  if (const status_t error = touchpad_->Touch(touchpad, x, y, pressure)) {
-    return binder::Status::fromStatusT(error);
-  }
-  return binder::Status::ok();
-}
-
-binder::Status VirtualTouchpadService::buttonState(int touchpad, int buttons) {
-  if (!CheckPermissions()) {
-    return binder::Status::fromStatusT(PERMISSION_DENIED);
-  }
-  if (const status_t error = touchpad_->ButtonState(touchpad, buttons)) {
-    return binder::Status::fromStatusT(error);
-  }
-  return binder::Status::ok();
-}
-
-binder::Status VirtualTouchpadService::scroll(int touchpad, float x, float y) {
-  if (!CheckPermissions()) {
-    return binder::Status::fromStatusT(PERMISSION_DENIED);
-  }
-  if (const status_t error = touchpad_->Scroll(touchpad, x, y)) {
-    return binder::Status::fromStatusT(error);
-  }
-  return binder::Status::ok();
-}
-
-status_t VirtualTouchpadService::dump(
-    int fd, const Vector<String16>& args[[gnu::unused]]) {
-  String8 result;
-  const android::IPCThreadState* ipc = android::IPCThreadState::self();
-  const pid_t pid = ipc->getCallingPid();
-  const uid_t uid = ipc->getCallingUid();
-  if ((uid != AID_SHELL) &&
-      !PermissionCache::checkPermission(kDumpPermission, pid, uid)) {
-    result.appendFormat("Permission denial: can't dump " LOG_TAG
-                        " from pid=%ld, uid=%ld\n",
-                        static_cast<long>(pid), static_cast<long>(uid));
-  } else {
-    result.appendFormat("[service]\nclient_pid = %ld\n\n",
-                        static_cast<long>(client_pid_));
-    touchpad_->dumpInternal(result);
-  }
-  write(fd, result.c_str(), result.size());
-  return OK;
-}
-
-bool VirtualTouchpadService::CheckPermissions() {
-  pid_t pid;
-  if (!CheckTouchPermission(&pid)) {
-    return false;
-  }
-  if (client_pid_ != pid) {
-    ALOGE("pid=%ld is not owner", static_cast<long>(pid));
-    return false;
-  }
-  return true;
-}
-
-bool VirtualTouchpadService::CheckTouchPermission(pid_t* out_pid) {
-  const android::IPCThreadState* ipc = android::IPCThreadState::self();
-  *out_pid = ipc->getCallingPid();
-  const uid_t uid = ipc->getCallingUid();
-  const bool permission = PermissionCache::checkPermission(kTouchPermission, *out_pid, uid);
-  if (!permission) {
-    ALOGE("permission denied to pid=%ld uid=%ld", static_cast<long>(*out_pid),
-          static_cast<long>(uid));
-  }
-  return permission;
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.h b/services/vr/virtual_touchpad/VirtualTouchpadService.h
deleted file mode 100644
index 2c88aec..0000000
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_SERVICE_H
-#define ANDROID_DVR_VIRTUAL_TOUCHPAD_SERVICE_H
-
-#include <android/dvr/BnVirtualTouchpadService.h>
-
-#include "VirtualTouchpad.h"
-
-namespace android {
-namespace dvr {
-
-// VirtualTouchpadService implements the service side of
-// the Binder interface defined in VirtualTouchpadService.aidl.
-//
-class VirtualTouchpadService : public BnVirtualTouchpadService {
- public:
-  explicit VirtualTouchpadService(std::unique_ptr<VirtualTouchpad> touchpad)
-      : touchpad_(std::move(touchpad)), client_pid_(0) {}
-  ~VirtualTouchpadService() override;
-
- protected:
-  // Implements IVirtualTouchpadService.
-  binder::Status attach() override;
-  binder::Status detach() override;
-  binder::Status touch(int touchpad, float x, float y, float pressure) override;
-  binder::Status buttonState(int touchpad, int buttons) override;
-  binder::Status scroll(int touchpad, float x, float y) override;
-
-  // Implements BBinder::dump().
-  status_t dump(int fd, const Vector<String16>& args) override;
-
- private:
-  bool CheckPermissions();
-  bool CheckTouchPermission(pid_t* out_pid);
-
-  std::unique_ptr<VirtualTouchpad> touchpad_;
-
-  // Only one client at a time can use the virtual touchpad.
-  pid_t client_pid_;
-
-  VirtualTouchpadService(const VirtualTouchpadService&) = delete;
-  void operator=(const VirtualTouchpadService&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_VIRTUAL_TOUCHPAD_SERVICE_H
diff --git a/services/vr/virtual_touchpad/aidl/android/dvr/IVirtualTouchpadService.aidl b/services/vr/virtual_touchpad/aidl/android/dvr/IVirtualTouchpadService.aidl
deleted file mode 100644
index 89aa44a..0000000
--- a/services/vr/virtual_touchpad/aidl/android/dvr/IVirtualTouchpadService.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-package android.dvr;
-
-/** @hide */
-interface IVirtualTouchpadService
-{
-  const String SERVICE_NAME = "virtual_touchpad";
-
-  /**
-   * Initialize the virtual touchpad.
-   */
-  void attach() = 0;
-
-  /**
-   * Shut down the virtual touchpad.
-   */
-  void detach() = 1;
-
-  /**
-   * Generate a simulated touch event.
-   *
-   * @param touchpad Selects touchpad.
-   * @param x Horizontal touch position.
-   * @param y Vertical touch position.
-   * @param pressure Touch pressure; use 0.0 for no touch (lift or hover).
-   *
-   * Position values in the range [0.0, 1.0) map to the screen.
-   */
-  void touch(int touchpad, float x, float y, float pressure) = 2;
-
-  /**
-   * Generate a simulated touchpad button state event.
-   *
-   * @param touchpad Selects touchpad.
-   * @param buttons A union of MotionEvent BUTTON_* values.
-   */
-  void buttonState(int touchpad, int buttons) = 3;
-
-  /**
-   * Generate a simulated scroll event.
-   *
-   * @param touchpad Selects touchpad.
-   * @param x Horizontal scroll increment.
-   * @param y Vertical scroll increment.
-   *
-   * Scroll values are in the range [-1.0, 1.0].
-   */
-  void scroll(int touchpad, float x, float y) = 4;
-}
diff --git a/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-0.idc b/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-0.idc
deleted file mode 100644
index 205e8b9..0000000
--- a/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-0.idc
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2017 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.
-
-#
-# Virtual touchpad for the primary display
-device.internal = 1
-
-touch.deviceType = touchScreen
-
-# Have input flinger treat injected scroll events like a G1 ball
-# rather than the default mouse wheel, because the latter requires
-# a visible pointer for targeting.
-device.type = rotaryEncoder
-device.res = 1.0e+2
-device.scalingFactor = 1.0e-2
diff --git a/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-1.idc b/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-1.idc
deleted file mode 100644
index d9714e0..0000000
--- a/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-1.idc
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2017 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.
-
-#
-# Virtual touchpad for the VR virtual display
-device.internal = 1
-
-touch.deviceType = touchScreen
-
-# Have input flinger treat injected scroll events like a G1 ball
-# rather than the default mouse wheel, because the latter requires
-# a visible pointer for targeting.
-device.type = rotaryEncoder
-device.res = 1.0e+2
-device.scalingFactor = 1.0e-2
-
-# This displayID matches the unique ID of the virtual display created for VR.
-# This will indicate to input flinger than it should link this input device
-# with the virtual display.
-touch.displayId = virtual:android:277f1a09-b88d-4d1e-8716-796f114d080b
diff --git a/services/vr/virtual_touchpad/include/VirtualTouchpad.h b/services/vr/virtual_touchpad/include/VirtualTouchpad.h
deleted file mode 100644
index 99b72fc..0000000
--- a/services/vr/virtual_touchpad/include/VirtualTouchpad.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_INTERFACE_H
-#define ANDROID_DVR_VIRTUAL_TOUCHPAD_INTERFACE_H
-
-#include "dvr/virtual_touchpad_client.h"
-
-#include <memory>
-#include <utils/Errors.h>
-#include <utils/String8.h>
-
-namespace android {
-namespace dvr {
-
-// Provides a virtual touchpad for injecting events into the input system.
-//
-class VirtualTouchpad {
- public:
-  enum : int {
-    PRIMARY = DVR_VIRTUAL_TOUCHPAD_PRIMARY,
-    VIRTUAL = DVR_VIRTUAL_TOUCHPAD_VIRTUAL,
-  };
-
-  virtual ~VirtualTouchpad() {}
-
-  // Create a virtual touchpad.
-  // Implementations should provide this, and hide their constructors.
-  // For the user, switching implementations should be as simple as changing
-  // the class whose |Create()| is called.
-  // Implementations should be minimial; major resource allocation should
-  // be performed in Attach().
-  static std::unique_ptr<VirtualTouchpad> Create() {
-    return nullptr;
-  }
-
-  // Initialize a virtual touchpad.
-  virtual status_t Attach() = 0;
-
-  // Shut down a virtual touchpad.
-  virtual status_t Detach() = 0;
-
-  // Generate a simulated touch event.
-  //
-  // @param touchpad Touchpad selector index.
-  // @param x Horizontal touch position.
-  // @param y Vertical touch position.
-  //            Values must be in the range [0.0, 1.0).
-  // @param pressure Touch pressure.
-  //            Positive values represent contact; use 1.0f if contact
-  //            is binary. Use 0.0f for no contact.
-  // @returns OK on success.
-  //
-  virtual status_t Touch(int touchpad, float x, float y, float pressure) = 0;
-
-  // Generate a simulated touchpad button state.
-  //
-  // @param touchpad Touchpad selector index.
-  // @param buttons A union of MotionEvent BUTTON_* values.
-  // @returns OK on success.
-  //
-  // Currently only BUTTON_BACK is supported, as the implementation
-  // restricts itself to operations actually required by VrWindowManager.
-  //
-  virtual status_t ButtonState(int touchpad, int buttons) = 0;
-
-  // Generate a simulated scroll event.
-  //
-  // @param touchpad Touchpad selector index.
-  // @param x Horizontal scroll increment.
-  // @param y Vertical scroll increment.
-  //            Values must be in the range [-1.0, 1.0].
-  // @returns OK on success.
-  //
-  virtual status_t Scroll(int touchpad, float x, float y) = 0;
-
-  // Report state for 'dumpsys'.
-  virtual void dumpInternal(String8& result) = 0;
-
- protected:
-  VirtualTouchpad() {}
-
- private:
-  VirtualTouchpad(const VirtualTouchpad&) = delete;
-  void operator=(const VirtualTouchpad&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_VIRTUAL_TOUCHPAD_INTERFACE_H
diff --git a/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h b/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
deleted file mode 100644
index 268e4bd..0000000
--- a/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
-#define ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
-
-#include "VirtualTouchpad.h"
-
-namespace android {
-namespace dvr {
-
-// VirtualTouchpadClient implements a VirtualTouchpad by connecting to
-// a VirtualTouchpadService over Binder.
-//
-class VirtualTouchpadClient : public VirtualTouchpad {
- public:
-  // VirtualTouchpad implementation:
-  static std::unique_ptr<VirtualTouchpad> Create();
-
- protected:
-  VirtualTouchpadClient() {}
-  ~VirtualTouchpadClient() override {}
-
- private:
-  VirtualTouchpadClient(const VirtualTouchpadClient&) = delete;
-  void operator=(const VirtualTouchpadClient&) = delete;
-};
-
-}  // namespace dvr
-}  // namespace android
-
-#endif  // ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
diff --git a/services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h b/services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h
deleted file mode 100644
index 09fb1cc..0000000
--- a/services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_C_CLIENT_H
-#define ANDROID_DVR_VIRTUAL_TOUCHPAD_C_CLIENT_H
-
-#include <dvr/dvr_api.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct DvrVirtualTouchpad DvrVirtualTouchpad;
-
-// Creates a new virtual touchpad client.
-//
-// @return Pointer to the created virtual touchpad client; nullptr on failure.
-//
-DvrVirtualTouchpad* dvrVirtualTouchpadCreate();
-
-// Destroys a virtual touchpad client.
-//
-// @param client Pointer to the virtual touchpad client to be destroyed.
-//
-void dvrVirtualTouchpadDestroy(DvrVirtualTouchpad* client);
-
-// Initialize the virtual touchpad.
-//
-// In the current server implementation, attachment creates and configures
-// the kernel virtual touchpad device(s). A single client may be attached
-// and detached repeatedly, e.g. on entering and leaving VR mode.
-//
-// @param client Pointer to the virtual touchpad client to be attached.
-// @return Zero on success, status_t-style error code on failure.
-//
-int dvrVirtualTouchpadAttach(DvrVirtualTouchpad* client);
-
-// Shut down the virtual touchpad.
-//
-// @param client Pointer to the virtual touchpad client to be detached.
-// @return Zero on success, status_t-style error code on failure.
-//
-int dvrVirtualTouchpadDetach(DvrVirtualTouchpad* client);
-
-// Generate a simulated touch event.
-//
-// @param client Pointer to the virtual touchpad client.
-// @param touchpad Selects touchpad.
-// @param x Horizontal touch position.
-// @param y Vertical touch position.
-// @param pressure Touch pressure; use 0.0 for no touch (lift or hover).
-// @return Zero on success, status_t-style error code on failure.
-//
-int dvrVirtualTouchpadTouch(DvrVirtualTouchpad* client, int touchpad, float x,
-                            float y, float pressure);
-
-// Generate a simulated touchpad button state event.
-//
-// @param client Pointer to the virtual touchpad client.
-// @param touchpad Selects touchpad.
-// @param buttons A union of MotionEvent BUTTON_* values.
-// @return Zero on success, status_t-style error code on failure.
-//
-int dvrVirtualTouchpadButtonState(DvrVirtualTouchpad* client, int touchpad,
-                                  int buttons);
-
-// Generate a simulated scroll event.
-//
-// @param client Pointer to the virtual touchpad client.
-// @param touchpad Selects touchpad.
-// @param x Horizontal scroll increment.
-// @param y Vertical scroll increment.
-// @return Zero on success, status_t-style error code on failure.
-//
-int dvrVirtualTouchpadScroll(DvrVirtualTouchpad* client, int touchpad, float x,
-                             float y);
-
-#ifdef __cplusplus
-}  // extern "C"
-#endif
-
-#endif  // ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
diff --git a/services/vr/virtual_touchpad/main.cpp b/services/vr/virtual_touchpad/main.cpp
deleted file mode 100644
index 55ac9bf..0000000
--- a/services/vr/virtual_touchpad/main.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <log/log.h>
-
-#include "VirtualTouchpadEvdev.h"
-#include "VirtualTouchpadService.h"
-
-int main() {
-  ALOGI("Starting");
-  android::sp<android::dvr::VirtualTouchpadService> touchpad_service =
-      new android::dvr::VirtualTouchpadService(
-          android::dvr::VirtualTouchpadEvdev::Create());
-
-  signal(SIGPIPE, SIG_IGN);
-  android::sp<android::ProcessState> ps(android::ProcessState::self());
-  ps->setThreadPoolMaxThreadCount(4);
-  ps->startThreadPool();
-  ps->giveThreadPoolName();
-
-  android::sp<android::IServiceManager> sm(android::defaultServiceManager());
-  const android::status_t service_status =
-      sm->addService(android::String16(touchpad_service->SERVICE_NAME()),
-                     touchpad_service, false /*allowIsolated*/);
-  if (service_status != android::OK) {
-    ALOGE("virtual touchpad service not added: %d",
-          static_cast<int>(service_status));
-    exit(2);
-  }
-
-  android::IPCThreadState::self()->joinThreadPool();
-  return 0;
-}
diff --git a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
deleted file mode 100644
index 198ed06..0000000
--- a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-#include <android/input.h>
-#include <gtest/gtest.h>
-#include <linux/input.h>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-
-#include "EvdevInjector.h"
-#include "VirtualTouchpadEvdev.h"
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-class UInputForTesting : public EvdevInjector::UInput {
- public:
-  ~UInputForTesting() override {}
-  void WriteInputEvent(uint16_t type, uint16_t code, int32_t value) {
-    struct input_event event;
-    memset(&event, 0, sizeof(event));
-    event.type = type;
-    event.code = code;
-    event.value = value;
-    Write(&event, sizeof(event));
-  }
-};
-
-// Recording test implementation of UInput.
-//
-class UInputRecorder : public UInputForTesting {
- public:
-  UInputRecorder() {}
-  ~UInputRecorder() override {}
-
-  const std::string& GetString() const { return s_; }
-  void Reset() { s_.clear(); }
-
-  // UInput overrides:
-
-  int Open() override {
-    s_ += "o;";
-    return 0;
-  }
-
-  int Close() override {
-    s_ += "c;";
-    return 0;
-  }
-
-  int Write(const void* buf, size_t count) override {
-    s_ += "w(";
-    s_ += Encode(&count, sizeof(count));
-    s_ += ",";
-    s_ += Encode(buf, count);
-    s_ += ");";
-    return 0;
-  }
-
-  int IoctlVoid(int request) override {
-    s_ += "i(";
-    s_ += Encode(&request, sizeof(request));
-    s_ += ");";
-    return 0;
-  }
-
-  int IoctlSetInt(int request, int value) override {
-    s_ += "i(";
-    s_ += Encode(&request, sizeof(request));
-    s_ += ",";
-    s_ += Encode(&value, sizeof(value));
-    s_ += ");";
-    return 0;
-  }
-
- private:
-  std::string s_;
-
-  std::string Encode(const void* buf, size_t count) {
-    const char* in = static_cast<const char*>(buf);
-    char out[2 * count + 1];
-    for (size_t i = 0; i < count; ++i) {
-      snprintf(&out[2 * i], 3, "%02X", in[i]);
-    }
-    return out;
-  }
-};
-
-class EvdevInjectorForTesting : public EvdevInjector {
- public:
-  EvdevInjectorForTesting() { SetUInputForTesting(&record); }
-  const uinput_user_dev* GetUiDev() const { return GetUiDevForTesting(); }
-  UInputRecorder record;
-};
-
-class VirtualTouchpadForTesting : public VirtualTouchpadEvdev {
- public:
-  static std::unique_ptr<VirtualTouchpad> Create() {
-    return std::unique_ptr<VirtualTouchpad>(New());
-  }
-  static VirtualTouchpadForTesting* New() {
-    VirtualTouchpadForTesting* const touchpad = new VirtualTouchpadForTesting();
-    touchpad->Reset();
-    for (int t = 0; t < kTouchpads; ++t) {
-      touchpad->SetEvdevInjectorForTesting(t, &touchpad->injector[t]);
-    }
-    return touchpad;
-  }
-  int GetTouchpadCount() const { return kTouchpads; }
-  EvdevInjectorForTesting injector[kTouchpads];
-};
-
-}  // anonymous namespace
-
-class VirtualTouchpadTest : public testing::Test {};
-
-TEST_F(VirtualTouchpadTest, Goodness) {
-  std::unique_ptr<VirtualTouchpadForTesting> touchpad(
-      VirtualTouchpadForTesting::New());
-  UInputRecorder expect;
-
-  status_t touch_status = touchpad->Attach();
-  EXPECT_EQ(0, touch_status);
-
-  // Check some aspects of uinput_user_dev.
-  const uinput_user_dev* uidev;
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    uidev = touchpad->injector[t].GetUiDev();
-    String8 name;
-    name.appendFormat("vr-virtual-touchpad-%d", t);
-    EXPECT_EQ(name, uidev->name);
-    for (int i = 0; i < ABS_CNT; ++i) {
-      EXPECT_EQ(0, uidev->absmin[i]);
-      EXPECT_EQ(0, uidev->absfuzz[i]);
-      EXPECT_EQ(0, uidev->absflat[i]);
-      if (i != ABS_MT_POSITION_X && i != ABS_MT_POSITION_Y &&
-          i != ABS_MT_SLOT) {
-        EXPECT_EQ(0, uidev->absmax[i]);
-      }
-    }
-  }
-  const int32_t width = 1 + uidev->absmax[ABS_MT_POSITION_X];
-  const int32_t height = 1 + uidev->absmax[ABS_MT_POSITION_Y];
-
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    // Check the system calls performed by initialization.
-    expect.Reset();
-    // From ConfigureBegin():
-    expect.Open();
-    // From ConfigureInputProperty(INPUT_PROP_DIRECT):
-    expect.IoctlSetInt(UI_SET_PROPBIT, INPUT_PROP_DIRECT);
-    // From ConfigureMultiTouchXY(0, 0, kWidth - 1, kHeight - 1):
-    expect.IoctlSetInt(UI_SET_EVBIT, EV_ABS);
-    expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_POSITION_X);
-    expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_POSITION_Y);
-    // From ConfigureAbsSlots(kSlots):
-    expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_SLOT);
-    // From ConfigureRel(REL_WHEEL):
-    expect.IoctlSetInt(UI_SET_EVBIT, EV_REL);
-    expect.IoctlSetInt(UI_SET_RELBIT, REL_WHEEL);
-    // From ConfigureRel(REL_HWHEEL):
-    expect.IoctlSetInt(UI_SET_RELBIT, REL_HWHEEL);
-    // From ConfigureKey(BTN_TOUCH):
-    expect.IoctlSetInt(UI_SET_EVBIT, EV_KEY);
-    expect.IoctlSetInt(UI_SET_KEYBIT, BTN_TOUCH);
-    expect.IoctlSetInt(UI_SET_KEYBIT, BTN_BACK);
-    // From ConfigureEnd():
-    expect.Write(touchpad->injector[t].GetUiDev(), sizeof(uinput_user_dev));
-    expect.IoctlVoid(UI_DEV_CREATE);
-    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
-  }
-
-  expect.Reset();
-  expect.WriteInputEvent(EV_ABS, ABS_MT_SLOT, 0);
-  expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
-  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0);
-  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0);
-  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    touchpad->injector[t].record.Reset();
-    touch_status = touchpad->Touch(t, 0, 0, 0);
-    EXPECT_EQ(0, touch_status);
-    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
-  }
-
-  expect.Reset();
-  expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
-  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.25f * width);
-  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0.75f * height);
-  expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_PRESS);
-  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    touchpad->injector[t].record.Reset();
-    touch_status = touchpad->Touch(t, 0.25f, 0.75f, 0.5f);
-    EXPECT_EQ(0, touch_status);
-    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
-  }
-
-  expect.Reset();
-  expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
-  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.99f * width);
-  expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0.99f * height);
-  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    touchpad->injector[t].record.Reset();
-    touch_status = touchpad->Touch(t, 0.99f, 0.99f, 0.99f);
-    EXPECT_EQ(0, touch_status);
-    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
-  }
-
-  expect.Reset();
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    touchpad->injector[t].record.Reset();
-    touch_status = touchpad->Touch(t, 1.0f, 1.0f, 1.0f);
-    EXPECT_EQ(EINVAL, touch_status);
-    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
-  }
-
-  expect.Reset();
-  expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_RELEASE);
-  expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, -1);
-  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    touchpad->injector[t].record.Reset();
-    touch_status = touchpad->Touch(t, 0.25f, 0.75f, -0.01f);
-    EXPECT_EQ(0, touch_status);
-    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
-  }
-
-  expect.Reset();
-  expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_PRESS);
-  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    touchpad->injector[t].record.Reset();
-    touch_status = touchpad->ButtonState(t, AMOTION_EVENT_BUTTON_BACK);
-    EXPECT_EQ(0, touch_status);
-    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
-  }
-
-  expect.Reset();
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    touchpad->injector[t].record.Reset();
-    touch_status = touchpad->ButtonState(t, AMOTION_EVENT_BUTTON_BACK);
-    EXPECT_EQ(0, touch_status);
-    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
-  }
-
-  expect.Reset();
-  expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_RELEASE);
-  expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    touchpad->injector[t].record.Reset();
-    touch_status = touchpad->ButtonState(t, 0);
-    EXPECT_EQ(0, touch_status);
-    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
-  }
-
-  expect.Reset();
-  expect.Close();
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    touchpad->injector[t].record.Reset();
-  }
-  touch_status = touchpad->Detach();
-  EXPECT_EQ(0, touch_status);
-  for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
-    SCOPED_TRACE(t);
-    EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
-  }
-}
-
-TEST_F(VirtualTouchpadTest, Badness) {
-  std::unique_ptr<VirtualTouchpadForTesting> touchpad(
-      VirtualTouchpadForTesting::New());
-  UInputRecorder expect;
-  UInputRecorder& record = touchpad->injector[VirtualTouchpad::PRIMARY].record;
-
-  status_t touch_status = touchpad->Attach();
-  EXPECT_EQ(0, touch_status);
-
-  // Touch off-screen should return an error,
-  // and should not result in any system calls.
-  expect.Reset();
-  record.Reset();
-  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, -0.25f, 0.75f, 1.0f);
-  EXPECT_NE(OK, touch_status);
-  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, -0.75f, 1.0f);
-  EXPECT_NE(OK, touch_status);
-  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 1.25f, 0.75f, 1.0f);
-  EXPECT_NE(OK, touch_status);
-  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, 1.75f, 1.0f);
-  EXPECT_NE(OK, touch_status);
-  EXPECT_EQ(expect.GetString(), record.GetString());
-
-  // Unsupported button should return an error,
-  // and should not result in any system calls.
-  expect.Reset();
-  record.Reset();
-  touch_status = touchpad->ButtonState(VirtualTouchpad::PRIMARY,
-                                       AMOTION_EVENT_BUTTON_FORWARD);
-  EXPECT_NE(OK, touch_status);
-  EXPECT_EQ(expect.GetString(), record.GetString());
-
-  // Repeated attach is an error.
-  touch_status = touchpad->Attach();
-  EXPECT_NE(0, touch_status);
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/services/vr/virtual_touchpad/virtual_touchpad.rc b/services/vr/virtual_touchpad/virtual_touchpad.rc
deleted file mode 100644
index 1612743..0000000
--- a/services/vr/virtual_touchpad/virtual_touchpad.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service virtual_touchpad /system/bin/virtual_touchpad
-  class core
-  user system
-  group system input uhid
-  task_profiles VrServiceCapacityNormal
diff --git a/vulkan/Android.bp b/vulkan/Android.bp
index 2bf905c..0da9cc0 100644
--- a/vulkan/Android.bp
+++ b/vulkan/Android.bp
@@ -26,6 +26,8 @@
 
 cc_library_headers {
     name: "hwvulkan_headers",
+    host_supported: true, // Used for verification in Berberis.
+    native_bridge_supported: true, // Used for verification in Berberis.
     vendor_available: true,
     header_libs: [
         "libcutils_headers",
diff --git a/vulkan/libvulkan/api_gen.cpp b/vulkan/libvulkan/api_gen.cpp
index a9706bc..a3fe33e 100644
--- a/vulkan/libvulkan/api_gen.cpp
+++ b/vulkan/libvulkan/api_gen.cpp
@@ -178,7 +178,7 @@
     INIT_PROC(false, instance, GetPhysicalDeviceExternalSemaphoreProperties);
     INIT_PROC(false, instance, GetPhysicalDeviceExternalFenceProperties);
     INIT_PROC(false, instance, EnumeratePhysicalDeviceGroups);
-    INIT_PROC_EXT(KHR_swapchain, false, instance, GetPhysicalDevicePresentRectanglesKHR);
+    INIT_PROC_EXT(KHR_swapchain, true, instance, GetPhysicalDevicePresentRectanglesKHR);
     INIT_PROC(false, instance, GetPhysicalDeviceToolProperties);
     // clang-format on
 
@@ -325,9 +325,9 @@
     INIT_PROC(false, dev, BindBufferMemory2);
     INIT_PROC(false, dev, BindImageMemory2);
     INIT_PROC(false, dev, CmdSetDeviceMask);
-    INIT_PROC_EXT(KHR_swapchain, false, dev, GetDeviceGroupPresentCapabilitiesKHR);
-    INIT_PROC_EXT(KHR_swapchain, false, dev, GetDeviceGroupSurfacePresentModesKHR);
-    INIT_PROC_EXT(KHR_swapchain, false, dev, AcquireNextImage2KHR);
+    INIT_PROC_EXT(KHR_swapchain, true, dev, GetDeviceGroupPresentCapabilitiesKHR);
+    INIT_PROC_EXT(KHR_swapchain, true, dev, GetDeviceGroupSurfacePresentModesKHR);
+    INIT_PROC_EXT(KHR_swapchain, true, dev, AcquireNextImage2KHR);
     INIT_PROC(false, dev, CmdDispatchBase);
     INIT_PROC(false, dev, CreateDescriptorUpdateTemplate);
     INIT_PROC(false, dev, DestroyDescriptorUpdateTemplate);
@@ -659,6 +659,8 @@
         "vkGetDrmDisplayEXT",
         "vkGetInstanceProcAddr",
         "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT",
+        "vkGetPhysicalDeviceCalibrateableTimeDomainsKHR",
+        "vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR",
         "vkGetPhysicalDeviceDisplayPlaneProperties2KHR",
         "vkGetPhysicalDeviceDisplayProperties2KHR",
         "vkGetPhysicalDeviceExternalBufferProperties",
@@ -703,6 +705,7 @@
         "vkGetPhysicalDeviceToolProperties",
         "vkGetPhysicalDeviceToolPropertiesEXT",
         "vkGetPhysicalDeviceVideoCapabilitiesKHR",
+        "vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR",
         "vkGetPhysicalDeviceVideoFormatPropertiesKHR",
         "vkSubmitDebugUtilsMessageEXT",
     };
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 9e67725..00e987f 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -1473,23 +1473,14 @@
         image_format_properties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
         image_format_properties.pNext = &ahb_usage;
 
-        if (instance_dispatch.GetPhysicalDeviceImageFormatProperties2) {
-            VkResult result = instance_dispatch.GetPhysicalDeviceImageFormatProperties2(
-                pdev, &image_format_info, &image_format_properties);
-            if (result != VK_SUCCESS) {
-                ALOGE("VkGetPhysicalDeviceImageFormatProperties2 for AHB usage failed: %d", result);
-                return VK_ERROR_SURFACE_LOST_KHR;
-            }
-        }
-        else {
-            VkResult result = instance_dispatch.GetPhysicalDeviceImageFormatProperties2KHR(
-                pdev, &image_format_info,
-                &image_format_properties);
-            if (result != VK_SUCCESS) {
-                ALOGE("VkGetPhysicalDeviceImageFormatProperties2KHR for AHB usage failed: %d",
-                    result);
-                return VK_ERROR_SURFACE_LOST_KHR;
-            }
+        VkResult result = GetPhysicalDeviceImageFormatProperties2(
+            pdev, &image_format_info, &image_format_properties);
+        if (result != VK_SUCCESS) {
+            ALOGE(
+                "VkGetPhysicalDeviceImageFormatProperties2 for AHB usage "
+                "failed: %d",
+                result);
+            return VK_ERROR_SURFACE_LOST_KHR;
         }
 
         // Determine if USAGE_FRONT_BUFFER is needed.
diff --git a/vulkan/scripts/generator_common.py b/vulkan/scripts/generator_common.py
index 866c1b7..6b4cbad 100644
--- a/vulkan/scripts/generator_common.py
+++ b/vulkan/scripts/generator_common.py
@@ -351,9 +351,50 @@
                           'external', 'vulkan-headers', 'registry', 'vk.xml')
   tree = element_tree.parse(registry)
   root = tree.getroot()
+
+  for exts in root.iter('extensions'):
+    for extension in exts.iter('extension'):
+      if 'vulkan' not in extension.get('supported').split(','):
+        # ANDROID_native_buffer is a weird special case -- it's declared in vk.xml as
+        # disabled but we _do_ want to generate plumbing for it in the Android loader.
+        if extension.get('name') != 'VK_ANDROID_native_buffer':
+          print('skip extension disabled or not for vulkan: ' + extension.get('name'))
+          continue
+
+      apiversion = 'VK_VERSION_1_0'
+      if extension.tag == 'extension':
+        extname = extension.get('name')
+        if (extension.get('type') == 'instance' and
+            extension.get('promotedto') is not None):
+          promoted_inst_ext_dict[extname] = \
+              version_2_api_version(extension.get('promotedto'))
+        for req in extension.iter('require'):
+          if req.get('feature') is not None:
+            apiversion = req.get('feature')
+          for commands in req:
+            if commands.tag == 'command':
+              cmd_name = commands.get('name')
+              if cmd_name not in extension_dict:
+                extension_dict[cmd_name] = extname
+                version_dict[cmd_name] = apiversion
+
+  for feature in root.iter('feature'):
+    if 'vulkan' not in feature.get('api').split(','):
+      continue
+
+    apiversion = feature.get('name')
+    for req in feature.iter('require'):
+      for command in req:
+        if command.tag == 'command':
+          cmd_name = command.get('name')
+          version_dict[cmd_name] = apiversion
+
   for commands in root.iter('commands'):
     for command in commands:
       if command.tag == 'command':
+        if command.get('api') == 'vulkansc':
+          continue
+
         parameter_list = []
         protoset = False
         cmd_name = ''
@@ -361,12 +402,18 @@
         if command.get('alias') is not None:
           alias = command.get('alias')
           cmd_name = command.get('name')
-          alias_dict[cmd_name] = alias
-          command_list.append(cmd_name)
-          param_dict[cmd_name] = param_dict[alias].copy()
-          return_type_dict[cmd_name] = return_type_dict[alias]
+          # At this stage all valid commands have been added to the version
+          # dict so we can use it to filter valid commands
+          if cmd_name in version_dict:
+            alias_dict[cmd_name] = alias
+            command_list.append(cmd_name)
+            param_dict[cmd_name] = param_dict[alias].copy()
+            return_type_dict[cmd_name] = return_type_dict[alias]
         for params in command:
           if params.tag == 'param':
+            if params.get('api') == 'vulkansc':
+              # skip SC-only param variant
+              continue
             param_type = ''
             if params.text is not None and params.text.strip():
               param_type = params.text.strip() + ' '
@@ -387,39 +434,13 @@
                 cmd_type = c.text
               if c.tag == 'name':
                 cmd_name = c.text
-                protoset = True
-                command_list.append(cmd_name)
-                return_type_dict[cmd_name] = cmd_type
+                if cmd_name in version_dict:
+                  protoset = True
+                  command_list.append(cmd_name)
+                  return_type_dict[cmd_name] = cmd_type
         if protoset:
           param_dict[cmd_name] = parameter_list.copy()
 
-  for exts in root.iter('extensions'):
-    for extension in exts:
-      apiversion = 'VK_VERSION_1_0'
-      if extension.tag == 'extension':
-        extname = extension.get('name')
-        if (extension.get('type') == 'instance' and
-            extension.get('promotedto') is not None):
-          promoted_inst_ext_dict[extname] = \
-              version_2_api_version(extension.get('promotedto'))
-        for req in extension:
-          if req.get('feature') is not None:
-            apiversion = req.get('feature')
-          for commands in req:
-            if commands.tag == 'command':
-              cmd_name = commands.get('name')
-              if cmd_name not in extension_dict:
-                extension_dict[cmd_name] = extname
-                version_dict[cmd_name] = apiversion
-
-  for feature in root.iter('feature'):
-    apiversion = feature.get('name')
-    for req in feature:
-      for command in req:
-        if command.tag == 'command':
-          cmd_name = command.get('name')
-          if cmd_name in command_list:
-            version_dict[cmd_name] = apiversion
 
   version_code_set = set()
   for version in version_dict.values():
diff --git a/vulkan/scripts/null_generator.py b/vulkan/scripts/null_generator.py
index e9faef6..3624c1d 100644
--- a/vulkan/scripts/null_generator.py
+++ b/vulkan/scripts/null_generator.py
@@ -89,6 +89,8 @@
     f.write(gencom.copyright_and_warning(2015))
 
     f.write("""\
+#include <android/hardware_buffer.h>
+
 #include <algorithm>
 
 #include "null_driver_gen.h"