Merge "Fix Surface HDR meta reset"
diff --git a/TEST_MAPPING b/TEST_MAPPING
index f54f132..e66bca0 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -28,9 +28,6 @@
           "include-filter": "*CropLatchingTest.*"
         },
         {
-          "include-filter": "*ChildLayerTest.*"
-        },
-        {
           "include-filter": "*ScreenCaptureTest.*"
         },
         {
@@ -56,9 +53,6 @@
         },
         {
           "include-filter": "*RefreshRateOverlayTest.*"
-        },
-        {
-          "exclude-filter": "*ChildLayerTest#ChildrenSurviveParentDestruction"
         }
       ]
     },
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index c1ae5b4..ee1c63a 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -170,6 +170,7 @@
 #define RECOVERY_DIR "/cache/recovery"
 #define RECOVERY_DATA_DIR "/data/misc/recovery"
 #define UPDATE_ENGINE_LOG_DIR "/data/misc/update_engine_log"
+#define UPDATE_ENGINE_PREF_DIR "/data/misc/update_engine/prefs"
 #define LOGPERSIST_DATA_DIR "/data/misc/logd"
 #define PREREBOOT_DATA_DIR "/data/misc/prereboot"
 #define PROFILE_DATA_DIR_CUR "/data/misc/profiles/cur"
@@ -234,6 +235,7 @@
 // task and the log title of the duration report.
 static const std::string DUMP_TRACES_TASK = "DUMP TRACES";
 static const std::string DUMP_INCIDENT_REPORT_TASK = "INCIDENT REPORT";
+static const std::string DUMP_NETSTATS_PROTO_TASK = "DUMP NETSTATS PROTO";
 static const std::string DUMP_HALS_TASK = "DUMP HALS";
 static const std::string DUMP_BOARD_TASK = "dumpstate_board()";
 static const std::string DUMP_CHECKINS_TASK = "DUMP CHECKINS";
@@ -1041,6 +1043,26 @@
     }
 }
 
+static void DumpNetstatsProto() {
+    const std::string path = ds.bugreport_internal_dir_ + "/tmp_netstats_proto";
+    auto fd = android::base::unique_fd(TEMP_FAILURE_RETRY(open(path.c_str(),
+                O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
+                S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
+    if (fd < 0) {
+        MYLOGE("Could not open %s to dump netstats proto.\n", path.c_str());
+        return;
+    }
+    RunCommandToFd(fd, "", {"dumpsys", "netstats", "--proto"},
+            CommandOptions::WithTimeout(120).Build());
+    bool empty = 0 == lseek(fd, 0, SEEK_END);
+    if (!empty) {
+        ds.EnqueueAddZipEntryAndCleanupIfNeeded(kProtoPath + "netstats" + kProtoExt,
+                path);
+    } else {
+        unlink(path.c_str());
+    }
+}
+
 static void MaybeAddSystemTraceToZip() {
     // This function copies into the .zip the system trace that was snapshotted
     // by the early call to MaybeSnapshotSystemTrace(), if any background
@@ -1576,7 +1598,8 @@
     DurationReporter duration_reporter("DUMPSTATE");
 
     // Enqueue slow functions into the thread pool, if the parallel run is enabled.
-    std::future<std::string> dump_hals, dump_incident_report, dump_board, dump_checkins;
+    std::future<std::string> dump_hals, dump_incident_report, dump_board, dump_checkins,
+            dump_netstats_report;
     if (ds.dump_pool_) {
         // Pool was shutdown in DumpstateDefaultAfterCritical method in order to
         // drop root user. Restarts it with two threads for the parallel run.
@@ -1585,6 +1608,8 @@
         dump_hals = ds.dump_pool_->enqueueTaskWithFd(DUMP_HALS_TASK, &DumpHals, _1);
         dump_incident_report = ds.dump_pool_->enqueueTask(
             DUMP_INCIDENT_REPORT_TASK, &DumpIncidentReport);
+        dump_netstats_report = ds.dump_pool_->enqueueTask(
+            DUMP_NETSTATS_PROTO_TASK, &DumpNetstatsProto);
         dump_board = ds.dump_pool_->enqueueTaskWithFd(
             DUMP_BOARD_TASK, &Dumpstate::DumpstateBoard, &ds, _1);
         dump_checkins = ds.dump_pool_->enqueueTaskWithFd(DUMP_CHECKINS_TASK, &DumpCheckins, _1);
@@ -1779,6 +1804,13 @@
     dump_frozen_cgroupfs();
 
     if (ds.dump_pool_) {
+        WAIT_TASK_WITH_CONSENT_CHECK(std::move(dump_netstats_report));
+    } else {
+        RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_NETSTATS_PROTO_TASK,
+                DumpNetstatsProto);
+    }
+
+    if (ds.dump_pool_) {
         WAIT_TASK_WITH_CONSENT_CHECK(std::move(dump_incident_report));
     } else {
         RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_INCIDENT_REPORT_TASK,
@@ -1828,6 +1860,7 @@
     ds.AddDir(RECOVERY_DIR, true);
     ds.AddDir(RECOVERY_DATA_DIR, true);
     ds.AddDir(UPDATE_ENGINE_LOG_DIR, true);
+    ds.AddDir(UPDATE_ENGINE_PREF_DIR, true);
     ds.AddDir(LOGPERSIST_DATA_DIR, false);
     if (!PropertiesHelper::IsUserBuild()) {
         ds.AddDir(PROFILE_DATA_DIR_CUR, true);
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index f0c19b9..b8e5ce1 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -60,6 +60,7 @@
     MOCK_METHOD1(isDeclared, bool(const String16&));
     MOCK_METHOD1(getDeclaredInstances, Vector<String16>(const String16&));
     MOCK_METHOD1(updatableViaApex, std::optional<String16>(const String16&));
+    MOCK_METHOD1(getUpdatableNames, Vector<String16>(const String16&));
     MOCK_METHOD1(getConnectionInfo, std::optional<ConnectionInfo>(const String16&));
     MOCK_METHOD2(registerForNotifications, status_t(const String16&,
                                              const sp<LocalRegistrationCallback>&));
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index ebb7891..34ea759 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1956,7 +1956,7 @@
                       join_fds(context_input_fds), swap_fd.get(), instruction_set, compiler_filter,
                       debuggable, boot_complete, for_restore, target_sdk_version,
                       enable_hidden_api_checks, generate_compact_dex, use_jitzygote_image,
-                      compilation_reason);
+                      background_job_compile, compilation_reason);
 
     bool cancelled = false;
     pid_t pid = dexopt_status_->check_cancellation_and_fork(&cancelled);
diff --git a/cmds/installd/run_dex2oat.cpp b/cmds/installd/run_dex2oat.cpp
index 51c4589..4221a3a 100644
--- a/cmds/installd/run_dex2oat.cpp
+++ b/cmds/installd/run_dex2oat.cpp
@@ -81,6 +81,7 @@
                             bool enable_hidden_api_checks,
                             bool generate_compact_dex,
                             bool use_jitzygote,
+                            bool background_job_compile,
                             const char* compilation_reason) {
     PrepareBootImageFlags(use_jitzygote);
 
@@ -92,7 +93,8 @@
                                debuggable, target_sdk_version, enable_hidden_api_checks,
                                generate_compact_dex, compilation_reason);
 
-    PrepareCompilerRuntimeAndPerfConfigFlags(post_bootcomplete, for_restore);
+    PrepareCompilerRuntimeAndPerfConfigFlags(post_bootcomplete, for_restore,
+                                             background_job_compile);
 
     const std::string dex2oat_flags = GetProperty("dalvik.vm.dex2oat-flags", "");
     std::vector<std::string> dex2oat_flags_args = SplitBySpaces(dex2oat_flags);
@@ -296,7 +298,8 @@
 }
 
 void RunDex2Oat::PrepareCompilerRuntimeAndPerfConfigFlags(bool post_bootcomplete,
-                                                          bool for_restore) {
+                                                          bool for_restore,
+                                                          bool background_job_compile) {
     // CPU set
     {
         std::string cpu_set_format = "--cpu-set=%s";
@@ -306,7 +309,12 @@
                            "dalvik.vm.restore-dex2oat-cpu-set",
                            "dalvik.vm.dex2oat-cpu-set",
                            cpu_set_format)
-                   : MapPropertyToArg("dalvik.vm.dex2oat-cpu-set", cpu_set_format))
+                   : (background_job_compile
+                      ? MapPropertyToArgWithBackup(
+                              "dalvik.vm.background-dex2oat-cpu-set",
+                              "dalvik.vm.dex2oat-cpu-set",
+                              cpu_set_format)
+                      : MapPropertyToArg("dalvik.vm.dex2oat-cpu-set", cpu_set_format)))
                 : MapPropertyToArg("dalvik.vm.boot-dex2oat-cpu-set", cpu_set_format);
         AddArg(dex2oat_cpu_set_arg);
     }
@@ -320,7 +328,12 @@
                            "dalvik.vm.restore-dex2oat-threads",
                            "dalvik.vm.dex2oat-threads",
                            threads_format)
-                   : MapPropertyToArg("dalvik.vm.dex2oat-threads", threads_format))
+                   : (background_job_compile
+                      ? MapPropertyToArgWithBackup(
+                              "dalvik.vm.background-dex2oat-threads",
+                              "dalvik.vm.dex2oat-threads",
+                              threads_format)
+                      : MapPropertyToArg("dalvik.vm.dex2oat-threads", threads_format)))
                 : MapPropertyToArg("dalvik.vm.boot-dex2oat-threads", threads_format);
         AddArg(dex2oat_threads_arg);
     }
diff --git a/cmds/installd/run_dex2oat.h b/cmds/installd/run_dex2oat.h
index 559244f..c13e1f1 100644
--- a/cmds/installd/run_dex2oat.h
+++ b/cmds/installd/run_dex2oat.h
@@ -51,6 +51,7 @@
                     bool enable_hidden_api_checks,
                     bool generate_compact_dex,
                     bool use_jitzygote,
+                    bool background_job_compile,
                     const char* compilation_reason);
 
     void Exec(int exit_code);
@@ -76,7 +77,9 @@
                                     bool enable_hidden_api_checks,
                                     bool generate_compact_dex,
                                     const char* compilation_reason);
-    void PrepareCompilerRuntimeAndPerfConfigFlags(bool post_bootcomplete, bool for_restore);
+    void PrepareCompilerRuntimeAndPerfConfigFlags(bool post_bootcomplete,
+                                                  bool for_restore,
+                                                  bool background_job_compile);
 
     virtual std::string GetProperty(const std::string& key, const std::string& default_value);
     virtual bool GetBoolProperty(const std::string& key, bool default_value);
diff --git a/cmds/installd/run_dex2oat_test.cpp b/cmds/installd/run_dex2oat_test.cpp
index 2a8135a..304ba7b 100644
--- a/cmds/installd/run_dex2oat_test.cpp
+++ b/cmds/installd/run_dex2oat_test.cpp
@@ -115,6 +115,7 @@
         bool enable_hidden_api_checks = false;
         bool generate_compact_dex = true;
         bool use_jitzygote = false;
+        bool background_job_compile = false;
         const char* compilation_reason = nullptr;
     };
 
@@ -259,6 +260,7 @@
                           args->enable_hidden_api_checks,
                           args->generate_compact_dex,
                           args->use_jitzygote,
+                          args->background_job_compile,
                           args->compilation_reason);
         runner.Exec(/*exit_code=*/ 0);
     }
@@ -375,6 +377,30 @@
     VerifyExpectedFlags();
 }
 
+TEST_F(RunDex2OatTest, CpuSetPostBootCompleteBackground) {
+    setSystemProperty("dalvik.vm.background-dex2oat-cpu-set", "1,3");
+    setSystemProperty("dalvik.vm.dex2oat-cpu-set", "1,2");
+    auto args = RunDex2OatArgs::MakeDefaultTestArgs();
+    args->post_bootcomplete = true;
+    args->background_job_compile = true;
+    CallRunDex2Oat(std::move(args));
+
+    SetExpectedFlagUsed("--cpu-set", "=1,3");
+    VerifyExpectedFlags();
+}
+
+TEST_F(RunDex2OatTest, CpuSetPostBootCompleteBackground_Backup) {
+    setSystemProperty("dalvik.vm.background-dex2oat-cpu-set", "");
+    setSystemProperty("dalvik.vm.dex2oat-cpu-set", "1,2");
+    auto args = RunDex2OatArgs::MakeDefaultTestArgs();
+    args->post_bootcomplete = true;
+    args->background_job_compile = true;
+    CallRunDex2Oat(std::move(args));
+
+    SetExpectedFlagUsed("--cpu-set", "=1,2");
+    VerifyExpectedFlags();
+}
+
 TEST_F(RunDex2OatTest, CpuSetPostBootCompleteForRestore) {
     setSystemProperty("dalvik.vm.restore-dex2oat-cpu-set", "1,2");
     setSystemProperty("dalvik.vm.dex2oat-cpu-set", "2,3");
@@ -481,6 +507,30 @@
     VerifyExpectedFlags();
 }
 
+TEST_F(RunDex2OatTest, ThreadsPostBootCompleteBackground) {
+    setSystemProperty("dalvik.vm.background-dex2oat-threads", "2");
+    setSystemProperty("dalvik.vm.dex2oat-threads", "3");
+    auto args = RunDex2OatArgs::MakeDefaultTestArgs();
+    args->post_bootcomplete = true;
+    args->background_job_compile = true;
+    CallRunDex2Oat(std::move(args));
+
+    SetExpectedFlagUsed("-j", "2");
+    VerifyExpectedFlags();
+}
+
+TEST_F(RunDex2OatTest, ThreadsPostBootCompleteBackground_Backup) {
+    setSystemProperty("dalvik.vm.background-dex2oat-threads", "");
+    setSystemProperty("dalvik.vm.dex2oat-threads", "3");
+    auto args = RunDex2OatArgs::MakeDefaultTestArgs();
+    args->post_bootcomplete = true;
+    args->background_job_compile = true;
+    CallRunDex2Oat(std::move(args));
+
+    SetExpectedFlagUsed("-j", "3");
+    VerifyExpectedFlags();
+}
+
 TEST_F(RunDex2OatTest, ThreadsPostBootCompleteForRestore) {
     setSystemProperty("dalvik.vm.restore-dex2oat-threads", "4");
     setSystemProperty("dalvik.vm.dex2oat-threads", "5");
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index 6ef41e3..3b589dc 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -23,6 +23,7 @@
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/macros.h>
 #include <android-base/properties.h>
 #include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
@@ -52,22 +53,7 @@
 
 constexpr int kTimeoutMs = 60000;
 
-// TODO(calin): try to dedup this code.
-#if defined(__arm__)
-static const std::string kRuntimeIsa = "arm";
-#elif defined(__aarch64__)
-static const std::string kRuntimeIsa = "arm64";
-#elif defined(__mips__) && !defined(__LP64__)
-static const std::string kRuntimeIsa = "mips";
-#elif defined(__mips__) && defined(__LP64__)
-static const std::string kRuntimeIsa = "mips64";
-#elif defined(__i386__)
-static const std::string kRuntimeIsa = "x86";
-#elif defined(__x86_64__)
-static const std::string kRuntimeIsa = "x86_64";
-#else
-static const std::string kRuntimeIsa = "none";
-#endif
+static const std::string kRuntimeIsa = ABI_STRING;
 
 int get_property(const char *key, char *value, const char *default_value) {
     return property_get(key, value, default_value);
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index fd879c6..1386660 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -48,14 +48,6 @@
 }
 
 cc_binary {
-    name: "servicemanager.microdroid",
-    defaults: ["servicemanager_defaults"],
-    init_rc: ["servicemanager.microdroid.rc"],
-    srcs: ["main.cpp"],
-    bootstrap: true,
-}
-
-cc_binary {
     name: "servicemanager.recovery",
     stem: "servicemanager",
     recovery: true,
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 3681d5b..cc038ae 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -136,12 +136,33 @@
             updatableViaApex = manifestInstance.updatableViaApex();
             return false; // break (libvintf uses opposite convention)
         });
+        if (updatableViaApex.has_value()) return true; // break (found match)
         return false; // continue
     });
 
     return updatableViaApex;
 }
 
+static std::vector<std::string> getVintfUpdatableInstances(const std::string& apexName) {
+    std::vector<std::string> instances;
+
+    forEachManifest([&](const ManifestWithDescription& mwd) {
+        mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
+            if (manifestInstance.format() == vintf::HalFormat::AIDL &&
+                manifestInstance.updatableViaApex().has_value() &&
+                manifestInstance.updatableViaApex().value() == apexName) {
+                std::string aname = manifestInstance.package() + "." +
+                        manifestInstance.interface() + "/" + manifestInstance.instance();
+                instances.push_back(aname);
+            }
+            return true; // continue (libvintf uses opposite convention)
+        });
+        return false; // continue
+    });
+
+    return instances;
+}
+
 static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) {
     AidlName aname;
     if (!AidlName::fill(name, &aname)) return std::nullopt;
@@ -512,6 +533,30 @@
     return Status::ok();
 }
 
+Status ServiceManager::getUpdatableNames([[maybe_unused]] const std::string& apexName,
+                                         std::vector<std::string>* outReturn) {
+    auto ctx = mAccess->getCallingContext();
+
+    std::vector<std::string> apexUpdatableInstances;
+#ifndef VENDORSERVICEMANAGER
+    apexUpdatableInstances = getVintfUpdatableInstances(apexName);
+#endif
+
+    outReturn->clear();
+
+    for (const std::string& instance : apexUpdatableInstances) {
+        if (mAccess->canFind(ctx, instance)) {
+            outReturn->push_back(instance);
+        }
+    }
+
+    if (outReturn->size() == 0 && apexUpdatableInstances.size() != 0) {
+        return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial");
+    }
+
+    return Status::ok();
+}
+
 Status ServiceManager::getConnectionInfo(const std::string& name,
                                          std::optional<ConnectionInfo>* outReturn) {
     auto ctx = mAccess->getCallingContext();
@@ -568,7 +613,8 @@
 }
 
 void ServiceManager::tryStartService(const std::string& name) {
-    ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service",
+    ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service. (if it's not "
+          "configured to be a lazy service, it may be stuck starting or still starting).",
           name.c_str());
 
     std::thread([=] {
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 07b79f8..b24c11c 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -49,6 +49,8 @@
     binder::Status getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) override;
     binder::Status updatableViaApex(const std::string& name,
                                     std::optional<std::string>* outReturn) override;
+    binder::Status getUpdatableNames(const std::string& apexName,
+                                     std::vector<std::string>* outReturn) override;
     binder::Status getConnectionInfo(const std::string& name,
                                      std::optional<ConnectionInfo>* outReturn) override;
     binder::Status registerClientCallback(const std::string& name, const sp<IBinder>& service,
diff --git a/cmds/servicemanager/main.cpp b/cmds/servicemanager/main.cpp
index a831d1b..c1a04dd 100644
--- a/cmds/servicemanager/main.cpp
+++ b/cmds/servicemanager/main.cpp
@@ -111,9 +111,7 @@
 };
 
 int main(int argc, char** argv) {
-#ifdef __ANDROID_RECOVERY__
     android::base::InitLogging(argv, android::base::KernelLogger);
-#endif
 
     if (argc > 2) {
         LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
diff --git a/cmds/servicemanager/servicemanager.microdroid.rc b/cmds/servicemanager/servicemanager.microdroid.rc
deleted file mode 100644
index c516043..0000000
--- a/cmds/servicemanager/servicemanager.microdroid.rc
+++ /dev/null
@@ -1,9 +0,0 @@
-service servicemanager /system/bin/servicemanager.microdroid
-    class core
-    user system
-    group system readproc
-    critical
-    onrestart setprop servicemanager.ready false
-    onrestart restart apexd
-    task_profiles ServiceCapacityLow
-    shutdown critical
diff --git a/cmds/servicemanager/servicemanager.rc b/cmds/servicemanager/servicemanager.rc
index 6b35265..3bd6db5 100644
--- a/cmds/servicemanager/servicemanager.rc
+++ b/cmds/servicemanager/servicemanager.rc
@@ -3,6 +3,7 @@
     user system
     group system readproc
     critical
+    file /dev/kmsg w
     onrestart setprop servicemanager.ready false
     onrestart restart apexd
     onrestart restart audioserver
diff --git a/cmds/servicemanager/test_sm.cpp b/cmds/servicemanager/test_sm.cpp
index 5d5a75e..0fd8d8e 100644
--- a/cmds/servicemanager/test_sm.cpp
+++ b/cmds/servicemanager/test_sm.cpp
@@ -14,13 +14,15 @@
  * limitations under the License.
  */
 
+#include <android-base/properties.h>
+#include <android-base/strings.h>
 #include <android/os/BnServiceCallback.h>
 #include <binder/Binder.h>
-#include <binder/ProcessState.h>
 #include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
 #include <cutils/android_filesystem_config.h>
-#include <gtest/gtest.h>
 #include <gmock/gmock.h>
+#include <gtest/gtest.h>
 
 #include "Access.h"
 #include "ServiceManager.h"
@@ -75,6 +77,11 @@
     return sm;
 }
 
+static bool isCuttlefish() {
+    return android::base::StartsWith(android::base::GetProperty("ro.product.vendor.device", ""),
+                                     "vsoc_");
+}
+
 TEST(AddService, HappyHappy) {
     auto sm = getPermissiveServiceManager();
     EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
@@ -306,6 +313,49 @@
     EXPECT_THAT(out, ElementsAre("sa"));
 }
 
+TEST(Vintf, UpdatableViaApex) {
+    if (!isCuttlefish()) GTEST_SKIP() << "Skipping non-Cuttlefish devices";
+
+    auto sm = getPermissiveServiceManager();
+    std::optional<std::string> updatableViaApex;
+    EXPECT_TRUE(sm->updatableViaApex("android.hardware.camera.provider.ICameraProvider/internal/0",
+                                     &updatableViaApex)
+                        .isOk());
+    EXPECT_EQ(std::make_optional<std::string>("com.google.emulated.camera.provider.hal"),
+              updatableViaApex);
+}
+
+TEST(Vintf, UpdatableViaApex_InvalidNameReturnsNullOpt) {
+    if (!isCuttlefish()) GTEST_SKIP() << "Skipping non-Cuttlefish devices";
+
+    auto sm = getPermissiveServiceManager();
+    std::optional<std::string> updatableViaApex;
+    EXPECT_TRUE(sm->updatableViaApex("android.hardware.camera.provider.ICameraProvider",
+                                     &updatableViaApex)
+                        .isOk()); // missing instance name
+    EXPECT_EQ(std::nullopt, updatableViaApex);
+}
+
+TEST(Vintf, GetUpdatableNames) {
+    if (!isCuttlefish()) GTEST_SKIP() << "Skipping non-Cuttlefish devices";
+
+    auto sm = getPermissiveServiceManager();
+    std::vector<std::string> names;
+    EXPECT_TRUE(sm->getUpdatableNames("com.google.emulated.camera.provider.hal", &names).isOk());
+    EXPECT_EQ(std::vector<
+                      std::string>{"android.hardware.camera.provider.ICameraProvider/internal/0"},
+              names);
+}
+
+TEST(Vintf, GetUpdatableNames_InvalidApexNameReturnsEmpty) {
+    if (!isCuttlefish()) GTEST_SKIP() << "Skipping non-Cuttlefish devices";
+
+    auto sm = getPermissiveServiceManager();
+    std::vector<std::string> names;
+    EXPECT_TRUE(sm->getUpdatableNames("non.existing.apex.name", &names).isOk());
+    EXPECT_EQ(std::vector<std::string>{}, names);
+}
+
 class CallbackHistorian : public BnServiceCallback {
     Status onRegistration(const std::string& name, const sp<IBinder>& binder) override {
         registrations.push_back(name);
diff --git a/cmds/servicemanager/vndservicemanager.rc b/cmds/servicemanager/vndservicemanager.rc
index c9305a1..80af1d1 100644
--- a/cmds/servicemanager/vndservicemanager.rc
+++ b/cmds/servicemanager/vndservicemanager.rc
@@ -2,6 +2,7 @@
     class core
     user system
     group system readproc
+    file /dev/kmsg w
     task_profiles ServiceCapacityLow
     onrestart class_restart main
     onrestart class_restart hal
diff --git a/libs/arect/Android.bp b/libs/arect/Android.bp
index 76e3e66..5e539f2 100644
--- a/libs/arect/Android.bp
+++ b/libs/arect/Android.bp
@@ -49,6 +49,9 @@
         "com.android.media",
         "com.android.media.swcodec",
     ],
+    llndk: {
+        llndk_headers: true,
+    },
 }
 
 cc_library_static {
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index df965ab..28369d6 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -161,7 +161,7 @@
     ],
 
     header_libs: [
-        "libandroid_runtime_vm_headers",
+        "jni_headers",
     ],
 
     export_header_lib_headers: [
@@ -315,7 +315,7 @@
         },
         recovery: {
             exclude_header_libs: [
-                "libandroid_runtime_vm_headers",
+                "jni_headers",
             ],
         },
     },
@@ -490,9 +490,6 @@
         java: {
             enabled: false,
         },
-        cpp: {
-            gen_trace: false,
-        },
     },
 }
 
@@ -504,6 +501,7 @@
         "libbase",
         "libbinder",
         "libbinder_ndk",
+        "libcutils_sockets",
         "liblog",
         "libutils",
     ],
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 11c8e5d..7770374 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -45,11 +45,11 @@
 
 #define IF_LOG_TRANSACTIONS() if (false)
 #define IF_LOG_COMMANDS() if (false)
-#define LOG_REMOTEREFS(...) 
+#define LOG_REMOTEREFS(...)
 #define IF_LOG_REMOTEREFS() if (false)
 
-#define LOG_THREADPOOL(...) 
-#define LOG_ONEWAY(...) 
+#define LOG_THREADPOOL(...)
+#define LOG_ONEWAY(...)
 
 #else
 
@@ -394,14 +394,92 @@
     // context, so we don't abort
 }
 
+constexpr uint32_t encodeExplicitIdentity(bool hasExplicitIdentity, pid_t callingPid) {
+    uint32_t as_unsigned = static_cast<uint32_t>(callingPid);
+    if (hasExplicitIdentity) {
+        return as_unsigned | (1 << 30);
+    } else {
+        return as_unsigned & ~(1 << 30);
+    }
+}
+
+constexpr int64_t packCallingIdentity(bool hasExplicitIdentity, uid_t callingUid,
+                                      pid_t callingPid) {
+    // Calling PID is a 32-bit signed integer, but doesn't consume the entire 32 bit space.
+    // To future-proof this and because we have extra capacity, we decided to also support -1,
+    // since this constant is used to represent invalid UID in other places of the system.
+    // Thus, we pack hasExplicitIdentity into the 2nd bit from the left.  This allows us to
+    // preserve the (left-most) bit for the sign while also encoding the value of
+    // hasExplicitIdentity.
+    //               32b     |        1b         |         1b            |        30b
+    // token = [ calling uid | calling pid(sign) | has explicit identity | calling pid(rest) ]
+    uint64_t token = (static_cast<uint64_t>(callingUid) << 32) |
+            encodeExplicitIdentity(hasExplicitIdentity, callingPid);
+    return static_cast<int64_t>(token);
+}
+
+constexpr bool unpackHasExplicitIdentity(int64_t token) {
+    return static_cast<int32_t>(token) & (1 << 30);
+}
+
+constexpr uid_t unpackCallingUid(int64_t token) {
+    return static_cast<uid_t>(token >> 32);
+}
+
+constexpr pid_t unpackCallingPid(int64_t token) {
+    int32_t encodedPid = static_cast<int32_t>(token);
+    if (encodedPid & (1 << 31)) {
+        return encodedPid | (1 << 30);
+    } else {
+        return encodedPid & ~(1 << 30);
+    }
+}
+
+static_assert(unpackHasExplicitIdentity(packCallingIdentity(true, 1000, 9999)) == true,
+              "pack true hasExplicit");
+
+static_assert(unpackCallingUid(packCallingIdentity(true, 1000, 9999)) == 1000, "pack true uid");
+
+static_assert(unpackCallingPid(packCallingIdentity(true, 1000, 9999)) == 9999, "pack true pid");
+
+static_assert(unpackHasExplicitIdentity(packCallingIdentity(false, 1000, 9999)) == false,
+              "pack false hasExplicit");
+
+static_assert(unpackCallingUid(packCallingIdentity(false, 1000, 9999)) == 1000, "pack false uid");
+
+static_assert(unpackCallingPid(packCallingIdentity(false, 1000, 9999)) == 9999, "pack false pid");
+
+static_assert(unpackHasExplicitIdentity(packCallingIdentity(true, 1000, -1)) == true,
+              "pack true (negative) hasExplicit");
+
+static_assert(unpackCallingUid(packCallingIdentity(true, 1000, -1)) == 1000,
+              "pack true (negative) uid");
+
+static_assert(unpackCallingPid(packCallingIdentity(true, 1000, -1)) == -1,
+              "pack true (negative) pid");
+
+static_assert(unpackHasExplicitIdentity(packCallingIdentity(false, 1000, -1)) == false,
+              "pack false (negative) hasExplicit");
+
+static_assert(unpackCallingUid(packCallingIdentity(false, 1000, -1)) == 1000,
+              "pack false (negative) uid");
+
+static_assert(unpackCallingPid(packCallingIdentity(false, 1000, -1)) == -1,
+              "pack false (negative) pid");
+
 int64_t IPCThreadState::clearCallingIdentity()
 {
     // ignore mCallingSid for legacy reasons
-    int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
+    int64_t token = packCallingIdentity(mHasExplicitIdentity, mCallingUid, mCallingPid);
     clearCaller();
+    mHasExplicitIdentity = true;
     return token;
 }
 
+bool IPCThreadState::hasExplicitIdentity() {
+    return mHasExplicitIdentity;
+}
+
 void IPCThreadState::setStrictModePolicy(int32_t policy)
 {
     mStrictModePolicy = policy;
@@ -474,9 +552,10 @@
 
 void IPCThreadState::restoreCallingIdentity(int64_t token)
 {
-    mCallingUid = (int)(token>>32);
+    mCallingUid = unpackCallingUid(token);
     mCallingSid = nullptr;  // not enough data to restore
-    mCallingPid = (int)token;
+    mCallingPid = unpackCallingPid(token);
+    mHasExplicitIdentity = unpackHasExplicitIdentity(token);
 }
 
 void IPCThreadState::clearCaller()
@@ -889,6 +968,7 @@
         mCallRestriction(mProcess->mCallRestriction) {
     pthread_setspecific(gTLS, this);
     clearCaller();
+    mHasExplicitIdentity = false;
     mIn.setDataCapacity(256);
     mOut.setDataCapacity(256);
 }
@@ -1279,6 +1359,7 @@
             const pid_t origPid = mCallingPid;
             const char* origSid = mCallingSid;
             const uid_t origUid = mCallingUid;
+            const bool origHasExplicitIdentity = mHasExplicitIdentity;
             const int32_t origStrictModePolicy = mStrictModePolicy;
             const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
             const int32_t origWorkSource = mWorkSource;
@@ -1292,6 +1373,7 @@
             mCallingPid = tr.sender_pid;
             mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx);
             mCallingUid = tr.sender_euid;
+            mHasExplicitIdentity = false;
             mLastTransactionBinderFlags = tr.flags;
 
             // ALOGI(">>>> TRANSACT from pid %d sid %s uid %d\n", mCallingPid,
@@ -1367,6 +1449,7 @@
             mCallingPid = origPid;
             mCallingSid = origSid;
             mCallingUid = origUid;
+            mHasExplicitIdentity = origHasExplicitIdentity;
             mStrictModePolicy = origStrictModePolicy;
             mLastTransactionBinderFlags = origTransactionBinderFlags;
             mWorkSource = origWorkSource;
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 05db774..a0c4334 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -81,6 +81,7 @@
     bool isDeclared(const String16& name) override;
     Vector<String16> getDeclaredInstances(const String16& interface) override;
     std::optional<String16> updatableViaApex(const String16& name) override;
+    Vector<String16> getUpdatableNames(const String16& apexName) override;
     std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override;
     class RegistrationWaiter : public android::os::BnServiceCallback {
     public:
@@ -479,6 +480,23 @@
     return declared ? std::optional<String16>(String16(declared.value().c_str())) : std::nullopt;
 }
 
+Vector<String16> ServiceManagerShim::getUpdatableNames(const String16& apexName) {
+    std::vector<std::string> out;
+    if (Status status = mTheRealServiceManager->getUpdatableNames(String8(apexName).c_str(), &out);
+        !status.isOk()) {
+        ALOGW("Failed to getUpdatableNames for %s: %s", String8(apexName).c_str(),
+              status.toString8().c_str());
+        return {};
+    }
+
+    Vector<String16> res;
+    res.setCapacity(out.size());
+    for (const std::string& instance : out) {
+        res.push(String16(instance.c_str()));
+    }
+    return res;
+}
+
 std::optional<IServiceManager::ConnectionInfo> ServiceManagerShim::getConnectionInfo(
         const String16& name) {
     std::optional<os::ConnectionInfo> connectionInfo;
diff --git a/libs/binder/OS.cpp b/libs/binder/OS.cpp
index 77e401f..ce60e33 100644
--- a/libs/binder/OS.cpp
+++ b/libs/binder/OS.cpp
@@ -67,7 +67,7 @@
     return RpcTransportCtxFactoryRaw::make();
 }
 
-int sendMessageOnSocket(
+ssize_t sendMessageOnSocket(
         const RpcTransportFd& socket, iovec* iovs, int niovs,
         const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) {
     if (ancillaryFds != nullptr && !ancillaryFds->empty()) {
@@ -112,7 +112,7 @@
     return TEMP_FAILURE_RETRY(sendmsg(socket.fd.get(), &msg, MSG_NOSIGNAL));
 }
 
-int receiveMessageFromSocket(
+ssize_t receiveMessageFromSocket(
         const RpcTransportFd& socket, iovec* iovs, int niovs,
         std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) {
     if (ancillaryFds != nullptr) {
diff --git a/libs/binder/OS.h b/libs/binder/OS.h
index 0d38968..fecae31 100644
--- a/libs/binder/OS.h
+++ b/libs/binder/OS.h
@@ -33,11 +33,11 @@
 
 std::unique_ptr<RpcTransportCtxFactory> makeDefaultRpcTransportCtxFactory();
 
-int sendMessageOnSocket(
+ssize_t sendMessageOnSocket(
         const RpcTransportFd& socket, iovec* iovs, int niovs,
         const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds);
 
-int receiveMessageFromSocket(
+ssize_t receiveMessageFromSocket(
         const RpcTransportFd& socket, iovec* iovs, int niovs,
         std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds);
 
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 07d0a65..4b07608 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -966,7 +966,15 @@
     }
 }
 
+void Parcel::setEnforceNoDataAvail(bool enforceNoDataAvail) {
+    mEnforceNoDataAvail = enforceNoDataAvail;
+}
+
 binder::Status Parcel::enforceNoDataAvail() const {
+    if (!mEnforceNoDataAvail) {
+        return binder::Status::ok();
+    }
+
     const auto n = dataAvail();
     if (n == 0) {
         return binder::Status::ok();
@@ -3077,6 +3085,7 @@
     mAllowFds = true;
     mDeallocZero = false;
     mOwner = nullptr;
+    mEnforceNoDataAvail = true;
 }
 
 void Parcel::scanForFds() const {
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index 83d0de7..0820cd1 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -531,33 +531,35 @@
     LOG_RPC_DETAIL("Setting up socket server %s", addr.toString().c_str());
     LOG_ALWAYS_FATAL_IF(hasServer(), "Each RpcServer can only have one server.");
 
-    RpcTransportFd transportFd(unique_fd(TEMP_FAILURE_RETRY(
-            socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0))));
-    if (!transportFd.fd.ok()) {
+    unique_fd socket_fd(TEMP_FAILURE_RETRY(
+            socket(addr.addr()->sa_family, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)));
+    if (!socket_fd.ok()) {
         int savedErrno = errno;
         ALOGE("Could not create socket: %s", strerror(savedErrno));
         return -savedErrno;
     }
-
-    if (0 != TEMP_FAILURE_RETRY(bind(transportFd.fd.get(), addr.addr(), addr.addrSize()))) {
+    if (0 != TEMP_FAILURE_RETRY(bind(socket_fd.get(), addr.addr(), addr.addrSize()))) {
         int savedErrno = errno;
         ALOGE("Could not bind socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
         return -savedErrno;
     }
 
+    return setupRawSocketServer(std::move(socket_fd));
+}
+
+status_t RpcServer::setupRawSocketServer(unique_fd socket_fd) {
+    LOG_ALWAYS_FATAL_IF(!socket_fd.ok(), "Socket must be setup to listen.");
+
     // Right now, we create all threads at once, making accept4 slow. To avoid hanging the client,
     // the backlog is increased to a large number.
     // TODO(b/189955605): Once we create threads dynamically & lazily, the backlog can be reduced
     //  to 1.
-    if (0 != TEMP_FAILURE_RETRY(listen(transportFd.fd.get(), 50 /*backlog*/))) {
+    if (0 != TEMP_FAILURE_RETRY(listen(socket_fd.get(), 50 /*backlog*/))) {
         int savedErrno = errno;
-        ALOGE("Could not listen socket at %s: %s", addr.toString().c_str(), strerror(savedErrno));
+        ALOGE("Could not listen initialized Unix socket: %s", strerror(savedErrno));
         return -savedErrno;
     }
-
-    LOG_RPC_DETAIL("Successfully setup socket server %s", addr.toString().c_str());
-
-    if (status_t status = setupExternalServer(std::move(transportFd.fd)); status != OK) {
+    if (status_t status = setupExternalServer(std::move(socket_fd)); status != OK) {
         ALOGE("Another thread has set up server while calling setupSocketServer. Race?");
         return status;
     }
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 7d6bcfc..ce6ef2b 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -46,8 +46,8 @@
 #include "Utils.h"
 
 #if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
-#include <android_runtime/vm.h>
 #include <jni.h>
+extern "C" JavaVM* AndroidRuntimeGetJavaVM();
 #endif
 
 namespace android {
@@ -408,10 +408,11 @@
                             "Unable to detach thread. No JavaVM, but it was present before!");
 
         LOG_RPC_DETAIL("Detaching current thread from JVM");
-        if (vm->DetachCurrentThread() != JNI_OK) {
+        int ret = vm->DetachCurrentThread();
+        if (ret == JNI_OK) {
             mAttached = false;
         } else {
-            ALOGW("Unable to detach current thread from JVM");
+            ALOGW("Unable to detach current thread from JVM (%d)", ret);
         }
     }
 
diff --git a/libs/binder/RpcTransportRaw.cpp b/libs/binder/RpcTransportRaw.cpp
index 1912d14..cd067bf 100644
--- a/libs/binder/RpcTransportRaw.cpp
+++ b/libs/binder/RpcTransportRaw.cpp
@@ -61,7 +61,8 @@
             override {
         bool sentFds = false;
         auto send = [&](iovec* iovs, int niovs) -> ssize_t {
-            int ret = sendMessageOnSocket(mSocket, iovs, niovs, sentFds ? nullptr : ancillaryFds);
+            ssize_t ret =
+                    sendMessageOnSocket(mSocket, iovs, niovs, sentFds ? nullptr : ancillaryFds);
             sentFds |= ret > 0;
             return ret;
         };
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 5880c0a..0fb1615 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -114,6 +114,12 @@
     @nullable @utf8InCpp String updatableViaApex(@utf8InCpp String name);
 
     /**
+     * Returns all instances which are updatable via the APEX. Instance names are fully qualified
+     * like `pack.age.IFoo/default`.
+     */
+    @utf8InCpp String[] getUpdatableNames(@utf8InCpp String apexName);
+
+    /**
      * If connection info is available for the given instance, returns the ConnectionInfo
      */
     @nullable ConnectionInfo getConnectionInfo(@utf8InCpp String name);
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index c01e92f..65b77c6 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -139,6 +139,7 @@
             int64_t             clearCallingIdentity();
             // Restores PID/UID (not SID)
             void                restoreCallingIdentity(int64_t token);
+            bool hasExplicitIdentity();
 
             status_t            setupPolling(int* fd);
             status_t            handlePolledCommands();
@@ -241,6 +242,7 @@
             bool                mPropagateWorkSource;
             bool                mIsLooper;
             bool mIsFlushing;
+            bool mHasExplicitIdentity;
             int32_t             mStrictModePolicy;
             int32_t             mLastTransactionBinderFlags;
             CallRestriction     mCallRestriction;
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 413c97f..79e771f 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -115,6 +115,12 @@
     virtual std::optional<String16> updatableViaApex(const String16& name) = 0;
 
     /**
+     * Returns all instances which are updatable via the APEX. Instance names are fully qualified
+     * like `pack.age.IFoo/default`.
+     */
+    virtual Vector<String16> getUpdatableNames(const String16& apexName) = 0;
+
+    /**
      * If this instance has declared remote connection information, returns
      * the ConnectionInfo.
      */
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 6de6ce8..f730acb 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -150,6 +150,9 @@
     // Returns Status(EX_BAD_PARCELABLE) when the Parcel is not consumed.
     binder::Status enforceNoDataAvail() const;
 
+    // This Api is used by fuzzers to skip dataAvail checks.
+    void setEnforceNoDataAvail(bool enforceNoDataAvail);
+
     void                freeData();
 
     size_t              objectsCount() const;
@@ -1329,6 +1332,9 @@
     // data to be overridden with zero when deallocated
     mutable bool        mDeallocZero;
 
+    // Set this to false to skip dataAvail checks.
+    bool mEnforceNoDataAvail;
+
     release_func        mOwner;
 
     size_t mReserved;
diff --git a/libs/binder/include/binder/RpcServer.h b/libs/binder/include/binder/RpcServer.h
index 81ae26a3..4ad0a47 100644
--- a/libs/binder/include/binder/RpcServer.h
+++ b/libs/binder/include/binder/RpcServer.h
@@ -71,6 +71,16 @@
     [[nodiscard]] status_t setupUnixDomainServer(const char* path);
 
     /**
+     * Sets up an RPC server with a raw socket file descriptor.
+     * The socket should be created and bound to a socket address already, e.g.
+     * the socket can be created in init.rc.
+     *
+     * This method is used in the libbinder_rpc_unstable API
+     * RunInitUnixDomainRpcServer().
+     */
+    [[nodiscard]] status_t setupRawSocketServer(base::unique_fd socket_fd);
+
+    /**
      * Creates an RPC server at the current port.
      */
     [[nodiscard]] status_t setupVsockServer(unsigned int port);
diff --git a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
index 5baa4d7..f08bde8 100644
--- a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
+++ b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
@@ -17,30 +17,56 @@
 #pragma once
 
 #include <sys/socket.h>
+#include <stdint.h>
 
 extern "C" {
 
 struct AIBinder;
+struct ARpcServer;
 
 // Starts an RPC server on a given port and a given root IBinder object.
-// This function sets up the server and joins before returning.
-bool RunRpcServer(AIBinder* service, unsigned int port);
+// Returns an opaque handle to the running server instance, or null if the server
+// could not be started.
+[[nodiscard]] ARpcServer* ARpcServer_newVsock(AIBinder* service, unsigned int port);
 
-// Starts an RPC server on a given port and a given root IBinder object.
-// This function sets up the server, calls readyCallback with a given param, and
-// then joins before returning.
-bool RunRpcServerCallback(AIBinder* service, unsigned int port, void (*readyCallback)(void* param),
-                          void* param);
+// Starts a Unix domain RPC server with a given init-managed Unix domain `name`
+// and a given root IBinder object.
+// The socket should be created in init.rc with the same `name`.
+// Returns an opaque handle to the running server instance, or null if the server
+// could not be started.
+[[nodiscard]] ARpcServer* ARpcServer_newInitUnixDomain(AIBinder* service, const char* name);
+
+// Runs ARpcServer_join() in a background thread. Immediately returns.
+void ARpcServer_start(ARpcServer* server);
+
+// Joins the thread of a running RpcServer instance. At any given point, there
+// can only be one thread calling ARpcServer_join().
+// If a client needs to actively terminate join, call ARpcServer_shutdown() in
+// a separate thread.
+void ARpcServer_join(ARpcServer* server);
+
+// Shuts down any running ARpcServer_join().
+void ARpcServer_shutdown(ARpcServer* server);
+
+// Frees the ARpcServer handle and drops the reference count on the underlying
+// RpcServer instance. The handle must not be reused afterwards.
+// This automatically calls ARpcServer_shutdown().
+void ARpcServer_free(ARpcServer* server);
 
 // Starts an RPC server on a given port and a given root IBinder factory.
-// RunRpcServerWithFactory acts like RunRpcServerCallback, but instead of
+// RunVsockRpcServerWithFactory acts like RunVsockRpcServerCallback, but instead of
 // assigning single root IBinder object to all connections, factory is called
 // whenever a client connects, making it possible to assign unique IBinder
 // object to each client.
-bool RunRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
-                          void* factoryContext, unsigned int port);
+bool RunVsockRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
+                                  void* factoryContext, unsigned int port);
 
-AIBinder* RpcClient(unsigned int cid, unsigned int port);
+AIBinder* VsockRpcClient(unsigned int cid, unsigned int port);
+
+// Gets the service via the RPC binder with Unix domain socket with the given
+// Unix socket `name`.
+// The final Unix domain socket path name is /dev/socket/`name`.
+AIBinder* UnixDomainRpcClient(const char* name);
 
 // Connect to an RPC server with preconnected file descriptors.
 //
@@ -50,5 +76,4 @@
 // param will be passed to requestFd. Callers can use param to pass contexts to
 // the requestFd function.
 AIBinder* RpcPreconnectedClient(int (*requestFd)(void* param), void* param);
-
 }
diff --git a/libs/binder/libbinder_rpc_unstable.cpp b/libs/binder/libbinder_rpc_unstable.cpp
index a3d42b7..f55c779 100644
--- a/libs/binder/libbinder_rpc_unstable.cpp
+++ b/libs/binder/libbinder_rpc_unstable.cpp
@@ -14,24 +14,47 @@
  * limitations under the License.
  */
 
+#include <binder_rpc_unstable.hpp>
+
 #include <android-base/logging.h>
 #include <android-base/unique_fd.h>
 #include <android/binder_libbinder.h>
 #include <binder/RpcServer.h>
 #include <binder/RpcSession.h>
+#include <cutils/sockets.h>
 #include <linux/vm_sockets.h>
 
 using android::OK;
 using android::RpcServer;
 using android::RpcSession;
+using android::sp;
 using android::status_t;
 using android::statusToString;
 using android::base::unique_fd;
 
+// Opaque handle for RpcServer.
+struct ARpcServer {};
+
+static sp<RpcServer> toRpcServer(ARpcServer* handle) {
+    auto ref = reinterpret_cast<RpcServer*>(handle);
+    return sp<RpcServer>::fromExisting(ref);
+}
+
+static ARpcServer* createRpcServerHandle(sp<RpcServer>& server) {
+    auto ref = server.get();
+    ref->incStrong(ref);
+    return reinterpret_cast<ARpcServer*>(ref);
+}
+
+static void freeRpcServerHandle(ARpcServer* handle) {
+    auto ref = reinterpret_cast<RpcServer*>(handle);
+    ref->decStrong(ref);
+}
+
 extern "C" {
 
-bool RunRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
-                             void* factoryContext, unsigned int port) {
+bool RunVsockRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
+                                  void* factoryContext, unsigned int port) {
     auto server = RpcServer::make();
     if (status_t status = server->setupVsockServer(port); status != OK) {
         LOG(ERROR) << "Failed to set up vsock server with port " << port
@@ -52,29 +75,50 @@
     return true;
 }
 
-bool RunRpcServerCallback(AIBinder* service, unsigned int port, void (*readyCallback)(void* param),
-                          void* param) {
+ARpcServer* ARpcServer_newVsock(AIBinder* service, unsigned int port) {
     auto server = RpcServer::make();
     if (status_t status = server->setupVsockServer(port); status != OK) {
         LOG(ERROR) << "Failed to set up vsock server with port " << port
                    << " error: " << statusToString(status).c_str();
-        return false;
+        return nullptr;
     }
     server->setRootObject(AIBinder_toPlatformBinder(service));
-
-    if (readyCallback) readyCallback(param);
-    server->join();
-
-    // Shutdown any open sessions since server failed.
-    (void)server->shutdown();
-    return true;
+    return createRpcServerHandle(server);
 }
 
-bool RunRpcServer(AIBinder* service, unsigned int port) {
-    return RunRpcServerCallback(service, port, nullptr, nullptr);
+ARpcServer* ARpcServer_newInitUnixDomain(AIBinder* service, const char* name) {
+    auto server = RpcServer::make();
+    auto fd = unique_fd(android_get_control_socket(name));
+    if (!fd.ok()) {
+        LOG(ERROR) << "Failed to get fd for the socket:" << name;
+        return nullptr;
+    }
+    if (status_t status = server->setupRawSocketServer(std::move(fd)); status != OK) {
+        LOG(ERROR) << "Failed to set up Unix Domain RPC server with name " << name
+                   << " error: " << statusToString(status).c_str();
+        return nullptr;
+    }
+    server->setRootObject(AIBinder_toPlatformBinder(service));
+    return createRpcServerHandle(server);
 }
 
-AIBinder* RpcClient(unsigned int cid, unsigned int port) {
+void ARpcServer_start(ARpcServer* handle) {
+    toRpcServer(handle)->start();
+}
+
+void ARpcServer_join(ARpcServer* handle) {
+    toRpcServer(handle)->join();
+}
+
+void ARpcServer_shutdown(ARpcServer* handle) {
+    toRpcServer(handle)->shutdown();
+}
+
+void ARpcServer_free(ARpcServer* handle) {
+    freeRpcServerHandle(handle);
+}
+
+AIBinder* VsockRpcClient(unsigned int cid, unsigned int port) {
     auto session = RpcSession::make();
     if (status_t status = session->setupVsockClient(cid, port); status != OK) {
         LOG(ERROR) << "Failed to set up vsock client with CID " << cid << " and port " << port
@@ -84,6 +128,18 @@
     return AIBinder_fromPlatformBinder(session->getRootObject());
 }
 
+AIBinder* UnixDomainRpcClient(const char* name) {
+    std::string pathname(name);
+    pathname = ANDROID_SOCKET_DIR "/" + pathname;
+    auto session = RpcSession::make();
+    if (status_t status = session->setupUnixDomainClient(pathname.c_str()); status != OK) {
+        LOG(ERROR) << "Failed to set up Unix Domain RPC client with path: " << pathname
+                   << " error: " << statusToString(status).c_str();
+        return nullptr;
+    }
+    return AIBinder_fromPlatformBinder(session->getRootObject());
+}
+
 AIBinder* RpcPreconnectedClient(int (*requestFd)(void* param), void* param) {
     auto session = RpcSession::make();
     auto request = [=] { return unique_fd{requestFd(param)}; };
diff --git a/libs/binder/libbinder_rpc_unstable.map.txt b/libs/binder/libbinder_rpc_unstable.map.txt
index e856569..1bc2416 100644
--- a/libs/binder/libbinder_rpc_unstable.map.txt
+++ b/libs/binder/libbinder_rpc_unstable.map.txt
@@ -1,8 +1,13 @@
 LIBBINDER_RPC_UNSTABLE_SHIM { # platform-only
   global:
-    RunRpcServer;
-    RunRpcServerCallback;
-    RpcClient;
+    ARpcServer_free;
+    ARpcServer_join;
+    ARpcServer_newInitUnixDomain;
+    ARpcServer_newVsock;
+    ARpcServer_shutdown;
+    ARpcServer_start;
+    VsockRpcClient;
+    UnixDomainRpcClient;
     RpcPreconnectedClient;
   local:
     *;
diff --git a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
index fccc0af..d6937c2 100644
--- a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
@@ -30,11 +30,11 @@
 #include <android/binder_internal_logging.h>
 #include <android/binder_parcel.h>
 #include <android/binder_status.h>
-
 #include <assert.h>
-
 #include <unistd.h>
+
 #include <cstddef>
+#include <iostream>
 #include <string>
 
 namespace ndk {
@@ -270,14 +270,19 @@
     std::string getDescription() const {
 #ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
         if (__builtin_available(android 30, *)) {
-#else
-        if (__ANDROID_API__ >= 30) {
 #endif
+
+#if defined(__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__) || __ANDROID_API__ >= 30
             const char* cStr = AStatus_getDescription(get());
             std::string ret = cStr;
             AStatus_deleteDescription(cStr);
             return ret;
+#endif
+
+#ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
         }
+#endif
+
         binder_exception_t exception = getExceptionCode();
         std::string desc = std::to_string(exception);
         if (exception == EX_SERVICE_SPECIFIC) {
@@ -315,6 +320,11 @@
     }
 };
 
+static inline std::ostream& operator<<(std::ostream& os, const ScopedAStatus& status) {
+    return os << status.getDescription();
+    return os;
+}
+
 /**
  * Convenience wrapper. See AIBinder_DeathRecipient.
  */
diff --git a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
index 78bcb43..81975e7 100644
--- a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
@@ -291,7 +291,10 @@
 binder_status_t ICInterface::ICInterfaceData::onDump(AIBinder* binder, int fd, const char** args,
                                                      uint32_t numArgs) {
     std::shared_ptr<ICInterface> interface = getInterface(binder);
-    return interface->dump(fd, args, numArgs);
+    if (interface != nullptr) {
+        return interface->dump(fd, args, numArgs);
+    }
+    return STATUS_DEAD_OBJECT;
 }
 
 #ifdef HAS_BINDER_SHELL_COMMAND
@@ -299,7 +302,10 @@
                                                                  int err, const char** argv,
                                                                  uint32_t argc) {
     std::shared_ptr<ICInterface> interface = getInterface(binder);
-    return interface->handleShellCommand(in, out, err, argv, argc);
+    if (interface != nullptr) {
+        return interface->handleShellCommand(in, out, err, argv, argc);
+    }
+    return STATUS_DEAD_OBJECT;
 }
 #endif
 
diff --git a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
index c1f2620..caee471 100644
--- a/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_parcelable_utils.h
@@ -41,68 +41,34 @@
         if (_status != STATUS_OK) return _status; \
     } while (false)
 
+// AParcelableHolder has been introduced in 31.
+#if __ANDROID_API__ >= 31
 class AParcelableHolder {
    public:
     AParcelableHolder() = delete;
     explicit AParcelableHolder(parcelable_stability_t stability)
         : mParcel(AParcel_create()), mStability(stability) {}
 
-#if __ANDROID_API__ >= 31
     AParcelableHolder(const AParcelableHolder& other)
         : mParcel(AParcel_create()), mStability(other.mStability) {
-        // AParcelableHolder has been introduced in 31.
-#ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
-        if (__builtin_available(android 31, *)) {
-#else
-        if (__ANDROID_API__ >= 31) {
-#endif
-            AParcel_appendFrom(other.mParcel.get(), this->mParcel.get(), 0,
-                               AParcel_getDataSize(other.mParcel.get()));
-        } else {
-            syslog(LOG_ERR,
-                   "sdk_version not compatible, AParcelableHolder need sdk_version >= 31!");
-        }
+        AParcel_appendFrom(other.mParcel.get(), this->mParcel.get(), 0,
+                           AParcel_getDataSize(other.mParcel.get()));
     }
-#endif
 
     AParcelableHolder(AParcelableHolder&& other) = default;
     virtual ~AParcelableHolder() = default;
 
     binder_status_t writeToParcel(AParcel* parcel) const {
         RETURN_ON_FAILURE(AParcel_writeInt32(parcel, static_cast<int32_t>(this->mStability)));
-#ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
-        if (__builtin_available(android 31, *)) {
-#else
-        if (__ANDROID_API__ >= 31) {
-#endif
-            int32_t size = AParcel_getDataSize(this->mParcel.get());
-            RETURN_ON_FAILURE(AParcel_writeInt32(parcel, size));
-        } else {
-            return STATUS_INVALID_OPERATION;
-        }
-#ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
-        if (__builtin_available(android 31, *)) {
-#else
-        if (__ANDROID_API__ >= 31) {
-#endif
-            int32_t size = AParcel_getDataSize(this->mParcel.get());
-            RETURN_ON_FAILURE(AParcel_appendFrom(this->mParcel.get(), parcel, 0, size));
-        } else {
-            return STATUS_INVALID_OPERATION;
-        }
+        int32_t size = AParcel_getDataSize(this->mParcel.get());
+        RETURN_ON_FAILURE(AParcel_writeInt32(parcel, size));
+        size = AParcel_getDataSize(this->mParcel.get());
+        RETURN_ON_FAILURE(AParcel_appendFrom(this->mParcel.get(), parcel, 0, size));
         return STATUS_OK;
     }
 
     binder_status_t readFromParcel(const AParcel* parcel) {
-#ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
-        if (__builtin_available(android 31, *)) {
-#else
-        if (__ANDROID_API__ >= 31) {
-#endif
-            AParcel_reset(mParcel.get());
-        } else {
-            return STATUS_INVALID_OPERATION;
-        }
+        AParcel_reset(mParcel.get());
 
         parcelable_stability_t wireStability;
         RETURN_ON_FAILURE(AParcel_readInt32(parcel, &wireStability));
@@ -123,15 +89,7 @@
             return STATUS_BAD_VALUE;
         }
 
-#ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
-        if (__builtin_available(android 31, *)) {
-#else
-        if (__ANDROID_API__ >= 31) {
-#endif
-            status = AParcel_appendFrom(parcel, mParcel.get(), dataStartPos, dataSize);
-        } else {
-            status = STATUS_INVALID_OPERATION;
-        }
+        status = AParcel_appendFrom(parcel, mParcel.get(), dataStartPos, dataSize);
         if (status != STATUS_OK) {
             return status;
         }
@@ -143,15 +101,7 @@
         if (this->mStability > T::_aidl_stability) {
             return STATUS_BAD_VALUE;
         }
-#ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
-        if (__builtin_available(android 31, *)) {
-#else
-        if (__ANDROID_API__ >= 31) {
-#endif
-            AParcel_reset(mParcel.get());
-        } else {
-            return STATUS_INVALID_OPERATION;
-        }
+        AParcel_reset(mParcel.get());
         AParcel_writeString(mParcel.get(), T::descriptor, strlen(T::descriptor));
         p.writeToParcel(mParcel.get());
         return STATUS_OK;
@@ -161,17 +111,9 @@
     binder_status_t getParcelable(std::optional<T>* ret) const {
         const std::string parcelableDesc(T::descriptor);
         AParcel_setDataPosition(mParcel.get(), 0);
-#ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
-        if (__builtin_available(android 31, *)) {
-#else
-        if (__ANDROID_API__ >= 31) {
-#endif
-            if (AParcel_getDataSize(mParcel.get()) == 0) {
-                *ret = std::nullopt;
-                return STATUS_OK;
-            }
-        } else {
-            return STATUS_INVALID_OPERATION;
+        if (AParcel_getDataSize(mParcel.get()) == 0) {
+            *ret = std::nullopt;
+            return STATUS_OK;
         }
         std::string parcelableDescInParcel;
         binder_status_t status = AParcel_readString(mParcel.get(), &parcelableDescInParcel);
@@ -188,18 +130,7 @@
         return STATUS_OK;
     }
 
-    void reset() {
-#ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
-        if (__builtin_available(android 31, *)) {
-#else
-        if (__ANDROID_API__ >= 31) {
-#endif
-            AParcel_reset(mParcel.get());
-        } else {
-            syslog(LOG_ERR,
-                   "sdk_version not compatible, AParcelableHolder need sdk_version >= 31!");
-        }
-    }
+    void reset() { AParcel_reset(mParcel.get()); }
 
     inline bool operator!=(const AParcelableHolder& rhs) const { return this != &rhs; }
     inline bool operator<(const AParcelableHolder& rhs) const { return this < &rhs; }
@@ -207,34 +138,23 @@
     inline bool operator==(const AParcelableHolder& rhs) const { return this == &rhs; }
     inline bool operator>(const AParcelableHolder& rhs) const { return this > &rhs; }
     inline bool operator>=(const AParcelableHolder& rhs) const { return this >= &rhs; }
-#if __ANDROID_API__ >= 31
     inline AParcelableHolder& operator=(const AParcelableHolder& rhs) {
-        // AParcelableHolder has been introduced in 31.
-#ifdef __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
-        if (__builtin_available(android 31, *)) {
-#else
-        if (__ANDROID_API__ >= 31) {
-#endif
-            this->reset();
-            if (this->mStability != rhs.mStability) {
-                syslog(LOG_ERR, "AParcelableHolder stability mismatch: this %d rhs %d!",
-                       this->mStability, rhs.mStability);
-                abort();
-            }
-            AParcel_appendFrom(rhs.mParcel.get(), this->mParcel.get(), 0,
-                               AParcel_getDataSize(rhs.mParcel.get()));
-        } else {
-            syslog(LOG_ERR,
-                   "sdk_version not compatible, AParcelableHolder need sdk_version >= 31!");
+        this->reset();
+        if (this->mStability != rhs.mStability) {
+            syslog(LOG_ERR, "AParcelableHolder stability mismatch: this %d rhs %d!",
+                   this->mStability, rhs.mStability);
+            abort();
         }
+        AParcel_appendFrom(rhs.mParcel.get(), this->mParcel.get(), 0,
+                           AParcel_getDataSize(rhs.mParcel.get()));
         return *this;
     }
-#endif
 
    private:
     mutable ndk::ScopedAParcel mParcel;
     parcelable_stability_t mStability;
 };
+#endif  // __ANDROID_API__ >= 31
 
 #undef RETURN_ON_FAILURE
 }  // namespace ndk
diff --git a/libs/binder/ndk/include_cpp/android/binder_to_string.h b/libs/binder/ndk/include_cpp/android/binder_to_string.h
index d7840ec..6a25db2 100644
--- a/libs/binder/ndk/include_cpp/android/binder_to_string.h
+++ b/libs/binder/ndk/include_cpp/android/binder_to_string.h
@@ -136,8 +136,10 @@
     template <typename _U>
     static std::enable_if_t<
 #ifdef HAS_NDK_INTERFACE
-            std::is_base_of_v<::ndk::ICInterface, _U> ||
-                    std::is_same_v<::ndk::AParcelableHolder, _U>
+            std::is_base_of_v<::ndk::ICInterface, _U>
+#if __ANDROID_API__ >= 31
+                    || std::is_same_v<::ndk::AParcelableHolder, _U>
+#endif
 #else
             std::is_base_of_v<IInterface, _U> || std::is_same_v<IBinder, _U> ||
                     std::is_same_v<os::ParcelFileDescriptor, _U> ||
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index dfa8ea2..ad4188f 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -68,6 +68,7 @@
  *
  * \param instance identifier of the service used to lookup the service.
  */
+[[deprecated("this polls 5s, use AServiceManager_waitForService or AServiceManager_checkService")]]
 __attribute__((warn_unused_result)) AIBinder* AServiceManager_getService(const char* instance)
         __INTRODUCED_IN(29);
 
@@ -108,6 +109,67 @@
         __INTRODUCED_IN(31);
 
 /**
+ * Function to call when a service is registered. The instance is passed as well as
+ * ownership of the binder named 'registered'.
+ *
+ * WARNING: a lock is held when this method is called in order to prevent races with
+ * AServiceManager_NotificationRegistration_delete. Do not make synchronous binder calls when
+ * implementing this method to avoid deadlocks.
+ *
+ * \param instance instance name of service registered
+ * \param registered ownership-passed instance of service registered
+ * \param cookie data passed during registration for notifications
+ */
+typedef void (*AServiceManager_onRegister)(const char* instance, AIBinder* registered,
+                                           void* cookie);
+
+/**
+ * Represents a registration to servicemanager which can be cleared anytime.
+ */
+struct AServiceManager_NotificationRegistration;
+
+/**
+ * Get notifications when a service is registered. If the service is already registered,
+ * you will immediately get a notification.
+ *
+ * WARNING: it is strongly recommended to use AServiceManager_waitForService API instead.
+ * That API will wait synchronously, which is what you usually want in cases, including
+ * using some feature or during boot up. There is a history of bugs where waiting for
+ * notifications like this races with service startup. Also, when this API is used, a service
+ * bug will result in silent failure (rather than a debuggable deadlock). Furthermore, there
+ * is a history of this API being used to know when a service is up as a proxy for whethre
+ * that service should be started. This should only be used if you are intending to get
+ * ahold of the service as a client. For lazy services, whether a service is registered
+ * should not be used as a proxy for when it should be registered, which is only known
+ * by the real client.
+ *
+ * WARNING: if you use this API, you must also ensure that you check missing services are
+ * started and crash otherwise. If service failures are ignored, the system rots.
+ *
+ * \param instance name of service to wait for notifications about
+ * \param onRegister callback for when service is registered
+ * \param cookie data associated with this callback
+ *
+ * \return the token for this registration. Deleting this token will unregister.
+ */
+__attribute__((warn_unused_result)) AServiceManager_NotificationRegistration*
+AServiceManager_registerForServiceNotifications(const char* instance,
+                                                AServiceManager_onRegister onRegister, void* cookie)
+        __INTRODUCED_IN(34);
+
+/**
+ * Unregister for notifications and delete the object.
+ *
+ * After this method is called, the callback is guaranteed to no longer be invoked. This will block
+ * until any in-progress onRegister callbacks have completed. It is therefore safe to immediately
+ * destroy the void* cookie that was registered when this method returns.
+ *
+ * \param notification object to dismiss
+ */
+void AServiceManager_NotificationRegistration_delete(
+        AServiceManager_NotificationRegistration* notification) __INTRODUCED_IN(34);
+
+/**
  * Check if a service is declared (e.g. VINTF manifest).
  *
  * \param instance identifier of the service.
@@ -143,6 +205,17 @@
 bool AServiceManager_isUpdatableViaApex(const char* instance) __INTRODUCED_IN(31);
 
 /**
+ * Returns the APEX name if a service is declared as updatable via an APEX module.
+ *
+ * \param instance identifier of the service
+ * \param context to pass to callback
+ * \param callback taking the APEX name (e.g. 'com.android.foo') and context
+ */
+void AServiceManager_getUpdatableApexName(const char* instance, void* context,
+                                          void (*callback)(const char*, void*))
+        __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
  * Prevent lazy services without client from shutting down their process
  *
  * This should only be used if it is every eventually set to false. If a
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 259a736..5c7005c 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -152,6 +152,13 @@
     AParcel_unmarshal;
 };
 
+LIBBINDER_NDK34 { # introduced=UpsideDownCake
+  global:
+    AServiceManager_getUpdatableApexName; # systemapi
+    AServiceManager_registerForServiceNotifications; # systemapi llndk
+    AServiceManager_NotificationRegistration_delete; # systemapi llndk
+};
+
 LIBBINDER_NDK_PLATFORM {
   global:
     AParcel_getAllowFds;
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index c320e8d..8693022 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -129,7 +129,13 @@
     }
 
     T* array;
-    if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
+    if (!allocator(arrayData, length, &array)) {
+        if (length < 0) {
+            return STATUS_UNEXPECTED_NULL;
+        } else {
+            return STATUS_NO_MEMORY;
+        }
+    }
 
     if (length <= 0) return STATUS_OK;
     if (array == nullptr) return STATUS_NO_MEMORY;
@@ -157,7 +163,13 @@
     }
 
     char16_t* array;
-    if (!allocator(arrayData, length, &array)) return STATUS_NO_MEMORY;
+    if (!allocator(arrayData, length, &array)) {
+        if (length < 0) {
+            return STATUS_UNEXPECTED_NULL;
+        } else {
+            return STATUS_NO_MEMORY;
+        }
+    }
 
     if (length <= 0) return STATUS_OK;
     if (array == nullptr) return STATUS_NO_MEMORY;
@@ -204,7 +216,13 @@
         return status;
     }
 
-    if (!allocator(arrayData, length)) return STATUS_NO_MEMORY;
+    if (!allocator(arrayData, length)) {
+        if (length < 0) {
+            return STATUS_UNEXPECTED_NULL;
+        } else {
+            return STATUS_NO_MEMORY;
+        }
+    }
 
     if (length <= 0) return STATUS_OK;
 
diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp
index 7649a26..e107c83 100644
--- a/libs/binder/ndk/service_manager.cpp
+++ b/libs/binder/ndk/service_manager.cpp
@@ -28,6 +28,7 @@
 using ::android::IServiceManager;
 using ::android::sp;
 using ::android::status_t;
+using ::android::statusToString;
 using ::android::String16;
 using ::android::String8;
 
@@ -86,6 +87,67 @@
     AIBinder_incStrong(ret.get());
     return ret.get();
 }
+typedef void (*AServiceManager_onRegister)(const char* instance, AIBinder* registered,
+                                           void* cookie);
+
+struct AServiceManager_NotificationRegistration
+    : public IServiceManager::LocalRegistrationCallback {
+    std::mutex m;
+    const char* instance = nullptr;
+    void* cookie = nullptr;
+    AServiceManager_onRegister onRegister = nullptr;
+
+    virtual void onServiceRegistration(const String16& smInstance, const sp<IBinder>& binder) {
+        std::lock_guard<std::mutex> l(m);
+        if (onRegister == nullptr) return;
+
+        CHECK_EQ(String8(smInstance), instance);
+
+        sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(binder);
+        AIBinder_incStrong(ret.get());
+
+        onRegister(instance, ret.get(), cookie);
+    }
+
+    void clear() {
+        std::lock_guard<std::mutex> l(m);
+        instance = nullptr;
+        cookie = nullptr;
+        onRegister = nullptr;
+    }
+};
+
+__attribute__((warn_unused_result)) AServiceManager_NotificationRegistration*
+AServiceManager_registerForServiceNotifications(const char* instance,
+                                                AServiceManager_onRegister onRegister,
+                                                void* cookie) {
+    CHECK_NE(instance, nullptr);
+    CHECK_NE(onRegister, nullptr) << instance;
+    // cookie can be nullptr
+
+    auto cb = sp<AServiceManager_NotificationRegistration>::make();
+    cb->instance = instance;
+    cb->onRegister = onRegister;
+    cb->cookie = cookie;
+
+    sp<IServiceManager> sm = defaultServiceManager();
+    if (status_t res = sm->registerForNotifications(String16(instance), cb); res != STATUS_OK) {
+        LOG(ERROR) << "Failed to register for service notifications for " << instance << ": "
+                   << statusToString(res);
+        return nullptr;
+    }
+
+    cb->incStrong(nullptr);
+    return cb.get();
+}
+
+void AServiceManager_NotificationRegistration_delete(
+        AServiceManager_NotificationRegistration* notification) {
+    CHECK_NE(notification, nullptr);
+    notification->clear();
+    notification->decStrong(nullptr);
+}
+
 bool AServiceManager_isDeclared(const char* instance) {
     if (instance == nullptr) {
         return false;
@@ -113,6 +175,18 @@
     sp<IServiceManager> sm = defaultServiceManager();
     return sm->updatableViaApex(String16(instance)) != std::nullopt;
 }
+void AServiceManager_getUpdatableApexName(const char* instance, void* context,
+                                          void (*callback)(const char*, void*)) {
+    CHECK_NE(instance, nullptr);
+    // context may be nullptr
+    CHECK_NE(callback, nullptr);
+
+    sp<IServiceManager> sm = defaultServiceManager();
+    std::optional<String16> updatableViaApex = sm->updatableViaApex(String16(instance));
+    if (updatableViaApex.has_value()) {
+        callback(String8(updatableViaApex.value()).c_str(), context);
+    }
+}
 void AServiceManager_forceLazyServicesPersist(bool persist) {
     auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
     serviceRegistrar.forcePersist(persist);
diff --git a/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp b/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp
index f3cd218..43b2cb8 100644
--- a/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp
+++ b/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp
@@ -106,7 +106,7 @@
         std::string outString;
         ScopedAStatus status = server->RepeatString("foo", &outString);
         EXPECT_EQ(STATUS_OK, AStatus_getExceptionCode(status.get()))
-                << serviceName << " " << status.getDescription();
+                << serviceName << " " << status;
         EXPECT_EQ("foo", outString) << serviceName;
     }
 }
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 01b9472..9d5ef68 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -33,13 +33,15 @@
 #include <binder/IResultReceiver.h>
 #include <binder/IServiceManager.h>
 #include <binder/IShellCallback.h>
-
 #include <sys/prctl.h>
+
 #include <chrono>
 #include <condition_variable>
 #include <iostream>
 #include <mutex>
+#include <optional>
 #include <thread>
+
 #include "android/binder_ibinder.h"
 
 using namespace android;
@@ -252,6 +254,47 @@
     AIBinder_decStrong(binder);
 }
 
+struct ServiceData {
+    std::string instance;
+    ndk::SpAIBinder binder;
+
+    static void fillOnRegister(const char* instance, AIBinder* binder, void* cookie) {
+        ServiceData* d = reinterpret_cast<ServiceData*>(cookie);
+        d->instance = instance;
+        d->binder = ndk::SpAIBinder(binder);
+    }
+};
+
+TEST(NdkBinder, RegisterForServiceNotificationsNonExisting) {
+    ServiceData data;
+    auto* notif = AServiceManager_registerForServiceNotifications(
+            "DOES_NOT_EXIST", ServiceData::fillOnRegister, (void*)&data);
+    ASSERT_NE(notif, nullptr);
+
+    sleep(1);  // give us a chance to fail
+    AServiceManager_NotificationRegistration_delete(notif);
+
+    // checking after deleting to avoid needing a mutex over the data - otherwise
+    // in an environment w/ multiple threads, you would need to guard access
+    EXPECT_EQ(data.instance, "");
+    EXPECT_EQ(data.binder, nullptr);
+}
+
+TEST(NdkBinder, RegisterForServiceNotificationsExisting) {
+    ServiceData data;
+    auto* notif = AServiceManager_registerForServiceNotifications(
+            kExistingNonNdkService, ServiceData::fillOnRegister, (void*)&data);
+    ASSERT_NE(notif, nullptr);
+
+    sleep(1);  // give us a chance to fail
+    AServiceManager_NotificationRegistration_delete(notif);
+
+    // checking after deleting to avoid needing a mutex over the data - otherwise
+    // in an environment w/ multiple threads, you would need to guard access
+    EXPECT_EQ(data.instance, kExistingNonNdkService);
+    EXPECT_EQ(data.binder, ndk::SpAIBinder(AServiceManager_checkService(kExistingNonNdkService)));
+}
+
 TEST(NdkBinder, UnimplementedDump) {
     sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
     ASSERT_NE(foo, nullptr);
@@ -337,6 +380,16 @@
     EXPECT_EQ(isUpdatable, false);
 }
 
+TEST(NdkBinder, GetUpdatableViaApex) {
+    std::optional<std::string> updatableViaApex;
+    AServiceManager_getUpdatableApexName(
+            "android.hardware.light.ILights/default", &updatableViaApex,
+            [](const char* apexName, void* context) {
+                *static_cast<std::optional<std::string>*>(context) = apexName;
+            });
+    EXPECT_EQ(updatableViaApex, std::nullopt) << *updatableViaApex;
+}
+
 // This is too slow
 TEST(NdkBinder, CheckLazyServiceShutDown) {
     ndk::SpAIBinder binder(AServiceManager_waitForService(kLazyBinderNdkUnitTestService));
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index a135796..afd414a 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -17,7 +17,6 @@
     rustlibs: [
         "libbinder_ndk_sys",
         "libdowncast_rs",
-        "liblazy_static",
         "liblibc",
     ],
     host_supported: true,
@@ -88,6 +87,7 @@
     min_sdk_version: "Tiramisu",
     lints: "none",
     clippy_lints: "none",
+    visibility: [":__subpackages__"],
 }
 
 rust_bindgen {
@@ -159,7 +159,6 @@
     rustlibs: [
         "libbinder_ndk_sys",
         "libdowncast_rs",
-        "liblazy_static",
         "liblibc",
     ],
 }
diff --git a/libs/binder/rust/rpcbinder/Android.bp b/libs/binder/rust/rpcbinder/Android.bp
index 5ebc27f..f70ebfc 100644
--- a/libs/binder/rust/rpcbinder/Android.bp
+++ b/libs/binder/rust/rpcbinder/Android.bp
@@ -19,7 +19,9 @@
         "libbinder_rpc_unstable_bindgen_sys",
         "libbinder_rs",
         "libdowncast_rs",
+        "libforeign_types",
         "liblibc",
+        "liblog_rust",
     ],
     apex_available: [
         "com.android.compos",
diff --git a/libs/binder/rust/rpcbinder/src/client.rs b/libs/binder/rust/rpcbinder/src/client.rs
index 743800b..48c787b 100644
--- a/libs/binder/rust/rpcbinder/src/client.rs
+++ b/libs/binder/rust/rpcbinder/src/client.rs
@@ -15,6 +15,7 @@
  */
 
 use binder::{unstable_api::new_spibinder, FromIBinder, SpIBinder, StatusCode, Strong};
+use std::ffi::CString;
 use std::os::{
     raw::{c_int, c_void},
     unix::io::RawFd,
@@ -22,9 +23,9 @@
 
 /// Connects to an RPC Binder server over vsock.
 pub fn get_vsock_rpc_service(cid: u32, port: u32) -> Option<SpIBinder> {
-    // SAFETY: AIBinder returned by RpcClient has correct reference count, and the ownership can
-    // safely be taken by new_spibinder.
-    unsafe { new_spibinder(binder_rpc_unstable_bindgen::RpcClient(cid, port)) }
+    // SAFETY: AIBinder returned by VsockRpcClient has correct reference count,
+    // and the ownership can safely be taken by new_spibinder.
+    unsafe { new_spibinder(binder_rpc_unstable_bindgen::VsockRpcClient(cid, port)) }
 }
 
 /// Connects to an RPC Binder server for a particular interface over vsock.
@@ -35,6 +36,27 @@
     interface_cast(get_vsock_rpc_service(cid, port))
 }
 
+/// Connects to an RPC Binder server over Unix domain socket.
+pub fn get_unix_domain_rpc_service(socket_name: &str) -> Option<SpIBinder> {
+    let socket_name = match CString::new(socket_name) {
+        Ok(s) => s,
+        Err(e) => {
+            log::error!("Cannot convert {} to CString. Error: {:?}", socket_name, e);
+            return None;
+        }
+    };
+    // SAFETY: AIBinder returned by UnixDomainRpcClient has correct reference count,
+    // and the ownership can safely be taken by new_spibinder.
+    unsafe { new_spibinder(binder_rpc_unstable_bindgen::UnixDomainRpcClient(socket_name.as_ptr())) }
+}
+
+/// Connects to an RPC Binder server for a particular interface over Unix domain socket.
+pub fn get_unix_domain_rpc_interface<T: FromIBinder + ?Sized>(
+    socket_name: &str,
+) -> Result<Strong<T>, StatusCode> {
+    interface_cast(get_unix_domain_rpc_service(socket_name))
+}
+
 /// Connects to an RPC Binder server, using the given callback to get (and take ownership of)
 /// file descriptors already connected to it.
 pub fn get_preconnected_rpc_service(
diff --git a/libs/binder/rust/rpcbinder/src/lib.rs b/libs/binder/rust/rpcbinder/src/lib.rs
index a5eea61..1b719aa 100644
--- a/libs/binder/rust/rpcbinder/src/lib.rs
+++ b/libs/binder/rust/rpcbinder/src/lib.rs
@@ -20,7 +20,7 @@
 mod server;
 
 pub use client::{
-    get_preconnected_rpc_interface, get_preconnected_rpc_service, get_vsock_rpc_interface,
-    get_vsock_rpc_service,
+    get_preconnected_rpc_interface, get_preconnected_rpc_service, get_unix_domain_rpc_interface,
+    get_unix_domain_rpc_service, get_vsock_rpc_interface, get_vsock_rpc_service,
 };
-pub use server::{run_rpc_server, run_rpc_server_with_factory};
+pub use server::{run_vsock_rpc_server_with_factory, RpcServer, RpcServerRef};
diff --git a/libs/binder/rust/rpcbinder/src/server.rs b/libs/binder/rust/rpcbinder/src/server.rs
index aeb23c6..42f5567 100644
--- a/libs/binder/rust/rpcbinder/src/server.rs
+++ b/libs/binder/rust/rpcbinder/src/server.rs
@@ -18,68 +18,89 @@
     unstable_api::{AIBinder, AsNative},
     SpIBinder,
 };
-use std::{os::raw, ptr::null_mut};
+use binder_rpc_unstable_bindgen::ARpcServer;
+use foreign_types::{foreign_type, ForeignType, ForeignTypeRef};
+use std::io::{Error, ErrorKind};
+use std::{ffi::CString, os::raw, ptr::null_mut};
 
-/// Runs a binder RPC server, serving the supplied binder service implementation on the given vsock
-/// port.
-///
-/// If and when the server is ready for connections (it is listening on the port), `on_ready` is
-/// called to allow appropriate action to be taken - e.g. to notify clients that they may now
-/// attempt to connect.
-///
-/// The current thread is joined to the binder thread pool to handle incoming messages.
-///
-/// Returns true if the server has shutdown normally, false if it failed in some way.
-pub fn run_rpc_server<F>(service: SpIBinder, port: u32, on_ready: F) -> bool
-where
-    F: FnOnce(),
-{
-    let mut ready_notifier = ReadyNotifier(Some(on_ready));
-    ready_notifier.run_server(service, port)
+foreign_type! {
+    type CType = binder_rpc_unstable_bindgen::ARpcServer;
+    fn drop = binder_rpc_unstable_bindgen::ARpcServer_free;
+
+    /// A type that represents a foreign instance of RpcServer.
+    #[derive(Debug)]
+    pub struct RpcServer;
+    /// A borrowed RpcServer.
+    pub struct RpcServerRef;
 }
 
-struct ReadyNotifier<F>(Option<F>)
-where
-    F: FnOnce();
+/// SAFETY - The opaque handle can be cloned freely.
+unsafe impl Send for RpcServer {}
+/// SAFETY - The underlying C++ RpcServer class is thread-safe.
+unsafe impl Sync for RpcServer {}
 
-impl<F> ReadyNotifier<F>
-where
-    F: FnOnce(),
-{
-    fn run_server(&mut self, mut service: SpIBinder, port: u32) -> bool {
+impl RpcServer {
+    /// Creates a binder RPC server, serving the supplied binder service implementation on the given
+    /// vsock port.
+    pub fn new_vsock(mut service: SpIBinder, port: u32) -> Result<RpcServer, Error> {
         let service = service.as_native_mut();
-        let param = self.as_void_ptr();
 
         // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
         // Plus the binder objects are threadsafe.
-        // RunRpcServerCallback does not retain a reference to `ready_callback` or `param`; it only
-        // uses them before it returns, which is during the lifetime of `self`.
         unsafe {
-            binder_rpc_unstable_bindgen::RunRpcServerCallback(
+            Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newVsock(service, port))
+        }
+    }
+
+    /// Creates a binder RPC server, serving the supplied binder service implementation on the given
+    /// socket file name. The socket should be initialized in init.rc with the same name.
+    pub fn new_init_unix_domain(
+        mut service: SpIBinder,
+        socket_name: &str,
+    ) -> Result<RpcServer, Error> {
+        let socket_name = match CString::new(socket_name) {
+            Ok(s) => s,
+            Err(e) => {
+                log::error!("Cannot convert {} to CString. Error: {:?}", socket_name, e);
+                return Err(Error::from(ErrorKind::InvalidInput));
+            }
+        };
+        let service = service.as_native_mut();
+
+        // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
+        // Plus the binder objects are threadsafe.
+        unsafe {
+            Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newInitUnixDomain(
                 service,
-                port,
-                Some(Self::ready_callback),
-                param,
-            )
+                socket_name.as_ptr(),
+            ))
         }
     }
 
-    fn as_void_ptr(&mut self) -> *mut raw::c_void {
-        self as *mut _ as *mut raw::c_void
-    }
-
-    unsafe extern "C" fn ready_callback(param: *mut raw::c_void) {
-        // SAFETY: This is only ever called by `RunRpcServerCallback`, within the lifetime of the
-        // `ReadyNotifier`, with `param` taking the value returned by `as_void_ptr` (so a properly
-        // aligned non-null pointer to an initialized instance).
-        let ready_notifier = param as *mut Self;
-        ready_notifier.as_mut().unwrap().notify()
-    }
-
-    fn notify(&mut self) {
-        if let Some(on_ready) = self.0.take() {
-            on_ready();
+    unsafe fn checked_from_ptr(ptr: *mut ARpcServer) -> Result<RpcServer, Error> {
+        if ptr.is_null() {
+            return Err(Error::new(ErrorKind::Other, "Failed to start server"));
         }
+        Ok(RpcServer::from_ptr(ptr))
+    }
+}
+
+impl RpcServerRef {
+    /// Starts a new background thread and calls join(). Returns immediately.
+    pub fn start(&self) {
+        unsafe { binder_rpc_unstable_bindgen::ARpcServer_start(self.as_ptr()) };
+    }
+
+    /// Joins the RpcServer thread. The call blocks until the server terminates.
+    /// This must be called from exactly one thread.
+    pub fn join(&self) {
+        unsafe { binder_rpc_unstable_bindgen::ARpcServer_join(self.as_ptr()) };
+    }
+
+    /// Shuts down the running RpcServer. Can be called multiple times and from
+    /// multiple threads. Called automatically during drop().
+    pub fn shutdown(&self) {
+        unsafe { binder_rpc_unstable_bindgen::ARpcServer_shutdown(self.as_ptr()) };
     }
 }
 
@@ -91,7 +112,7 @@
 /// The current thread is joined to the binder thread pool to handle incoming messages.
 ///
 /// Returns true if the server has shutdown normally, false if it failed in some way.
-pub fn run_rpc_server_with_factory(
+pub fn run_vsock_rpc_server_with_factory(
     port: u32,
     mut factory: impl FnMut(u32) -> Option<SpIBinder> + Send + Sync,
 ) -> bool {
@@ -100,18 +121,22 @@
     let mut factory_ref: RpcServerFactoryRef = &mut factory;
     let context = &mut factory_ref as *mut RpcServerFactoryRef as *mut raw::c_void;
 
-    // SAFETY: `factory_wrapper` is only ever called by `RunRpcServerWithFactory`, with context
+    // SAFETY: `factory_wrapper` is only ever called by `RunVsockRpcServerWithFactory`, with context
     // taking the pointer value above (so a properly aligned non-null pointer to an initialized
     // `RpcServerFactoryRef`), within the lifetime of `factory_ref` (i.e. no more calls will be made
-    // after `RunRpcServerWithFactory` returns).
+    // after `RunVsockRpcServerWithFactory` returns).
     unsafe {
-        binder_rpc_unstable_bindgen::RunRpcServerWithFactory(Some(factory_wrapper), context, port)
+        binder_rpc_unstable_bindgen::RunVsockRpcServerWithFactory(
+            Some(factory_wrapper),
+            context,
+            port,
+        )
     }
 }
 
 unsafe extern "C" fn factory_wrapper(cid: u32, context: *mut raw::c_void) -> *mut AIBinder {
     // SAFETY: `context` was created from an `&mut RpcServerFactoryRef` by
-    // `run_rpc_server_with_factory`, and we are still within the lifetime of the value it is
+    // `run_vsock_rpc_server_with_factory`, and we are still within the lifetime of the value it is
     // pointing to.
     let factory_ptr = context as *mut RpcServerFactoryRef;
     let factory = factory_ptr.as_mut().unwrap();
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index 195d9ac..a0e61d9 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -148,4 +148,5 @@
     pub use crate::binder::AsNative;
     pub use crate::proxy::unstable_api::new_spibinder;
     pub use crate::sys::AIBinder;
+    pub use crate::sys::AParcel;
 }
diff --git a/libs/binder/rust/src/native.rs b/libs/binder/rust/src/native.rs
index dee05d0..6f686fb 100644
--- a/libs/binder/rust/src/native.rs
+++ b/libs/binder/rust/src/native.rs
@@ -22,7 +22,6 @@
 use crate::proxy::SpIBinder;
 use crate::sys;
 
-use lazy_static::lazy_static;
 use std::convert::TryFrom;
 use std::ffi::{c_void, CStr, CString};
 use std::fs::File;
@@ -508,10 +507,8 @@
     _private: (),
 }
 
-lazy_static! {
-    // Count of how many LazyServiceGuard objects are in existence.
-    static ref GUARD_COUNT: Mutex<u64> = Mutex::new(0);
-}
+// Count of how many LazyServiceGuard objects are in existence.
+static GUARD_COUNT: Mutex<u64> = Mutex::new(0);
 
 impl LazyServiceGuard {
     /// Create a new LazyServiceGuard to prevent the service manager prematurely killing this
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index 4e10fa9..ca2cedc 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -502,7 +502,7 @@
         let instances = binder::get_declared_instances("android.hardware.light.ILights")
             .expect("Could not get declared instances");
 
-        let expected_defaults = if has_lights { 1 } else { 0 };
+        let expected_defaults = usize::from(has_lights);
         assert_eq!(expected_defaults, instances.iter().filter(|i| i.as_str() == "default").count());
     }
 
diff --git a/libs/binder/rust/tests/parcel_fuzzer/Android.bp b/libs/binder/rust/tests/parcel_fuzzer/Android.bp
new file mode 100644
index 0000000..28e0200
--- /dev/null
+++ b/libs/binder/rust/tests/parcel_fuzzer/Android.bp
@@ -0,0 +1,25 @@
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
+rust_fuzz {
+    name: "parcel_fuzzer_rs",
+    srcs: [
+        "parcel_fuzzer.rs",
+    ],
+    rustlibs: [
+        "libarbitrary",
+        "libnum_traits",
+        "libbinder_rs",
+        "libbinder_random_parcel_rs",
+        "binderReadParcelIface-rust",
+    ],
+
+    fuzz_config: {
+        cc: [
+            "waghpawan@google.com",
+            "smoreland@google.com",
+        ],
+    },
+}
diff --git a/libs/binder/rust/tests/parcel_fuzzer/parcel_fuzzer.rs b/libs/binder/rust/tests/parcel_fuzzer/parcel_fuzzer.rs
new file mode 100644
index 0000000..c5c7719
--- /dev/null
+++ b/libs/binder/rust/tests/parcel_fuzzer/parcel_fuzzer.rs
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#![allow(missing_docs)]
+#![no_main]
+
+#[macro_use]
+extern crate libfuzzer_sys;
+
+mod read_utils;
+
+use crate::read_utils::READ_FUNCS;
+use binder::binder_impl::{
+    Binder, BorrowedParcel, IBinderInternal, Parcel, Stability, TransactionCode,
+};
+use binder::{
+    declare_binder_interface, BinderFeatures, Interface, Parcelable, ParcelableHolder, SpIBinder,
+    StatusCode,
+};
+use binder_random_parcel_rs::create_random_parcel;
+use libfuzzer_sys::arbitrary::Arbitrary;
+
+#[derive(Arbitrary, Debug)]
+enum ReadOperation {
+    SetDataPosition { pos: i32 },
+    GetDataSize,
+    ReadParcelableHolder { is_vintf: bool },
+    ReadBasicTypes { instructions: Vec<usize> },
+}
+
+#[derive(Arbitrary, Debug)]
+enum Operation<'a> {
+    Transact { code: u32, flag: u32, data: &'a [u8] },
+    Append { start: i32, len: i32, data1: &'a [u8], data2: &'a [u8], append_all: bool },
+    Read { read_operations: Vec<ReadOperation>, data: &'a [u8] },
+}
+
+/// Interface to fuzz transact with random parcel
+pub trait BinderTransactTest: Interface {}
+
+declare_binder_interface! {
+    BinderTransactTest["Binder_Transact_Test"] {
+        native: BnBinderTransactTest(on_transact),
+        proxy: BpBinderTransactTest,
+    }
+}
+
+impl BinderTransactTest for Binder<BnBinderTransactTest> {}
+
+impl BinderTransactTest for BpBinderTransactTest {}
+
+impl BinderTransactTest for () {}
+
+fn on_transact(
+    _service: &dyn BinderTransactTest,
+    _code: TransactionCode,
+    _parcel: &BorrowedParcel<'_>,
+    _reply: &mut BorrowedParcel<'_>,
+) -> Result<(), StatusCode> {
+    Err(StatusCode::UNKNOWN_ERROR)
+}
+
+fn do_transact(code: u32, data: &[u8], flag: u32) {
+    let p: Parcel = create_random_parcel(data);
+    let spibinder: Option<SpIBinder> =
+        Some(BnBinderTransactTest::new_binder((), BinderFeatures::default()).as_binder());
+    let _reply = spibinder.submit_transact(code, p, flag);
+}
+
+fn do_append_fuzz(start: i32, len: i32, data1: &[u8], data2: &[u8], append_all: bool) {
+    let mut p1 = create_random_parcel(data1);
+    let p2 = create_random_parcel(data2);
+
+    // Fuzz both append methods
+    if append_all {
+        match p1.append_all_from(&p2) {
+            Ok(result) => result,
+            Err(e) => {
+                println!("Error occurred while appending a parcel using append_all_from: {:?}", e)
+            }
+        }
+    } else {
+        match p1.append_from(&p2, start, len) {
+            Ok(result) => result,
+            Err(e) => {
+                println!("Error occurred while appending a parcel using append_from: {:?}", e)
+            }
+        }
+    };
+}
+
+fn do_read_fuzz(read_operations: Vec<ReadOperation>, data: &[u8]) {
+    let parcel = create_random_parcel(data);
+
+    for operation in read_operations {
+        match operation {
+            ReadOperation::SetDataPosition { pos } => {
+                unsafe {
+                    // Safety: Safe if pos is less than current size of the parcel.
+                    // It relies on C++ code for bound checks
+                    match parcel.set_data_position(pos) {
+                        Ok(result) => result,
+                        Err(e) => println!("error occurred while setting data position: {:?}", e),
+                    }
+                }
+            }
+
+            ReadOperation::GetDataSize => {
+                let data_size = parcel.get_data_size();
+                println!("data size from parcel: {:?}", data_size);
+            }
+
+            ReadOperation::ReadParcelableHolder { is_vintf } => {
+                let stability = if is_vintf { Stability::Vintf } else { Stability::Local };
+                let mut holder: ParcelableHolder = ParcelableHolder::new(stability);
+                match holder.read_from_parcel(parcel.borrowed_ref()) {
+                    Ok(result) => result,
+                    Err(err) => {
+                        println!("error occurred while reading from parcel: {:?}", err)
+                    }
+                }
+            }
+
+            ReadOperation::ReadBasicTypes { instructions } => {
+                for instruction in instructions.iter() {
+                    let read_index = instruction % READ_FUNCS.len();
+                    READ_FUNCS[read_index](parcel.borrowed_ref());
+                }
+            }
+        }
+    }
+}
+
+fuzz_target!(|operation: Operation| {
+    match operation {
+        Operation::Transact { code, flag, data } => {
+            do_transact(code, data, flag);
+        }
+
+        Operation::Append { start, len, data1, data2, append_all } => {
+            do_append_fuzz(start, len, data1, data2, append_all);
+        }
+
+        Operation::Read { read_operations, data } => {
+            do_read_fuzz(read_operations, data);
+        }
+    }
+});
diff --git a/libs/binder/rust/tests/parcel_fuzzer/random_parcel/Android.bp b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/Android.bp
new file mode 100644
index 0000000..43a3094
--- /dev/null
+++ b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/Android.bp
@@ -0,0 +1,52 @@
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
+rust_bindgen {
+    name: "libbinder_random_parcel_bindgen",
+    crate_name: "binder_random_parcel_bindgen",
+    host_supported: true,
+    wrapper_src: "wrappers/RandomParcelWrapper.hpp",
+    source_stem: "bindings",
+    visibility: [":__subpackages__"],
+    bindgen_flags: [
+        "--size_t-is-usize",
+        "--allowlist-function",
+        "createRandomParcel",
+        "--allowlist-function",
+        "fuzzRustService",
+    ],
+    shared_libs: [
+        "libc++",
+        "libbinder_ndk",
+    ],
+    rustlibs: [
+        "libbinder_rs",
+    ],
+}
+
+rust_library {
+    name: "libbinder_random_parcel_rs",
+    crate_name: "binder_random_parcel_rs",
+    host_supported: true,
+    srcs: [
+        "src/lib.rs",
+    ],
+    shared_libs: [
+        "libbinder",
+        "libutils",
+        "libcutils",
+        "libc++",
+    ],
+    static_libs: [
+        "libbinder_create_parcel",
+        "libbinder_random_parcel",
+    ],
+    rustlibs: [
+        "libbinder_rs",
+        "libbinder_random_parcel_bindgen",
+    ],
+    lints: "none",
+    clippy_lints: "none",
+}
diff --git a/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/Android.bp b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/Android.bp
new file mode 100644
index 0000000..43e407c
--- /dev/null
+++ b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/Android.bp
@@ -0,0 +1,33 @@
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
+aidl_interface {
+    name: "testServiceInterface",
+    srcs: ["ITestService.aidl"],
+    unstable: true,
+    backend: {
+        rust: {
+            enabled: true,
+        },
+    },
+}
+
+rust_fuzz {
+    name: "example_service_fuzzer",
+    srcs: [
+        "service_fuzzer.rs",
+    ],
+    rustlibs: [
+        "libbinder_rs",
+        "libbinder_random_parcel_rs",
+        "testServiceInterface-rust",
+    ],
+    fuzz_config: {
+        cc: [
+            "waghpawan@google.com",
+            "smoreland@google.com",
+        ],
+    },
+}
diff --git a/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/ITestService.aidl b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/ITestService.aidl
new file mode 100644
index 0000000..8ce6558
--- /dev/null
+++ b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/ITestService.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+interface ITestService {
+    boolean repeatData(boolean token);
+}
\ No newline at end of file
diff --git a/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/service_fuzzer.rs b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/service_fuzzer.rs
new file mode 100644
index 0000000..a427f28
--- /dev/null
+++ b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/fuzz_service_test/service_fuzzer.rs
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#![allow(missing_docs)]
+#![no_main]
+#[macro_use]
+extern crate libfuzzer_sys;
+
+use binder::{self, BinderFeatures, Interface};
+use binder_random_parcel_rs::fuzz_service;
+use testServiceInterface::aidl::ITestService::{self, BnTestService};
+
+struct TestService;
+
+impl Interface for TestService {}
+
+impl ITestService::ITestService for TestService {
+    fn repeatData(&self, token: bool) -> binder::Result<bool> {
+        Ok(token)
+    }
+}
+
+fuzz_target!(|data: &[u8]| {
+    let service = BnTestService::new_binder(TestService, BinderFeatures::default());
+    fuzz_service(&mut service.as_binder(), data);
+});
diff --git a/libs/binder/rust/tests/parcel_fuzzer/random_parcel/src/lib.rs b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/src/lib.rs
new file mode 100644
index 0000000..1bbd674
--- /dev/null
+++ b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/src/lib.rs
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use binder::binder_impl::Parcel;
+use binder::unstable_api::{AParcel, AsNative};
+use binder::SpIBinder;
+use binder_random_parcel_bindgen::{createRandomParcel, fuzzRustService};
+use std::os::raw::c_void;
+
+/// This API creates a random parcel to be used by fuzzers
+pub fn create_random_parcel(fuzzer_data: &[u8]) -> Parcel {
+    let mut parcel = Parcel::new();
+    let aparcel_ptr: *mut AParcel = parcel.as_native_mut();
+    let ptr = aparcel_ptr as *mut c_void;
+    unsafe {
+        // Safety: `Parcel::as_native_mut` and `slice::as_ptr` always
+        // return valid pointers.
+        createRandomParcel(ptr, fuzzer_data.as_ptr(), fuzzer_data.len());
+    }
+    parcel
+}
+
+/// This API automatically fuzzes provided service
+pub fn fuzz_service(binder: &mut SpIBinder, fuzzer_data: &[u8]) {
+    let ptr = binder.as_native_mut() as *mut c_void;
+    unsafe {
+        // Safety: `SpIBinder::as_native_mut` and `slice::as_ptr` always
+        // return valid pointers.
+        fuzzRustService(ptr, fuzzer_data.as_ptr(), fuzzer_data.len());
+    }
+}
diff --git a/libs/binder/rust/tests/parcel_fuzzer/random_parcel/wrappers/RandomParcelWrapper.hpp b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/wrappers/RandomParcelWrapper.hpp
new file mode 100644
index 0000000..831bd56
--- /dev/null
+++ b/libs/binder/rust/tests/parcel_fuzzer/random_parcel/wrappers/RandomParcelWrapper.hpp
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <cstdint>
+#include <cstddef>
+
+extern "C" {
+    // This API is used by rust to fill random parcel.
+    void createRandomParcel(void* aParcel, const uint8_t* data, size_t len);
+
+    // This API is used by fuzzers to automatically fuzz aidl services
+    void fuzzRustService(void* binder, const uint8_t* data, size_t len);
+}
\ No newline at end of file
diff --git a/libs/binder/rust/tests/parcel_fuzzer/read_utils.rs b/libs/binder/rust/tests/parcel_fuzzer/read_utils.rs
new file mode 100644
index 0000000..d2bfde1
--- /dev/null
+++ b/libs/binder/rust/tests/parcel_fuzzer/read_utils.rs
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use binder::binder_impl::BorrowedParcel;
+use binder::{ParcelFileDescriptor, Parcelable, SpIBinder};
+use binderReadParcelIface::aidl::EmptyParcelable::EmptyParcelable;
+use binderReadParcelIface::aidl::GenericDataParcelable::GenericDataParcelable;
+use binderReadParcelIface::aidl::SingleDataParcelable::SingleDataParcelable;
+
+macro_rules! read_parcel_interface {
+    ($data_type:ty) => {
+        |parcel: &BorrowedParcel<'_>| {
+            let _res = parcel.read::<$data_type>();
+        }
+    };
+}
+
+#[derive(Debug, Default)]
+pub struct SomeParcelable {
+    pub data: i32,
+}
+
+impl binder::Parcelable for SomeParcelable {
+    fn write_to_parcel(
+        &self,
+        parcel: &mut binder::binder_impl::BorrowedParcel,
+    ) -> std::result::Result<(), binder::StatusCode> {
+        parcel.sized_write(|subparcel| subparcel.write(&self.data))
+    }
+
+    fn read_from_parcel(
+        &mut self,
+        parcel: &binder::binder_impl::BorrowedParcel,
+    ) -> std::result::Result<(), binder::StatusCode> {
+        parcel.sized_read(|subparcel| match subparcel.read() {
+            Ok(result) => {
+                self.data = result;
+                Ok(())
+            }
+            Err(e) => Err(e),
+        })
+    }
+}
+
+binder::impl_deserialize_for_parcelable!(SomeParcelable);
+
+pub const READ_FUNCS: &[fn(&BorrowedParcel<'_>)] = &[
+    //read basic types
+    read_parcel_interface!(bool),
+    read_parcel_interface!(i8),
+    read_parcel_interface!(i32),
+    read_parcel_interface!(i64),
+    read_parcel_interface!(f32),
+    read_parcel_interface!(f64),
+    read_parcel_interface!(u16),
+    read_parcel_interface!(u32),
+    read_parcel_interface!(u64),
+    read_parcel_interface!(String),
+    //read vec of basic types
+    read_parcel_interface!(Vec<i8>),
+    read_parcel_interface!(Vec<i32>),
+    read_parcel_interface!(Vec<i64>),
+    read_parcel_interface!(Vec<f32>),
+    read_parcel_interface!(Vec<f64>),
+    read_parcel_interface!(Vec<u16>),
+    read_parcel_interface!(Vec<u32>),
+    read_parcel_interface!(Vec<u64>),
+    read_parcel_interface!(Vec<String>),
+    read_parcel_interface!(Option<Vec<i8>>),
+    read_parcel_interface!(Option<Vec<i32>>),
+    read_parcel_interface!(Option<Vec<i64>>),
+    read_parcel_interface!(Option<Vec<f32>>),
+    read_parcel_interface!(Option<Vec<f64>>),
+    read_parcel_interface!(Option<Vec<u16>>),
+    read_parcel_interface!(Option<Vec<u32>>),
+    read_parcel_interface!(Option<Vec<u64>>),
+    read_parcel_interface!(Option<Vec<String>>),
+    read_parcel_interface!(ParcelFileDescriptor),
+    read_parcel_interface!(Vec<Option<ParcelFileDescriptor>>),
+    read_parcel_interface!(Option<Vec<ParcelFileDescriptor>>),
+    read_parcel_interface!(Option<Vec<Option<ParcelFileDescriptor>>>),
+    read_parcel_interface!(SpIBinder),
+    read_parcel_interface!(Vec<Option<SpIBinder>>),
+    read_parcel_interface!(Option<Vec<SpIBinder>>),
+    read_parcel_interface!(Option<Vec<Option<SpIBinder>>>),
+    read_parcel_interface!(SomeParcelable),
+    read_parcel_interface!(Vec<Option<SomeParcelable>>),
+    read_parcel_interface!(Option<Vec<SomeParcelable>>),
+    read_parcel_interface!(Option<Vec<Option<SomeParcelable>>>),
+    // Fuzz read_from_parcel for AIDL generated parcelables
+    |parcel| {
+        let mut empty_parcelable: EmptyParcelable = EmptyParcelable::default();
+        match empty_parcelable.read_from_parcel(parcel) {
+            Ok(result) => result,
+            Err(e) => {
+                println!("EmptyParcelable: error occurred while reading from a parcel: {:?}", e)
+            }
+        }
+    },
+    |parcel| {
+        let mut single_parcelable: SingleDataParcelable = SingleDataParcelable::default();
+        match single_parcelable.read_from_parcel(parcel) {
+            Ok(result) => result,
+            Err(e) => println!(
+                "SingleDataParcelable: error occurred while reading from a parcel: {:?}",
+                e
+            ),
+        }
+    },
+    |parcel| {
+        let mut generic_parcelable: GenericDataParcelable = GenericDataParcelable::default();
+        match generic_parcelable.read_from_parcel(parcel) {
+            Ok(result) => result,
+            Err(e) => println!(
+                "GenericDataParcelable: error occurred while reading from a parcel: {:?}",
+                e
+            ),
+        }
+    },
+];
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
index 777f3c9..692cc95 100644
--- a/libs/binder/servicedispatcher.cpp
+++ b/libs/binder/servicedispatcher.cpp
@@ -156,6 +156,10 @@
                                              std::optional<std::string>* _aidl_return) override {
         return mImpl->updatableViaApex(name, _aidl_return);
     }
+    android::binder::Status getUpdatableNames(const std::string& apexName,
+                                              std::vector<std::string>* _aidl_return) override {
+        return mImpl->getUpdatableNames(apexName, _aidl_return);
+    }
     android::binder::Status getConnectionInfo(
             const std::string& name,
             std::optional<android::os::ConnectionInfo>* _aidl_return) override {
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 92d132f..a999d59 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -232,6 +232,7 @@
     srcs: [
         "binderRpcTest.cpp",
         "binderRpcTestCommon.cpp",
+        "binderRpcUniversalTests.cpp",
     ],
 
     test_suites: ["general-tests"],
@@ -722,5 +723,7 @@
             "smoreland@google.com",
             "waghpawan@google.com",
         ],
+        // Adds bugs to hotlist "AIDL fuzzers bugs" on buganizer
+        hotlists: ["4637097"],
     },
 }
diff --git a/libs/binder/tests/BinderRpcTestServerConfig.aidl b/libs/binder/tests/BinderRpcTestServerConfig.aidl
index 4cdeac4..b2e0ef2 100644
--- a/libs/binder/tests/BinderRpcTestServerConfig.aidl
+++ b/libs/binder/tests/BinderRpcTestServerConfig.aidl
@@ -21,6 +21,6 @@
     int rpcSecurity;
     int serverVersion;
     int vsockPort;
-    int unixBootstrapFd; // Inherited from parent
+    int socketFd; // Inherited from the parent process.
     @utf8InCpp String addr;
 }
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 7294305..68a827b 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -15,7 +15,6 @@
  */
 
 #include <android-base/stringprintf.h>
-#include <gtest/gtest.h>
 
 #include <chrono>
 #include <cstdlib>
@@ -29,6 +28,7 @@
 #include <sys/socket.h>
 
 #include "binderRpcTestCommon.h"
+#include "binderRpcTestFixture.h"
 
 using namespace std::chrono_literals;
 using namespace std::placeholders;
@@ -44,37 +44,6 @@
 constexpr bool kEnableSharedLibs = true;
 #endif
 
-static_assert(RPC_WIRE_PROTOCOL_VERSION + 1 == RPC_WIRE_PROTOCOL_VERSION_NEXT ||
-              RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
-
-TEST(BinderRpcParcel, EntireParcelFormatted) {
-    Parcel p;
-    p.writeInt32(3);
-
-    EXPECT_DEATH(p.markForBinder(sp<BBinder>::make()), "format must be set before data is written");
-}
-
-TEST(BinderRpc, CannotUseNextWireVersion) {
-    auto session = RpcSession::make();
-    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT));
-    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT + 1));
-    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT + 2));
-    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT + 15));
-}
-
-TEST(BinderRpc, CanUseExperimentalWireVersion) {
-    auto session = RpcSession::make();
-    EXPECT_TRUE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL));
-}
-
-using android::binder::Status;
-
-#define EXPECT_OK(status)                 \
-    do {                                  \
-        Status stat = (status);           \
-        EXPECT_TRUE(stat.isOk()) << stat; \
-    } while (false)
-
 static std::string WaitStatusToString(int wstatus) {
     if (WIFEXITED(wstatus)) {
         return base::StringPrintf("exit status %d", WEXITSTATUS(wstatus));
@@ -92,7 +61,15 @@
 
 class Process {
 public:
-    Process(Process&&) = default;
+    Process(Process&& other)
+          : mCustomExitStatusCheck(std::move(other.mCustomExitStatusCheck)),
+            mReadEnd(std::move(other.mReadEnd)),
+            mWriteEnd(std::move(other.mWriteEnd)) {
+        // The default move constructor doesn't clear mPid after moving it,
+        // which we need to do because the destructor checks for mPid!=0
+        mPid = other.mPid;
+        other.mPid = 0;
+    }
     Process(const std::function<void(android::base::borrowed_fd /* writeEnd */,
                                      android::base::borrowed_fd /* readEnd */)>& f) {
         android::base::unique_fd childWriteEnd;
@@ -152,21 +129,26 @@
     return vsockPort++;
 }
 
-struct ProcessSession {
+static base::unique_fd initUnixSocket(std::string addr) {
+    auto socket_addr = UnixSocketAddress(addr.c_str());
+    base::unique_fd fd(
+            TEMP_FAILURE_RETRY(socket(socket_addr.addr()->sa_family, SOCK_STREAM, AF_UNIX)));
+    CHECK(fd.ok());
+    CHECK_EQ(0, TEMP_FAILURE_RETRY(bind(fd.get(), socket_addr.addr(), socket_addr.addrSize())));
+    return fd;
+}
+
+// Destructors need to be defined, even if pure virtual
+ProcessSession::~ProcessSession() {}
+
+class LinuxProcessSession : public ProcessSession {
+public:
     // reference to process hosting a socket server
     Process host;
 
-    struct SessionInfo {
-        sp<RpcSession> session;
-        sp<IBinder> root;
-    };
-
-    // client session objects associated with other process
-    // each one represents a separate session
-    std::vector<SessionInfo> sessions;
-
-    ProcessSession(ProcessSession&&) = default;
-    ~ProcessSession() {
+    LinuxProcessSession(LinuxProcessSession&&) = default;
+    LinuxProcessSession(Process&& host) : host(std::move(host)) {}
+    ~LinuxProcessSession() override {
         for (auto& session : sessions) {
             session.root = nullptr;
         }
@@ -197,46 +179,12 @@
             }
         }
     }
-};
 
-// Process session where the process hosts IBinderRpcTest, the server used
-// for most testing here
-struct BinderRpcTestProcessSession {
-    ProcessSession proc;
-
-    // pre-fetched root object (for first session)
-    sp<IBinder> rootBinder;
-
-    // pre-casted root object (for first session)
-    sp<IBinderRpcTest> rootIface;
-
-    // whether session should be invalidated by end of run
-    bool expectAlreadyShutdown = false;
-
-    BinderRpcTestProcessSession(BinderRpcTestProcessSession&&) = default;
-    ~BinderRpcTestProcessSession() {
-        if (!expectAlreadyShutdown) {
-            EXPECT_NE(nullptr, rootIface);
-            if (rootIface == nullptr) return;
-
-            std::vector<int32_t> remoteCounts;
-            // calling over any sessions counts across all sessions
-            EXPECT_OK(rootIface->countBinders(&remoteCounts));
-            EXPECT_EQ(remoteCounts.size(), proc.sessions.size());
-            for (auto remoteCount : remoteCounts) {
-                EXPECT_EQ(remoteCount, 1);
-            }
-
-            // even though it is on another thread, shutdown races with
-            // the transaction reply being written
-            if (auto status = rootIface->scheduleShutdown(); !status.isOk()) {
-                EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status;
-            }
-        }
-
-        rootIface = nullptr;
-        rootBinder = nullptr;
+    void setCustomExitStatusCheck(std::function<void(int wstatus)> f) override {
+        host.setCustomExitStatusCheck(std::move(f));
     }
+
+    void terminate() override { host.terminate(); }
 };
 
 static base::unique_fd connectTo(const RpcSocketAddress& addr) {
@@ -273,552 +221,138 @@
     return std::move(sockClient);
 }
 
-using RunServiceFn = void (*)(android::base::borrowed_fd writeEnd,
-                              android::base::borrowed_fd readEnd);
-
-class BinderRpc : public ::testing::TestWithParam<
-                          std::tuple<SocketType, RpcSecurity, uint32_t, uint32_t, bool, bool>> {
-public:
-    SocketType socketType() const { return std::get<0>(GetParam()); }
-    RpcSecurity rpcSecurity() const { return std::get<1>(GetParam()); }
-    uint32_t clientVersion() const { return std::get<2>(GetParam()); }
-    uint32_t serverVersion() const { return std::get<3>(GetParam()); }
-    bool serverSingleThreaded() const { return std::get<4>(GetParam()); }
-    bool noKernel() const { return std::get<5>(GetParam()); }
-
-    bool clientOrServerSingleThreaded() const {
-        return !kEnableRpcThreads || serverSingleThreaded();
+std::string BinderRpc::PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
+    auto [type, security, clientVersion, serverVersion, singleThreaded, noKernel] = info.param;
+    auto ret = PrintToString(type) + "_" + newFactory(security)->toCString() + "_clientV" +
+            std::to_string(clientVersion) + "_serverV" + std::to_string(serverVersion);
+    if (singleThreaded) {
+        ret += "_single_threaded";
     }
-
-    // Whether the test params support sending FDs in parcels.
-    bool supportsFdTransport() const {
-        return clientVersion() >= 1 && serverVersion() >= 1 && rpcSecurity() != RpcSecurity::TLS &&
-                (socketType() == SocketType::PRECONNECTED || socketType() == SocketType::UNIX ||
-                 socketType() == SocketType::UNIX_BOOTSTRAP);
+    if (noKernel) {
+        ret += "_no_kernel";
     }
+    return ret;
+}
 
-    void SetUp() override {
-        if (socketType() == SocketType::UNIX_BOOTSTRAP && rpcSecurity() == RpcSecurity::TLS) {
-            GTEST_SKIP() << "Unix bootstrap not supported over a TLS transport";
-        }
-    }
+// This creates a new process serving an interface on a certain number of
+// threads.
+std::unique_ptr<ProcessSession> BinderRpc::createRpcTestSocketServerProcessEtc(
+        const BinderRpcOptions& options) {
+    CHECK_GE(options.numSessions, 1) << "Must have at least one session to a server";
 
-    static inline std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info) {
-        auto [type, security, clientVersion, serverVersion, singleThreaded, noKernel] = info.param;
-        auto ret = PrintToString(type) + "_" + newFactory(security)->toCString() + "_clientV" +
-                std::to_string(clientVersion) + "_serverV" + std::to_string(serverVersion);
-        if (singleThreaded) {
-            ret += "_single_threaded";
-        }
-        if (noKernel) {
-            ret += "_no_kernel";
-        }
-        return ret;
-    }
+    SocketType socketType = std::get<0>(GetParam());
+    RpcSecurity rpcSecurity = std::get<1>(GetParam());
+    uint32_t clientVersion = std::get<2>(GetParam());
+    uint32_t serverVersion = std::get<3>(GetParam());
+    bool singleThreaded = std::get<4>(GetParam());
+    bool noKernel = std::get<5>(GetParam());
 
-    // This creates a new process serving an interface on a certain number of
-    // threads.
-    ProcessSession createRpcTestSocketServerProcessEtc(const BinderRpcOptions& options) {
-        CHECK_GE(options.numSessions, 1) << "Must have at least one session to a server";
+    std::string path = android::base::GetExecutableDirectory();
+    auto servicePath = android::base::StringPrintf("%s/binder_rpc_test_service%s%s", path.c_str(),
+                                                   singleThreaded ? "_single_threaded" : "",
+                                                   noKernel ? "_no_kernel" : "");
 
-        SocketType socketType = std::get<0>(GetParam());
-        RpcSecurity rpcSecurity = std::get<1>(GetParam());
-        uint32_t clientVersion = std::get<2>(GetParam());
-        uint32_t serverVersion = std::get<3>(GetParam());
-        bool singleThreaded = std::get<4>(GetParam());
-        bool noKernel = std::get<5>(GetParam());
+    base::unique_fd bootstrapClientFd, socketFd;
 
-        std::string path = android::base::GetExecutableDirectory();
-        auto servicePath =
-                android::base::StringPrintf("%s/binder_rpc_test_service%s%s", path.c_str(),
-                                            singleThreaded ? "_single_threaded" : "",
-                                            noKernel ? "_no_kernel" : "");
-
-        base::unique_fd bootstrapClientFd, bootstrapServerFd;
+    auto addr = allocateSocketAddress();
+    // Initializes the socket before the fork/exec.
+    if (socketType == SocketType::UNIX_RAW) {
+        socketFd = initUnixSocket(addr);
+    } else if (socketType == SocketType::UNIX_BOOTSTRAP) {
         // Do not set O_CLOEXEC, bootstrapServerFd needs to survive fork/exec.
         // This is because we cannot pass ParcelFileDescriptor over a pipe.
-        if (!base::Socketpair(SOCK_STREAM, &bootstrapClientFd, &bootstrapServerFd)) {
+        if (!base::Socketpair(SOCK_STREAM, &bootstrapClientFd, &socketFd)) {
             int savedErrno = errno;
             LOG(FATAL) << "Failed socketpair(): " << strerror(savedErrno);
         }
+    }
 
-        auto ret = ProcessSession{
-                .host = Process([=](android::base::borrowed_fd writeEnd,
-                                    android::base::borrowed_fd readEnd) {
-                    auto writeFd = std::to_string(writeEnd.get());
-                    auto readFd = std::to_string(readEnd.get());
-                    execl(servicePath.c_str(), servicePath.c_str(), writeFd.c_str(), readFd.c_str(),
-                          NULL);
-                }),
-        };
+    auto ret = std::make_unique<LinuxProcessSession>(
+            Process([=](android::base::borrowed_fd writeEnd, android::base::borrowed_fd readEnd) {
+                auto writeFd = std::to_string(writeEnd.get());
+                auto readFd = std::to_string(readEnd.get());
+                execl(servicePath.c_str(), servicePath.c_str(), writeFd.c_str(), readFd.c_str(),
+                      NULL);
+            }));
 
-        BinderRpcTestServerConfig serverConfig;
-        serverConfig.numThreads = options.numThreads;
-        serverConfig.socketType = static_cast<int32_t>(socketType);
-        serverConfig.rpcSecurity = static_cast<int32_t>(rpcSecurity);
-        serverConfig.serverVersion = serverVersion;
-        serverConfig.vsockPort = allocateVsockPort();
-        serverConfig.addr = allocateSocketAddress();
-        serverConfig.unixBootstrapFd = bootstrapServerFd.get();
-        for (auto mode : options.serverSupportedFileDescriptorTransportModes) {
-            serverConfig.serverSupportedFileDescriptorTransportModes.push_back(
-                    static_cast<int32_t>(mode));
-        }
-        writeToFd(ret.host.writeEnd(), serverConfig);
+    BinderRpcTestServerConfig serverConfig;
+    serverConfig.numThreads = options.numThreads;
+    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) {
+        serverConfig.serverSupportedFileDescriptorTransportModes.push_back(
+                static_cast<int32_t>(mode));
+    }
+    writeToFd(ret->host.writeEnd(), serverConfig);
 
-        std::vector<sp<RpcSession>> sessions;
-        auto certVerifier = std::make_shared<RpcCertificateVerifierSimple>();
-        for (size_t i = 0; i < options.numSessions; i++) {
-            sessions.emplace_back(RpcSession::make(newFactory(rpcSecurity, certVerifier)));
-        }
+    std::vector<sp<RpcSession>> sessions;
+    auto certVerifier = std::make_shared<RpcCertificateVerifierSimple>();
+    for (size_t i = 0; i < options.numSessions; i++) {
+        sessions.emplace_back(RpcSession::make(newFactory(rpcSecurity, certVerifier)));
+    }
 
-        auto serverInfo = readFromFd<BinderRpcTestServerInfo>(ret.host.readEnd());
-        BinderRpcTestClientInfo clientInfo;
-        for (const auto& session : sessions) {
-            auto& parcelableCert = clientInfo.certs.emplace_back();
-            parcelableCert.data = session->getCertificate(RpcCertificateFormat::PEM);
-        }
-        writeToFd(ret.host.writeEnd(), clientInfo);
+    auto serverInfo = readFromFd<BinderRpcTestServerInfo>(ret->host.readEnd());
+    BinderRpcTestClientInfo clientInfo;
+    for (const auto& session : sessions) {
+        auto& parcelableCert = clientInfo.certs.emplace_back();
+        parcelableCert.data = session->getCertificate(RpcCertificateFormat::PEM);
+    }
+    writeToFd(ret->host.writeEnd(), clientInfo);
 
-        CHECK_LE(serverInfo.port, std::numeric_limits<unsigned int>::max());
-        if (socketType == SocketType::INET) {
-            CHECK_NE(0, serverInfo.port);
-        }
+    CHECK_LE(serverInfo.port, std::numeric_limits<unsigned int>::max());
+    if (socketType == SocketType::INET) {
+        CHECK_NE(0, serverInfo.port);
+    }
 
-        if (rpcSecurity == RpcSecurity::TLS) {
-            const auto& serverCert = serverInfo.cert.data;
-            CHECK_EQ(OK,
-                     certVerifier->addTrustedPeerCertificate(RpcCertificateFormat::PEM,
-                                                             serverCert));
-        }
+    if (rpcSecurity == RpcSecurity::TLS) {
+        const auto& serverCert = serverInfo.cert.data;
+        CHECK_EQ(OK,
+                 certVerifier->addTrustedPeerCertificate(RpcCertificateFormat::PEM, serverCert));
+    }
 
-        status_t status;
+    status_t status;
 
-        for (const auto& session : sessions) {
-            CHECK(session->setProtocolVersion(clientVersion));
-            session->setMaxIncomingThreads(options.numIncomingConnections);
-            session->setMaxOutgoingThreads(options.numOutgoingConnections);
-            session->setFileDescriptorTransportMode(options.clientFileDescriptorTransportMode);
+    for (const auto& session : sessions) {
+        CHECK(session->setProtocolVersion(clientVersion));
+        session->setMaxIncomingThreads(options.numIncomingConnections);
+        session->setMaxOutgoingThreads(options.numOutgoingConnections);
+        session->setFileDescriptorTransportMode(options.clientFileDescriptorTransportMode);
 
-            switch (socketType) {
-                case SocketType::PRECONNECTED:
-                    status = session->setupPreconnectedClient({}, [=]() {
-                        return connectTo(UnixSocketAddress(serverConfig.addr.c_str()));
-                    });
-                    break;
-                case SocketType::UNIX:
-                    status = session->setupUnixDomainClient(serverConfig.addr.c_str());
-                    break;
-                case SocketType::UNIX_BOOTSTRAP:
-                    status = session->setupUnixDomainSocketBootstrapClient(
-                            base::unique_fd(dup(bootstrapClientFd.get())));
-                    break;
-                case SocketType::VSOCK:
-                    status = session->setupVsockClient(VMADDR_CID_LOCAL, serverConfig.vsockPort);
-                    break;
-                case SocketType::INET:
-                    status = session->setupInetClient("127.0.0.1", serverInfo.port);
-                    break;
-                default:
-                    LOG_ALWAYS_FATAL("Unknown socket type");
-            }
-            if (options.allowConnectFailure && status != OK) {
-                ret.sessions.clear();
+        switch (socketType) {
+            case SocketType::PRECONNECTED:
+                status = session->setupPreconnectedClient({}, [=]() {
+                    return connectTo(UnixSocketAddress(serverConfig.addr.c_str()));
+                });
                 break;
-            }
-            CHECK_EQ(status, OK) << "Could not connect: " << statusToString(status);
-            ret.sessions.push_back({session, session->getRootObject()});
+            case SocketType::UNIX_RAW:
+            case SocketType::UNIX:
+                status = session->setupUnixDomainClient(serverConfig.addr.c_str());
+                break;
+            case SocketType::UNIX_BOOTSTRAP:
+                status = session->setupUnixDomainSocketBootstrapClient(
+                        base::unique_fd(dup(bootstrapClientFd.get())));
+                break;
+            case SocketType::VSOCK:
+                status = session->setupVsockClient(VMADDR_CID_LOCAL, serverConfig.vsockPort);
+                break;
+            case SocketType::INET:
+                status = session->setupInetClient("127.0.0.1", serverInfo.port);
+                break;
+            default:
+                LOG_ALWAYS_FATAL("Unknown socket type");
         }
-        return ret;
+        if (options.allowConnectFailure && status != OK) {
+            ret->sessions.clear();
+            break;
+        }
+        CHECK_EQ(status, OK) << "Could not connect: " << statusToString(status);
+        ret->sessions.push_back({session, session->getRootObject()});
     }
-
-    BinderRpcTestProcessSession createRpcTestSocketServerProcess(const BinderRpcOptions& options) {
-        BinderRpcTestProcessSession ret{
-                .proc = createRpcTestSocketServerProcessEtc(options),
-        };
-
-        ret.rootBinder = ret.proc.sessions.empty() ? nullptr : ret.proc.sessions.at(0).root;
-        ret.rootIface = interface_cast<IBinderRpcTest>(ret.rootBinder);
-
-        return ret;
-    }
-
-    void testThreadPoolOverSaturated(sp<IBinderRpcTest> iface, size_t numCalls,
-                                     size_t sleepMs = 500);
-};
-
-TEST_P(BinderRpc, Ping) {
-    auto proc = createRpcTestSocketServerProcess({});
-    ASSERT_NE(proc.rootBinder, nullptr);
-    EXPECT_EQ(OK, proc.rootBinder->pingBinder());
-}
-
-TEST_P(BinderRpc, GetInterfaceDescriptor) {
-    auto proc = createRpcTestSocketServerProcess({});
-    ASSERT_NE(proc.rootBinder, nullptr);
-    EXPECT_EQ(IBinderRpcTest::descriptor, proc.rootBinder->getInterfaceDescriptor());
-}
-
-TEST_P(BinderRpc, MultipleSessions) {
-    if (serverSingleThreaded()) {
-        // Tests with multiple sessions require a multi-threaded service,
-        // but work fine on a single-threaded client
-        GTEST_SKIP() << "This test requires a multi-threaded service";
-    }
-
-    auto proc = createRpcTestSocketServerProcess({.numThreads = 1, .numSessions = 5});
-    for (auto session : proc.proc.sessions) {
-        ASSERT_NE(nullptr, session.root);
-        EXPECT_EQ(OK, session.root->pingBinder());
-    }
-}
-
-TEST_P(BinderRpc, SeparateRootObject) {
-    if (serverSingleThreaded()) {
-        GTEST_SKIP() << "This test requires a multi-threaded service";
-    }
-
-    SocketType type = std::get<0>(GetParam());
-    if (type == SocketType::PRECONNECTED || type == SocketType::UNIX ||
-        type == SocketType::UNIX_BOOTSTRAP) {
-        // we can't get port numbers for unix sockets
-        return;
-    }
-
-    auto proc = createRpcTestSocketServerProcess({.numSessions = 2});
-
-    int port1 = 0;
-    EXPECT_OK(proc.rootIface->getClientPort(&port1));
-
-    sp<IBinderRpcTest> rootIface2 = interface_cast<IBinderRpcTest>(proc.proc.sessions.at(1).root);
-    int port2;
-    EXPECT_OK(rootIface2->getClientPort(&port2));
-
-    // we should have a different IBinderRpcTest object created for each
-    // session, because we use setPerSessionRootObject
-    EXPECT_NE(port1, port2);
-}
-
-TEST_P(BinderRpc, TransactionsMustBeMarkedRpc) {
-    auto proc = createRpcTestSocketServerProcess({});
-    Parcel data;
-    Parcel reply;
-    EXPECT_EQ(BAD_TYPE, proc.rootBinder->transact(IBinder::PING_TRANSACTION, data, &reply, 0));
-}
-
-TEST_P(BinderRpc, AppendSeparateFormats) {
-    auto proc1 = createRpcTestSocketServerProcess({});
-    auto proc2 = createRpcTestSocketServerProcess({});
-
-    Parcel pRaw;
-
-    Parcel p1;
-    p1.markForBinder(proc1.rootBinder);
-    p1.writeInt32(3);
-
-    EXPECT_EQ(BAD_TYPE, p1.appendFrom(&pRaw, 0, pRaw.dataSize()));
-    EXPECT_EQ(BAD_TYPE, pRaw.appendFrom(&p1, 0, p1.dataSize()));
-
-    Parcel p2;
-    p2.markForBinder(proc2.rootBinder);
-    p2.writeInt32(7);
-
-    EXPECT_EQ(BAD_TYPE, p1.appendFrom(&p2, 0, p2.dataSize()));
-    EXPECT_EQ(BAD_TYPE, p2.appendFrom(&p1, 0, p1.dataSize()));
-}
-
-TEST_P(BinderRpc, UnknownTransaction) {
-    auto proc = createRpcTestSocketServerProcess({});
-    Parcel data;
-    data.markForBinder(proc.rootBinder);
-    Parcel reply;
-    EXPECT_EQ(UNKNOWN_TRANSACTION, proc.rootBinder->transact(1337, data, &reply, 0));
-}
-
-TEST_P(BinderRpc, SendSomethingOneway) {
-    auto proc = createRpcTestSocketServerProcess({});
-    EXPECT_OK(proc.rootIface->sendString("asdf"));
-}
-
-TEST_P(BinderRpc, SendAndGetResultBack) {
-    auto proc = createRpcTestSocketServerProcess({});
-    std::string doubled;
-    EXPECT_OK(proc.rootIface->doubleString("cool ", &doubled));
-    EXPECT_EQ("cool cool ", doubled);
-}
-
-TEST_P(BinderRpc, SendAndGetResultBackBig) {
-    auto proc = createRpcTestSocketServerProcess({});
-    std::string single = std::string(1024, 'a');
-    std::string doubled;
-    EXPECT_OK(proc.rootIface->doubleString(single, &doubled));
-    EXPECT_EQ(single + single, doubled);
-}
-
-TEST_P(BinderRpc, InvalidNullBinderReturn) {
-    auto proc = createRpcTestSocketServerProcess({});
-
-    sp<IBinder> outBinder;
-    EXPECT_EQ(proc.rootIface->getNullBinder(&outBinder).transactionError(), UNEXPECTED_NULL);
-}
-
-TEST_P(BinderRpc, CallMeBack) {
-    auto proc = createRpcTestSocketServerProcess({});
-
-    int32_t pingResult;
-    EXPECT_OK(proc.rootIface->pingMe(new MyBinderRpcSession("foo"), &pingResult));
-    EXPECT_EQ(OK, pingResult);
-
-    EXPECT_EQ(0, MyBinderRpcSession::gNum);
-}
-
-TEST_P(BinderRpc, RepeatBinder) {
-    auto proc = createRpcTestSocketServerProcess({});
-
-    sp<IBinder> inBinder = new MyBinderRpcSession("foo");
-    sp<IBinder> outBinder;
-    EXPECT_OK(proc.rootIface->repeatBinder(inBinder, &outBinder));
-    EXPECT_EQ(inBinder, outBinder);
-
-    wp<IBinder> weak = inBinder;
-    inBinder = nullptr;
-    outBinder = nullptr;
-
-    // Force reading a reply, to process any pending dec refs from the other
-    // process (the other process will process dec refs there before processing
-    // the ping here).
-    EXPECT_EQ(OK, proc.rootBinder->pingBinder());
-
-    EXPECT_EQ(nullptr, weak.promote());
-
-    EXPECT_EQ(0, MyBinderRpcSession::gNum);
-}
-
-TEST_P(BinderRpc, RepeatTheirBinder) {
-    auto proc = createRpcTestSocketServerProcess({});
-
-    sp<IBinderRpcSession> session;
-    EXPECT_OK(proc.rootIface->openSession("aoeu", &session));
-
-    sp<IBinder> inBinder = IInterface::asBinder(session);
-    sp<IBinder> outBinder;
-    EXPECT_OK(proc.rootIface->repeatBinder(inBinder, &outBinder));
-    EXPECT_EQ(inBinder, outBinder);
-
-    wp<IBinder> weak = inBinder;
-    session = nullptr;
-    inBinder = nullptr;
-    outBinder = nullptr;
-
-    // Force reading a reply, to process any pending dec refs from the other
-    // process (the other process will process dec refs there before processing
-    // the ping here).
-    EXPECT_EQ(OK, proc.rootBinder->pingBinder());
-
-    EXPECT_EQ(nullptr, weak.promote());
-}
-
-TEST_P(BinderRpc, RepeatBinderNull) {
-    auto proc = createRpcTestSocketServerProcess({});
-
-    sp<IBinder> outBinder;
-    EXPECT_OK(proc.rootIface->repeatBinder(nullptr, &outBinder));
-    EXPECT_EQ(nullptr, outBinder);
-}
-
-TEST_P(BinderRpc, HoldBinder) {
-    auto proc = createRpcTestSocketServerProcess({});
-
-    IBinder* ptr = nullptr;
-    {
-        sp<IBinder> binder = new BBinder();
-        ptr = binder.get();
-        EXPECT_OK(proc.rootIface->holdBinder(binder));
-    }
-
-    sp<IBinder> held;
-    EXPECT_OK(proc.rootIface->getHeldBinder(&held));
-
-    EXPECT_EQ(held.get(), ptr);
-
-    // stop holding binder, because we test to make sure references are cleaned
-    // up
-    EXPECT_OK(proc.rootIface->holdBinder(nullptr));
-    // and flush ref counts
-    EXPECT_EQ(OK, proc.rootBinder->pingBinder());
-}
-
-// START TESTS FOR LIMITATIONS OF SOCKET BINDER
-// These are behavioral differences form regular binder, where certain usecases
-// aren't supported.
-
-TEST_P(BinderRpc, CannotMixBindersBetweenUnrelatedSocketSessions) {
-    auto proc1 = createRpcTestSocketServerProcess({});
-    auto proc2 = createRpcTestSocketServerProcess({});
-
-    sp<IBinder> outBinder;
-    EXPECT_EQ(INVALID_OPERATION,
-              proc1.rootIface->repeatBinder(proc2.rootBinder, &outBinder).transactionError());
-}
-
-TEST_P(BinderRpc, CannotMixBindersBetweenTwoSessionsToTheSameServer) {
-    if (serverSingleThreaded()) {
-        GTEST_SKIP() << "This test requires a multi-threaded service";
-    }
-
-    auto proc = createRpcTestSocketServerProcess({.numThreads = 1, .numSessions = 2});
-
-    sp<IBinder> outBinder;
-    EXPECT_EQ(INVALID_OPERATION,
-              proc.rootIface->repeatBinder(proc.proc.sessions.at(1).root, &outBinder)
-                      .transactionError());
-}
-
-TEST_P(BinderRpc, CannotSendRegularBinderOverSocketBinder) {
-    if (!kEnableKernelIpc || noKernel()) {
-        GTEST_SKIP() << "Test disabled because Binder kernel driver was disabled "
-                        "at build time.";
-    }
-
-    auto proc = createRpcTestSocketServerProcess({});
-
-    sp<IBinder> someRealBinder = IInterface::asBinder(defaultServiceManager());
-    sp<IBinder> outBinder;
-    EXPECT_EQ(INVALID_OPERATION,
-              proc.rootIface->repeatBinder(someRealBinder, &outBinder).transactionError());
-}
-
-TEST_P(BinderRpc, CannotSendSocketBinderOverRegularBinder) {
-    if (!kEnableKernelIpc || noKernel()) {
-        GTEST_SKIP() << "Test disabled because Binder kernel driver was disabled "
-                        "at build time.";
-    }
-
-    auto proc = createRpcTestSocketServerProcess({});
-
-    // for historical reasons, IServiceManager interface only returns the
-    // exception code
-    EXPECT_EQ(binder::Status::EX_TRANSACTION_FAILED,
-              defaultServiceManager()->addService(String16("not_suspicious"), proc.rootBinder));
-}
-
-// END TESTS FOR LIMITATIONS OF SOCKET BINDER
-
-TEST_P(BinderRpc, RepeatRootObject) {
-    auto proc = createRpcTestSocketServerProcess({});
-
-    sp<IBinder> outBinder;
-    EXPECT_OK(proc.rootIface->repeatBinder(proc.rootBinder, &outBinder));
-    EXPECT_EQ(proc.rootBinder, outBinder);
-}
-
-TEST_P(BinderRpc, NestedTransactions) {
-    auto proc = createRpcTestSocketServerProcess({
-            // Enable FD support because it uses more stack space and so represents
-            // something closer to a worst case scenario.
-            .clientFileDescriptorTransportMode = RpcSession::FileDescriptorTransportMode::UNIX,
-            .serverSupportedFileDescriptorTransportModes =
-                    {RpcSession::FileDescriptorTransportMode::UNIX},
-    });
-
-    auto nastyNester = sp<MyBinderRpcTest>::make();
-    EXPECT_OK(proc.rootIface->nestMe(nastyNester, 10));
-
-    wp<IBinder> weak = nastyNester;
-    nastyNester = nullptr;
-    EXPECT_EQ(nullptr, weak.promote());
-}
-
-TEST_P(BinderRpc, SameBinderEquality) {
-    auto proc = createRpcTestSocketServerProcess({});
-
-    sp<IBinder> a;
-    EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&a));
-
-    sp<IBinder> b;
-    EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&b));
-
-    EXPECT_EQ(a, b);
-}
-
-TEST_P(BinderRpc, SameBinderEqualityWeak) {
-    auto proc = createRpcTestSocketServerProcess({});
-
-    sp<IBinder> a;
-    EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&a));
-    wp<IBinder> weak = a;
-    a = nullptr;
-
-    sp<IBinder> b;
-    EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&b));
-
-    // this is the wrong behavior, since BpBinder
-    // doesn't implement onIncStrongAttempted
-    // but make sure there is no crash
-    EXPECT_EQ(nullptr, weak.promote());
-
-    GTEST_SKIP() << "Weak binders aren't currently re-promotable for RPC binder.";
-
-    // In order to fix this:
-    // - need to have incStrongAttempted reflected across IPC boundary (wait for
-    //   response to promote - round trip...)
-    // - sendOnLastWeakRef, to delete entries out of RpcState table
-    EXPECT_EQ(b, weak.promote());
-}
-
-#define expectSessions(expected, iface)                   \
-    do {                                                  \
-        int session;                                      \
-        EXPECT_OK((iface)->getNumOpenSessions(&session)); \
-        EXPECT_EQ(expected, session);                     \
-    } while (false)
-
-TEST_P(BinderRpc, SingleSession) {
-    auto proc = createRpcTestSocketServerProcess({});
-
-    sp<IBinderRpcSession> session;
-    EXPECT_OK(proc.rootIface->openSession("aoeu", &session));
-    std::string out;
-    EXPECT_OK(session->getName(&out));
-    EXPECT_EQ("aoeu", out);
-
-    expectSessions(1, proc.rootIface);
-    session = nullptr;
-    expectSessions(0, proc.rootIface);
-}
-
-TEST_P(BinderRpc, ManySessions) {
-    auto proc = createRpcTestSocketServerProcess({});
-
-    std::vector<sp<IBinderRpcSession>> sessions;
-
-    for (size_t i = 0; i < 15; i++) {
-        expectSessions(i, proc.rootIface);
-        sp<IBinderRpcSession> session;
-        EXPECT_OK(proc.rootIface->openSession(std::to_string(i), &session));
-        sessions.push_back(session);
-    }
-    expectSessions(sessions.size(), proc.rootIface);
-    for (size_t i = 0; i < sessions.size(); i++) {
-        std::string out;
-        EXPECT_OK(sessions.at(i)->getName(&out));
-        EXPECT_EQ(std::to_string(i), out);
-    }
-    expectSessions(sessions.size(), proc.rootIface);
-
-    while (!sessions.empty()) {
-        sessions.pop_back();
-        expectSessions(sessions.size(), proc.rootIface);
-    }
-    expectSessions(0, proc.rootIface);
-}
-
-size_t epochMillis() {
-    using std::chrono::duration_cast;
-    using std::chrono::milliseconds;
-    using std::chrono::seconds;
-    using std::chrono::system_clock;
-    return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
+    return ret;
 }
 
 TEST_P(BinderRpc, ThreadPoolGreaterThanEqualRequested) {
@@ -857,8 +391,8 @@
     for (auto& t : ts) t.join();
 }
 
-void BinderRpc::testThreadPoolOverSaturated(sp<IBinderRpcTest> iface, size_t numCalls,
-                                            size_t sleepMs) {
+static void testThreadPoolOverSaturated(sp<IBinderRpcTest> iface, size_t numCalls,
+                                        size_t sleepMs = 500) {
     size_t epochMsBefore = epochMillis();
 
     std::vector<std::thread> ts;
@@ -958,20 +492,6 @@
     saturateThreadPool(kNumServerThreads, proc.rootIface);
 }
 
-TEST_P(BinderRpc, OnewayCallDoesNotWait) {
-    constexpr size_t kReallyLongTimeMs = 100;
-    constexpr size_t kSleepMs = kReallyLongTimeMs * 5;
-
-    auto proc = createRpcTestSocketServerProcess({});
-
-    size_t epochMsBefore = epochMillis();
-
-    EXPECT_OK(proc.rootIface->sleepMsAsync(kSleepMs));
-
-    size_t epochMsAfter = epochMillis();
-    EXPECT_LT(epochMsAfter, epochMsBefore + kReallyLongTimeMs);
-}
-
 TEST_P(BinderRpc, OnewayCallQueueingWithFds) {
     if (!supportsFdTransport()) {
         GTEST_SKIP() << "Would fail trivially (which is tested elsewhere)";
@@ -1057,7 +577,7 @@
     // Build up oneway calls on the second session to make sure it terminates
     // and shuts down. The first session should be unaffected (proc destructor
     // checks the first session).
-    auto iface = interface_cast<IBinderRpcTest>(proc.proc.sessions.at(1).root);
+    auto iface = interface_cast<IBinderRpcTest>(proc.proc->sessions.at(1).root);
 
     std::vector<std::thread> threads;
     for (size_t i = 0; i < kNumClients; i++) {
@@ -1085,66 +605,7 @@
     // any pending commands). We need to erase this session from the record
     // here, so that the destructor for our session won't check that this
     // session is valid, but we still want it to test the other session.
-    proc.proc.sessions.erase(proc.proc.sessions.begin() + 1);
-}
-
-TEST_P(BinderRpc, Callbacks) {
-    const static std::string kTestString = "good afternoon!";
-
-    for (bool callIsOneway : {true, false}) {
-        for (bool callbackIsOneway : {true, false}) {
-            for (bool delayed : {true, false}) {
-                if (clientOrServerSingleThreaded() &&
-                    (callIsOneway || callbackIsOneway || delayed)) {
-                    // we have no incoming connections to receive the callback
-                    continue;
-                }
-
-                size_t numIncomingConnections = clientOrServerSingleThreaded() ? 0 : 1;
-                auto proc = createRpcTestSocketServerProcess(
-                        {.numThreads = 1,
-                         .numSessions = 1,
-                         .numIncomingConnections = numIncomingConnections});
-                auto cb = sp<MyBinderRpcCallback>::make();
-
-                if (callIsOneway) {
-                    EXPECT_OK(proc.rootIface->doCallbackAsync(cb, callbackIsOneway, delayed,
-                                                              kTestString));
-                } else {
-                    EXPECT_OK(
-                            proc.rootIface->doCallback(cb, callbackIsOneway, delayed, kTestString));
-                }
-
-                // if both transactions are synchronous and the response is sent back on the
-                // same thread, everything should have happened in a nested call. Otherwise,
-                // the callback will be processed on another thread.
-                if (callIsOneway || callbackIsOneway || delayed) {
-                    using std::literals::chrono_literals::operator""s;
-                    RpcMutexUniqueLock _l(cb->mMutex);
-                    cb->mCv.wait_for(_l, 1s, [&] { return !cb->mValues.empty(); });
-                }
-
-                EXPECT_EQ(cb->mValues.size(), 1)
-                        << "callIsOneway: " << callIsOneway
-                        << " callbackIsOneway: " << callbackIsOneway << " delayed: " << delayed;
-                if (cb->mValues.empty()) continue;
-                EXPECT_EQ(cb->mValues.at(0), kTestString)
-                        << "callIsOneway: " << callIsOneway
-                        << " callbackIsOneway: " << callbackIsOneway << " delayed: " << delayed;
-
-                // since we are severing the connection, we need to go ahead and
-                // tell the server to shutdown and exit so that waitpid won't hang
-                if (auto status = proc.rootIface->scheduleShutdown(); !status.isOk()) {
-                    EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status;
-                }
-
-                // since this session has an incoming connection w/ a threadpool, we
-                // need to manually shut it down
-                EXPECT_TRUE(proc.proc.sessions.at(0).session->shutdownAndWait(true));
-                proc.expectAlreadyShutdown = true;
-            }
-        }
-    }
+    proc.proc->sessions.erase(proc.proc->sessions.begin() + 1);
 }
 
 TEST_P(BinderRpc, SingleDeathRecipient) {
@@ -1177,7 +638,7 @@
     ASSERT_TRUE(dr->mCv.wait_for(lock, 100ms, [&]() { return dr->dead; }));
 
     // need to wait for the session to shutdown so we don't "Leak session"
-    EXPECT_TRUE(proc.proc.sessions.at(0).session->shutdownAndWait(true));
+    EXPECT_TRUE(proc.proc->sessions.at(0).session->shutdownAndWait(true));
     proc.expectAlreadyShutdown = true;
 }
 
@@ -1205,7 +666,7 @@
 
     // Explicitly calling shutDownAndWait will cause the death recipients
     // to be called.
-    EXPECT_TRUE(proc.proc.sessions.at(0).session->shutdownAndWait(true));
+    EXPECT_TRUE(proc.proc->sessions.at(0).session->shutdownAndWait(true));
 
     std::unique_lock<std::mutex> lock(dr->mMtx);
     if (!dr->dead) {
@@ -1213,8 +674,8 @@
     }
     EXPECT_TRUE(dr->dead) << "Failed to receive the death notification.";
 
-    proc.proc.host.terminate();
-    proc.proc.host.setCustomExitStatusCheck([](int wstatus) {
+    proc.proc->terminate();
+    proc.proc->setCustomExitStatusCheck([](int wstatus) {
         EXPECT_TRUE(WIFSIGNALED(wstatus) && WTERMSIG(wstatus) == SIGTERM)
                 << "server process failed incorrectly: " << WaitStatusToString(wstatus);
     });
@@ -1259,18 +720,10 @@
     }
 
     // need to wait for the session to shutdown so we don't "Leak session"
-    EXPECT_TRUE(proc.proc.sessions.at(0).session->shutdownAndWait(true));
+    EXPECT_TRUE(proc.proc->sessions.at(0).session->shutdownAndWait(true));
     proc.expectAlreadyShutdown = true;
 }
 
-TEST_P(BinderRpc, OnewayCallbackWithNoThread) {
-    auto proc = createRpcTestSocketServerProcess({});
-    auto cb = sp<MyBinderRpcCallback>::make();
-
-    Status status = proc.rootIface->doCallback(cb, true /*oneway*/, false /*delayed*/, "anything");
-    EXPECT_EQ(WOULD_BLOCK, status.transactionError());
-}
-
 TEST_P(BinderRpc, Die) {
     for (bool doDeathCleanup : {true, false}) {
         auto proc = createRpcTestSocketServerProcess({});
@@ -1286,7 +739,7 @@
         EXPECT_EQ(DEAD_OBJECT, proc.rootIface->die(doDeathCleanup).transactionError())
                 << "Do death cleanup: " << doDeathCleanup;
 
-        proc.proc.host.setCustomExitStatusCheck([](int wstatus) {
+        proc.proc->setCustomExitStatusCheck([](int wstatus) {
             EXPECT_TRUE(WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 1)
                     << "server process failed incorrectly: " << WaitStatusToString(wstatus);
         });
@@ -1316,7 +769,7 @@
     // second time! we catch the error :)
     EXPECT_EQ(DEAD_OBJECT, proc.rootIface->useKernelBinderCallingId().transactionError());
 
-    proc.proc.host.setCustomExitStatusCheck([](int wstatus) {
+    proc.proc->setCustomExitStatusCheck([](int wstatus) {
         EXPECT_TRUE(WIFSIGNALED(wstatus) && WTERMSIG(wstatus) == SIGABRT)
                 << "server process failed incorrectly: " << WaitStatusToString(wstatus);
     });
@@ -1330,9 +783,9 @@
                     {RpcSession::FileDescriptorTransportMode::UNIX},
             .allowConnectFailure = true,
     });
-    EXPECT_TRUE(proc.proc.sessions.empty()) << "session connections should have failed";
-    proc.proc.host.terminate();
-    proc.proc.host.setCustomExitStatusCheck([](int wstatus) {
+    EXPECT_TRUE(proc.proc->sessions.empty()) << "session connections should have failed";
+    proc.proc->terminate();
+    proc.proc->setCustomExitStatusCheck([](int wstatus) {
         EXPECT_TRUE(WIFSIGNALED(wstatus) && WTERMSIG(wstatus) == SIGTERM)
                 << "server process failed incorrectly: " << WaitStatusToString(wstatus);
     });
@@ -1346,9 +799,9 @@
                     {RpcSession::FileDescriptorTransportMode::NONE},
             .allowConnectFailure = true,
     });
-    EXPECT_TRUE(proc.proc.sessions.empty()) << "session connections should have failed";
-    proc.proc.host.terminate();
-    proc.proc.host.setCustomExitStatusCheck([](int wstatus) {
+    EXPECT_TRUE(proc.proc->sessions.empty()) << "session connections should have failed";
+    proc.proc->terminate();
+    proc.proc->setCustomExitStatusCheck([](int wstatus) {
         EXPECT_TRUE(WIFSIGNALED(wstatus) && WTERMSIG(wstatus) == SIGTERM)
                 << "server process failed incorrectly: " << WaitStatusToString(wstatus);
     });
@@ -1516,16 +969,6 @@
     ASSERT_EQ(beforeFds, countFds()) << (system("ls -l /proc/self/fd/"), "fd leak?");
 }
 
-TEST_P(BinderRpc, AidlDelegatorTest) {
-    auto proc = createRpcTestSocketServerProcess({});
-    auto myDelegator = sp<IBinderRpcTestDelegator>::make(proc.rootIface);
-    ASSERT_NE(nullptr, myDelegator);
-
-    std::string doubled;
-    EXPECT_OK(myDelegator->doubleString("cool ", &doubled));
-    EXPECT_EQ("cool cool ", doubled);
-}
-
 static bool testSupportVsockLoopback() {
     // We don't need to enable TLS to know if vsock is supported.
     unsigned int vsockPort = allocateVsockPort();
@@ -1616,7 +1059,8 @@
 }
 
 static std::vector<SocketType> testSocketTypes(bool hasPreconnected = true) {
-    std::vector<SocketType> ret = {SocketType::UNIX, SocketType::UNIX_BOOTSTRAP, SocketType::INET};
+    std::vector<SocketType> ret = {SocketType::UNIX, SocketType::UNIX_BOOTSTRAP, SocketType::INET,
+                                   SocketType::UNIX_RAW};
 
     if (hasPreconnected) ret.push_back(SocketType::PRECONNECTED);
 
@@ -1858,6 +1302,17 @@
                     mAcceptConnection = &Server::recvmsgServerConnection;
                     mConnectToServer = [this] { return connectToUnixBootstrap(mBootstrapSocket); };
                 } break;
+                case SocketType::UNIX_RAW: {
+                    auto addr = allocateSocketAddress();
+                    auto status = rpcServer->setupRawSocketServer(initUnixSocket(addr));
+                    if (status != OK) {
+                        return AssertionFailure()
+                                << "setupRawSocketServer: " << statusToString(status);
+                    }
+                    mConnectToServer = [addr] {
+                        return connectTo(UnixSocketAddress(addr.c_str()));
+                    };
+                } break;
                 case SocketType::VSOCK: {
                     auto port = allocateVsockPort();
                     auto status = rpcServer->setupVsockServer(port);
diff --git a/libs/binder/tests/binderRpcTestCommon.h b/libs/binder/tests/binderRpcTestCommon.h
index 823bbf6..654e16c 100644
--- a/libs/binder/tests/binderRpcTestCommon.h
+++ b/libs/binder/tests/binderRpcTestCommon.h
@@ -69,6 +69,7 @@
     PRECONNECTED,
     UNIX,
     UNIX_BOOTSTRAP,
+    UNIX_RAW,
     VSOCK,
     INET,
 };
@@ -81,6 +82,8 @@
             return "unix_domain_socket";
         case SocketType::UNIX_BOOTSTRAP:
             return "unix_domain_socket_bootstrap";
+        case SocketType::UNIX_RAW:
+            return "raw_uds";
         case SocketType::VSOCK:
             return "vm_socket";
         case SocketType::INET:
@@ -91,6 +94,14 @@
     }
 }
 
+static inline size_t epochMillis() {
+    using std::chrono::duration_cast;
+    using std::chrono::milliseconds;
+    using std::chrono::seconds;
+    using std::chrono::system_clock;
+    return duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
+}
+
 struct BinderRpcOptions {
     size_t numThreads = 1;
     size_t numSessions = 1;
diff --git a/libs/binder/tests/binderRpcTestFixture.h b/libs/binder/tests/binderRpcTestFixture.h
new file mode 100644
index 0000000..5a78782
--- /dev/null
+++ b/libs/binder/tests/binderRpcTestFixture.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <gtest/gtest.h>
+
+#include "binderRpcTestCommon.h"
+
+#define EXPECT_OK(status)                        \
+    do {                                         \
+        android::binder::Status stat = (status); \
+        EXPECT_TRUE(stat.isOk()) << stat;        \
+    } while (false)
+
+namespace android {
+
+// Abstract base class with a virtual destructor that handles the
+// ownership of a process session for BinderRpcTestSession below
+class ProcessSession {
+public:
+    struct SessionInfo {
+        sp<RpcSession> session;
+        sp<IBinder> root;
+    };
+
+    // client session objects associated with other process
+    // each one represents a separate session
+    std::vector<SessionInfo> sessions;
+
+    virtual ~ProcessSession() = 0;
+
+    // If the process exits with a status, run the given callback on that value.
+    virtual void setCustomExitStatusCheck(std::function<void(int wstatus)> f) = 0;
+
+    // Kill the process. Avoid if possible. Shutdown gracefully via an RPC instead.
+    virtual void terminate() = 0;
+};
+
+// Process session where the process hosts IBinderRpcTest, the server used
+// for most testing here
+struct BinderRpcTestProcessSession {
+    std::unique_ptr<ProcessSession> proc;
+
+    // pre-fetched root object (for first session)
+    sp<IBinder> rootBinder;
+
+    // pre-casted root object (for first session)
+    sp<IBinderRpcTest> rootIface;
+
+    // whether session should be invalidated by end of run
+    bool expectAlreadyShutdown = false;
+
+    BinderRpcTestProcessSession(BinderRpcTestProcessSession&&) = default;
+    ~BinderRpcTestProcessSession() {
+        if (!expectAlreadyShutdown) {
+            EXPECT_NE(nullptr, rootIface);
+            if (rootIface == nullptr) return;
+
+            std::vector<int32_t> remoteCounts;
+            // calling over any sessions counts across all sessions
+            EXPECT_OK(rootIface->countBinders(&remoteCounts));
+            EXPECT_EQ(remoteCounts.size(), proc->sessions.size());
+            for (auto remoteCount : remoteCounts) {
+                EXPECT_EQ(remoteCount, 1);
+            }
+
+            // even though it is on another thread, shutdown races with
+            // the transaction reply being written
+            if (auto status = rootIface->scheduleShutdown(); !status.isOk()) {
+                EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status;
+            }
+        }
+
+        rootIface = nullptr;
+        rootBinder = nullptr;
+    }
+};
+
+class BinderRpc : public ::testing::TestWithParam<
+                          std::tuple<SocketType, RpcSecurity, uint32_t, uint32_t, bool, bool>> {
+public:
+    SocketType socketType() const { return std::get<0>(GetParam()); }
+    RpcSecurity rpcSecurity() const { return std::get<1>(GetParam()); }
+    uint32_t clientVersion() const { return std::get<2>(GetParam()); }
+    uint32_t serverVersion() const { return std::get<3>(GetParam()); }
+    bool serverSingleThreaded() const { return std::get<4>(GetParam()); }
+    bool noKernel() const { return std::get<5>(GetParam()); }
+
+    bool clientOrServerSingleThreaded() const {
+        return !kEnableRpcThreads || serverSingleThreaded();
+    }
+
+    // Whether the test params support sending FDs in parcels.
+    bool supportsFdTransport() const {
+        return clientVersion() >= 1 && serverVersion() >= 1 && rpcSecurity() != RpcSecurity::TLS &&
+                (socketType() == SocketType::PRECONNECTED || socketType() == SocketType::UNIX ||
+                 socketType() == SocketType::UNIX_BOOTSTRAP ||
+                 socketType() == SocketType::UNIX_RAW);
+    }
+
+    void SetUp() override {
+        if (socketType() == SocketType::UNIX_BOOTSTRAP && rpcSecurity() == RpcSecurity::TLS) {
+            GTEST_SKIP() << "Unix bootstrap not supported over a TLS transport";
+        }
+    }
+
+    BinderRpcTestProcessSession createRpcTestSocketServerProcess(const BinderRpcOptions& options) {
+        BinderRpcTestProcessSession ret{
+                .proc = createRpcTestSocketServerProcessEtc(options),
+        };
+
+        ret.rootBinder = ret.proc->sessions.empty() ? nullptr : ret.proc->sessions.at(0).root;
+        ret.rootIface = interface_cast<IBinderRpcTest>(ret.rootBinder);
+
+        return ret;
+    }
+
+    static std::string PrintParamInfo(const testing::TestParamInfo<ParamType>& info);
+
+protected:
+    std::unique_ptr<ProcessSession> createRpcTestSocketServerProcessEtc(
+            const BinderRpcOptions& options);
+};
+
+} // namespace android
diff --git a/libs/binder/tests/binderRpcTestService.cpp b/libs/binder/tests/binderRpcTestService.cpp
index a922b21..995e761 100644
--- a/libs/binder/tests/binderRpcTestService.cpp
+++ b/libs/binder/tests/binderRpcTestService.cpp
@@ -42,7 +42,7 @@
     server->setSupportedFileDescriptorTransportModes(serverSupportedFileDescriptorTransportModes);
 
     unsigned int outPort = 0;
-    base::unique_fd unixBootstrapFd(serverConfig.unixBootstrapFd);
+    base::unique_fd socketFd(serverConfig.socketFd);
 
     switch (socketType) {
         case SocketType::PRECONNECTED:
@@ -52,7 +52,10 @@
                     << serverConfig.addr;
             break;
         case SocketType::UNIX_BOOTSTRAP:
-            CHECK_EQ(OK, server->setupUnixDomainSocketBootstrapServer(std::move(unixBootstrapFd)));
+            CHECK_EQ(OK, server->setupUnixDomainSocketBootstrapServer(std::move(socketFd)));
+            break;
+        case SocketType::UNIX_RAW:
+            CHECK_EQ(OK, server->setupRawSocketServer(std::move(socketFd)));
             break;
         case SocketType::VSOCK:
             CHECK_EQ(OK, server->setupVsockServer(serverConfig.vsockPort));
diff --git a/libs/binder/tests/binderRpcUniversalTests.cpp b/libs/binder/tests/binderRpcUniversalTests.cpp
new file mode 100644
index 0000000..f960442
--- /dev/null
+++ b/libs/binder/tests/binderRpcUniversalTests.cpp
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <chrono>
+#include <cstdlib>
+#include <type_traits>
+
+#include "binderRpcTestCommon.h"
+#include "binderRpcTestFixture.h"
+
+using namespace std::chrono_literals;
+using namespace std::placeholders;
+using testing::AssertionFailure;
+using testing::AssertionResult;
+using testing::AssertionSuccess;
+
+namespace android {
+
+static_assert(RPC_WIRE_PROTOCOL_VERSION + 1 == RPC_WIRE_PROTOCOL_VERSION_NEXT ||
+              RPC_WIRE_PROTOCOL_VERSION == RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL);
+
+TEST(BinderRpcParcel, EntireParcelFormatted) {
+    Parcel p;
+    p.writeInt32(3);
+
+    EXPECT_DEATH_IF_SUPPORTED(p.markForBinder(sp<BBinder>::make()),
+                              "format must be set before data is written");
+}
+
+TEST(BinderRpc, CannotUseNextWireVersion) {
+    auto session = RpcSession::make();
+    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT));
+    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT + 1));
+    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT + 2));
+    EXPECT_FALSE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_NEXT + 15));
+}
+
+TEST(BinderRpc, CanUseExperimentalWireVersion) {
+    auto session = RpcSession::make();
+    EXPECT_TRUE(session->setProtocolVersion(RPC_WIRE_PROTOCOL_VERSION_EXPERIMENTAL));
+}
+
+TEST_P(BinderRpc, Ping) {
+    auto proc = createRpcTestSocketServerProcess({});
+    ASSERT_NE(proc.rootBinder, nullptr);
+    EXPECT_EQ(OK, proc.rootBinder->pingBinder());
+}
+
+TEST_P(BinderRpc, GetInterfaceDescriptor) {
+    auto proc = createRpcTestSocketServerProcess({});
+    ASSERT_NE(proc.rootBinder, nullptr);
+    EXPECT_EQ(IBinderRpcTest::descriptor, proc.rootBinder->getInterfaceDescriptor());
+}
+
+TEST_P(BinderRpc, MultipleSessions) {
+    if (serverSingleThreaded()) {
+        // Tests with multiple sessions require a multi-threaded service,
+        // but work fine on a single-threaded client
+        GTEST_SKIP() << "This test requires a multi-threaded service";
+    }
+
+    auto proc = createRpcTestSocketServerProcess({.numThreads = 1, .numSessions = 5});
+    for (auto session : proc.proc->sessions) {
+        ASSERT_NE(nullptr, session.root);
+        EXPECT_EQ(OK, session.root->pingBinder());
+    }
+}
+
+TEST_P(BinderRpc, SeparateRootObject) {
+    if (serverSingleThreaded()) {
+        GTEST_SKIP() << "This test requires a multi-threaded service";
+    }
+
+    SocketType type = std::get<0>(GetParam());
+    if (type == SocketType::PRECONNECTED || type == SocketType::UNIX ||
+        type == SocketType::UNIX_BOOTSTRAP || type == SocketType::UNIX_RAW) {
+        // we can't get port numbers for unix sockets
+        return;
+    }
+
+    auto proc = createRpcTestSocketServerProcess({.numSessions = 2});
+
+    int port1 = 0;
+    EXPECT_OK(proc.rootIface->getClientPort(&port1));
+
+    sp<IBinderRpcTest> rootIface2 = interface_cast<IBinderRpcTest>(proc.proc->sessions.at(1).root);
+    int port2;
+    EXPECT_OK(rootIface2->getClientPort(&port2));
+
+    // we should have a different IBinderRpcTest object created for each
+    // session, because we use setPerSessionRootObject
+    EXPECT_NE(port1, port2);
+}
+
+TEST_P(BinderRpc, TransactionsMustBeMarkedRpc) {
+    auto proc = createRpcTestSocketServerProcess({});
+    Parcel data;
+    Parcel reply;
+    EXPECT_EQ(BAD_TYPE, proc.rootBinder->transact(IBinder::PING_TRANSACTION, data, &reply, 0));
+}
+
+TEST_P(BinderRpc, AppendSeparateFormats) {
+    auto proc1 = createRpcTestSocketServerProcess({});
+    auto proc2 = createRpcTestSocketServerProcess({});
+
+    Parcel pRaw;
+
+    Parcel p1;
+    p1.markForBinder(proc1.rootBinder);
+    p1.writeInt32(3);
+
+    EXPECT_EQ(BAD_TYPE, p1.appendFrom(&pRaw, 0, pRaw.dataSize()));
+    EXPECT_EQ(BAD_TYPE, pRaw.appendFrom(&p1, 0, p1.dataSize()));
+
+    Parcel p2;
+    p2.markForBinder(proc2.rootBinder);
+    p2.writeInt32(7);
+
+    EXPECT_EQ(BAD_TYPE, p1.appendFrom(&p2, 0, p2.dataSize()));
+    EXPECT_EQ(BAD_TYPE, p2.appendFrom(&p1, 0, p1.dataSize()));
+}
+
+TEST_P(BinderRpc, UnknownTransaction) {
+    auto proc = createRpcTestSocketServerProcess({});
+    Parcel data;
+    data.markForBinder(proc.rootBinder);
+    Parcel reply;
+    EXPECT_EQ(UNKNOWN_TRANSACTION, proc.rootBinder->transact(1337, data, &reply, 0));
+}
+
+TEST_P(BinderRpc, SendSomethingOneway) {
+    auto proc = createRpcTestSocketServerProcess({});
+    EXPECT_OK(proc.rootIface->sendString("asdf"));
+}
+
+TEST_P(BinderRpc, SendAndGetResultBack) {
+    auto proc = createRpcTestSocketServerProcess({});
+    std::string doubled;
+    EXPECT_OK(proc.rootIface->doubleString("cool ", &doubled));
+    EXPECT_EQ("cool cool ", doubled);
+}
+
+TEST_P(BinderRpc, SendAndGetResultBackBig) {
+    auto proc = createRpcTestSocketServerProcess({});
+    std::string single = std::string(1024, 'a');
+    std::string doubled;
+    EXPECT_OK(proc.rootIface->doubleString(single, &doubled));
+    EXPECT_EQ(single + single, doubled);
+}
+
+TEST_P(BinderRpc, InvalidNullBinderReturn) {
+    auto proc = createRpcTestSocketServerProcess({});
+
+    sp<IBinder> outBinder;
+    EXPECT_EQ(proc.rootIface->getNullBinder(&outBinder).transactionError(), UNEXPECTED_NULL);
+}
+
+TEST_P(BinderRpc, CallMeBack) {
+    auto proc = createRpcTestSocketServerProcess({});
+
+    int32_t pingResult;
+    EXPECT_OK(proc.rootIface->pingMe(new MyBinderRpcSession("foo"), &pingResult));
+    EXPECT_EQ(OK, pingResult);
+
+    EXPECT_EQ(0, MyBinderRpcSession::gNum);
+}
+
+TEST_P(BinderRpc, RepeatBinder) {
+    auto proc = createRpcTestSocketServerProcess({});
+
+    sp<IBinder> inBinder = new MyBinderRpcSession("foo");
+    sp<IBinder> outBinder;
+    EXPECT_OK(proc.rootIface->repeatBinder(inBinder, &outBinder));
+    EXPECT_EQ(inBinder, outBinder);
+
+    wp<IBinder> weak = inBinder;
+    inBinder = nullptr;
+    outBinder = nullptr;
+
+    // Force reading a reply, to process any pending dec refs from the other
+    // process (the other process will process dec refs there before processing
+    // the ping here).
+    EXPECT_EQ(OK, proc.rootBinder->pingBinder());
+
+    EXPECT_EQ(nullptr, weak.promote());
+
+    EXPECT_EQ(0, MyBinderRpcSession::gNum);
+}
+
+TEST_P(BinderRpc, RepeatTheirBinder) {
+    auto proc = createRpcTestSocketServerProcess({});
+
+    sp<IBinderRpcSession> session;
+    EXPECT_OK(proc.rootIface->openSession("aoeu", &session));
+
+    sp<IBinder> inBinder = IInterface::asBinder(session);
+    sp<IBinder> outBinder;
+    EXPECT_OK(proc.rootIface->repeatBinder(inBinder, &outBinder));
+    EXPECT_EQ(inBinder, outBinder);
+
+    wp<IBinder> weak = inBinder;
+    session = nullptr;
+    inBinder = nullptr;
+    outBinder = nullptr;
+
+    // Force reading a reply, to process any pending dec refs from the other
+    // process (the other process will process dec refs there before processing
+    // the ping here).
+    EXPECT_EQ(OK, proc.rootBinder->pingBinder());
+
+    EXPECT_EQ(nullptr, weak.promote());
+}
+
+TEST_P(BinderRpc, RepeatBinderNull) {
+    auto proc = createRpcTestSocketServerProcess({});
+
+    sp<IBinder> outBinder;
+    EXPECT_OK(proc.rootIface->repeatBinder(nullptr, &outBinder));
+    EXPECT_EQ(nullptr, outBinder);
+}
+
+TEST_P(BinderRpc, HoldBinder) {
+    auto proc = createRpcTestSocketServerProcess({});
+
+    IBinder* ptr = nullptr;
+    {
+        sp<IBinder> binder = new BBinder();
+        ptr = binder.get();
+        EXPECT_OK(proc.rootIface->holdBinder(binder));
+    }
+
+    sp<IBinder> held;
+    EXPECT_OK(proc.rootIface->getHeldBinder(&held));
+
+    EXPECT_EQ(held.get(), ptr);
+
+    // stop holding binder, because we test to make sure references are cleaned
+    // up
+    EXPECT_OK(proc.rootIface->holdBinder(nullptr));
+    // and flush ref counts
+    EXPECT_EQ(OK, proc.rootBinder->pingBinder());
+}
+
+// START TESTS FOR LIMITATIONS OF SOCKET BINDER
+// These are behavioral differences form regular binder, where certain usecases
+// aren't supported.
+
+TEST_P(BinderRpc, CannotMixBindersBetweenUnrelatedSocketSessions) {
+    auto proc1 = createRpcTestSocketServerProcess({});
+    auto proc2 = createRpcTestSocketServerProcess({});
+
+    sp<IBinder> outBinder;
+    EXPECT_EQ(INVALID_OPERATION,
+              proc1.rootIface->repeatBinder(proc2.rootBinder, &outBinder).transactionError());
+}
+
+TEST_P(BinderRpc, CannotMixBindersBetweenTwoSessionsToTheSameServer) {
+    if (serverSingleThreaded()) {
+        GTEST_SKIP() << "This test requires a multi-threaded service";
+    }
+
+    auto proc = createRpcTestSocketServerProcess({.numThreads = 1, .numSessions = 2});
+
+    sp<IBinder> outBinder;
+    EXPECT_EQ(INVALID_OPERATION,
+              proc.rootIface->repeatBinder(proc.proc->sessions.at(1).root, &outBinder)
+                      .transactionError());
+}
+
+TEST_P(BinderRpc, CannotSendRegularBinderOverSocketBinder) {
+    if (!kEnableKernelIpc || noKernel()) {
+        GTEST_SKIP() << "Test disabled because Binder kernel driver was disabled "
+                        "at build time.";
+    }
+
+    auto proc = createRpcTestSocketServerProcess({});
+
+    sp<IBinder> someRealBinder = IInterface::asBinder(defaultServiceManager());
+    sp<IBinder> outBinder;
+    EXPECT_EQ(INVALID_OPERATION,
+              proc.rootIface->repeatBinder(someRealBinder, &outBinder).transactionError());
+}
+
+TEST_P(BinderRpc, CannotSendSocketBinderOverRegularBinder) {
+    if (!kEnableKernelIpc || noKernel()) {
+        GTEST_SKIP() << "Test disabled because Binder kernel driver was disabled "
+                        "at build time.";
+    }
+
+    auto proc = createRpcTestSocketServerProcess({});
+
+    // for historical reasons, IServiceManager interface only returns the
+    // exception code
+    EXPECT_EQ(binder::Status::EX_TRANSACTION_FAILED,
+              defaultServiceManager()->addService(String16("not_suspicious"), proc.rootBinder));
+}
+
+// END TESTS FOR LIMITATIONS OF SOCKET BINDER
+
+TEST_P(BinderRpc, RepeatRootObject) {
+    auto proc = createRpcTestSocketServerProcess({});
+
+    sp<IBinder> outBinder;
+    EXPECT_OK(proc.rootIface->repeatBinder(proc.rootBinder, &outBinder));
+    EXPECT_EQ(proc.rootBinder, outBinder);
+}
+
+TEST_P(BinderRpc, NestedTransactions) {
+    auto proc = createRpcTestSocketServerProcess({
+            // Enable FD support because it uses more stack space and so represents
+            // something closer to a worst case scenario.
+            .clientFileDescriptorTransportMode = RpcSession::FileDescriptorTransportMode::UNIX,
+            .serverSupportedFileDescriptorTransportModes =
+                    {RpcSession::FileDescriptorTransportMode::UNIX},
+    });
+
+    auto nastyNester = sp<MyBinderRpcTest>::make();
+    EXPECT_OK(proc.rootIface->nestMe(nastyNester, 10));
+
+    wp<IBinder> weak = nastyNester;
+    nastyNester = nullptr;
+    EXPECT_EQ(nullptr, weak.promote());
+}
+
+TEST_P(BinderRpc, SameBinderEquality) {
+    auto proc = createRpcTestSocketServerProcess({});
+
+    sp<IBinder> a;
+    EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&a));
+
+    sp<IBinder> b;
+    EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&b));
+
+    EXPECT_EQ(a, b);
+}
+
+TEST_P(BinderRpc, SameBinderEqualityWeak) {
+    auto proc = createRpcTestSocketServerProcess({});
+
+    sp<IBinder> a;
+    EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&a));
+    wp<IBinder> weak = a;
+    a = nullptr;
+
+    sp<IBinder> b;
+    EXPECT_OK(proc.rootIface->alwaysGiveMeTheSameBinder(&b));
+
+    // this is the wrong behavior, since BpBinder
+    // doesn't implement onIncStrongAttempted
+    // but make sure there is no crash
+    EXPECT_EQ(nullptr, weak.promote());
+
+    GTEST_SKIP() << "Weak binders aren't currently re-promotable for RPC binder.";
+
+    // In order to fix this:
+    // - need to have incStrongAttempted reflected across IPC boundary (wait for
+    //   response to promote - round trip...)
+    // - sendOnLastWeakRef, to delete entries out of RpcState table
+    EXPECT_EQ(b, weak.promote());
+}
+
+#define expectSessions(expected, iface)                   \
+    do {                                                  \
+        int session;                                      \
+        EXPECT_OK((iface)->getNumOpenSessions(&session)); \
+        EXPECT_EQ(expected, session);                     \
+    } while (false)
+
+TEST_P(BinderRpc, SingleSession) {
+    auto proc = createRpcTestSocketServerProcess({});
+
+    sp<IBinderRpcSession> session;
+    EXPECT_OK(proc.rootIface->openSession("aoeu", &session));
+    std::string out;
+    EXPECT_OK(session->getName(&out));
+    EXPECT_EQ("aoeu", out);
+
+    expectSessions(1, proc.rootIface);
+    session = nullptr;
+    expectSessions(0, proc.rootIface);
+}
+
+TEST_P(BinderRpc, ManySessions) {
+    auto proc = createRpcTestSocketServerProcess({});
+
+    std::vector<sp<IBinderRpcSession>> sessions;
+
+    for (size_t i = 0; i < 15; i++) {
+        expectSessions(i, proc.rootIface);
+        sp<IBinderRpcSession> session;
+        EXPECT_OK(proc.rootIface->openSession(std::to_string(i), &session));
+        sessions.push_back(session);
+    }
+    expectSessions(sessions.size(), proc.rootIface);
+    for (size_t i = 0; i < sessions.size(); i++) {
+        std::string out;
+        EXPECT_OK(sessions.at(i)->getName(&out));
+        EXPECT_EQ(std::to_string(i), out);
+    }
+    expectSessions(sessions.size(), proc.rootIface);
+
+    while (!sessions.empty()) {
+        sessions.pop_back();
+        expectSessions(sessions.size(), proc.rootIface);
+    }
+    expectSessions(0, proc.rootIface);
+}
+
+TEST_P(BinderRpc, OnewayCallDoesNotWait) {
+    constexpr size_t kReallyLongTimeMs = 100;
+    constexpr size_t kSleepMs = kReallyLongTimeMs * 5;
+
+    auto proc = createRpcTestSocketServerProcess({});
+
+    size_t epochMsBefore = epochMillis();
+
+    EXPECT_OK(proc.rootIface->sleepMsAsync(kSleepMs));
+
+    size_t epochMsAfter = epochMillis();
+    EXPECT_LT(epochMsAfter, epochMsBefore + kReallyLongTimeMs);
+}
+
+TEST_P(BinderRpc, Callbacks) {
+    const static std::string kTestString = "good afternoon!";
+
+    for (bool callIsOneway : {true, false}) {
+        for (bool callbackIsOneway : {true, false}) {
+            for (bool delayed : {true, false}) {
+                if (clientOrServerSingleThreaded() &&
+                    (callIsOneway || callbackIsOneway || delayed)) {
+                    // we have no incoming connections to receive the callback
+                    continue;
+                }
+
+                size_t numIncomingConnections = clientOrServerSingleThreaded() ? 0 : 1;
+                auto proc = createRpcTestSocketServerProcess(
+                        {.numThreads = 1,
+                         .numSessions = 1,
+                         .numIncomingConnections = numIncomingConnections});
+                auto cb = sp<MyBinderRpcCallback>::make();
+
+                if (callIsOneway) {
+                    EXPECT_OK(proc.rootIface->doCallbackAsync(cb, callbackIsOneway, delayed,
+                                                              kTestString));
+                } else {
+                    EXPECT_OK(
+                            proc.rootIface->doCallback(cb, callbackIsOneway, delayed, kTestString));
+                }
+
+                // if both transactions are synchronous and the response is sent back on the
+                // same thread, everything should have happened in a nested call. Otherwise,
+                // the callback will be processed on another thread.
+                if (callIsOneway || callbackIsOneway || delayed) {
+                    using std::literals::chrono_literals::operator""s;
+                    RpcMutexUniqueLock _l(cb->mMutex);
+                    cb->mCv.wait_for(_l, 1s, [&] { return !cb->mValues.empty(); });
+                }
+
+                EXPECT_EQ(cb->mValues.size(), 1)
+                        << "callIsOneway: " << callIsOneway
+                        << " callbackIsOneway: " << callbackIsOneway << " delayed: " << delayed;
+                if (cb->mValues.empty()) continue;
+                EXPECT_EQ(cb->mValues.at(0), kTestString)
+                        << "callIsOneway: " << callIsOneway
+                        << " callbackIsOneway: " << callbackIsOneway << " delayed: " << delayed;
+
+                // since we are severing the connection, we need to go ahead and
+                // tell the server to shutdown and exit so that waitpid won't hang
+                if (auto status = proc.rootIface->scheduleShutdown(); !status.isOk()) {
+                    EXPECT_EQ(DEAD_OBJECT, status.transactionError()) << status;
+                }
+
+                // since this session has an incoming connection w/ a threadpool, we
+                // need to manually shut it down
+                EXPECT_TRUE(proc.proc->sessions.at(0).session->shutdownAndWait(true));
+                proc.expectAlreadyShutdown = true;
+            }
+        }
+    }
+}
+
+TEST_P(BinderRpc, OnewayCallbackWithNoThread) {
+    auto proc = createRpcTestSocketServerProcess({});
+    auto cb = sp<MyBinderRpcCallback>::make();
+
+    Status status = proc.rootIface->doCallback(cb, true /*oneway*/, false /*delayed*/, "anything");
+    EXPECT_EQ(WOULD_BLOCK, status.transactionError());
+}
+
+TEST_P(BinderRpc, AidlDelegatorTest) {
+    auto proc = createRpcTestSocketServerProcess({});
+    auto myDelegator = sp<IBinderRpcTestDelegator>::make(proc.rootIface);
+    ASSERT_NE(nullptr, myDelegator);
+
+    std::string doubled;
+    EXPECT_OK(myDelegator->doubleString("cool ", &doubled));
+    EXPECT_EQ("cool cool ", doubled);
+}
+
+} // namespace android
diff --git a/libs/binder/tests/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp
index 3904e1d..61a2412 100644
--- a/libs/binder/tests/parcel_fuzzer/Android.bp
+++ b/libs/binder/tests/parcel_fuzzer/Android.bp
@@ -20,6 +20,9 @@
         java: {
             enabled: false,
         },
+        rust: {
+            enabled: true,
+        },
     },
 }
 
diff --git a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
index 25f6096..86461c8 100644
--- a/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
+++ b/libs/binder/tests/parcel_fuzzer/libbinder_driver.cpp
@@ -18,6 +18,7 @@
 #include <fuzzbinder/random_parcel.h>
 
 #include <android-base/logging.h>
+#include <binder/IPCThreadState.h>
 #include <binder/ProcessState.h>
 
 namespace android {
@@ -30,10 +31,17 @@
             .extraFds = {},
     };
 
+    if (provider.ConsumeBool()) {
+        // set calling uid
+        IPCThreadState::self()->restoreCallingIdentity(provider.ConsumeIntegral<int64_t>());
+    }
+
     while (provider.remaining_bytes() > 0) {
         uint32_t code = provider.ConsumeIntegral<uint32_t>();
         uint32_t flags = provider.ConsumeIntegral<uint32_t>();
         Parcel data;
+        // for increased fuzz coverage
+        data.setEnforceNoDataAvail(provider.ConsumeBool());
 
         sp<IBinder> target = options.extraBinders.at(
                 provider.ConsumeIntegralInRange<size_t>(0, options.extraBinders.size() - 1));
@@ -50,6 +58,8 @@
         fillRandomParcel(&data, FuzzedDataProvider(subData.data(), subData.size()), &options);
 
         Parcel reply;
+        // for increased fuzz coverage
+        reply.setEnforceNoDataAvail(provider.ConsumeBool());
         (void)target->transact(code, data, &reply, flags);
 
         // feed back in binders and fds that are returned from the service, so that
diff --git a/libs/binder/tests/parcel_fuzzer/libbinder_ndk_driver.cpp b/libs/binder/tests/parcel_fuzzer/libbinder_ndk_driver.cpp
index 462ef9a..a1fb701 100644
--- a/libs/binder/tests/parcel_fuzzer/libbinder_ndk_driver.cpp
+++ b/libs/binder/tests/parcel_fuzzer/libbinder_ndk_driver.cpp
@@ -29,3 +29,12 @@
 }
 
 } // namespace android
+
+extern "C" {
+// This API is used by fuzzers to automatically fuzz aidl services
+void fuzzRustService(void* binder, const uint8_t* data, size_t len) {
+    AIBinder* aiBinder = static_cast<AIBinder*>(binder);
+    FuzzedDataProvider provider(data, len);
+    android::fuzzService(aiBinder, std::move(provider));
+}
+} // extern "C"
diff --git a/libs/binder/tests/parcel_fuzzer/rust_interface/Android.bp b/libs/binder/tests/parcel_fuzzer/rust_interface/Android.bp
new file mode 100644
index 0000000..b48dc27
--- /dev/null
+++ b/libs/binder/tests/parcel_fuzzer/rust_interface/Android.bp
@@ -0,0 +1,24 @@
+package {
+    default_applicable_licenses: ["frameworks_native_license"],
+}
+
+cc_library_static {
+    name: "libbinder_create_parcel",
+    host_supported: true,
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+    srcs: [
+        "RandomParcelWrapper.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libbinder_ndk",
+    ],
+    static_libs: [
+        "libbinder_random_parcel",
+    ],
+}
diff --git a/libs/binder/tests/parcel_fuzzer/rust_interface/RandomParcelWrapper.cpp b/libs/binder/tests/parcel_fuzzer/rust_interface/RandomParcelWrapper.cpp
new file mode 100644
index 0000000..2fb7820
--- /dev/null
+++ b/libs/binder/tests/parcel_fuzzer/rust_interface/RandomParcelWrapper.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_libbinder.h>
+#include <android/binder_parcel.h>
+#include <fuzzbinder/random_parcel.h>
+
+extern "C" {
+
+void createRandomParcel(void* aParcel, const uint8_t* data, size_t len) {
+    CHECK_NE(aParcel, nullptr);
+    AParcel* parcel = static_cast<AParcel*>(aParcel);
+    FuzzedDataProvider provider(data, len);
+    android::RandomParcelOptions options;
+
+    android::Parcel* platformParcel = AParcel_viewPlatformParcel(parcel);
+    fillRandomParcel(platformParcel, std::move(provider), &options);
+}
+
+} // extern "C"
\ No newline at end of file
diff --git a/libs/binder/trusty/OS.cpp b/libs/binder/trusty/OS.cpp
index 397ff41..8ec9823 100644
--- a/libs/binder/trusty/OS.cpp
+++ b/libs/binder/trusty/OS.cpp
@@ -59,14 +59,14 @@
     return RpcTransportCtxFactoryTipcTrusty::make();
 }
 
-int sendMessageOnSocket(
+ssize_t sendMessageOnSocket(
         const RpcTransportFd& /* socket */, iovec* /* iovs */, int /* niovs */,
         const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* /* ancillaryFds */) {
     errno = ENOTSUP;
     return -1;
 }
 
-int receiveMessageFromSocket(
+ssize_t receiveMessageFromSocket(
         const RpcTransportFd& /* socket */, iovec* /* iovs */, int /* niovs */,
         std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* /* ancillaryFds */) {
     errno = ENOTSUP;
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index a6585c5..067ce17 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -208,5 +208,5 @@
     cmdline = std::string(cmdline.c_str());
 
     return cmdline == "zygote" || cmdline == "zygote64" || cmdline == "usap32" ||
-            cmdline == "usap64";
+            cmdline == "usap64" || cmdline == "webview_zygote";
 }
diff --git a/libs/fakeservicemanager/ServiceManager.cpp b/libs/fakeservicemanager/ServiceManager.cpp
index 6c6d7f3..1109ad8 100644
--- a/libs/fakeservicemanager/ServiceManager.cpp
+++ b/libs/fakeservicemanager/ServiceManager.cpp
@@ -36,6 +36,9 @@
 status_t ServiceManager::addService(const String16& name, const sp<IBinder>& service,
                                 bool /*allowIsolated*/,
                                 int /*dumpsysFlags*/) {
+    if (service == nullptr) {
+        return UNEXPECTED_NULL;
+    }
     mNameToService[name] = service;
     return NO_ERROR;
 }
@@ -78,6 +81,11 @@
     return std::nullopt;
 }
 
+Vector<String16> ServiceManager::getUpdatableNames(const String16& apexName) {
+    (void)apexName;
+    return {};
+}
+
 std::optional<IServiceManager::ConnectionInfo> ServiceManager::getConnectionInfo(
         const String16& name) {
     (void)name;
@@ -98,4 +106,8 @@
     std::vector<IServiceManager::ServiceDebugInfo> ret;
     return ret;
 }
+
+void ServiceManager::clear() {
+    mNameToService.clear();
+}
 }  // namespace android
diff --git a/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h b/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
index e0af5d4..ba6bb7d 100644
--- a/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
+++ b/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
@@ -52,6 +52,8 @@
 
     std::optional<String16> updatableViaApex(const String16& name) override;
 
+    Vector<String16> getUpdatableNames(const String16& apexName) override;
+
     std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override;
 
     status_t registerForNotifications(const String16& name,
@@ -62,6 +64,9 @@
 
     std::vector<IServiceManager::ServiceDebugInfo> getServiceDebugInfo() override;
 
+    // Clear all of the registered services
+    void clear();
+
 private:
     std::map<String16, sp<IBinder>> mNameToService;
 };
diff --git a/libs/fakeservicemanager/test_sm.cpp b/libs/fakeservicemanager/test_sm.cpp
index 71e5abe..8682c1c 100644
--- a/libs/fakeservicemanager/test_sm.cpp
+++ b/libs/fakeservicemanager/test_sm.cpp
@@ -50,6 +50,12 @@
         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
 }
 
+TEST(AddService, SadNullBinder) {
+    auto sm = new ServiceManager();
+    EXPECT_EQ(sm->addService(String16("foo"), nullptr, false /*allowIsolated*/,
+        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), android::UNEXPECTED_NULL);
+}
+
 TEST(AddService, HappyOverExistingService) {
     auto sm = new ServiceManager();
     EXPECT_EQ(sm->addService(String16("foo"), getBinder(), false /*allowIsolated*/,
@@ -58,6 +64,15 @@
         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
 }
 
+TEST(AddService, HappyClearAddedService) {
+    auto sm = new ServiceManager();
+    EXPECT_EQ(sm->addService(String16("foo"), getBinder(), false /*allowIsolated*/,
+        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
+    EXPECT_NE(sm->getService(String16("foo")), nullptr);
+    sm->clear();
+    EXPECT_EQ(sm->getService(String16("foo")), nullptr);
+}
+
 TEST(GetService, HappyHappy) {
     auto sm = new ServiceManager();
     sp<IBinder> service = getBinder();
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 7f0cac5..4a0a839 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -364,26 +364,61 @@
     return (mUseAngle == YES) ? true : false;
 }
 
+bool GraphicsEnv::angleIsSystemDriver() {
+    // Make sure we are init'ed
+    if (mAngleAppName.empty()) {
+        ALOGV("App name is empty. setAngleInfo() has not been called to enable ANGLE.");
+        return false;
+    }
+
+    return (mAngleIsSystemDriver == YES) ? true : false;
+}
+
+bool GraphicsEnv::shouldForceLegacyDriver() {
+    // Make sure we are init'ed
+    if (mAngleAppName.empty()) {
+        ALOGV("App name is empty. setAngleInfo() has not been called to enable ANGLE.");
+        return false;
+    }
+
+    return (mAngleIsSystemDriver == YES && mUseAngle == NO) ? true : false;
+}
+
+std::string GraphicsEnv::getLegacySuffix() {
+    return mLegacyDriverSuffix;
+}
+
 void GraphicsEnv::updateUseAngle() {
     mUseAngle = NO;
 
     const char* ANGLE_PREFER_ANGLE = "angle";
+    const char* ANGLE_PREFER_LEGACY = "legacy";
+    // The following is a deprecated version of "legacy"
     const char* ANGLE_PREFER_NATIVE = "native";
 
     mUseAngle = NO;
     if (mAngleDeveloperOptIn == ANGLE_PREFER_ANGLE) {
-        ALOGV("User set \"Developer Options\" to force the use of ANGLE");
+        ALOGI("Using ANGLE, the %s GLES driver for package '%s'",
+              mAngleIsSystemDriver == YES ? "system" : "optional", mAngleAppName.c_str());
         mUseAngle = YES;
-    } else if (mAngleDeveloperOptIn == ANGLE_PREFER_NATIVE) {
-        ALOGV("User set \"Developer Options\" to force the use of Native");
+    } else if (mAngleDeveloperOptIn == ANGLE_PREFER_LEGACY ||
+               mAngleDeveloperOptIn == ANGLE_PREFER_NATIVE) {
+        ALOGI("Using the (%s) Legacy GLES driver for package '%s'",
+              mAngleIsSystemDriver == YES ? "optional" : "system", mAngleAppName.c_str());
     } else {
         ALOGV("User set invalid \"Developer Options\": '%s'", mAngleDeveloperOptIn.c_str());
     }
 }
 
 void GraphicsEnv::setAngleInfo(const std::string path, const std::string appName,
-                               const std::string developerOptIn,
+                               const bool angleIsSystemDriver, const std::string developerOptIn,
                                const std::vector<std::string> eglFeatures) {
+    // Set whether ANGLE is the system driver:
+    mAngleIsSystemDriver = angleIsSystemDriver ? YES : NO;
+
+    // Note: Given the current logic and lack of the old rules file processing,
+    // there seems to be little chance that mUseAngle != UNKNOWN.  Leave this
+    // for now, even though it seems outdated.
     if (mUseAngle != UNKNOWN) {
         // We've already figured out an answer for this app, so just return.
         ALOGV("Already evaluated the rules file for '%s': use ANGLE = %s", appName.c_str(),
@@ -404,6 +439,25 @@
     updateUseAngle();
 }
 
+void GraphicsEnv::setLegacyDriverInfo(const std::string appName, const bool angleIsSystemDriver,
+                                      const std::string legacyDriverName) {
+    ALOGV("setting legacy app name to '%s'", appName.c_str());
+    mAngleAppName = appName;
+
+    // Force the use of the legacy driver instead of ANGLE
+    const char* ANGLE_PREFER_LEGACY = "legacy";
+    mAngleDeveloperOptIn = ANGLE_PREFER_LEGACY;
+    ALOGV("setting ANGLE application opt-in to 'legacy'");
+
+    // Set whether ANGLE is the system driver:
+    mAngleIsSystemDriver = angleIsSystemDriver ? YES : NO;
+
+    mLegacyDriverSuffix = legacyDriverName;
+
+    // Update the current status of whether we should use ANGLE or not
+    updateUseAngle();
+}
+
 void GraphicsEnv::setLayerPaths(NativeLoaderNamespace* appNamespace, const std::string layerPaths) {
     if (mLayerPaths.empty()) {
         mLayerPaths = layerPaths;
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index 56d1139..82a6b6c 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -91,17 +91,28 @@
     bool shouldUseAngle(std::string appName);
     // Check if this app process should use ANGLE.
     bool shouldUseAngle();
+    // If ANGLE is the system GLES driver
+    bool angleIsSystemDriver();
+    // If should use legacy driver instead of a system ANGLE driver
+    bool shouldForceLegacyDriver();
     // Set a search path for loading ANGLE libraries. The path is a list of
     // directories separated by ':'. A directory can be contained in a zip file
     // (libraries must be stored uncompressed and page aligned); such elements
     // in the search path must have a '!' after the zip filename, e.g.
     //     /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk!/lib/arm64-v8a
-    void setAngleInfo(const std::string path, const std::string appName, std::string devOptIn,
+    void setAngleInfo(const std::string path, const std::string appName,
+                      const bool angleIsSystemDriver, std::string devOptIn,
                       const std::vector<std::string> eglFeatures);
+    // Set the state so that the legacy driver will be used, and in case ANGLE
+    // is the system driver, provide the name of the legacy driver.
+    void setLegacyDriverInfo(const std::string appName, const bool angleIsSystemDriver,
+                             const std::string legacyDriverName);
     // Get the ANGLE driver namespace.
     android_namespace_t* getAngleNamespace();
     // Get the app name for ANGLE debug message.
     std::string& getAngleAppName();
+    // Get the legacy driver's suffix name.
+    std::string getLegacySuffix();
 
     const std::vector<std::string>& getAngleEglFeatures();
 
@@ -156,6 +167,10 @@
     std::string mAngleDeveloperOptIn;
     // ANGLE EGL features;
     std::vector<std::string> mAngleEglFeatures;
+    // ANGLE is System Driver flag.
+    UseAngle mAngleIsSystemDriver = UNKNOWN;
+    // Legacy driver name to use when ANGLE is the system driver.
+    std::string mLegacyDriverSuffix;
     // Use ANGLE flag.
     UseAngle mUseAngle = UNKNOWN;
     // Vulkan debug layers libs.
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 56b17ae..6c39bbf 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -177,8 +177,6 @@
 
         "BitTube.cpp",
         "BLASTBufferQueue.cpp",
-        "BufferHubConsumer.cpp",
-        "BufferHubProducer.cpp",
         "BufferItemConsumer.cpp",
         "ConsumerBase.cpp",
         "CpuConsumer.cpp",
@@ -216,9 +214,6 @@
 
     shared_libs: [
         "libbinder",
-        "libbufferhub",
-        "libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui.
-        "libpdx_default_transport",
     ],
 
     export_shared_lib_headers: [
@@ -229,24 +224,6 @@
         "libgui_aidl_headers",
     ],
 
-    // bufferhub is not used when building libgui for vendors
-    target: {
-        vendor: {
-            cflags: [
-                "-DNO_BUFFERHUB",
-            ],
-            exclude_srcs: [
-                "BufferHubConsumer.cpp",
-                "BufferHubProducer.cpp",
-            ],
-            exclude_shared_libs: [
-                "libbufferhub",
-                "libbufferhubqueue",
-                "libpdx_default_transport",
-            ],
-        },
-    },
-
     aidl: {
         export_aidl_headers: true,
     },
@@ -276,7 +253,6 @@
     min_sdk_version: "29",
 
     cflags: [
-        "-DNO_BUFFERHUB",
         "-DNO_BINDER",
     ],
 
diff --git a/libs/gui/BufferHubConsumer.cpp b/libs/gui/BufferHubConsumer.cpp
deleted file mode 100644
index b5cdeb2..0000000
--- a/libs/gui/BufferHubConsumer.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gui/BufferHubConsumer.h>
-
-namespace android {
-
-using namespace dvr;
-
-/* static */
-sp<BufferHubConsumer> BufferHubConsumer::Create(const std::shared_ptr<ConsumerQueue>& queue) {
-    sp<BufferHubConsumer> consumer = new BufferHubConsumer;
-    consumer->mQueue = queue;
-    return consumer;
-}
-
-/* static */ sp<BufferHubConsumer> BufferHubConsumer::Create(ConsumerQueueParcelable parcelable) {
-    if (!parcelable.IsValid()) {
-        ALOGE("BufferHubConsumer::Create: Invalid consumer parcelable.");
-        return nullptr;
-    }
-
-    sp<BufferHubConsumer> consumer = new BufferHubConsumer;
-    consumer->mQueue = ConsumerQueue::Import(parcelable.TakeChannelHandle());
-    return consumer;
-}
-
-status_t BufferHubConsumer::acquireBuffer(BufferItem* /*buffer*/, nsecs_t /*presentWhen*/,
-                                          uint64_t /*maxFrameNumber*/) {
-    ALOGE("BufferHubConsumer::acquireBuffer: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::detachBuffer(int /*slot*/) {
-    ALOGE("BufferHubConsumer::detachBuffer: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::attachBuffer(int* /*outSlot*/, const sp<GraphicBuffer>& /*buffer*/) {
-    ALOGE("BufferHubConsumer::attachBuffer: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::releaseBuffer(int /*buf*/, uint64_t /*frameNumber*/,
-                                          EGLDisplay /*display*/, EGLSyncKHR /*fence*/,
-                                          const sp<Fence>& /*releaseFence*/) {
-    ALOGE("BufferHubConsumer::releaseBuffer: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::consumerConnect(const sp<IConsumerListener>& /*consumer*/,
-                                            bool /*controlledByApp*/) {
-    ALOGE("BufferHubConsumer::consumerConnect: not implemented.");
-
-    // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to
-    // make IGraphicBufferConsumer_test happy.
-    return NO_ERROR;
-}
-
-status_t BufferHubConsumer::consumerDisconnect() {
-    ALOGE("BufferHubConsumer::consumerDisconnect: not implemented.");
-
-    // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to
-    // make IGraphicBufferConsumer_test happy.
-    return NO_ERROR;
-}
-
-status_t BufferHubConsumer::getReleasedBuffers(uint64_t* /*slotMask*/) {
-    ALOGE("BufferHubConsumer::getReleasedBuffers: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {
-    ALOGE("BufferHubConsumer::setDefaultBufferSize: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setMaxBufferCount(int /*bufferCount*/) {
-    ALOGE("BufferHubConsumer::setMaxBufferCount: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setMaxAcquiredBufferCount(int /*maxAcquiredBuffers*/) {
-    ALOGE("BufferHubConsumer::setMaxAcquiredBufferCount: not implemented.");
-
-    // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to
-    // make IGraphicBufferConsumer_test happy.
-    return NO_ERROR;
-}
-
-status_t BufferHubConsumer::setConsumerName(const String8& /*name*/) {
-    ALOGE("BufferHubConsumer::setConsumerName: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setDefaultBufferFormat(PixelFormat /*defaultFormat*/) {
-    ALOGE("BufferHubConsumer::setDefaultBufferFormat: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setDefaultBufferDataSpace(android_dataspace /*defaultDataSpace*/) {
-    ALOGE("BufferHubConsumer::setDefaultBufferDataSpace: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setConsumerUsageBits(uint64_t /*usage*/) {
-    ALOGE("BufferHubConsumer::setConsumerUsageBits: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setConsumerIsProtected(bool /*isProtected*/) {
-    ALOGE("BufferHubConsumer::setConsumerIsProtected: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setTransformHint(uint32_t /*hint*/) {
-    ALOGE("BufferHubConsumer::setTransformHint: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::getSidebandStream(sp<NativeHandle>* /*outStream*/) const {
-    ALOGE("BufferHubConsumer::getSidebandStream: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::getOccupancyHistory(
-        bool /*forceFlush*/, std::vector<OccupancyTracker::Segment>* /*outHistory*/) {
-    ALOGE("BufferHubConsumer::getOccupancyHistory: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::discardFreeBuffers() {
-    ALOGE("BufferHubConsumer::discardFreeBuffers: not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::dumpState(const String8& /*prefix*/, String8* /*outResult*/) const {
-    ALOGE("BufferHubConsumer::dumpState: not implemented.");
-    return INVALID_OPERATION;
-}
-
-IBinder* BufferHubConsumer::onAsBinder() {
-    ALOGE("BufferHubConsumer::onAsBinder: BufferHubConsumer should never be used as an Binder "
-          "object.");
-    return nullptr;
-}
-
-} // namespace android
diff --git a/libs/gui/BufferHubProducer.cpp b/libs/gui/BufferHubProducer.cpp
deleted file mode 100644
index 1f71e23..0000000
--- a/libs/gui/BufferHubProducer.cpp
+++ /dev/null
@@ -1,868 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <dvr/dvr_api.h>
-#include <gui/BufferHubProducer.h>
-#include <inttypes.h>
-#include <log/log.h>
-#include <system/window.h>
-
-namespace android {
-
-using namespace dvr;
-
-/* static */
-sp<BufferHubProducer> BufferHubProducer::Create(const std::shared_ptr<ProducerQueue>& queue) {
-    sp<BufferHubProducer> producer = new BufferHubProducer;
-    producer->queue_ = queue;
-    return producer;
-}
-
-/* static */
-sp<BufferHubProducer> BufferHubProducer::Create(ProducerQueueParcelable parcelable) {
-    if (!parcelable.IsValid()) {
-        ALOGE("BufferHubProducer::Create: Invalid producer parcelable.");
-        return nullptr;
-    }
-
-    sp<BufferHubProducer> producer = new BufferHubProducer;
-    producer->queue_ = ProducerQueue::Import(parcelable.TakeChannelHandle());
-    return producer;
-}
-
-status_t BufferHubProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
-    ALOGV("requestBuffer: slot=%d", slot);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("requestBuffer: BufferHubProducer has no connected producer");
-        return NO_INIT;
-    }
-
-    if (slot < 0 || slot >= max_buffer_count_) {
-        ALOGE("requestBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
-        return BAD_VALUE;
-    } else if (!buffers_[slot].mBufferState.isDequeued()) {
-        ALOGE("requestBuffer: slot %d is not owned by the producer (state = %s)", slot,
-              buffers_[slot].mBufferState.string());
-        return BAD_VALUE;
-    } else if (buffers_[slot].mGraphicBuffer != nullptr) {
-        ALOGE("requestBuffer: slot %d is not empty.", slot);
-        return BAD_VALUE;
-    } else if (buffers_[slot].mProducerBuffer == nullptr) {
-        ALOGE("requestBuffer: slot %d is not dequeued.", slot);
-        return BAD_VALUE;
-    }
-
-    const auto& producer_buffer = buffers_[slot].mProducerBuffer;
-    sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
-
-    buffers_[slot].mGraphicBuffer = graphic_buffer;
-    buffers_[slot].mRequestBufferCalled = true;
-
-    *buf = graphic_buffer;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::setMaxDequeuedBufferCount(int max_dequeued_buffers) {
-    ALOGV("setMaxDequeuedBufferCount: max_dequeued_buffers=%d", max_dequeued_buffers);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (max_dequeued_buffers <= 0 ||
-        max_dequeued_buffers >
-                int(BufferHubQueue::kMaxQueueCapacity - kDefaultUndequeuedBuffers)) {
-        ALOGE("setMaxDequeuedBufferCount: %d out of range (0, %zu]", max_dequeued_buffers,
-              BufferHubQueue::kMaxQueueCapacity);
-        return BAD_VALUE;
-    }
-
-    // The new dequeued_buffers count should not be violated by the number
-    // of currently dequeued buffers.
-    int dequeued_count = 0;
-    for (const auto& buf : buffers_) {
-        if (buf.mBufferState.isDequeued()) {
-            dequeued_count++;
-        }
-    }
-    if (dequeued_count > max_dequeued_buffers) {
-        ALOGE("setMaxDequeuedBufferCount: the requested dequeued_buffers"
-              "count (%d) exceeds the current dequeued buffer count (%d)",
-              max_dequeued_buffers, dequeued_count);
-        return BAD_VALUE;
-    }
-
-    max_dequeued_buffer_count_ = max_dequeued_buffers;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::setAsyncMode(bool async) {
-    if (async) {
-        // TODO(b/36724099) BufferHubQueue's consumer end always acquires the buffer
-        // automatically and behaves differently from IGraphicBufferConsumer. Thus,
-        // android::BufferQueue's async mode (a.k.a. allocating an additional buffer
-        // to prevent dequeueBuffer from being blocking) technically does not apply
-        // here.
-        //
-        // In Daydream, non-blocking producer side dequeue is guaranteed by careful
-        // buffer consumer implementations. In another word, BufferHubQueue based
-        // dequeueBuffer should never block whether setAsyncMode(true) is set or
-        // not.
-        //
-        // See: IGraphicBufferProducer::setAsyncMode and
-        // BufferQueueProducer::setAsyncMode for more about original implementation.
-        ALOGW("BufferHubProducer::setAsyncMode: BufferHubQueue should always be "
-              "asynchronous. This call makes no effact.");
-        return NO_ERROR;
-    }
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width,
-                                          uint32_t height, PixelFormat format, uint64_t usage,
-                                          uint64_t* /*outBufferAge*/,
-                                          FrameEventHistoryDelta* /* out_timestamps */) {
-    ALOGV("dequeueBuffer: w=%u, h=%u, format=%d, usage=%" PRIu64, width, height, format, usage);
-
-    status_t ret;
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("dequeueBuffer: BufferQueue has no connected producer");
-        return NO_INIT;
-    }
-
-    const uint32_t kLayerCount = 1;
-    if (int32_t(queue_->capacity()) < max_dequeued_buffer_count_ + kDefaultUndequeuedBuffers) {
-        // Lazy allocation. When the capacity of |queue_| has not reached
-        // |max_dequeued_buffer_count_|, allocate new buffer.
-        // TODO(jwcai) To save memory, the really reasonable thing to do is to go
-        // over existing slots and find first existing one to dequeue.
-        ret = AllocateBuffer(width, height, kLayerCount, format, usage);
-        if (ret < 0) return ret;
-    }
-
-    size_t slot = 0;
-    std::shared_ptr<ProducerBuffer> producer_buffer;
-
-    for (size_t retry = 0; retry < BufferHubQueue::kMaxQueueCapacity; retry++) {
-        LocalHandle fence;
-        auto buffer_status = queue_->Dequeue(dequeue_timeout_ms_, &slot, &fence);
-        if (!buffer_status) return NO_MEMORY;
-
-        producer_buffer = buffer_status.take();
-        if (!producer_buffer) return NO_MEMORY;
-
-        if (width == producer_buffer->width() && height == producer_buffer->height() &&
-            uint32_t(format) == producer_buffer->format()) {
-            // The producer queue returns a producer buffer matches the request.
-            break;
-        }
-
-        // Needs reallocation.
-        // TODO(jwcai) Consider use VLOG instead if we find this log is not useful.
-        ALOGI("dequeueBuffer: requested buffer (w=%u, h=%u, format=%u) is different "
-              "from the buffer returned at slot: %zu (w=%u, h=%u, format=%u). Need "
-              "re-allocattion.",
-              width, height, format, slot, producer_buffer->width(), producer_buffer->height(),
-              producer_buffer->format());
-        // Mark the slot as reallocating, so that later we can set
-        // BUFFER_NEEDS_REALLOCATION when the buffer actually get dequeued.
-        buffers_[slot].mIsReallocating = true;
-
-        // Remove the old buffer once the allocation before allocating its
-        // replacement.
-        RemoveBuffer(slot);
-
-        // Allocate a new producer buffer with new buffer configs. Note that if
-        // there are already multiple buffers in the queue, the next one returned
-        // from |queue_->Dequeue| may not be the new buffer we just reallocated.
-        // Retry up to BufferHubQueue::kMaxQueueCapacity times.
-        ret = AllocateBuffer(width, height, kLayerCount, format, usage);
-        if (ret < 0) return ret;
-    }
-
-    // With the BufferHub backed solution. Buffer slot returned from
-    // |queue_->Dequeue| is guaranteed to avaiable for producer's use.
-    // It's either in free state (if the buffer has never been used before) or
-    // in queued state (if the buffer has been dequeued and queued back to
-    // BufferHubQueue).
-    LOG_ALWAYS_FATAL_IF((!buffers_[slot].mBufferState.isFree() &&
-                         !buffers_[slot].mBufferState.isQueued()),
-                        "dequeueBuffer: slot %zu is not free or queued, actual state: %s.", slot,
-                        buffers_[slot].mBufferState.string());
-
-    buffers_[slot].mBufferState.freeQueued();
-    buffers_[slot].mBufferState.dequeue();
-    ALOGV("dequeueBuffer: slot=%zu", slot);
-
-    // TODO(jwcai) Handle fence properly. |BufferHub| has full fence support, we
-    // just need to exopose that through |BufferHubQueue| once we need fence.
-    *out_fence = Fence::NO_FENCE;
-    *out_slot = int(slot);
-    ret = NO_ERROR;
-
-    if (buffers_[slot].mIsReallocating) {
-        ret |= BUFFER_NEEDS_REALLOCATION;
-        buffers_[slot].mIsReallocating = false;
-    }
-
-    return ret;
-}
-
-status_t BufferHubProducer::detachBuffer(int slot) {
-    ALOGV("detachBuffer: slot=%d", slot);
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    return DetachBufferLocked(static_cast<size_t>(slot));
-}
-
-status_t BufferHubProducer::DetachBufferLocked(size_t slot) {
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("detachBuffer: BufferHubProducer is not connected.");
-        return NO_INIT;
-    }
-
-    if (slot >= static_cast<size_t>(max_buffer_count_)) {
-        ALOGE("detachBuffer: slot index %zu out of range [0, %d)", slot, max_buffer_count_);
-        return BAD_VALUE;
-    } else if (!buffers_[slot].mBufferState.isDequeued()) {
-        ALOGE("detachBuffer: slot %zu is not owned by the producer (state = %s)", slot,
-              buffers_[slot].mBufferState.string());
-        return BAD_VALUE;
-    } else if (!buffers_[slot].mRequestBufferCalled) {
-        ALOGE("detachBuffer: buffer in slot %zu has not been requested", slot);
-        return BAD_VALUE;
-    }
-    std::shared_ptr<ProducerBuffer> producer_buffer = queue_->GetBuffer(slot);
-    if (producer_buffer == nullptr || producer_buffer->buffer() == nullptr) {
-        ALOGE("detachBuffer: Invalid ProducerBuffer at slot %zu.", slot);
-        return BAD_VALUE;
-    }
-    sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
-    if (graphic_buffer == nullptr) {
-        ALOGE("detachBuffer: Invalid GraphicBuffer at slot %zu.", slot);
-        return BAD_VALUE;
-    }
-
-    // Remove the ProducerBuffer from the ProducerQueue.
-    status_t error = RemoveBuffer(slot);
-    if (error != NO_ERROR) {
-        ALOGE("detachBuffer: Failed to remove buffer, slot=%zu, error=%d.", slot, error);
-        return error;
-    }
-
-    // Here we need to convert the existing ProducerBuffer into a DetachedBufferHandle and inject
-    // the handle into the GraphicBuffer object at the requested slot.
-    auto status_or_handle = producer_buffer->Detach();
-    if (!status_or_handle.ok()) {
-        ALOGE("detachBuffer: Failed to detach from a ProducerBuffer at slot %zu, error=%d.", slot,
-              status_or_handle.error());
-        return BAD_VALUE;
-    }
-
-    // TODO(b/70912269): Reimplement BufferHubProducer::DetachBufferLocked() once GraphicBuffer can
-    // be directly backed by BufferHub.
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubProducer::detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence) {
-    ALOGV("detachNextBuffer.");
-
-    if (out_buffer == nullptr || out_fence == nullptr) {
-        ALOGE("detachNextBuffer: Invalid parameter: out_buffer=%p, out_fence=%p", out_buffer,
-              out_fence);
-        return BAD_VALUE;
-    }
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("detachNextBuffer: BufferHubProducer is not connected.");
-        return NO_INIT;
-    }
-
-    // detachNextBuffer is equivalent to calling dequeueBuffer, requestBuffer, and detachBuffer in
-    // sequence, except for two things:
-    //
-    // 1) It is unnecessary to know the dimensions, format, or usage of the next buffer, i.e. the
-    // function just returns whatever ProducerBuffer is available from the ProducerQueue and no
-    // buffer allocation or re-allocation will happen.
-    // 2) It will not block, since if it cannot find an appropriate buffer to return, it will return
-    // an error instead.
-    size_t slot = 0;
-    LocalHandle fence;
-
-    // First, dequeue a ProducerBuffer from the ProducerQueue with no timeout. Report error
-    // immediately if ProducerQueue::Dequeue() fails.
-    auto status_or_buffer = queue_->Dequeue(/*timeout=*/0, &slot, &fence);
-    if (!status_or_buffer.ok()) {
-        ALOGE("detachNextBuffer: Failed to dequeue buffer, error=%d.", status_or_buffer.error());
-        return NO_MEMORY;
-    }
-
-    std::shared_ptr<ProducerBuffer> producer_buffer = status_or_buffer.take();
-    if (producer_buffer == nullptr) {
-        ALOGE("detachNextBuffer: Dequeued buffer is null.");
-        return NO_MEMORY;
-    }
-
-    // With the BufferHub backed solution, slot returned from |queue_->Dequeue| is guaranteed to
-    // be available for producer's use. It's either in free state (if the buffer has never been used
-    // before) or in queued state (if the buffer has been dequeued and queued back to
-    // BufferHubQueue).
-    if (!buffers_[slot].mBufferState.isFree() && !buffers_[slot].mBufferState.isQueued()) {
-        ALOGE("detachNextBuffer: slot %zu is not free or queued, actual state: %s.", slot,
-              buffers_[slot].mBufferState.string());
-        return BAD_VALUE;
-    }
-    if (buffers_[slot].mProducerBuffer == nullptr) {
-        ALOGE("detachNextBuffer: ProducerBuffer at slot %zu is null.", slot);
-        return BAD_VALUE;
-    }
-    if (buffers_[slot].mProducerBuffer->id() != producer_buffer->id()) {
-        ALOGE("detachNextBuffer: ProducerBuffer at slot %zu has mismatched id, actual: "
-              "%d, expected: %d.",
-              slot, buffers_[slot].mProducerBuffer->id(), producer_buffer->id());
-        return BAD_VALUE;
-    }
-
-    ALOGV("detachNextBuffer: slot=%zu", slot);
-    buffers_[slot].mBufferState.freeQueued();
-    buffers_[slot].mBufferState.dequeue();
-
-    // Second, request the buffer.
-    sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
-    buffers_[slot].mGraphicBuffer = producer_buffer->buffer()->buffer();
-
-    // Finally, detach the buffer and then return.
-    status_t error = DetachBufferLocked(slot);
-    if (error == NO_ERROR) {
-        *out_fence = new Fence(fence.Release());
-        *out_buffer = graphic_buffer;
-    }
-    return error;
-}
-
-status_t BufferHubProducer::attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) {
-    // In the BufferHub design, all buffers are allocated and owned by the BufferHub. Thus only
-    // GraphicBuffers that are originated from BufferHub can be attached to a BufferHubProducer.
-    ALOGV("queueBuffer: buffer=%p", buffer.get());
-
-    if (out_slot == nullptr) {
-        ALOGE("attachBuffer: out_slot cannot be NULL.");
-        return BAD_VALUE;
-    }
-    if (buffer == nullptr) {
-        ALOGE("attachBuffer: invalid GraphicBuffer.");
-        return BAD_VALUE;
-    }
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("attachBuffer: BufferQueue has no connected producer");
-        return NO_INIT;
-    }
-
-    // Before attaching the buffer, caller is supposed to call
-    // IGraphicBufferProducer::setGenerationNumber to inform the
-    // BufferHubProducer the next generation number.
-    if (buffer->getGenerationNumber() != generation_number_) {
-        ALOGE("attachBuffer: Mismatched generation number, buffer: %u, queue: %u.",
-              buffer->getGenerationNumber(), generation_number_);
-        return BAD_VALUE;
-    }
-
-    // TODO(b/70912269): Reimplement BufferHubProducer::DetachBufferLocked() once GraphicBuffer can
-    // be directly backed by BufferHub.
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubProducer::queueBuffer(int slot, const QueueBufferInput& input,
-                                        QueueBufferOutput* output) {
-    ALOGV("queueBuffer: slot %d", slot);
-
-    if (output == nullptr) {
-        return BAD_VALUE;
-    }
-
-    int64_t timestamp;
-    bool is_auto_timestamp;
-    android_dataspace dataspace;
-    Rect crop(Rect::EMPTY_RECT);
-    int scaling_mode;
-    uint32_t transform;
-    sp<Fence> fence;
-
-    input.deflate(&timestamp, &is_auto_timestamp, &dataspace, &crop, &scaling_mode, &transform,
-                  &fence);
-
-    // Check input scaling mode is valid.
-    switch (scaling_mode) {
-        case NATIVE_WINDOW_SCALING_MODE_FREEZE:
-        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
-        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
-        case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
-            break;
-        default:
-            ALOGE("queueBuffer: unknown scaling mode %d", scaling_mode);
-            return BAD_VALUE;
-    }
-
-    // Check input fence is valid.
-    if (fence == nullptr) {
-        ALOGE("queueBuffer: fence is NULL");
-        return BAD_VALUE;
-    }
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("queueBuffer: BufferQueue has no connected producer");
-        return NO_INIT;
-    }
-
-    if (slot < 0 || slot >= max_buffer_count_) {
-        ALOGE("queueBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
-        return BAD_VALUE;
-    } else if (!buffers_[slot].mBufferState.isDequeued()) {
-        ALOGE("queueBuffer: slot %d is not owned by the producer (state = %s)", slot,
-              buffers_[slot].mBufferState.string());
-        return BAD_VALUE;
-    } else if ((!buffers_[slot].mRequestBufferCalled || buffers_[slot].mGraphicBuffer == nullptr)) {
-        ALOGE("queueBuffer: slot %d is not requested (mRequestBufferCalled=%d, "
-              "mGraphicBuffer=%p)",
-              slot, buffers_[slot].mRequestBufferCalled, buffers_[slot].mGraphicBuffer.get());
-        return BAD_VALUE;
-    }
-
-    // Post the producer buffer with timestamp in the metadata.
-    const auto& producer_buffer = buffers_[slot].mProducerBuffer;
-
-    // Check input crop is not out of boundary of current buffer.
-    Rect buffer_rect(producer_buffer->width(), producer_buffer->height());
-    Rect cropped_rect(Rect::EMPTY_RECT);
-    crop.intersect(buffer_rect, &cropped_rect);
-    if (cropped_rect != crop) {
-        ALOGE("queueBuffer: slot %d has out-of-boundary crop.", slot);
-        return BAD_VALUE;
-    }
-
-    LocalHandle fence_fd(fence->isValid() ? fence->dup() : -1);
-
-    DvrNativeBufferMetadata meta_data;
-    meta_data.timestamp = timestamp;
-    meta_data.is_auto_timestamp = int32_t(is_auto_timestamp);
-    meta_data.dataspace = int32_t(dataspace);
-    meta_data.crop_left = crop.left;
-    meta_data.crop_top = crop.top;
-    meta_data.crop_right = crop.right;
-    meta_data.crop_bottom = crop.bottom;
-    meta_data.scaling_mode = int32_t(scaling_mode);
-    meta_data.transform = int32_t(transform);
-
-    producer_buffer->PostAsync(&meta_data, fence_fd);
-    buffers_[slot].mBufferState.queue();
-
-    output->width = producer_buffer->width();
-    output->height = producer_buffer->height();
-    output->transformHint = 0; // default value, we don't use it yet.
-
-    // |numPendingBuffers| counts of the number of buffers that has been enqueued
-    // by the producer but not yet acquired by the consumer. Due to the nature
-    // of BufferHubQueue design, this is hard to trace from the producer's client
-    // side, but it's safe to assume it's zero.
-    output->numPendingBuffers = 0;
-
-    // Note that we are not setting nextFrameNumber here as it seems to be only
-    // used by surface flinger. See more at b/22802885, ag/791760.
-    output->nextFrameNumber = 0;
-
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
-    ALOGV(__FUNCTION__);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ == kNoConnectedApi) {
-        ALOGE("cancelBuffer: BufferQueue has no connected producer");
-        return NO_INIT;
-    }
-
-    if (slot < 0 || slot >= max_buffer_count_) {
-        ALOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
-        return BAD_VALUE;
-    } else if (!buffers_[slot].mBufferState.isDequeued()) {
-        ALOGE("cancelBuffer: slot %d is not owned by the producer (state = %s)", slot,
-              buffers_[slot].mBufferState.string());
-        return BAD_VALUE;
-    } else if (fence == nullptr) {
-        ALOGE("cancelBuffer: fence is NULL");
-        return BAD_VALUE;
-    }
-
-    auto producer_buffer = buffers_[slot].mProducerBuffer;
-    queue_->Enqueue(producer_buffer, size_t(slot), 0U);
-    buffers_[slot].mBufferState.cancel();
-    buffers_[slot].mFence = fence;
-    ALOGV("cancelBuffer: slot %d", slot);
-
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::query(int what, int* out_value) {
-    ALOGV(__FUNCTION__);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (out_value == nullptr) {
-        ALOGE("query: out_value was NULL");
-        return BAD_VALUE;
-    }
-
-    int value = 0;
-    switch (what) {
-        case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
-            // TODO(b/36187402) This should be the maximum number of buffers that this
-            // producer queue's consumer can acquire. Set to be at least one. Need to
-            // find a way to set from the consumer side.
-            value = kDefaultUndequeuedBuffers;
-            break;
-        case NATIVE_WINDOW_BUFFER_AGE:
-            value = 0;
-            break;
-        case NATIVE_WINDOW_WIDTH:
-            value = int32_t(queue_->default_width());
-            break;
-        case NATIVE_WINDOW_HEIGHT:
-            value = int32_t(queue_->default_height());
-            break;
-        case NATIVE_WINDOW_FORMAT:
-            value = int32_t(queue_->default_format());
-            break;
-        case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
-            // BufferHubQueue is always operating in async mode, thus semantically
-            // consumer can never be running behind. See BufferQueueCore.cpp core
-            // for more information about the original meaning of this flag.
-            value = 0;
-            break;
-        case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
-            // TODO(jwcai) This is currently not implement as we don't need
-            // IGraphicBufferConsumer parity.
-            value = 0;
-            break;
-        case NATIVE_WINDOW_DEFAULT_DATASPACE:
-            // TODO(jwcai) Return the default value android::BufferQueue is using as
-            // there is no way dvr::ConsumerQueue can set it.
-            value = 0; // HAL_DATASPACE_UNKNOWN
-            break;
-        case NATIVE_WINDOW_STICKY_TRANSFORM:
-            // TODO(jwcai) Return the default value android::BufferQueue is using as
-            // there is no way dvr::ConsumerQueue can set it.
-            value = 0;
-            break;
-        case NATIVE_WINDOW_CONSUMER_IS_PROTECTED:
-            // In Daydream's implementation, the consumer end (i.e. VR Compostior)
-            // knows how to handle protected buffers.
-            value = 1;
-            break;
-        default:
-            return BAD_VALUE;
-    }
-
-    ALOGV("query: key=%d, v=%d", what, value);
-    *out_value = value;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::connect(const sp<IProducerListener>& /* listener */, int api,
-                                    bool /* producer_controlled_by_app */,
-                                    QueueBufferOutput* output) {
-    // Consumer interaction are actually handled by buffer hub, and we need
-    // to maintain consumer operations here. We only need to perform basic input
-    // parameter checks here.
-    ALOGV(__FUNCTION__);
-
-    if (output == nullptr) {
-        return BAD_VALUE;
-    }
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (connected_api_ != kNoConnectedApi) {
-        return BAD_VALUE;
-    }
-
-    if (!queue_->is_connected()) {
-        ALOGE("BufferHubProducer::connect: This BufferHubProducer is not "
-              "connected to bufferhud. Has it been taken out as a parcelable?");
-        return BAD_VALUE;
-    }
-
-    switch (api) {
-        case NATIVE_WINDOW_API_EGL:
-        case NATIVE_WINDOW_API_CPU:
-        case NATIVE_WINDOW_API_MEDIA:
-        case NATIVE_WINDOW_API_CAMERA:
-            connected_api_ = api;
-
-            output->width = queue_->default_width();
-            output->height = queue_->default_height();
-
-            // default values, we don't use them yet.
-            output->transformHint = 0;
-            output->numPendingBuffers = 0;
-            output->nextFrameNumber = 0;
-            output->bufferReplaced = false;
-
-            break;
-        default:
-            ALOGE("BufferHubProducer::connect: unknow API %d", api);
-            return BAD_VALUE;
-    }
-
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::disconnect(int api, DisconnectMode /*mode*/) {
-    // Consumer interaction are actually handled by buffer hub, and we need
-    // to maintain consumer operations here.  We only need to perform basic input
-    // parameter checks here.
-    ALOGV(__FUNCTION__);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-
-    if (kNoConnectedApi == connected_api_) {
-        return NO_INIT;
-    } else if (api != connected_api_) {
-        return BAD_VALUE;
-    }
-
-    FreeAllBuffers();
-    connected_api_ = kNoConnectedApi;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::setSidebandStream(const sp<NativeHandle>& stream) {
-    if (stream != nullptr) {
-        // TODO(jwcai) Investigate how is is used, maybe use BufferHubBuffer's
-        // metadata.
-        ALOGE("SidebandStream is not currently supported.");
-        return INVALID_OPERATION;
-    }
-    return NO_ERROR;
-}
-
-void BufferHubProducer::allocateBuffers(uint32_t /* width */, uint32_t /* height */,
-                                        PixelFormat /* format */, uint64_t /* usage */) {
-    // TODO(jwcai) |allocateBuffers| aims to preallocate up to the maximum number
-    // of buffers permitted by the current BufferQueue configuration (aka
-    // |max_buffer_count_|).
-    ALOGE("BufferHubProducer::allocateBuffers not implemented.");
-}
-
-status_t BufferHubProducer::allowAllocation(bool /* allow */) {
-    ALOGE("BufferHubProducer::allowAllocation not implemented.");
-    return INVALID_OPERATION;
-}
-
-status_t BufferHubProducer::setGenerationNumber(uint32_t generation_number) {
-    ALOGV(__FUNCTION__);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-    generation_number_ = generation_number;
-    return NO_ERROR;
-}
-
-String8 BufferHubProducer::getConsumerName() const {
-    // BufferHub based implementation could have one to many producer/consumer
-    // relationship, thus |getConsumerName| from the producer side does not
-    // make any sense.
-    ALOGE("BufferHubProducer::getConsumerName not supported.");
-    return String8("BufferHubQueue::StubConsumer");
-}
-
-status_t BufferHubProducer::setSharedBufferMode(bool shared_buffer_mode) {
-    if (shared_buffer_mode) {
-        ALOGE("BufferHubProducer::setSharedBufferMode(true) is not supported.");
-        // TODO(b/36373181) Front buffer mode for buffer hub queue as ANativeWindow.
-        return INVALID_OPERATION;
-    }
-    // Setting to default should just work as a no-op.
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::setAutoRefresh(bool auto_refresh) {
-    if (auto_refresh) {
-        ALOGE("BufferHubProducer::setAutoRefresh(true) is not supported.");
-        return INVALID_OPERATION;
-    }
-    // Setting to default should just work as a no-op.
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::setDequeueTimeout(nsecs_t timeout) {
-    ALOGV(__FUNCTION__);
-
-    std::unique_lock<std::mutex> lock(mutex_);
-    dequeue_timeout_ms_ = static_cast<int>(timeout / (1000 * 1000));
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::getLastQueuedBuffer(sp<GraphicBuffer>* /* out_buffer */,
-                                                sp<Fence>* /* out_fence */,
-                                                float /*out_transform_matrix*/[16]) {
-    ALOGE("BufferHubProducer::getLastQueuedBuffer not implemented.");
-    return INVALID_OPERATION;
-}
-
-void BufferHubProducer::getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) {
-    ALOGE("BufferHubProducer::getFrameTimestamps not implemented.");
-}
-
-status_t BufferHubProducer::getUniqueId(uint64_t* out_id) const {
-    ALOGV(__FUNCTION__);
-
-    *out_id = unique_id_;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::getConsumerUsage(uint64_t* out_usage) const {
-    ALOGV(__FUNCTION__);
-
-    // same value as returned by querying NATIVE_WINDOW_CONSUMER_USAGE_BITS
-    *out_usage = 0;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::TakeAsParcelable(ProducerQueueParcelable* out_parcelable) {
-    if (!out_parcelable || out_parcelable->IsValid()) return BAD_VALUE;
-
-    if (connected_api_ != kNoConnectedApi) {
-        ALOGE("BufferHubProducer::TakeAsParcelable: BufferHubProducer has "
-              "connected client. Must disconnect first.");
-        return BAD_VALUE;
-    }
-
-    if (!queue_->is_connected()) {
-        ALOGE("BufferHubProducer::TakeAsParcelable: This BufferHubProducer "
-              "is not connected to bufferhud. Has it been taken out as a "
-              "parcelable?");
-        return BAD_VALUE;
-    }
-
-    auto status = queue_->TakeAsParcelable();
-    if (!status) {
-        ALOGE("BufferHubProducer::TakeAsParcelable: Failed to take out "
-              "ProducuerQueueParcelable from the producer queue, error: %s.",
-              status.GetErrorMessage().c_str());
-        return BAD_VALUE;
-    }
-
-    *out_parcelable = status.take();
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
-                                           PixelFormat format, uint64_t usage) {
-    auto status = queue_->AllocateBuffer(width, height, layer_count, uint32_t(format), usage);
-    if (!status) {
-        ALOGE("BufferHubProducer::AllocateBuffer: Failed to allocate buffer: %s",
-              status.GetErrorMessage().c_str());
-        return NO_MEMORY;
-    }
-
-    size_t slot = status.get();
-    auto producer_buffer = queue_->GetBuffer(slot);
-
-    LOG_ALWAYS_FATAL_IF(producer_buffer == nullptr,
-                        "Failed to get the producer buffer at slot: %zu", slot);
-
-    buffers_[slot].mProducerBuffer = producer_buffer;
-
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::RemoveBuffer(size_t slot) {
-    auto status = queue_->RemoveBuffer(slot);
-    if (!status) {
-        ALOGE("BufferHubProducer::RemoveBuffer: Failed to remove buffer at slot: %zu, error: %s.",
-              slot, status.GetErrorMessage().c_str());
-        return INVALID_OPERATION;
-    }
-
-    // Reset in memory objects related the the buffer.
-    buffers_[slot].mProducerBuffer = nullptr;
-    buffers_[slot].mBufferState.detachProducer();
-    buffers_[slot].mFence = Fence::NO_FENCE;
-    buffers_[slot].mGraphicBuffer = nullptr;
-    buffers_[slot].mRequestBufferCalled = false;
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::FreeAllBuffers() {
-    for (size_t slot = 0; slot < BufferHubQueue::kMaxQueueCapacity; slot++) {
-        // Reset in memory objects related the the buffer.
-        buffers_[slot].mProducerBuffer = nullptr;
-        buffers_[slot].mBufferState.reset();
-        buffers_[slot].mFence = Fence::NO_FENCE;
-        buffers_[slot].mGraphicBuffer = nullptr;
-        buffers_[slot].mRequestBufferCalled = false;
-    }
-
-    auto status = queue_->FreeAllBuffers();
-    if (!status) {
-        ALOGE("BufferHubProducer::FreeAllBuffers: Failed to free all buffers on "
-              "the queue: %s",
-              status.GetErrorMessage().c_str());
-    }
-
-    if (queue_->capacity() != 0 || queue_->count() != 0) {
-        LOG_ALWAYS_FATAL("BufferHubProducer::FreeAllBuffers: Not all buffers are freed.");
-    }
-
-    return NO_ERROR;
-}
-
-status_t BufferHubProducer::exportToParcel(Parcel* parcel) {
-    status_t res = TakeAsParcelable(&pending_producer_parcelable_);
-    if (res != NO_ERROR) return res;
-
-    if (!pending_producer_parcelable_.IsValid()) {
-        ALOGE("BufferHubProducer::exportToParcel: Invalid parcelable object.");
-        return BAD_VALUE;
-    }
-
-    res = parcel->writeUint32(USE_BUFFER_HUB);
-    if (res != NO_ERROR) {
-        ALOGE("BufferHubProducer::exportToParcel: Cannot write magic, res=%d.", res);
-        return res;
-    }
-
-    return pending_producer_parcelable_.writeToParcel(parcel);
-}
-
-IBinder* BufferHubProducer::onAsBinder() {
-    ALOGE("BufferHubProducer::onAsBinder: BufferHubProducer should never be used as an Binder "
-          "object.");
-    return nullptr;
-}
-
-} // namespace android
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index c1d92a2..66cad03 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -18,11 +18,6 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 //#define LOG_NDEBUG 0
 
-#ifndef NO_BUFFERHUB
-#include <gui/BufferHubConsumer.h>
-#include <gui/BufferHubProducer.h>
-#endif
-
 #include <gui/BufferQueue.h>
 #include <gui/BufferQueueConsumer.h>
 #include <gui/BufferQueueCore.h>
@@ -127,32 +122,4 @@
     *outConsumer = consumer;
 }
 
-#ifndef NO_BUFFERHUB
-void BufferQueue::createBufferHubQueue(sp<IGraphicBufferProducer>* outProducer,
-                                       sp<IGraphicBufferConsumer>* outConsumer) {
-    LOG_ALWAYS_FATAL_IF(outProducer == nullptr, "BufferQueue: outProducer must not be NULL");
-    LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BufferQueue: outConsumer must not be NULL");
-
-    sp<IGraphicBufferProducer> producer;
-    sp<IGraphicBufferConsumer> consumer;
-
-    dvr::ProducerQueueConfigBuilder configBuilder;
-    std::shared_ptr<dvr::ProducerQueue> producerQueue =
-            dvr::ProducerQueue::Create(configBuilder.Build(), dvr::UsagePolicy{});
-    LOG_ALWAYS_FATAL_IF(producerQueue == nullptr, "BufferQueue: failed to create ProducerQueue.");
-
-    std::shared_ptr<dvr::ConsumerQueue> consumerQueue = producerQueue->CreateConsumerQueue();
-    LOG_ALWAYS_FATAL_IF(consumerQueue == nullptr, "BufferQueue: failed to create ConsumerQueue.");
-
-    producer = BufferHubProducer::Create(producerQueue);
-    consumer = BufferHubConsumer::Create(consumerQueue);
-
-    LOG_ALWAYS_FATAL_IF(producer == nullptr, "BufferQueue: failed to create BufferQueueProducer");
-    LOG_ALWAYS_FATAL_IF(consumer == nullptr, "BufferQueue: failed to create BufferQueueConsumer");
-
-    *outProducer = producer;
-    *outConsumer = consumer;
-}
-#endif
-
 }; // namespace android
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 797069c..918ff2d 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -27,10 +27,6 @@
 #include <binder/Parcel.h>
 #include <binder/IInterface.h>
 
-#ifndef NO_BUFFERHUB
-#include <gui/BufferHubProducer.h>
-#endif
-
 #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
 #include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
 #include <gui/BufferQueueDefs.h>
@@ -1012,17 +1008,7 @@
         }
         case USE_BUFFER_HUB: {
             ALOGE("createFromParcel: BufferHub not implemented.");
-#ifndef NO_BUFFERHUB
-            dvr::ProducerQueueParcelable producerParcelable;
-            res = producerParcelable.readFromParcel(parcel);
-            if (res != NO_ERROR) {
-                ALOGE("createFromParcel: Failed to read from parcel, error=%d", res);
-                return nullptr;
-            }
-            return BufferHubProducer::Create(std::move(producerParcelable));
-#else
             return nullptr;
-#endif
         }
         default: {
             ALOGE("createFromParcel: Unexpected mgaic: 0x%x.", outMagic);
diff --git a/libs/gui/include/gui/BufferHubConsumer.h b/libs/gui/include/gui/BufferHubConsumer.h
deleted file mode 100644
index d380770..0000000
--- a/libs/gui/include/gui/BufferHubConsumer.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_GUI_BUFFERHUBCONSUMER_H_
-#define ANDROID_GUI_BUFFERHUBCONSUMER_H_
-
-#include <gui/IGraphicBufferConsumer.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/buffer_hub_queue_parcelable.h>
-
-namespace android {
-
-class BufferHubConsumer : public IGraphicBufferConsumer {
-public:
-    // Creates a BufferHubConsumer instance by importing an existing producer queue.
-    static sp<BufferHubConsumer> Create(const std::shared_ptr<dvr::ConsumerQueue>& queue);
-
-    // Creates a BufferHubConsumer instance by importing an existing producer
-    // parcelable. Note that this call takes the ownership of the parcelable
-    // object and is guaranteed to succeed if parcelable object is valid.
-    static sp<BufferHubConsumer> Create(dvr::ConsumerQueueParcelable parcelable);
-
-    // See |IGraphicBufferConsumer::acquireBuffer|
-    status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen,
-                           uint64_t maxFrameNumber = 0) override;
-
-    // See |IGraphicBufferConsumer::detachBuffer|
-    status_t detachBuffer(int slot) override;
-
-    // See |IGraphicBufferConsumer::attachBuffer|
-    status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer) override;
-
-    // See |IGraphicBufferConsumer::releaseBuffer|
-    status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display, EGLSyncKHR fence,
-                           const sp<Fence>& releaseFence) override;
-
-    // See |IGraphicBufferConsumer::consumerConnect|
-    status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) override;
-
-    // See |IGraphicBufferConsumer::consumerDisconnect|
-    status_t consumerDisconnect() override;
-
-    // See |IGraphicBufferConsumer::getReleasedBuffers|
-    status_t getReleasedBuffers(uint64_t* slotMask) override;
-
-    // See |IGraphicBufferConsumer::setDefaultBufferSize|
-    status_t setDefaultBufferSize(uint32_t w, uint32_t h) override;
-
-    // See |IGraphicBufferConsumer::setMaxBufferCount|
-    status_t setMaxBufferCount(int bufferCount) override;
-
-    // See |IGraphicBufferConsumer::setMaxAcquiredBufferCount|
-    status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) override;
-
-    // See |IGraphicBufferConsumer::setConsumerName|
-    status_t setConsumerName(const String8& name) override;
-
-    // See |IGraphicBufferConsumer::setDefaultBufferFormat|
-    status_t setDefaultBufferFormat(PixelFormat defaultFormat) override;
-
-    // See |IGraphicBufferConsumer::setDefaultBufferDataSpace|
-    status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace) override;
-
-    // See |IGraphicBufferConsumer::setConsumerUsageBits|
-    status_t setConsumerUsageBits(uint64_t usage) override;
-
-    // See |IGraphicBufferConsumer::setConsumerIsProtected|
-    status_t setConsumerIsProtected(bool isProtected) override;
-
-    // See |IGraphicBufferConsumer::setTransformHint|
-    status_t setTransformHint(uint32_t hint) override;
-
-    // See |IGraphicBufferConsumer::getSidebandStream|
-    status_t getSidebandStream(sp<NativeHandle>* outStream) const override;
-
-    // See |IGraphicBufferConsumer::getOccupancyHistory|
-    status_t getOccupancyHistory(bool forceFlush,
-                                 std::vector<OccupancyTracker::Segment>* outHistory) override;
-
-    // See |IGraphicBufferConsumer::discardFreeBuffers|
-    status_t discardFreeBuffers() override;
-
-    // See |IGraphicBufferConsumer::dumpState|
-    status_t dumpState(const String8& prefix, String8* outResult) const override;
-
-    // BufferHubConsumer provides its own logic to cast to a binder object.
-    IBinder* onAsBinder() override;
-
-private:
-    // Private constructor to force use of |Create|.
-    BufferHubConsumer() = default;
-
-    // Concrete implementation backed by BufferHubBuffer.
-    std::shared_ptr<dvr::ConsumerQueue> mQueue;
-};
-
-} // namespace android
-
-#endif // ANDROID_GUI_BUFFERHUBCONSUMER_H_
diff --git a/libs/gui/include/gui/BufferHubProducer.h b/libs/gui/include/gui/BufferHubProducer.h
deleted file mode 100644
index 0e925ce..0000000
--- a/libs/gui/include/gui/BufferHubProducer.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_GUI_BUFFERHUBPRODUCER_H_
-#define ANDROID_GUI_BUFFERHUBPRODUCER_H_
-
-#include <gui/BufferSlot.h>
-#include <gui/IGraphicBufferProducer.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/buffer_hub_queue_parcelable.h>
-
-namespace android {
-
-class BufferHubProducer : public IGraphicBufferProducer {
-public:
-    static constexpr int kNoConnectedApi = -1;
-
-    // TODO(b/36187402) The actual implementation of BufferHubQueue's consumer
-    // side logic doesn't limit the number of buffer it can acquire
-    // simultaneously. We need a way for consumer logic to configure and enforce
-    // that.
-    static constexpr int kDefaultUndequeuedBuffers = 1;
-
-    // Creates a BufferHubProducer instance by importing an existing prodcuer
-    // queue.
-    static sp<BufferHubProducer> Create(const std::shared_ptr<dvr::ProducerQueue>& producer);
-
-    // Creates a BufferHubProducer instance by importing an existing prodcuer
-    // parcelable. Note that this call takes the ownership of the parcelable
-    // object and is guaranteed to succeed if parcelable object is valid.
-    static sp<BufferHubProducer> Create(dvr::ProducerQueueParcelable parcelable);
-
-    // See |IGraphicBufferProducer::requestBuffer|
-    status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override;
-
-    // For the BufferHub based implementation. All buffers in the queue are
-    // allowed to be dequeued from the consumer side. It call always returns
-    // 0 for |NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS| query. Thus setting
-    // |max_dequeued_buffers| here can be considered the same as setting queue
-    // capacity.
-    //
-    // See |IGraphicBufferProducer::setMaxDequeuedBufferCount| for more info
-    status_t setMaxDequeuedBufferCount(int max_dequeued_buffers) override;
-
-    // See |IGraphicBufferProducer::setAsyncMode|
-    status_t setAsyncMode(bool async) override;
-
-    // See |IGraphicBufferProducer::dequeueBuffer|
-    status_t dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width, uint32_t height,
-                           PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
-                           FrameEventHistoryDelta* outTimestamps) override;
-
-    // See |IGraphicBufferProducer::detachBuffer|
-    status_t detachBuffer(int slot) override;
-
-    // See |IGraphicBufferProducer::detachNextBuffer|
-    status_t detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence) override;
-
-    // See |IGraphicBufferProducer::attachBuffer|
-    status_t attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) override;
-
-    // See |IGraphicBufferProducer::queueBuffer|
-    status_t queueBuffer(int slot, const QueueBufferInput& input,
-                         QueueBufferOutput* output) override;
-
-    // See |IGraphicBufferProducer::cancelBuffer|
-    status_t cancelBuffer(int slot, const sp<Fence>& fence) override;
-
-    // See |IGraphicBufferProducer::query|
-    status_t query(int what, int* out_value) override;
-
-    // See |IGraphicBufferProducer::connect|
-    status_t connect(const sp<IProducerListener>& listener, int api,
-                     bool producer_controlled_by_app, QueueBufferOutput* output) override;
-
-    // See |IGraphicBufferProducer::disconnect|
-    status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api) override;
-
-    // See |IGraphicBufferProducer::setSidebandStream|
-    status_t setSidebandStream(const sp<NativeHandle>& stream) override;
-
-    // See |IGraphicBufferProducer::allocateBuffers|
-    void allocateBuffers(uint32_t width, uint32_t height, PixelFormat format,
-                         uint64_t usage) override;
-
-    // See |IGraphicBufferProducer::allowAllocation|
-    status_t allowAllocation(bool allow) override;
-
-    // See |IGraphicBufferProducer::setGenerationNumber|
-    status_t setGenerationNumber(uint32_t generation_number) override;
-
-    // See |IGraphicBufferProducer::getConsumerName|
-    String8 getConsumerName() const override;
-
-    // See |IGraphicBufferProducer::setSharedBufferMode|
-    status_t setSharedBufferMode(bool shared_buffer_mode) override;
-
-    // See |IGraphicBufferProducer::setAutoRefresh|
-    status_t setAutoRefresh(bool auto_refresh) override;
-
-    // See |IGraphicBufferProducer::setDequeueTimeout|
-    status_t setDequeueTimeout(nsecs_t timeout) override;
-
-    // See |IGraphicBufferProducer::getLastQueuedBuffer|
-    status_t getLastQueuedBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence,
-                                 float out_transform_matrix[16]) override;
-
-    // See |IGraphicBufferProducer::getFrameTimestamps|
-    void getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) override;
-
-    // See |IGraphicBufferProducer::getUniqueId|
-    status_t getUniqueId(uint64_t* out_id) const override;
-
-    // See |IGraphicBufferProducer::getConsumerUsage|
-    status_t getConsumerUsage(uint64_t* out_usage) const override;
-
-    // Takes out the current producer as a binder parcelable object. Note that the
-    // producer must be disconnected to be exportable. After successful export,
-    // the producer queue can no longer be connected again. Returns NO_ERROR when
-    // takeout is successful and out_parcelable will hold the new parcelable
-    // object. Also note that out_parcelable cannot be NULL and must points to an
-    // invalid parcelable.
-    status_t TakeAsParcelable(dvr::ProducerQueueParcelable* out_parcelable);
-
-    IBinder* onAsBinder() override;
-
-protected:
-    // See |IGraphicBufferProducer::exportToParcel|
-    status_t exportToParcel(Parcel* parcel) override;
-
-private:
-    using LocalHandle = pdx::LocalHandle;
-
-    // Private constructor to force use of |Create|.
-    BufferHubProducer() {}
-
-    static uint64_t genUniqueId() {
-        static std::atomic<uint32_t> counter{0};
-        static uint64_t id = static_cast<uint64_t>(getpid()) << 32;
-        return id | counter++;
-    }
-
-    // Allocate new buffer through BufferHub and add it into |queue_| for
-    // bookkeeping.
-    status_t AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
-                            PixelFormat format, uint64_t usage);
-
-    // Remove a buffer via BufferHubRPC.
-    status_t RemoveBuffer(size_t slot);
-
-    // Free all buffers which are owned by the prodcuer. Note that if graphic
-    // buffers are acquired by the consumer, we can't .
-    status_t FreeAllBuffers();
-
-    // Helper function that implements the detachBuffer() call, but assuming |mutex_| has been
-    // locked already.
-    status_t DetachBufferLocked(size_t slot);
-
-    // Concreate implementation backed by BufferHubBuffer.
-    std::shared_ptr<dvr::ProducerQueue> queue_;
-
-    // Mutex for thread safety.
-    std::mutex mutex_;
-
-    // Connect client API, should be one of the NATIVE_WINDOW_API_* flags.
-    int connected_api_{kNoConnectedApi};
-
-    // |max_buffer_count_| sets the capacity of the underlying buffer queue.
-    int32_t max_buffer_count_{dvr::BufferHubQueue::kMaxQueueCapacity};
-
-    // |max_dequeued_buffer_count_| set the maximum number of buffers that can
-    // be dequeued at the same momment.
-    int32_t max_dequeued_buffer_count_{1};
-
-    // Sets how long dequeueBuffer or attachBuffer will block if a buffer or
-    // slot is not yet available. The timeout is stored in milliseconds.
-    int dequeue_timeout_ms_{dvr::BufferHubQueue::kNoTimeOut};
-
-    // |generation_number_| stores the current generation number of the attached
-    // producer. Any attempt to attach a buffer with a different generation
-    // number will fail.
-    // TOOD(b/38137191) Currently not used as we don't support
-    // IGraphicBufferProducer::detachBuffer.
-    uint32_t generation_number_{0};
-
-    // |buffers_| stores the buffers that have been dequeued from
-    // |dvr::BufferHubQueue|, It is initialized to invalid buffers, and gets
-    // filled in with the result of |Dequeue|.
-    // TODO(jwcai) The buffer allocated to a slot will also be replaced if the
-    // requested buffer usage or geometry differs from that of the buffer
-    // allocated to a slot.
-    struct BufferHubSlot : public BufferSlot {
-        BufferHubSlot() : mProducerBuffer(nullptr), mIsReallocating(false) {}
-        // BufferSlot comes from android framework, using m prefix to comply with
-        // the name convention with the reset of data fields from BufferSlot.
-        std::shared_ptr<dvr::ProducerBuffer> mProducerBuffer;
-        bool mIsReallocating;
-    };
-    BufferHubSlot buffers_[dvr::BufferHubQueue::kMaxQueueCapacity];
-
-    // A uniqueId used by IGraphicBufferProducer interface.
-    const uint64_t unique_id_{genUniqueId()};
-
-    // A pending parcelable object which keeps the bufferhub channel alive.
-    dvr::ProducerQueueParcelable pending_producer_parcelable_;
-};
-
-} // namespace android
-
-#endif // ANDROID_GUI_BUFFERHUBPRODUCER_H_
diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h
index 91f80d2..690587f 100644
--- a/libs/gui/include/gui/BufferQueue.h
+++ b/libs/gui/include/gui/BufferQueue.h
@@ -82,12 +82,6 @@
             sp<IGraphicBufferConsumer>* outConsumer,
             bool consumerIsSurfaceFlinger = false);
 
-#ifndef NO_BUFFERHUB
-    // Creates an IGraphicBufferProducer and IGraphicBufferConsumer pair backed by BufferHub.
-    static void createBufferHubQueue(sp<IGraphicBufferProducer>* outProducer,
-                                     sp<IGraphicBufferConsumer>* outConsumer);
-#endif
-
     BufferQueue() = delete; // Create through createBufferQueue
 };
 
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index fc68ad2..fa54c7d 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -92,39 +92,6 @@
     header_libs: ["libsurfaceflinger_headers"],
 }
 
-// Build a separate binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
-// This test has a main method, and requires a separate binary to be built.
-// To add move tests like this, just add additional cc_test statements,
-// as opposed to adding more source files to this one.
-cc_test {
-    name: "SurfaceParcelable_test",
-    test_suites: ["device-tests"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    srcs: [
-        "SurfaceParcelable_test.cpp",
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libbinder",
-        "libcutils",
-        "libgui",
-        "libui",
-        "libutils",
-        "libbufferhubqueue", // TODO(b/70046255): Remove these once BufferHub is integrated into libgui.
-        "libpdx_default_transport",
-    ],
-
-    header_libs: [
-        "libdvr_headers",
-    ],
-}
-
 cc_test {
     name: "SamplingDemo",
 
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index 2af2fe1..3427731 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -42,10 +42,6 @@
 #define TEST_CONTROLLED_BY_APP false
 #define TEST_PRODUCER_USAGE_BITS (0)
 
-#ifndef USE_BUFFER_HUB_AS_BUFFER_QUEUE
-#define USE_BUFFER_HUB_AS_BUFFER_QUEUE 0
-#endif
-
 namespace android {
 
 namespace {
@@ -77,7 +73,6 @@
     // Enums to control which IGraphicBufferProducer backend to test.
     enum IGraphicBufferProducerTestCode {
         USE_BUFFER_QUEUE_PRODUCER = 0,
-        USE_BUFFER_HUB_PRODUCER,
     };
 }; // namespace anonymous
 
@@ -99,10 +94,6 @@
                 BufferQueue::createBufferQueue(&mProducer, &mConsumer);
                 break;
             }
-            case USE_BUFFER_HUB_PRODUCER: {
-                BufferQueue::createBufferHubQueue(&mProducer, &mConsumer);
-                break;
-            }
             default: {
                 // Should never reach here.
                 LOG_ALWAYS_FATAL("Invalid test params: %u", GetParam());
@@ -880,11 +871,6 @@
 }
 
 TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Succeeds) {
-    if (GetParam() == USE_BUFFER_HUB_PRODUCER) {
-        // TODO(b/36724099): Add support for BufferHubProducer::setAsyncMode(true)
-        return;
-    }
-
     ASSERT_OK(mConsumer->setMaxAcquiredBufferCount(1)) << "maxAcquire: " << 1;
     ASSERT_NO_FATAL_FAILURE(ConnectProducer());
     ASSERT_OK(mProducer->setAsyncMode(true)) << "async mode: " << true;
@@ -1117,14 +1103,7 @@
     }
 }
 
-#if USE_BUFFER_HUB_AS_BUFFER_QUEUE
-INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
-                        ::testing::Values(USE_BUFFER_QUEUE_PRODUCER, USE_BUFFER_HUB_PRODUCER));
-#else
-// TODO(b/70046255): Remove the #ifdef here and always tests both backends once BufferHubQueue can
-// pass all existing libgui tests.
 INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
                         ::testing::Values(USE_BUFFER_QUEUE_PRODUCER));
-#endif
 
 } // namespace android
diff --git a/libs/gui/tests/SurfaceParcelable_test.cpp b/libs/gui/tests/SurfaceParcelable_test.cpp
deleted file mode 100644
index 686dc82..0000000
--- a/libs/gui/tests/SurfaceParcelable_test.cpp
+++ /dev/null
@@ -1,168 +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.
- */
-
-#define LOG_TAG "SurfaceParcelable_test"
-
-#include <gtest/gtest.h>
-
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <gui/BufferHubProducer.h>
-#include <gui/BufferQueue.h>
-#include <gui/view/Surface.h>
-#include <utils/Log.h>
-
-namespace android {
-
-static const String16 kTestServiceName = String16("SurfaceParcelableTestService");
-static const String16 kSurfaceName = String16("TEST_SURFACE");
-static const uint32_t kBufferWidth = 100;
-static const uint32_t kBufferHeight = 1;
-static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
-
-enum SurfaceParcelableTestServiceCode {
-    CREATE_BUFFER_QUEUE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
-    CREATE_BUFFER_HUB_SURFACE,
-};
-
-class SurfaceParcelableTestService : public BBinder {
-public:
-    SurfaceParcelableTestService() {
-        // BufferQueue
-        BufferQueue::createBufferQueue(&mBufferQueueProducer, &mBufferQueueConsumer);
-
-        // BufferHub
-        dvr::ProducerQueueConfigBuilder configBuilder;
-        mProducerQueue = dvr::ProducerQueue::Create(configBuilder.SetDefaultWidth(kBufferWidth)
-                                                            .SetDefaultHeight(kBufferHeight)
-                                                            .SetDefaultFormat(kBufferFormat)
-                                                            .Build(),
-                                                    dvr::UsagePolicy{});
-        mBufferHubProducer = BufferHubProducer::Create(mProducerQueue);
-    }
-
-    ~SurfaceParcelableTestService() = default;
-
-    virtual status_t onTransact(uint32_t code, const Parcel& /*data*/, Parcel* reply,
-                                uint32_t /*flags*/ = 0) {
-        switch (code) {
-            case CREATE_BUFFER_QUEUE_SURFACE: {
-                view::Surface surfaceShim;
-                surfaceShim.name = kSurfaceName;
-                surfaceShim.graphicBufferProducer = mBufferQueueProducer;
-                return surfaceShim.writeToParcel(reply);
-            }
-            case CREATE_BUFFER_HUB_SURFACE: {
-                view::Surface surfaceShim;
-                surfaceShim.name = kSurfaceName;
-                surfaceShim.graphicBufferProducer = mBufferHubProducer;
-                return surfaceShim.writeToParcel(reply);
-            }
-            default:
-                return UNKNOWN_TRANSACTION;
-        };
-    }
-
-protected:
-    sp<IGraphicBufferProducer> mBufferQueueProducer;
-    sp<IGraphicBufferConsumer> mBufferQueueConsumer;
-
-    std::shared_ptr<dvr::ProducerQueue> mProducerQueue;
-    sp<IGraphicBufferProducer> mBufferHubProducer;
-};
-
-static int runBinderServer() {
-    ProcessState::self()->startThreadPool();
-
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<SurfaceParcelableTestService> service = new SurfaceParcelableTestService;
-    sm->addService(kTestServiceName, service, false);
-
-    ALOGI("Binder server running...");
-
-    while (true) {
-        int stat, retval;
-        retval = wait(&stat);
-        if (retval == -1 && errno == ECHILD) {
-            break;
-        }
-    }
-
-    ALOGI("Binder server exiting...");
-    return 0;
-}
-
-class SurfaceParcelableTest : public ::testing::TestWithParam<uint32_t> {
-protected:
-    virtual void SetUp() {
-        mService = defaultServiceManager()->getService(kTestServiceName);
-        if (mService == nullptr) {
-            ALOGE("Failed to connect to the test service.");
-            return;
-        }
-
-        ALOGI("Binder service is ready for client.");
-    }
-
-    status_t GetSurface(view::Surface* surfaceShim) {
-        ALOGI("...Test: %d", GetParam());
-
-        uint32_t opCode = GetParam();
-        Parcel data;
-        Parcel reply;
-        status_t error = mService->transact(opCode, data, &reply);
-        if (error != NO_ERROR) {
-            ALOGE("Failed to get surface over binder, error=%d.", error);
-            return error;
-        }
-
-        error = surfaceShim->readFromParcel(&reply);
-        if (error != NO_ERROR) {
-            ALOGE("Failed to get surface from parcel, error=%d.", error);
-            return error;
-        }
-
-        return NO_ERROR;
-    }
-
-private:
-    sp<IBinder> mService;
-};
-
-TEST_P(SurfaceParcelableTest, SendOverBinder) {
-    view::Surface surfaceShim;
-    EXPECT_EQ(GetSurface(&surfaceShim), NO_ERROR);
-    EXPECT_EQ(surfaceShim.name, kSurfaceName);
-    EXPECT_FALSE(surfaceShim.graphicBufferProducer == nullptr);
-}
-
-INSTANTIATE_TEST_CASE_P(SurfaceBackends, SurfaceParcelableTest,
-                        ::testing::Values(CREATE_BUFFER_QUEUE_SURFACE, CREATE_BUFFER_HUB_SURFACE));
-
-} // namespace android
-
-int main(int argc, char** argv) {
-    pid_t pid = fork();
-    if (pid == 0) {
-        android::ProcessState::self()->startThreadPool();
-        ::testing::InitGoogleTest(&argc, argv);
-        return RUN_ALL_TESTS();
-
-    } else {
-        ALOGI("Test process pid: %d.", pid);
-        return android::runBinderServer();
-    }
-}
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index d7db6bd..cedc522 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -74,6 +74,9 @@
         override_export_include_dirs: [
             "include",
         ],
+        export_llndk_headers: [
+            "libarect_headers",
+        ],
     },
     export_include_dirs: [
         "include",
@@ -108,16 +111,14 @@
     ],
 
     header_libs: [
+        "libarect_headers",
         "libnativebase_headers",
         "libnativewindow_headers",
     ],
 
     // headers we include in our public headers
-    export_static_lib_headers: [
-        "libarect",
-    ],
-
     export_header_lib_headers: [
+        "libarect_headers",
         "libnativebase_headers",
     ],
 
diff --git a/libs/sensor/Android.bp b/libs/sensor/Android.bp
index 2b93c6e..b6b9cc4 100644
--- a/libs/sensor/Android.bp
+++ b/libs/sensor/Android.bp
@@ -21,9 +21,10 @@
     default_applicable_licenses: ["frameworks_native_license"],
 }
 
-cc_library_shared {
+cc_library {
     name: "libsensor",
 
+    host_supported: true,
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 0f771a9..98d9b94 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -155,6 +155,8 @@
     ],
 
     defaults: [
+        "android.hardware.graphics.allocator-ndk_shared",
+        "android.hardware.graphics.common-ndk_shared",
         "libui-defaults",
         // Uncomment the following line to enable VALIDATE_REGIONS traces
         //defaults: ["libui-validate-regions-defaults"],
@@ -164,8 +166,6 @@
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.allocator@3.0",
         "android.hardware.graphics.allocator@4.0",
-        "android.hardware.graphics.allocator-V1-ndk",
-        "android.hardware.graphics.common-V3-ndk",
         "android.hardware.graphics.common@1.2",
         "android.hardware.graphics.mapper@2.0",
         "android.hardware.graphics.mapper@2.1",
@@ -183,7 +183,6 @@
 
     export_shared_lib_headers: [
         "android.hardware.graphics.common@1.2",
-        "android.hardware.graphics.common-V3-ndk",
         "android.hardware.graphics.mapper@4.0",
         "libgralloctypes",
     ],
diff --git a/libs/vibrator/Android.bp b/libs/vibrator/Android.bp
index 83c250a..2af51a7 100644
--- a/libs/vibrator/Android.bp
+++ b/libs/vibrator/Android.bp
@@ -21,31 +21,8 @@
     default_applicable_licenses: ["frameworks_native_license"],
 }
 
-cc_library {
-    name: "libvibrator",
-    vendor_available: true,
-    double_loadable: true,
-
-    shared_libs: [
-        "libbinder",
-        "liblog",
-        "libutils",
-    ],
-
-    header_libs: [
-        "libaudio_system_headers",
-    ],
-
-    aidl: {
-        include_dirs: ["frameworks/base/core/java"],
-        local_include_dirs: ["include/"],
-        export_aidl_headers: true,
-    },
-
-    srcs: [
-        ":libvibrator_aidl",
-        "*.cpp",
-    ],
+cc_defaults {
+    name: "libvibrator_defaults",
 
     cflags: [
         "-Wall",
@@ -64,3 +41,54 @@
         },
     },
 }
+
+cc_library {
+    name: "libvibrator",
+    defaults: ["libvibrator_defaults"],
+
+    shared_libs: [
+        "libbinder",
+        "liblog",
+        "libutils",
+    ],
+
+    whole_static_libs: [
+        "libvibratorutils",
+    ],
+
+    header_libs: [
+        "libaudio_system_headers",
+    ],
+
+    aidl: {
+        include_dirs: ["frameworks/base/core/java"],
+        local_include_dirs: ["include/"],
+        export_aidl_headers: true,
+    },
+
+    srcs: [
+        ":libvibrator_aidl",
+        "ExternalVibration.cpp",
+    ],
+}
+
+cc_library {
+    name: "libvibratorutils",
+    defaults: ["libvibrator_defaults"],
+
+    vendor_available: true,
+    double_loadable: true,
+
+    shared_libs: [
+        "libutils",
+    ],
+
+    srcs: [
+        "ExternalVibrationUtils.cpp",
+    ],
+
+    visibility: [
+        "//frameworks/native/libs/vibrator",
+        "//frameworks/av/media/libeffects/hapticgenerator",
+    ],
+}
diff --git a/libs/vibrator/ExternalVibration.cpp b/libs/vibrator/ExternalVibration.cpp
index f6fc19e..ec90645 100644
--- a/libs/vibrator/ExternalVibration.cpp
+++ b/libs/vibrator/ExternalVibration.cpp
@@ -15,11 +15,22 @@
  */
 
 #include <vibrator/ExternalVibration.h>
+#include <vibrator/ExternalVibrationUtils.h>
 
+#include <android/os/IExternalVibratorService.h>
 #include <binder/Parcel.h>
 #include <log/log.h>
 #include <utils/Errors.h>
 
+
+// To guarantee if HapticScale enum has the same value as IExternalVibratorService
+static_assert(static_cast<int>(android::os::HapticScale::MUTE) == static_cast<int>(android::os::IExternalVibratorService::SCALE_MUTE));
+static_assert(static_cast<int>(android::os::HapticScale::VERY_LOW) == static_cast<int>(android::os::IExternalVibratorService::SCALE_VERY_LOW));
+static_assert(static_cast<int>(android::os::HapticScale::LOW) == static_cast<int>(android::os::IExternalVibratorService::SCALE_LOW));
+static_assert(static_cast<int>(android::os::HapticScale::NONE) == static_cast<int>(android::os::IExternalVibratorService::SCALE_NONE));
+static_assert(static_cast<int>(android::os::HapticScale::HIGH) == static_cast<int>(android::os::IExternalVibratorService::SCALE_HIGH));
+static_assert(static_cast<int>(android::os::HapticScale::VERY_HIGH) == static_cast<int>(android::os::IExternalVibratorService::SCALE_VERY_HIGH));
+
 void writeAudioAttributes(const audio_attributes_t& attrs, android::Parcel* out) {
     out->writeInt32(attrs.usage);
     out->writeInt32(attrs.content_type);
diff --git a/libs/vibrator/include/vibrator/ExternalVibrationUtils.h b/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
index 84357fc..c588bfd 100644
--- a/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
+++ b/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
@@ -17,17 +17,17 @@
 #ifndef ANDROID_EXTERNAL_VIBRATION_UTILS_H
 #define ANDROID_EXTERNAL_VIBRATION_UTILS_H
 
-#include <android/os/IExternalVibratorService.h>
-
 namespace android::os {
 
+// Copied from frameworks/base/core/java/android/os/IExternalVibratorService.aidl
+// The values are checked in ExternalVibration.cpp
 enum class HapticScale {
-    MUTE = IExternalVibratorService::SCALE_MUTE,
-    VERY_LOW = IExternalVibratorService::SCALE_VERY_LOW,
-    LOW = IExternalVibratorService::SCALE_LOW,
-    NONE = IExternalVibratorService::SCALE_NONE,
-    HIGH = IExternalVibratorService::SCALE_HIGH,
-    VERY_HIGH = IExternalVibratorService::SCALE_VERY_HIGH,
+    MUTE = -100,
+    VERY_LOW = -2,
+    LOW = -1,
+    NONE = 0,
+    HIGH = 1,
+    VERY_HIGH = 2,
 };
 
 bool isValidHapticScale(HapticScale scale);
diff --git a/libs/vr/libbufferhubqueue/benchmarks/Android.bp b/libs/vr/libbufferhubqueue/benchmarks/Android.bp
deleted file mode 100644
index e33e03b..0000000
--- a/libs/vr/libbufferhubqueue/benchmarks/Android.bp
+++ /dev/null
@@ -1,35 +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_benchmark {
-    srcs: ["buffer_transport_benchmark.cpp"],
-    shared_libs: [
-        "libbase",
-        "libbinder",
-        "libcutils",
-        "libdvr.google",
-        "libgui",
-        "liblog",
-        "libhardware",
-        "libui",
-        "libutils",
-        "libnativewindow",
-        "libbufferhubqueue",
-        "libpdx_default_transport",
-    ],
-    cflags: [
-        "-DLOG_TAG=\"buffer_transport_benchmark\"",
-        "-DTRACE=0",
-        "-O2",
-        "-Wall",
-        "-Werror",
-    ],
-    name: "buffer_transport_benchmark",
-}
diff --git a/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp b/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp
deleted file mode 100644
index b6813eb..0000000
--- a/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp
+++ /dev/null
@@ -1,589 +0,0 @@
-#include <android-base/logging.h>
-#include <android/native_window.h>
-#include <benchmark/benchmark.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <dvr/dvr_api.h>
-#include <gui/BufferItem.h>
-#include <gui/BufferItemConsumer.h>
-#include <gui/Surface.h>
-#include <private/dvr/epoll_file_descriptor.h>
-#include <utils/Trace.h>
-
-#include <chrono>
-#include <functional>
-#include <iostream>
-#include <thread>
-#include <vector>
-
-#include <dlfcn.h>
-#include <poll.h>
-#include <sys/epoll.h>
-#include <sys/wait.h>
-
-// Use ALWAYS at the tag level. Control is performed manually during command
-// line processing.
-#ifdef ATRACE_TAG
-#undef ATRACE_TAG
-#endif
-#define ATRACE_TAG ATRACE_TAG_ALWAYS
-
-using namespace android;
-using ::benchmark::State;
-
-static const String16 kBinderService = String16("bufferTransport");
-static const uint32_t kBufferWidth = 100;
-static const uint32_t kBufferHeight = 1;
-static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
-static const uint64_t kBufferUsage =
-    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
-static const uint32_t kBufferLayer = 1;
-static const int kMaxAcquiredImages = 1;
-static const int kQueueDepth = 2;  // We are double buffering for this test.
-static const size_t kMaxQueueCounts = 128;
-static const int kInvalidFence = -1;
-
-enum BufferTransportServiceCode {
-  CREATE_BUFFER_QUEUE = IBinder::FIRST_CALL_TRANSACTION,
-};
-
-// A binder services that minics a compositor that consumes buffers. It provides
-// one Binder interface to create a new Surface for buffer producer to write
-// into; while itself will carry out no-op buffer consuming by acquiring then
-// releasing the buffer immediately.
-class BufferTransportService : public BBinder {
- public:
-  BufferTransportService() = default;
-  ~BufferTransportService() = default;
-
-  virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-                              uint32_t flags = 0) {
-    (void)flags;
-    (void)data;
-    switch (code) {
-      case CREATE_BUFFER_QUEUE: {
-        auto new_queue = std::make_shared<BufferQueueHolder>(this);
-        reply->writeStrongBinder(
-            IGraphicBufferProducer::asBinder(new_queue->producer));
-        buffer_queues_.push_back(new_queue);
-        return OK;
-      }
-      default:
-        return UNKNOWN_TRANSACTION;
-    };
-  }
-
- private:
-  struct FrameListener : public ConsumerBase::FrameAvailableListener {
-   public:
-    FrameListener(BufferTransportService* /*service*/,
-                  sp<BufferItemConsumer> buffer_item_consumer)
-        : buffer_item_consumer_(buffer_item_consumer) {}
-
-    void onFrameAvailable(const BufferItem& /*item*/) override {
-      BufferItem buffer;
-      status_t ret = 0;
-      {
-        ATRACE_NAME("AcquireBuffer");
-        ret = buffer_item_consumer_->acquireBuffer(&buffer, /*presentWhen=*/0,
-                                                   /*waitForFence=*/false);
-      }
-
-      if (ret != OK) {
-        LOG(ERROR) << "Failed to acquire next buffer.";
-        return;
-      }
-
-      {
-        ATRACE_NAME("ReleaseBuffer");
-        ret = buffer_item_consumer_->releaseBuffer(buffer);
-      }
-
-      if (ret != OK) {
-        LOG(ERROR) << "Failed to release buffer.";
-        return;
-      }
-    }
-
-   private:
-    sp<BufferItemConsumer> buffer_item_consumer_;
-  };
-
-  struct BufferQueueHolder {
-    explicit BufferQueueHolder(BufferTransportService* service) {
-      BufferQueue::createBufferQueue(&producer, &consumer);
-
-      sp<BufferItemConsumer> buffer_item_consumer =
-          new BufferItemConsumer(consumer, kBufferUsage, kMaxAcquiredImages,
-                                 /*controlledByApp=*/true);
-      buffer_item_consumer->setName(String8("BinderBufferTransport"));
-      frame_listener_ = new FrameListener(service, buffer_item_consumer);
-      buffer_item_consumer->setFrameAvailableListener(frame_listener_);
-    }
-
-    sp<IGraphicBufferProducer> producer;
-    sp<IGraphicBufferConsumer> consumer;
-
-   private:
-    sp<FrameListener> frame_listener_;
-  };
-
-  std::vector<std::shared_ptr<BufferQueueHolder>> buffer_queues_;
-};
-
-// A virtual interfaces that abstracts the common BufferQueue operations, so
-// that the test suite can use the same test case to drive different types of
-// transport backends.
-class BufferTransport {
- public:
-  virtual ~BufferTransport() {}
-
-  virtual int Start() = 0;
-  virtual sp<Surface> CreateSurface() = 0;
-};
-
-// Binder-based buffer transport backend.
-//
-// On Start() a new process will be swapned to run a Binder server that
-// actually consumes the buffer.
-// On CreateSurface() a new Binder BufferQueue will be created, which the
-// service holds the concrete binder node of the IGraphicBufferProducer while
-// sending the binder proxy to the client. In another word, the producer side
-// operations are carried out process while the consumer side operations are
-// carried out within the BufferTransportService's own process.
-class BinderBufferTransport : public BufferTransport {
- public:
-  BinderBufferTransport() {}
-
-  int Start() override {
-    sp<IServiceManager> sm = defaultServiceManager();
-    service_ = sm->getService(kBinderService);
-    if (service_ == nullptr) {
-      LOG(ERROR) << "Failed to get the benchmark service.";
-      return -EIO;
-    }
-
-    LOG(INFO) << "Binder server is ready for client.";
-    return 0;
-  }
-
-  sp<Surface> CreateSurface() override {
-    Parcel data;
-    Parcel reply;
-    int error = service_->transact(CREATE_BUFFER_QUEUE, data, &reply);
-    if (error != OK) {
-      LOG(ERROR) << "Failed to get buffer queue over binder.";
-      return nullptr;
-    }
-
-    sp<IBinder> binder;
-    error = reply.readNullableStrongBinder(&binder);
-    if (error != OK) {
-      LOG(ERROR) << "Failed to get IGraphicBufferProducer over binder.";
-      return nullptr;
-    }
-
-    auto producer = interface_cast<IGraphicBufferProducer>(binder);
-    if (producer == nullptr) {
-      LOG(ERROR) << "Failed to get IGraphicBufferProducer over binder.";
-      return nullptr;
-    }
-
-    sp<Surface> surface = new Surface(producer, /*controlledByApp=*/true);
-
-    // Set buffer dimension.
-    ANativeWindow* window = static_cast<ANativeWindow*>(surface.get());
-    ANativeWindow_setBuffersGeometry(window, kBufferWidth, kBufferHeight,
-                                     kBufferFormat);
-
-    return surface;
-  }
-
- private:
-  sp<IBinder> service_;
-};
-
-class DvrApi {
- public:
-  DvrApi() {
-    handle_ = dlopen("libdvr.google.so", RTLD_NOW | RTLD_LOCAL);
-    CHECK(handle_);
-
-    auto dvr_get_api =
-        reinterpret_cast<decltype(&dvrGetApi)>(dlsym(handle_, "dvrGetApi"));
-    int ret = dvr_get_api(&api_, sizeof(api_), /*version=*/1);
-
-    CHECK(ret == 0);
-  }
-
-  ~DvrApi() { dlclose(handle_); }
-
-  const DvrApi_v1& Api() { return api_; }
-
- private:
-  void* handle_ = nullptr;
-  DvrApi_v1 api_;
-};
-
-// BufferHub/PDX-based buffer transport.
-//
-// On Start() a new thread will be swapned to run an epoll polling thread which
-// minics the behavior of a compositor. Similar to Binder-based backend, the
-// buffer available handler is also a no-op: Buffer gets acquired and released
-// immediately.
-// On CreateSurface() a pair of dvr::ProducerQueue and dvr::ConsumerQueue will
-// be created. The epoll thread holds on the consumer queue and dequeues buffer
-// from it; while the producer queue will be wrapped in a Surface and returned
-// to test suite.
-class BufferHubTransport : public BufferTransport {
- public:
-  virtual ~BufferHubTransport() {
-    stopped_.store(true);
-    if (reader_thread_.joinable()) {
-      reader_thread_.join();
-    }
-  }
-
-  int Start() override {
-    int ret = epoll_fd_.Create();
-    if (ret < 0) {
-      LOG(ERROR) << "Failed to create epoll fd: %s", strerror(-ret);
-      return -1;
-    }
-
-    // Create the reader thread.
-    reader_thread_ = std::thread([this]() {
-      int ret = dvr_.Api().PerformanceSetSchedulerPolicy(0, "graphics");
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to set scheduler policy, ret=" << ret;
-        return;
-      }
-
-      stopped_.store(false);
-      LOG(INFO) << "Reader Thread Running...";
-
-      while (!stopped_.load()) {
-        std::array<epoll_event, kMaxQueueCounts> events;
-
-        // Don't sleep forever so that we will have a chance to wake up.
-        const int ret = epoll_fd_.Wait(events.data(), events.size(),
-                                       /*timeout=*/100);
-        if (ret < 0) {
-          LOG(ERROR) << "Error polling consumer queues.";
-          continue;
-        }
-        if (ret == 0) {
-          continue;
-        }
-
-        const int num_events = ret;
-        for (int i = 0; i < num_events; i++) {
-          uint32_t index = events[i].data.u32;
-          dvr_.Api().ReadBufferQueueHandleEvents(
-              buffer_queues_[index]->GetReadQueue());
-        }
-      }
-
-      LOG(INFO) << "Reader Thread Exiting...";
-    });
-
-    return 0;
-  }
-
-  sp<Surface> CreateSurface() override {
-    auto new_queue = std::make_shared<BufferQueueHolder>();
-    if (!new_queue->IsReady()) {
-      LOG(ERROR) << "Failed to create BufferHub-based BufferQueue.";
-      return nullptr;
-    }
-
-    // Set buffer dimension.
-    ANativeWindow_setBuffersGeometry(new_queue->GetSurface(), kBufferWidth,
-                                     kBufferHeight, kBufferFormat);
-
-    // Use the next position as buffer_queue index.
-    uint32_t index = buffer_queues_.size();
-    epoll_event event = {.events = EPOLLIN | EPOLLET, .data = {.u32 = index}};
-    int queue_fd =
-        dvr_.Api().ReadBufferQueueGetEventFd(new_queue->GetReadQueue());
-    const int ret = epoll_fd_.Control(EPOLL_CTL_ADD, queue_fd, &event);
-    if (ret < 0) {
-      LOG(ERROR) << "Failed to track consumer queue: " << strerror(-ret)
-                 << ", consumer queue fd: " << queue_fd;
-      return nullptr;
-    }
-
-    buffer_queues_.push_back(new_queue);
-    ANativeWindow_acquire(new_queue->GetSurface());
-    return static_cast<Surface*>(new_queue->GetSurface());
-  }
-
- private:
-  struct BufferQueueHolder {
-    BufferQueueHolder() {
-      int ret = 0;
-      ret = dvr_.Api().WriteBufferQueueCreate(
-          kBufferWidth, kBufferHeight, kBufferFormat, kBufferLayer,
-          kBufferUsage, 0, sizeof(DvrNativeBufferMetadata), &write_queue_);
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to create write buffer queue, ret=" << ret;
-        return;
-      }
-
-      ret = dvr_.Api().WriteBufferQueueCreateReadQueue(write_queue_,
-                                                       &read_queue_);
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to create read buffer queue, ret=" << ret;
-        return;
-      }
-
-      ret = dvr_.Api().ReadBufferQueueSetBufferAvailableCallback(
-          read_queue_, BufferAvailableCallback, this);
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to create buffer available callback, ret=" << ret;
-        return;
-      }
-
-      ret =
-          dvr_.Api().WriteBufferQueueGetANativeWindow(write_queue_, &surface_);
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to create surface, ret=" << ret;
-        return;
-      }
-    }
-
-    static void BufferAvailableCallback(void* context) {
-      BufferQueueHolder* thiz = static_cast<BufferQueueHolder*>(context);
-      thiz->HandleBufferAvailable();
-    }
-
-    DvrReadBufferQueue* GetReadQueue() { return read_queue_; }
-
-    ANativeWindow* GetSurface() { return surface_; }
-
-    bool IsReady() {
-      return write_queue_ != nullptr && read_queue_ != nullptr &&
-             surface_ != nullptr;
-    }
-
-    void HandleBufferAvailable() {
-      int ret = 0;
-      DvrNativeBufferMetadata meta;
-      DvrReadBuffer* buffer = nullptr;
-      DvrNativeBufferMetadata metadata;
-      int acquire_fence = kInvalidFence;
-
-      {
-        ATRACE_NAME("AcquireBuffer");
-        ret = dvr_.Api().ReadBufferQueueAcquireBuffer(
-            read_queue_, 0, &buffer, &metadata, &acquire_fence);
-      }
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to acquire consumer buffer, error: " << ret;
-        return;
-      }
-
-      if (buffer != nullptr) {
-        ATRACE_NAME("ReleaseBuffer");
-        ret = dvr_.Api().ReadBufferQueueReleaseBuffer(read_queue_, buffer,
-                                                      &meta, kInvalidFence);
-      }
-      if (ret < 0) {
-        LOG(ERROR) << "Failed to release consumer buffer, error: " << ret;
-      }
-    }
-
-   private:
-    DvrWriteBufferQueue* write_queue_ = nullptr;
-    DvrReadBufferQueue* read_queue_ = nullptr;
-    ANativeWindow* surface_ = nullptr;
-  };
-
-  static DvrApi dvr_;
-  std::atomic<bool> stopped_;
-  std::thread reader_thread_;
-
-  dvr::EpollFileDescriptor epoll_fd_;
-  std::vector<std::shared_ptr<BufferQueueHolder>> buffer_queues_;
-};
-
-DvrApi BufferHubTransport::dvr_ = {};
-
-enum TransportType {
-  kBinderBufferTransport,
-  kBufferHubTransport,
-};
-
-// Main test suite, which supports two transport backend: 1) BinderBufferQueue,
-// 2) BufferHubQueue. The test case drives the producer end of both transport
-// backend by queuing buffers into the buffer queue by using ANativeWindow API.
-class BufferTransportBenchmark : public ::benchmark::Fixture {
- public:
-  void SetUp(State& state) override {
-    if (state.thread_index == 0) {
-      const int transport = state.range(0);
-      switch (transport) {
-        case kBinderBufferTransport:
-          transport_.reset(new BinderBufferTransport);
-          break;
-        case kBufferHubTransport:
-          transport_.reset(new BufferHubTransport);
-          break;
-        default:
-          CHECK(false) << "Unknown test case.";
-          break;
-      }
-
-      CHECK(transport_);
-      const int ret = transport_->Start();
-      CHECK_EQ(ret, 0);
-
-      LOG(INFO) << "Transport backend running, transport=" << transport << ".";
-
-      // Create surfaces for each thread.
-      surfaces_.resize(state.threads);
-      for (int i = 0; i < state.threads; i++) {
-        // Common setup every thread needs.
-        surfaces_[i] = transport_->CreateSurface();
-        CHECK(surfaces_[i]);
-
-        LOG(INFO) << "Surface initialized on thread " << i << ".";
-      }
-    }
-  }
-
-  void TearDown(State& state) override {
-    if (state.thread_index == 0) {
-      surfaces_.clear();
-      transport_.reset();
-      LOG(INFO) << "Tear down benchmark.";
-    }
-  }
-
- protected:
-  std::unique_ptr<BufferTransport> transport_;
-  std::vector<sp<Surface>> surfaces_;
-};
-
-BENCHMARK_DEFINE_F(BufferTransportBenchmark, Producers)(State& state) {
-  ANativeWindow* window = nullptr;
-  ANativeWindow_Buffer buffer;
-  int32_t error = 0;
-  double total_gain_buffer_us = 0;
-  double total_post_buffer_us = 0;
-  int iterations = 0;
-
-  while (state.KeepRunning()) {
-    if (window == nullptr) {
-      CHECK(surfaces_[state.thread_index]);
-      window = static_cast<ANativeWindow*>(surfaces_[state.thread_index].get());
-
-      // Lock buffers a couple time from the queue, so that we have the buffer
-      // allocated.
-      for (int i = 0; i < kQueueDepth; i++) {
-        error = ANativeWindow_lock(window, &buffer,
-                                   /*inOutDirtyBounds=*/nullptr);
-        CHECK_EQ(error, 0);
-        error = ANativeWindow_unlockAndPost(window);
-        CHECK_EQ(error, 0);
-      }
-    }
-
-    {
-      ATRACE_NAME("GainBuffer");
-      auto t1 = std::chrono::high_resolution_clock::now();
-      error = ANativeWindow_lock(window, &buffer,
-                                 /*inOutDirtyBounds=*/nullptr);
-      auto t2 = std::chrono::high_resolution_clock::now();
-      std::chrono::duration<double, std::micro> delta_us = t2 - t1;
-      total_gain_buffer_us += delta_us.count();
-    }
-    CHECK_EQ(error, 0);
-
-    {
-      ATRACE_NAME("PostBuffer");
-      auto t1 = std::chrono::high_resolution_clock::now();
-      error = ANativeWindow_unlockAndPost(window);
-      auto t2 = std::chrono::high_resolution_clock::now();
-      std::chrono::duration<double, std::micro> delta_us = t2 - t1;
-      total_post_buffer_us += delta_us.count();
-    }
-    CHECK_EQ(error, 0);
-
-    iterations++;
-  }
-
-  state.counters["gain_buffer_us"] = ::benchmark::Counter(
-      total_gain_buffer_us / iterations, ::benchmark::Counter::kAvgThreads);
-  state.counters["post_buffer_us"] = ::benchmark::Counter(
-      total_post_buffer_us / iterations, ::benchmark::Counter::kAvgThreads);
-  state.counters["producer_us"] = ::benchmark::Counter(
-      (total_gain_buffer_us + total_post_buffer_us) / iterations,
-      ::benchmark::Counter::kAvgThreads);
-}
-
-BENCHMARK_REGISTER_F(BufferTransportBenchmark, Producers)
-    ->Unit(::benchmark::kMicrosecond)
-    ->Ranges({{kBinderBufferTransport, kBufferHubTransport}})
-    ->ThreadRange(1, 32);
-
-static void runBinderServer() {
-  ProcessState::self()->setThreadPoolMaxThreadCount(0);
-  ProcessState::self()->startThreadPool();
-
-  sp<IServiceManager> sm = defaultServiceManager();
-  sp<BufferTransportService> service = new BufferTransportService;
-  sm->addService(kBinderService, service, false);
-
-  LOG(INFO) << "Binder server running...";
-
-  while (true) {
-    int stat, retval;
-    retval = wait(&stat);
-    if (retval == -1 && errno == ECHILD) {
-      break;
-    }
-  }
-
-  LOG(INFO) << "Service Exiting...";
-}
-
-// To run binder-based benchmark, use:
-// adb shell buffer_transport_benchmark \
-//   --benchmark_filter="BufferTransportBenchmark/ContinuousLoad/0/"
-//
-// To run bufferhub-based benchmark, use:
-// adb shell buffer_transport_benchmark \
-//   --benchmark_filter="BufferTransportBenchmark/ContinuousLoad/1/"
-int main(int argc, char** argv) {
-  bool tracing_enabled = false;
-
-  // Parse arguments in addition to "--benchmark_filter" paramters.
-  for (int i = 1; i < argc; i++) {
-    if (std::string(argv[i]) == "--help") {
-      std::cout << "Usage: binderThroughputTest [OPTIONS]" << std::endl;
-      std::cout << "\t--trace: Enable systrace logging." << std::endl;
-      return 0;
-    }
-    if (std::string(argv[i]) == "--trace") {
-      tracing_enabled = true;
-      continue;
-    }
-  }
-
-  // Setup ATRACE/systrace based on command line.
-  atrace_setup();
-  atrace_set_tracing_enabled(tracing_enabled);
-
-  pid_t pid = fork();
-  if (pid == 0) {
-    // Child, i.e. the client side.
-    ProcessState::self()->startThreadPool();
-
-    ::benchmark::Initialize(&argc, argv);
-    ::benchmark::RunSpecifiedBenchmarks();
-  } else {
-    LOG(INFO) << "Benchmark process pid: " << pid;
-    runBinderServer();
-  }
-}
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
index 33a0d75..e373376 100644
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -48,19 +48,3 @@
     ],
     name: "buffer_hub_queue-test",
 }
-
-cc_test {
-    srcs: ["buffer_hub_queue_producer-test.cpp"],
-    header_libs: header_libraries,
-    static_libs: static_libraries,
-    shared_libs: shared_libraries,
-    cflags: [
-        "-DLOG_TAG=\"buffer_hub_queue_producer-test\"",
-        "-DTRACE=0",
-        "-O0",
-        "-g",
-        "-Wall",
-        "-Werror",
-    ],
-    name: "buffer_hub_queue_producer-test",
-}
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp
deleted file mode 100644
index fab1097..0000000
--- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp
+++ /dev/null
@@ -1,603 +0,0 @@
-#include <base/logging.h>
-#include <gui/BufferHubProducer.h>
-#include <gui/IProducerListener.h>
-#include <gui/Surface.h>
-#include <pdx/default_transport/channel_parcelable.h>
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace dvr {
-
-using pdx::LocalHandle;
-
-namespace {
-
-// Default dimensions before setDefaultBufferSize is called by the consumer.
-constexpr uint32_t kDefaultWidth = 1;
-constexpr uint32_t kDefaultHeight = 1;
-
-// Default format before setDefaultBufferFormat is called by the consumer.
-constexpr PixelFormat kDefaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-constexpr int kDefaultConsumerUsageBits = 0;
-
-// Default transform hint before setTransformHint is called by the consumer.
-constexpr uint32_t kDefaultTransformHint = 0;
-
-constexpr int kTestApi = NATIVE_WINDOW_API_CPU;
-constexpr int kTestApiOther = NATIVE_WINDOW_API_EGL;
-constexpr int kTestApiInvalid = 0xDEADBEEF;
-constexpr int kTestProducerUsageBits = 0;
-constexpr bool kTestControlledByApp = true;
-
-// Builder pattern to slightly vary *almost* correct input
-// -- avoids copying and pasting
-struct QueueBufferInputBuilder {
-  IGraphicBufferProducer::QueueBufferInput build() {
-    return IGraphicBufferProducer::QueueBufferInput(
-        mTimestamp, mIsAutoTimestamp, mDataSpace, mCrop, mScalingMode,
-        mTransform, mFence);
-  }
-
-  QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
-    this->mTimestamp = timestamp;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
-    this->mIsAutoTimestamp = isAutoTimestamp;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
-    this->mDataSpace = dataSpace;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setCrop(Rect crop) {
-    this->mCrop = crop;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setScalingMode(int scalingMode) {
-    this->mScalingMode = scalingMode;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setTransform(uint32_t transform) {
-    this->mTransform = transform;
-    return *this;
-  }
-
-  QueueBufferInputBuilder& setFence(sp<Fence> fence) {
-    this->mFence = fence;
-    return *this;
-  }
-
- private:
-  int64_t mTimestamp{1384888611};
-  bool mIsAutoTimestamp{false};
-  android_dataspace mDataSpace{HAL_DATASPACE_UNKNOWN};
-  Rect mCrop{Rect(kDefaultWidth, kDefaultHeight)};
-  int mScalingMode{0};
-  uint32_t mTransform{0};
-  sp<Fence> mFence{Fence::NO_FENCE};
-};
-
-// This is a test that covers our implementation of bufferhubqueue-based
-// IGraphicBufferProducer.
-class BufferHubQueueProducerTest : public ::testing::Test {
- protected:
-  virtual void SetUp() {
-    const ::testing::TestInfo* const testInfo =
-        ::testing::UnitTest::GetInstance()->current_test_info();
-    ALOGD_IF(TRACE, "Begin test: %s.%s", testInfo->test_case_name(),
-             testInfo->name());
-
-    auto config = ProducerQueueConfigBuilder().Build();
-    auto queue = ProducerQueue::Create(config, UsagePolicy{});
-    ASSERT_TRUE(queue != nullptr);
-
-    mProducer = BufferHubProducer::Create(std::move(queue));
-    ASSERT_TRUE(mProducer != nullptr);
-    mSurface = new Surface(mProducer, true);
-    ASSERT_TRUE(mSurface != nullptr);
-  }
-
-  // Connect to a producer in a 'correct' fashion.
-  void ConnectProducer() {
-    IGraphicBufferProducer::QueueBufferOutput output;
-    // Can connect the first time.
-    ASSERT_EQ(OK, mProducer->connect(kStubListener, kTestApi,
-                                     kTestControlledByApp, &output));
-  }
-
-  // Dequeue a buffer in a 'correct' fashion.
-  //   Precondition: Producer is connected.
-  void DequeueBuffer(int* outSlot) {
-    sp<Fence> fence;
-    ASSERT_NO_FATAL_FAILURE(DequeueBuffer(outSlot, &fence));
-  }
-
-  void DequeueBuffer(int* outSlot, sp<Fence>* outFence) {
-    ASSERT_NE(nullptr, outSlot);
-    ASSERT_NE(nullptr, outFence);
-
-    int ret = mProducer->dequeueBuffer(
-        outSlot, outFence, kDefaultWidth, kDefaultHeight, kDefaultFormat,
-        kTestProducerUsageBits, nullptr, nullptr);
-    // BUFFER_NEEDS_REALLOCATION can be either on or off.
-    ASSERT_EQ(0, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & ret);
-
-    // Slot number should be in boundary.
-    ASSERT_LE(0, *outSlot);
-    ASSERT_GT(BufferQueueDefs::NUM_BUFFER_SLOTS, *outSlot);
-  }
-
-  // Create a generic "valid" input for queueBuffer
-  // -- uses the default buffer format, width, etc.
-  static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
-    return QueueBufferInputBuilder().build();
-  }
-
-  const sp<IProducerListener> kStubListener{new StubProducerListener};
-
-  sp<BufferHubProducer> mProducer;
-  sp<Surface> mSurface;
-};
-
-TEST_F(BufferHubQueueProducerTest, ConnectFirst_ReturnsError) {
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  // NULL output returns BAD_VALUE
-  EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi,
-                                          kTestControlledByApp, nullptr));
-
-  // Invalid API returns bad value
-  EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApiInvalid,
-                                          kTestControlledByApp, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest, ConnectAgain_ReturnsError) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  // Can't connect when there is already a producer connected.
-  IGraphicBufferProducer::QueueBufferOutput output;
-  EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi,
-                                          kTestControlledByApp, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest, Disconnect_Succeeds) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
-}
-
-TEST_F(BufferHubQueueProducerTest, Disconnect_ReturnsError) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  // Must disconnect with same API number
-  EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiOther));
-  // API must not be out of range
-  EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiInvalid));
-}
-
-TEST_F(BufferHubQueueProducerTest, Query_Succeeds) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  int32_t value = -1;
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
-  EXPECT_EQ(kDefaultWidth, static_cast<uint32_t>(value));
-
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
-  EXPECT_EQ(kDefaultHeight, static_cast<uint32_t>(value));
-
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
-  EXPECT_EQ(kDefaultFormat, value);
-
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
-  EXPECT_LE(0, value);
-  EXPECT_GE(BufferQueueDefs::NUM_BUFFER_SLOTS, value);
-
-  EXPECT_EQ(OK,
-            mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
-  EXPECT_FALSE(value);  // Can't run behind when we haven't touched the queue
-
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
-  EXPECT_EQ(kDefaultConsumerUsageBits, value);
-}
-
-TEST_F(BufferHubQueueProducerTest, Query_ReturnsError) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  // One past the end of the last 'query' enum value. Update this if we add more
-  // enums.
-  const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1;
-
-  int value;
-  // What was out of range
-  EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ -1, &value));
-  EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ 0xDEADBEEF, &value));
-  EXPECT_EQ(BAD_VALUE,
-            mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));
-
-  // Some enums from window.h are 'invalid'
-  EXPECT_EQ(BAD_VALUE,
-            mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
-  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
-  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
-  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
-  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));
-
-  // Value was NULL
-  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/ NULL));
-}
-
-TEST_F(BufferHubQueueProducerTest, Queue_Succeeds) {
-  int slot = -1;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  // Request the buffer (pre-requisite for queueing)
-  sp<GraphicBuffer> buffer;
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  // A generic "valid" input
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  // Queue the buffer back into the BQ
-  ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
-
-  EXPECT_EQ(kDefaultWidth, output.width);
-  EXPECT_EQ(kDefaultHeight, output.height);
-  EXPECT_EQ(kDefaultTransformHint, output.transformHint);
-
-  // BufferHubQueue delivers buffers to consumer immediately.
-  EXPECT_EQ(0u, output.numPendingBuffers);
-
-  // Note that BufferHubQueue doesn't support nextFrameNumber as it seems to
-  // be a SurfaceFlinger specific optimization.
-  EXPECT_EQ(0u, output.nextFrameNumber);
-
-  // Buffer was not in the dequeued state
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test invalid slot number
-TEST_F(BufferHubQueueProducerTest, QueueInvalidSlot_ReturnsError) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  // A generic "valid" input
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ -1, input, &output));
-  EXPECT_EQ(BAD_VALUE,
-            mProducer->queueBuffer(/*slot*/ 0xDEADBEEF, input, &output));
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueueDefs::NUM_BUFFER_SLOTS,
-                                              input, &output));
-}
-
-// Slot was not in the dequeued state (all slots start out in Free state)
-TEST_F(BufferHubQueueProducerTest, QueueNotDequeued_ReturnsError) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ 0, input, &output));
-}
-
-// Slot was enqueued without requesting a buffer
-TEST_F(BufferHubQueueProducerTest, QueueNotRequested_ReturnsError) {
-  int slot = -1;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test when fence was NULL
-TEST_F(BufferHubQueueProducerTest, QueueNoFence_ReturnsError) {
-  int slot = -1;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  sp<GraphicBuffer> buffer;
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  sp<Fence> nullFence = NULL;
-
-  IGraphicBufferProducer::QueueBufferInput input =
-      QueueBufferInputBuilder().setFence(nullFence).build();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test scaling mode was invalid
-TEST_F(BufferHubQueueProducerTest, QueueTestInvalidScalingMode_ReturnsError) {
-  int slot = -1;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  sp<GraphicBuffer> buffer;
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  IGraphicBufferProducer::QueueBufferInput input =
-      QueueBufferInputBuilder().setScalingMode(-1).build();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-
-  input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test crop rect is out of bounds of the buffer dimensions
-TEST_F(BufferHubQueueProducerTest, QueueCropOutOfBounds_ReturnsError) {
-  int slot = -1;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  sp<GraphicBuffer> buffer;
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  IGraphicBufferProducer::QueueBufferInput input =
-      QueueBufferInputBuilder()
-          .setCrop(Rect(kDefaultWidth + 1, kDefaultHeight + 1))
-          .build();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest, CancelBuffer_Succeeds) {
-  int slot = -1;
-  sp<Fence> fence;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));
-
-  // Should be able to cancel buffer after a dequeue.
-  EXPECT_EQ(OK, mProducer->cancelBuffer(slot, fence));
-}
-
-TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
-  return;
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  int minUndequeuedBuffers;
-  ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
-                                 &minUndequeuedBuffers));
-
-  const int minBuffers = 1;
-  const int maxBuffers =
-      BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
-
-  ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false;
-  ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(minBuffers))
-      << "bufferCount: " << minBuffers;
-
-  // Should now be able to dequeue up to minBuffers times
-  // Should now be able to dequeue up to maxBuffers times
-  int slot = -1;
-  for (int i = 0; i < minBuffers; ++i) {
-    ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-  }
-
-  ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers));
-
-  // queue the first buffer to enable max dequeued buffer count checking
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-  sp<GraphicBuffer> buffer;
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-  ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
-
-  sp<Fence> fence;
-  for (int i = 0; i < maxBuffers; ++i) {
-    ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));
-  }
-
-  // Cancel a buffer, so we can decrease the buffer count
-  ASSERT_EQ(OK, mProducer->cancelBuffer(slot, fence));
-
-  // Should now be able to decrease the max dequeued count by 1
-  ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers - 1));
-}
-
-TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Fails) {
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
-  int minUndequeuedBuffers;
-  ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
-                                 &minUndequeuedBuffers));
-
-  const int minBuffers = 1;
-  const int maxBuffers =
-      BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
-
-  ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false;
-  // Buffer count was out of range
-  EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0))
-      << "bufferCount: " << 0;
-  EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1))
-      << "bufferCount: " << maxBuffers + 1;
-
-  // Set max dequeue count to 2
-  ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
-  // Dequeue 2 buffers
-  int slot = -1;
-  sp<Fence> fence;
-  for (int i = 0; i < 2; i++) {
-    ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
-                      (mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth,
-                                                kDefaultHeight, kDefaultFormat,
-                                                kTestProducerUsageBits,
-                                                nullptr, nullptr)))
-        << "slot: " << slot;
-  }
-
-  // Client has too many buffers dequeued
-  EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1))
-      << "bufferCount: " << minBuffers;
-}
-
-TEST_F(BufferHubQueueProducerTest,
-       DisconnectedProducerReturnsError_dequeueBuffer) {
-  int slot = -1;
-  sp<Fence> fence;
-
-  ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth,
-                                              kDefaultHeight, kDefaultFormat,
-                                              kTestProducerUsageBits,
-                                              nullptr, nullptr));
-}
-
-TEST_F(BufferHubQueueProducerTest,
-       DisconnectedProducerReturnsError_requestBuffer) {
-  int slot = -1;
-  sp<GraphicBuffer> buffer;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
-  // Shouldn't be able to request buffer after disconnect.
-  ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
-  ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
-}
-
-TEST_F(BufferHubQueueProducerTest,
-       DisconnectedProducerReturnsError_queueBuffer) {
-  int slot = -1;
-  sp<GraphicBuffer> buffer;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  // A generic "valid" input
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  // Shouldn't be able to queue buffer after disconnect.
-  ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
-  ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest,
-       DisconnectedProducerReturnsError_cancelBuffer) {
-  int slot = -1;
-  sp<GraphicBuffer> buffer;
-
-  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-  ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
-  // Shouldn't be able to cancel buffer after disconnect.
-  ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
-  ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, Fence::NO_FENCE));
-}
-
-TEST_F(BufferHubQueueProducerTest, ConnectDisconnectReconnect) {
-  int slot = -1;
-  sp<GraphicBuffer> buffer;
-  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
-  IGraphicBufferProducer::QueueBufferOutput output;
-
-  EXPECT_NO_FATAL_FAILURE(ConnectProducer());
-
-  constexpr int maxDequeuedBuffers = 1;
-  int minUndequeuedBuffers;
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
-                                 &minUndequeuedBuffers));
-  EXPECT_EQ(OK, mProducer->setAsyncMode(false));
-  EXPECT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxDequeuedBuffers));
-
-  int maxCapacity = maxDequeuedBuffers + minUndequeuedBuffers;
-
-  // Dequeue, request, and queue all buffers.
-  for (int i = 0; i < maxCapacity; i++) {
-    EXPECT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-    EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-    EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
-  }
-
-  // Disconnect then reconnect.
-  EXPECT_EQ(OK, mProducer->disconnect(kTestApi));
-  EXPECT_NO_FATAL_FAILURE(ConnectProducer());
-
-  // Dequeue, request, and queue all buffers.
-  for (int i = 0; i < maxCapacity; i++) {
-    EXPECT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-    EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-    EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
-  }
-
-  EXPECT_EQ(OK, mProducer->disconnect(kTestApi));
-}
-
-TEST_F(BufferHubQueueProducerTest, TakeAsParcelable) {
-  // Connected producer cannot be taken out as a parcelable.
-  EXPECT_NO_FATAL_FAILURE(ConnectProducer());
-  ProducerQueueParcelable producer_parcelable;
-  EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), BAD_VALUE);
-
-  // Create a valid fake producer parcelable.
-  auto fake_channel_parcelable =
-      std::make_unique<pdx::default_transport::ChannelParcelable>(
-          LocalHandle(0), LocalHandle(0), LocalHandle(0));
-  EXPECT_TRUE(fake_channel_parcelable->IsValid());
-  ProducerQueueParcelable fake_producer_parcelable(
-      std::move(fake_channel_parcelable));
-  EXPECT_TRUE(fake_producer_parcelable.IsValid());
-
-  // Disconnect producer can be taken out, but only to an invalid parcelable.
-  ASSERT_EQ(mProducer->disconnect(kTestApi), OK);
-  EXPECT_EQ(mProducer->TakeAsParcelable(&fake_producer_parcelable), BAD_VALUE);
-  EXPECT_FALSE(producer_parcelable.IsValid());
-  EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), OK);
-  EXPECT_TRUE(producer_parcelable.IsValid());
-
-  // Should still be able to query buffer dimension after disconnect.
-  int32_t value = -1;
-  EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
-  EXPECT_EQ(static_cast<uint32_t>(value), kDefaultWidth);
-
-  EXPECT_EQ(mProducer->query(NATIVE_WINDOW_HEIGHT, &value), OK);
-  EXPECT_EQ(static_cast<uint32_t>(value), kDefaultHeight);
-
-  EXPECT_EQ(mProducer->query(NATIVE_WINDOW_FORMAT, &value), OK);
-  EXPECT_EQ(value, kDefaultFormat);
-
-  // But connect to API will fail.
-  IGraphicBufferProducer::QueueBufferOutput output;
-  EXPECT_EQ(mProducer->connect(kStubListener, kTestApi, kTestControlledByApp,
-                               &output),
-            BAD_VALUE);
-
-  // Create a new producer from the parcelable and connect to kTestApi should
-  // succeed.
-  sp<BufferHubProducer> new_producer =
-      BufferHubProducer::Create(std::move(producer_parcelable));
-  ASSERT_TRUE(new_producer != nullptr);
-  EXPECT_EQ(new_producer->connect(kStubListener, kTestApi, kTestControlledByApp,
-                                  &output),
-            OK);
-}
-
-}  // namespace
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp
index 96023dd..9dbeacb 100644
--- a/libs/vr/libdvr/Android.bp
+++ b/libs/vr/libdvr/Android.bp
@@ -33,87 +33,3 @@
     ],
     min_sdk_version: "29",
 }
-
-cc_library_headers {
-    name: "libdvr_private_headers",
-    export_include_dirs: ["."],
-    vendor_available: false,
-}
-
-cflags = [
-    "-DDVR_TRACKING_IMPLEMENTED=0",
-    "-DLOG_TAG=\"libdvr\"",
-    "-DTRACE=0",
-    "-Wall",
-    "-Werror",
-]
-
-srcs = [
-    "dvr_api.cpp",
-    "dvr_buffer.cpp",
-    "dvr_buffer_queue.cpp",
-    "dvr_configuration_data.cpp",
-    "dvr_display_manager.cpp",
-    "dvr_hardware_composer_client.cpp",
-    "dvr_performance.cpp",
-    "dvr_pose.cpp",
-    "dvr_surface.cpp",
-    "dvr_tracking.cpp",
-]
-
-static_libs = [
-    "libbroadcastring",
-    "libvrsensor",
-    "libdisplay",
-    "libvirtualtouchpadclient",
-    "libvr_hwc-impl",
-    "libvr_hwc-binder",
-    "libgrallocusage",
-    "libperformance",
-]
-
-shared_libs = [
-    "android.hardware.graphics.bufferqueue@1.0",
-    "android.hidl.token@1.0-utils",
-    "libbase",
-    "libbufferhubqueue",
-    "libbinder",
-    "liblog",
-    "libcutils",
-    "libutils",
-    "libnativewindow",
-    "libgui",
-    "libui",
-    "libpdx_default_transport",
-]
-
-cc_library_shared {
-    name: "libdvr.google",
-    system_ext_specific: true,
-    owner: "google",
-    cflags: cflags,
-    header_libs: ["libdvr_headers"],
-    export_header_lib_headers: ["libdvr_headers"],
-    srcs: srcs,
-    static_libs: static_libs,
-    shared_libs: shared_libs,
-    version_script: "exported_apis.lds",
-}
-
-// Also build a static libdvr for linking into tests. The linker script
-// restricting function access in the shared lib makes it inconvenient to use in
-// test code.
-cc_library_static {
-    name: "libdvr_static.google",
-    owner: "google",
-    cflags: cflags,
-    header_libs: ["libdvr_headers"],
-    export_header_lib_headers: ["libdvr_headers"],
-    srcs: srcs,
-    static_libs: static_libs,
-    shared_libs: shared_libs,
-}
-
-subdirs = [
-    "tests",
-]
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
deleted file mode 100644
index e099f6a..0000000
--- a/libs/vr/libdvr/dvr_api.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#include "include/dvr/dvr_api.h"
-
-#include <errno.h>
-#include <utils/Log.h>
-
-#include <algorithm>
-
-// Headers from libdvr
-#include <dvr/dvr_buffer.h>
-#include <dvr/dvr_buffer_queue.h>
-#include <dvr/dvr_configuration_data.h>
-#include <dvr/dvr_display_manager.h>
-#include <dvr/dvr_performance.h>
-#include <dvr/dvr_surface.h>
-#include <dvr/dvr_tracking.h>
-#include <dvr/dvr_vsync.h>
-
-// Headers not yet moved into libdvr.
-// TODO(jwcai) Move these once their callers are moved into Google3.
-#include <dvr/dvr_hardware_composer_client.h>
-#include <dvr/pose_client.h>
-#include <dvr/virtual_touchpad_client.h>
-
-extern "C" {
-
-int dvrGetApi(void* api, size_t struct_size, int version) {
-  ALOGI("dvrGetApi: api=%p struct_size=%zu version=%d", api, struct_size,
-        version);
-  if (version == 1) {
-    // New entry points are added at the end. If the caller's struct and
-    // this library have different sizes, we define the entry points in common.
-    // The caller is expected to handle unset entry points if necessary.
-    size_t clamped_struct_size = std::min(struct_size, sizeof(DvrApi_v1));
-    DvrApi_v1* dvr_api = static_cast<DvrApi_v1*>(api);
-
-// Defines an API entry for V1 (no version suffix).
-#define DVR_V1_API_ENTRY(name)                                 \
-  do {                                                         \
-    if ((offsetof(DvrApi_v1, name) + sizeof(dvr_api->name)) <= \
-        clamped_struct_size) {                                 \
-      dvr_api->name = dvr##name;                               \
-    }                                                          \
-  } while (0)
-
-#define DVR_V1_API_ENTRY_DEPRECATED(name)                      \
-  do {                                                         \
-    if ((offsetof(DvrApi_v1, name) + sizeof(dvr_api->name)) <= \
-        clamped_struct_size) {                                 \
-      dvr_api->name = nullptr;                                 \
-    }                                                          \
-  } while (0)
-
-#include "include/dvr/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
-
-    return 0;
-  }
-
-  ALOGE("dvrGetApi: Unknown API version=%d", version);
-  return -EINVAL;
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_buffer.cpp b/libs/vr/libdvr/dvr_buffer.cpp
deleted file mode 100644
index c11706f..0000000
--- a/libs/vr/libdvr/dvr_buffer.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "include/dvr/dvr_buffer.h"
-
-#include <android/hardware_buffer.h>
-#include <dvr/dvr_shared_buffers.h>
-#include <private/dvr/consumer_buffer.h>
-#include <private/dvr/producer_buffer.h>
-#include <ui/GraphicBuffer.h>
-
-#include "dvr_internal.h"
-
-using namespace android;
-
-namespace android {
-namespace dvr {
-
-DvrBuffer* CreateDvrBufferFromIonBuffer(
-    const std::shared_ptr<IonBuffer>& ion_buffer) {
-  if (!ion_buffer)
-    return nullptr;
-  return new DvrBuffer{std::move(ion_buffer)};
-}
-
-}  // namespace dvr
-}  // namespace android
-
-namespace {
-
-int ConvertToAHardwareBuffer(GraphicBuffer* graphic_buffer,
-                             AHardwareBuffer** hardware_buffer) {
-  if (!hardware_buffer || !graphic_buffer) {
-    return -EINVAL;
-  }
-  *hardware_buffer = reinterpret_cast<AHardwareBuffer*>(graphic_buffer);
-  AHardwareBuffer_acquire(*hardware_buffer);
-  return 0;
-}
-
-}  // anonymous namespace
-
-extern "C" {
-
-void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer) {
-  if (write_buffer != nullptr) {
-    ALOGW_IF(
-        write_buffer->slot != -1,
-        "dvrWriteBufferDestroy: Destroying a buffer associated with a valid "
-        "buffer queue slot. This may indicate possible leaks, buffer_id=%d.",
-        dvrWriteBufferGetId(write_buffer));
-    delete write_buffer;
-  }
-}
-
-int dvrWriteBufferIsValid(DvrWriteBuffer* write_buffer) {
-  return write_buffer && write_buffer->write_buffer;
-}
-
-int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer) {
-  if (!write_buffer || !write_buffer->write_buffer)
-    return -EINVAL;
-
-  return write_buffer->write_buffer->id();
-}
-
-int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
-                                     AHardwareBuffer** hardware_buffer) {
-  if (!write_buffer || !write_buffer->write_buffer)
-    return -EINVAL;
-
-  return ConvertToAHardwareBuffer(
-      write_buffer->write_buffer->buffer()->buffer().get(), hardware_buffer);
-}
-
-void dvrReadBufferDestroy(DvrReadBuffer* read_buffer) {
-  if (read_buffer != nullptr) {
-    ALOGW_IF(
-        read_buffer->slot != -1,
-        "dvrReadBufferDestroy: Destroying a buffer associated with a valid "
-        "buffer queue slot. This may indicate possible leaks, buffer_id=%d.",
-        dvrReadBufferGetId(read_buffer));
-    delete read_buffer;
-  }
-}
-
-int dvrReadBufferIsValid(DvrReadBuffer* read_buffer) {
-  return read_buffer && read_buffer->read_buffer;
-}
-
-int dvrReadBufferGetId(DvrReadBuffer* read_buffer) {
-  if (!read_buffer || !read_buffer->read_buffer)
-    return -EINVAL;
-
-  return read_buffer->read_buffer->id();
-}
-
-int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
-                                    AHardwareBuffer** hardware_buffer) {
-  if (!read_buffer || !read_buffer->read_buffer)
-    return -EINVAL;
-
-  return ConvertToAHardwareBuffer(
-      read_buffer->read_buffer->buffer()->buffer().get(), hardware_buffer);
-}
-
-void dvrBufferDestroy(DvrBuffer* buffer) { delete buffer; }
-
-int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
-                                AHardwareBuffer** hardware_buffer) {
-  if (!buffer || !buffer->buffer || !hardware_buffer) {
-    return -EINVAL;
-  }
-
-  return ConvertToAHardwareBuffer(buffer->buffer->buffer().get(),
-                                  hardware_buffer);
-}
-
-// Retrieve the shared buffer layout version defined in dvr_shared_buffers.h.
-int dvrBufferGlobalLayoutVersionGet() {
-  return android::dvr::kSharedBufferLayoutVersion;
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_buffer_queue.cpp b/libs/vr/libdvr/dvr_buffer_queue.cpp
deleted file mode 100644
index 1ca653c..0000000
--- a/libs/vr/libdvr/dvr_buffer_queue.cpp
+++ /dev/null
@@ -1,552 +0,0 @@
-#include "include/dvr/dvr_api.h"
-#include "include/dvr/dvr_buffer_queue.h"
-
-#include <android/native_window.h>
-#include <gui/BufferHubProducer.h>
-
-#include "dvr_internal.h"
-#include "dvr_buffer_queue_internal.h"
-
-using namespace android;
-using android::dvr::BufferHubBase;
-using android::dvr::ConsumerBuffer;
-using android::dvr::ConsumerQueue;
-using android::dvr::ProducerBuffer;
-using android::dvr::ProducerQueue;
-using android::dvr::ProducerQueueConfigBuilder;
-using android::dvr::UsagePolicy;
-
-extern "C" {
-
-DvrWriteBufferQueue::DvrWriteBufferQueue(
-    const std::shared_ptr<ProducerQueue>& producer_queue)
-    : producer_queue_(producer_queue),
-      width_(producer_queue->default_width()),
-      height_(producer_queue->default_height()),
-      format_(producer_queue->default_format()) {}
-
-int DvrWriteBufferQueue::GetNativeWindow(ANativeWindow** out_window) {
-  if (native_window_ == nullptr) {
-    // Lazy creation of |native_window|, as not everyone is using
-    // DvrWriteBufferQueue as an external surface.
-    sp<IGraphicBufferProducer> gbp = BufferHubProducer::Create(producer_queue_);
-    native_window_ = new Surface(gbp, true);
-  }
-
-  *out_window = static_cast<ANativeWindow*>(native_window_.get());
-  return 0;
-}
-
-int DvrWriteBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) {
-  std::unique_ptr<ConsumerQueue> consumer_queue =
-      producer_queue_->CreateConsumerQueue();
-  if (consumer_queue == nullptr) {
-    ALOGE(
-        "DvrWriteBufferQueue::CreateReadQueue: Failed to create consumer queue "
-        "from producer queue: queue_id=%d.", producer_queue_->id());
-    return -ENOMEM;
-  }
-
-  *out_read_queue = new DvrReadBufferQueue(std::move(consumer_queue));
-  return 0;
-}
-
-int DvrWriteBufferQueue::Dequeue(int timeout, DvrWriteBuffer* write_buffer,
-                                 int* out_fence_fd) {
-  DvrNativeBufferMetadata meta;
-  DvrWriteBuffer* buffer = nullptr;
-  int fence_fd = -1;
-  if (const int ret = GainBuffer(timeout, &buffer, &meta, &fence_fd))
-    return ret;
-  if (!buffer)
-    return -ENOMEM;
-
-  write_buffers_[buffer->slot].reset(buffer);
-  write_buffer->write_buffer = std::move(buffer->write_buffer);
-  *out_fence_fd = fence_fd;
-  return 0;
-}
-
-int DvrWriteBufferQueue::GainBuffer(int timeout,
-                                    DvrWriteBuffer** out_write_buffer,
-                                    DvrNativeBufferMetadata* out_meta,
-                                    int* out_fence_fd) {
-  size_t slot;
-  pdx::LocalHandle release_fence;
-
-  // Need to retry N+1 times, where N is total number of buffers in the queue.
-  // As in the worst case, we will dequeue all N buffers and reallocate them, on
-  // the {N+1}th dequeue, we are guaranteed to get a buffer with new dimension.
-  size_t max_retries = 1 + producer_queue_->capacity();
-  size_t retry = 0;
-
-  for (; retry < max_retries; retry++) {
-    auto buffer_status =
-        producer_queue_->Dequeue(timeout, &slot, out_meta, &release_fence);
-    if (!buffer_status) {
-      ALOGE_IF(buffer_status.error() != ETIMEDOUT,
-               "DvrWriteBufferQueue::GainBuffer: Failed to dequeue buffer: %s",
-               buffer_status.GetErrorMessage().c_str());
-      return -buffer_status.error();
-    }
-
-    if (write_buffers_[slot] == nullptr) {
-      // Lazy initialization of a write_buffers_ slot. Note that a slot will
-      // only be dynamically allocated once during the entire cycle life of a
-      // queue.
-      write_buffers_[slot] = std::make_unique<DvrWriteBuffer>();
-      write_buffers_[slot]->slot = slot;
-    }
-
-    LOG_ALWAYS_FATAL_IF(
-        write_buffers_[slot]->write_buffer,
-        "DvrWriteBufferQueue::GainBuffer: Buffer slot is not empty: %zu", slot);
-    write_buffers_[slot]->write_buffer = std::move(buffer_status.take());
-
-    const auto& producer_buffer = write_buffers_[slot]->write_buffer;
-    if (!producer_buffer)
-      return -ENOMEM;
-
-    if (width_ == producer_buffer->width() &&
-        height_ == producer_buffer->height() &&
-        format_ == producer_buffer->format()) {
-      // Producer queue returns a buffer matches the current request.
-      break;
-    }
-
-    // Needs reallocation. Note that if there are already multiple available
-    // buffers in the queue, the next one returned from |queue_->Dequeue| may
-    // still have the old buffer dimension or format. Retry up to N+1 times or
-    // until we dequeued a buffer with new configuration.
-    ALOGD_IF(TRACE,
-             "DvrWriteBufferQueue::Dequeue: requested buffer at slot: %zu "
-             "(w=%u, h=%u, fmt=%u) is different from the buffer returned "
-             "(w=%u, h=%u, fmt=%u). Need re-allocation.",
-             slot, width_, height_, format_, producer_buffer->width(),
-             producer_buffer->height(), producer_buffer->format());
-
-    // Currently, we are not storing |layer_count| and |usage| in queue
-    // configuration. Copy those setup from the last buffer dequeued before we
-    // remove it.
-    uint32_t old_layer_count = producer_buffer->layer_count();
-    uint64_t old_usage = producer_buffer->usage();
-
-    // Allocate a new producer buffer with new buffer configs. Note that if
-    // there are already multiple available buffers in the queue, the next one
-    // returned from |queue_->Dequeue| may still have the old buffer dimension
-    // or format. Retry up to BufferHubQueue::kMaxQueueCapacity times or until
-    // we dequeued a buffer with new configuration.
-    auto remove_status = producer_queue_->RemoveBuffer(slot);
-    if (!remove_status) {
-      ALOGE("DvrWriteBufferQueue::Dequeue: Failed to remove buffer: %s",
-            remove_status.GetErrorMessage().c_str());
-      return -remove_status.error();
-    }
-    // Make sure that the previously allocated buffer is dereferenced from
-    // write_buffers_ array.
-    write_buffers_[slot]->write_buffer = nullptr;
-
-    auto allocate_status = producer_queue_->AllocateBuffer(
-        width_, height_, old_layer_count, format_, old_usage);
-    if (!allocate_status) {
-      ALOGE("DvrWriteBufferQueue::Dequeue: Failed to allocate buffer: %s",
-            allocate_status.GetErrorMessage().c_str());
-      return -allocate_status.error();
-    }
-  }
-
-  if (retry >= max_retries) {
-    ALOGE(
-        "DvrWriteBufferQueue::Dequeue: Failed to re-allocate buffer after "
-        "resizing.");
-    return -ENOMEM;
-  }
-
-  *out_write_buffer = write_buffers_[slot].release();
-  *out_fence_fd = release_fence.Release();
-
-  return 0;
-}
-
-int DvrWriteBufferQueue::PostBuffer(DvrWriteBuffer* write_buffer,
-                                    const DvrNativeBufferMetadata* meta,
-                                    int ready_fence_fd) {
-  // Some basic sanity checks before we put the buffer back into a slot.
-  size_t slot = static_cast<size_t>(write_buffer->slot);
-  LOG_FATAL_IF(
-      (write_buffers->slot < 0 || write_buffers->slot >= write_buffers_.size()),
-      "DvrWriteBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot);
-
-  if (write_buffers_[slot] != nullptr) {
-    ALOGE("DvrWriteBufferQueue::PostBuffer: Slot is not empty: %zu", slot);
-    return -EINVAL;
-  }
-  if (write_buffer->write_buffer == nullptr) {
-    ALOGE("DvrWriteBufferQueue::PostBuffer: Invalid write buffer.");
-    return -EINVAL;
-  }
-  if (write_buffer->write_buffer->id() != producer_queue_->GetBufferId(slot)) {
-    ALOGE(
-        "DvrWriteBufferQueue::PostBuffer: Buffer to be posted does not "
-        "belong to this buffer queue. Posting buffer: id=%d, buffer in "
-        "queue: id=%d",
-        write_buffer->write_buffer->id(), producer_queue_->GetBufferId(slot));
-    return -EINVAL;
-  }
-
-  write_buffer->write_buffer->SetQueueIndex(next_post_index_++);
-  pdx::LocalHandle fence(ready_fence_fd);
-  const int ret = write_buffer->write_buffer->PostAsync(meta, fence);
-  if (ret < 0) {
-    ALOGE("DvrWriteBufferQueue::PostBuffer: Failed to post buffer, ret=%d",
-          ret);
-    return ret;
-  }
-
-  // Put the DvrWriteBuffer pointer back into its slot for reuse.
-  write_buffers_[slot].reset(write_buffer);
-  // It's import to reset the write buffer client now. It should stay invalid
-  // until next GainBuffer on the same slot.
-  write_buffers_[slot]->write_buffer = nullptr;
-  return 0;
-}
-
-int DvrWriteBufferQueue::ResizeBuffer(uint32_t width, uint32_t height) {
-  if (width == 0 || height == 0) {
-    ALOGE(
-        "DvrWriteBufferQueue::ResizeBuffer: invalid buffer dimension: w=%u, "
-        "h=%u.",
-        width, height);
-    return -EINVAL;
-  }
-
-  width_ = width;
-  height_ = height;
-  return 0;
-}
-
-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) {
-  if (!out_write_queue)
-    return -EINVAL;
-
-  auto config_builder = ProducerQueueConfigBuilder()
-                            .SetDefaultWidth(width)
-                            .SetDefaultHeight(height)
-                            .SetDefaultFormat(format)
-                            .SetMetadataSize(metadata_size);
-  std::unique_ptr<ProducerQueue> producer_queue =
-      ProducerQueue::Create(config_builder.Build(), UsagePolicy{});
-  if (!producer_queue) {
-    ALOGE("dvrWriteBufferQueueCreate: Failed to create producer queue.");
-    return -ENOMEM;
-  }
-
-  auto status = producer_queue->AllocateBuffers(width, height, layer_count,
-                                                format, usage, capacity);
-  if (!status.ok()) {
-    ALOGE("dvrWriteBufferQueueCreate: Failed to allocate buffers.");
-    return -ENOMEM;
-  }
-
-  *out_write_queue = new DvrWriteBufferQueue(std::move(producer_queue));
-  return 0;
-}
-
-void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue) {
-  delete write_queue;
-}
-
-ssize_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue) {
-  if (!write_queue)
-    return -EINVAL;
-
-  return write_queue->capacity();
-}
-
-int dvrWriteBufferQueueGetId(DvrWriteBufferQueue* write_queue) {
-  if (!write_queue)
-    return -EINVAL;
-
-  return write_queue->id();
-}
-
-int dvrWriteBufferQueueGetANativeWindow(DvrWriteBufferQueue* write_queue,
-                                        ANativeWindow** out_window) {
-  if (!write_queue || !out_window)
-    return -EINVAL;
-
-  return write_queue->GetNativeWindow(out_window);
-}
-
-int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
-                                       DvrReadBufferQueue** out_read_queue) {
-  if (!write_queue || !out_read_queue)
-    return -EINVAL;
-
-  return write_queue->CreateReadQueue(out_read_queue);
-}
-
-int dvrWriteBufferQueueGainBuffer(DvrWriteBufferQueue* write_queue, int timeout,
-                                  DvrWriteBuffer** out_write_buffer,
-                                  DvrNativeBufferMetadata* out_meta,
-                                  int* out_fence_fd) {
-  if (!write_queue || !out_write_buffer || !out_meta || !out_fence_fd)
-    return -EINVAL;
-
-  return write_queue->GainBuffer(timeout, out_write_buffer, out_meta,
-                                 out_fence_fd);
-}
-
-int dvrWriteBufferQueuePostBuffer(DvrWriteBufferQueue* write_queue,
-                                  DvrWriteBuffer* write_buffer,
-                                  const DvrNativeBufferMetadata* meta,
-                                  int ready_fence_fd) {
-  if (!write_queue || !write_buffer || !write_buffer->write_buffer || !meta)
-    return -EINVAL;
-
-  return write_queue->PostBuffer(write_buffer, meta, ready_fence_fd);
-}
-
-int dvrWriteBufferQueueResizeBuffer(DvrWriteBufferQueue* write_queue,
-                                    uint32_t width, uint32_t height) {
-  if (!write_queue)
-    return -EINVAL;
-
-  return write_queue->ResizeBuffer(width, height);
-}
-
-// ReadBufferQueue
-
-DvrReadBufferQueue::DvrReadBufferQueue(
-    const std::shared_ptr<ConsumerQueue>& consumer_queue)
-    : consumer_queue_(consumer_queue) {}
-
-int DvrReadBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) {
-  std::unique_ptr<ConsumerQueue> consumer_queue =
-      consumer_queue_->CreateConsumerQueue();
-  if (consumer_queue == nullptr) {
-    ALOGE(
-        "DvrReadBufferQueue::CreateReadQueue: Failed to create consumer queue "
-        "from producer queue: queue_id=%d.", consumer_queue_->id());
-    return -ENOMEM;
-  }
-
-  *out_read_queue = new DvrReadBufferQueue(std::move(consumer_queue));
-  return 0;
-}
-
-int DvrReadBufferQueue::AcquireBuffer(int timeout,
-                                      DvrReadBuffer** out_read_buffer,
-                                      DvrNativeBufferMetadata* out_meta,
-                                      int* out_fence_fd) {
-  size_t slot;
-  pdx::LocalHandle acquire_fence;
-  auto buffer_status =
-      consumer_queue_->Dequeue(timeout, &slot, out_meta, &acquire_fence);
-  if (!buffer_status) {
-    ALOGE_IF(buffer_status.error() != ETIMEDOUT,
-             "DvrReadBufferQueue::AcquireBuffer: Failed to dequeue buffer: %s",
-             buffer_status.GetErrorMessage().c_str());
-    return -buffer_status.error();
-  }
-
-  if (read_buffers_[slot] == nullptr) {
-    // Lazy initialization of a read_buffers_ slot. Note that a slot will only
-    // be dynamically allocated once during the entire cycle life of a queue.
-    read_buffers_[slot] = std::make_unique<DvrReadBuffer>();
-    read_buffers_[slot]->slot = slot;
-  }
-
-  LOG_FATAL_IF(
-      read_buffers_[slot]->read_buffer,
-      "DvrReadBufferQueue::AcquireBuffer: Buffer slot is not empty: %zu", slot);
-  read_buffers_[slot]->read_buffer = std::move(buffer_status.take());
-
-  *out_read_buffer = read_buffers_[slot].release();
-  *out_fence_fd = acquire_fence.Release();
-
-  return 0;
-}
-
-int DvrReadBufferQueue::ReleaseBuffer(DvrReadBuffer* read_buffer,
-                                      const DvrNativeBufferMetadata* meta,
-                                      int release_fence_fd) {
-  // Some basic sanity checks before we put the buffer back into a slot.
-  size_t slot = static_cast<size_t>(read_buffer->slot);
-  LOG_FATAL_IF(
-      (read_buffers->slot < 0 || read_buffers->slot >= read_buffers_size()),
-      "DvrReadBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot);
-
-  if (read_buffers_[slot] != nullptr) {
-    ALOGE("DvrReadBufferQueue::ReleaseBuffer: Slot is not empty: %zu", slot);
-    return -EINVAL;
-  }
-  if (read_buffer->read_buffer == nullptr) {
-    ALOGE("DvrReadBufferQueue::ReleaseBuffer: Invalid read buffer.");
-    return -EINVAL;
-  }
-  if (read_buffer->read_buffer->id() != consumer_queue_->GetBufferId(slot)) {
-    if (consumer_queue_->GetBufferId(slot) > 0) {
-      ALOGE(
-          "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released may not "
-          "belong to this queue (queue_id=%d): attempting to release buffer "
-          "(buffer_id=%d) at slot %d which holds a different buffer "
-          "(buffer_id=%d).",
-          consumer_queue_->id(), read_buffer->read_buffer->id(),
-          static_cast<int>(slot), consumer_queue_->GetBufferId(slot));
-    } else {
-      ALOGI(
-          "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released may not "
-          "belong to this queue (queue_id=%d): attempting to release buffer "
-          "(buffer_id=%d) at slot %d which is empty.",
-          consumer_queue_->id(), read_buffer->read_buffer->id(),
-          static_cast<int>(slot));
-    }
-  }
-
-  pdx::LocalHandle fence(release_fence_fd);
-  int ret = read_buffer->read_buffer->ReleaseAsync(meta, fence);
-  if (ret < 0) {
-    ALOGE("DvrReadBufferQueue::ReleaseBuffer: Failed to release buffer, ret=%d",
-          ret);
-    return ret;
-  }
-
-  // Put the DvrReadBuffer pointer back into its slot for reuse.
-  read_buffers_[slot].reset(read_buffer);
-  // It's import to reset the read buffer client now. It should stay invalid
-  // until next AcquireBuffer on the same slot.
-  read_buffers_[slot]->read_buffer = nullptr;
-  return 0;
-}
-
-void DvrReadBufferQueue::SetBufferAvailableCallback(
-    DvrReadBufferQueueBufferAvailableCallback callback, void* context) {
-  if (callback == nullptr) {
-    consumer_queue_->SetBufferAvailableCallback(nullptr);
-  } else {
-    consumer_queue_->SetBufferAvailableCallback(
-        [callback, context]() { callback(context); });
-  }
-}
-
-void DvrReadBufferQueue::SetBufferRemovedCallback(
-    DvrReadBufferQueueBufferRemovedCallback callback, void* context) {
-  if (callback == nullptr) {
-    consumer_queue_->SetBufferRemovedCallback(nullptr);
-  } else {
-    consumer_queue_->SetBufferRemovedCallback(
-        [callback, context](const std::shared_ptr<BufferHubBase>& buffer) {
-          // When buffer is removed from the queue, the slot is already invalid.
-          auto read_buffer = std::make_unique<DvrReadBuffer>();
-          read_buffer->read_buffer =
-              std::static_pointer_cast<ConsumerBuffer>(buffer);
-          callback(read_buffer.release(), context);
-        });
-  }
-}
-
-int DvrReadBufferQueue::HandleEvents() {
-  // TODO(jwcai) Probably should change HandleQueueEvents to return Status.
-  consumer_queue_->HandleQueueEvents();
-  return 0;
-}
-
-void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue) {
-  delete read_queue;
-}
-
-ssize_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue) {
-  if (!read_queue)
-    return -EINVAL;
-
-  return read_queue->capacity();
-}
-
-int dvrReadBufferQueueGetId(DvrReadBufferQueue* read_queue) {
-  if (!read_queue)
-    return -EINVAL;
-
-  return read_queue->id();
-}
-
-int dvrReadBufferQueueGetEventFd(DvrReadBufferQueue* read_queue) {
-  if (!read_queue)
-    return -EINVAL;
-
-  return read_queue->event_fd();
-}
-
-int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
-                                      DvrReadBufferQueue** out_read_queue) {
-  if (!read_queue || !out_read_queue)
-    return -EINVAL;
-
-  return read_queue->CreateReadQueue(out_read_queue);
-}
-
-int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout,
-                              DvrReadBuffer* read_buffer, int* out_fence_fd,
-                              void* out_meta, size_t meta_size_bytes) {
-  if (!read_queue || !read_buffer || !out_fence_fd)
-    return -EINVAL;
-
-  if (meta_size_bytes != 0 && !out_meta)
-    return -EINVAL;
-
-  return read_queue->Dequeue(timeout, read_buffer, out_fence_fd, out_meta,
-                             meta_size_bytes);
-}
-
-int dvrReadBufferQueueAcquireBuffer(DvrReadBufferQueue* read_queue, int timeout,
-                                    DvrReadBuffer** out_read_buffer,
-                                    DvrNativeBufferMetadata* out_meta,
-                                    int* out_fence_fd) {
-  if (!read_queue || !out_read_buffer || !out_meta || !out_fence_fd)
-    return -EINVAL;
-
-  return read_queue->AcquireBuffer(timeout, out_read_buffer, out_meta,
-                                   out_fence_fd);
-}
-
-int dvrReadBufferQueueReleaseBuffer(DvrReadBufferQueue* read_queue,
-                                    DvrReadBuffer* read_buffer,
-                                    const DvrNativeBufferMetadata* meta,
-                                    int release_fence_fd) {
-  if (!read_queue || !read_buffer || !read_buffer->read_buffer || !meta)
-    return -EINVAL;
-
-  return read_queue->ReleaseBuffer(read_buffer, meta, release_fence_fd);
-}
-
-int dvrReadBufferQueueSetBufferAvailableCallback(
-    DvrReadBufferQueue* read_queue,
-    DvrReadBufferQueueBufferAvailableCallback callback, void* context) {
-  if (!read_queue)
-    return -EINVAL;
-
-  read_queue->SetBufferAvailableCallback(callback, context);
-  return 0;
-}
-
-int dvrReadBufferQueueSetBufferRemovedCallback(
-    DvrReadBufferQueue* read_queue,
-    DvrReadBufferQueueBufferRemovedCallback callback, void* context) {
-  if (!read_queue)
-    return -EINVAL;
-
-  read_queue->SetBufferRemovedCallback(callback, context);
-  return 0;
-}
-
-int dvrReadBufferQueueHandleEvents(DvrReadBufferQueue* read_queue) {
-  if (!read_queue)
-    return -EINVAL;
-
-  return read_queue->HandleEvents();
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_buffer_queue_internal.h b/libs/vr/libdvr/dvr_buffer_queue_internal.h
deleted file mode 100644
index e53a686..0000000
--- a/libs/vr/libdvr/dvr_buffer_queue_internal.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_
-#define ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_
-
-#include <gui/Surface.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <sys/cdefs.h>
-
-#include <array>
-#include <memory>
-
-#include "dvr_internal.h"
-
-struct ANativeWindow;
-
-typedef struct DvrNativeBufferMetadata DvrNativeBufferMetadata;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-typedef void (*DvrReadBufferQueueBufferAvailableCallback)(void* context);
-typedef void (*DvrReadBufferQueueBufferRemovedCallback)(DvrReadBuffer* buffer,
-                                                        void* context);
-
-struct DvrWriteBufferQueue {
-  using BufferHubQueue = android::dvr::BufferHubQueue;
-  using ProducerQueue = android::dvr::ProducerQueue;
-
-  // Create a concrete object for DvrWriteBufferQueue.
-  //
-  // @param producer_queue The BufferHub's ProducerQueue that is used to back
-  //     this DvrWriteBufferQueue, must not be NULL.
-  explicit DvrWriteBufferQueue(
-      const std::shared_ptr<ProducerQueue>& producer_queue);
-
-  int id() const { return producer_queue_->id(); }
-  uint32_t width() const { return width_; };
-  uint32_t height() const { return height_; };
-  uint32_t format() const { return format_; };
-  size_t capacity() const { return producer_queue_->capacity(); }
-  const std::shared_ptr<ProducerQueue>& producer_queue() const {
-    return producer_queue_;
-  }
-
-  int GetNativeWindow(ANativeWindow** out_window);
-  int CreateReadQueue(DvrReadBufferQueue** out_read_queue);
-  int Dequeue(int timeout, DvrWriteBuffer* write_buffer, int* out_fence_fd);
-  int GainBuffer(int timeout, DvrWriteBuffer** out_write_buffer,
-                 DvrNativeBufferMetadata* out_meta, int* out_fence_fd);
-  int PostBuffer(DvrWriteBuffer* write_buffer,
-                 const DvrNativeBufferMetadata* meta, int ready_fence_fd);
-  int ResizeBuffer(uint32_t width, uint32_t height);
-
- private:
-  std::shared_ptr<ProducerQueue> producer_queue_;
-  std::array<std::unique_ptr<DvrWriteBuffer>, BufferHubQueue::kMaxQueueCapacity>
-      write_buffers_;
-
-  int64_t next_post_index_ = 0;
-  uint32_t width_;
-  uint32_t height_;
-  uint32_t format_;
-
-  android::sp<android::Surface> native_window_;
-};
-
-struct DvrReadBufferQueue {
-  using BufferHubQueue = android::dvr::BufferHubQueue;
-  using ConsumerQueue = android::dvr::ConsumerQueue;
-
-  explicit DvrReadBufferQueue(
-      const std::shared_ptr<ConsumerQueue>& consumer_queue);
-
-  int id() const { return consumer_queue_->id(); }
-  int event_fd() const { return consumer_queue_->queue_fd(); }
-  size_t capacity() const { return consumer_queue_->capacity(); }
-
-  int CreateReadQueue(DvrReadBufferQueue** out_read_queue);
-  int Dequeue(int timeout, DvrReadBuffer* read_buffer, int* out_fence_fd,
-              void* out_meta, size_t user_metadata_size);
-  int AcquireBuffer(int timeout, DvrReadBuffer** out_read_buffer,
-                    DvrNativeBufferMetadata* out_meta, int* out_fence_fd);
-  int ReleaseBuffer(DvrReadBuffer* read_buffer,
-                    const DvrNativeBufferMetadata* meta, int release_fence_fd);
-  void SetBufferAvailableCallback(
-      DvrReadBufferQueueBufferAvailableCallback callback, void* context);
-  void SetBufferRemovedCallback(
-      DvrReadBufferQueueBufferRemovedCallback callback, void* context);
-  int HandleEvents();
-
- private:
-  std::shared_ptr<ConsumerQueue> consumer_queue_;
-  std::array<std::unique_ptr<DvrReadBuffer>, BufferHubQueue::kMaxQueueCapacity>
-      read_buffers_;
-};
-
-#endif  // ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_
diff --git a/libs/vr/libdvr/dvr_configuration_data.cpp b/libs/vr/libdvr/dvr_configuration_data.cpp
deleted file mode 100644
index df0d54e..0000000
--- a/libs/vr/libdvr/dvr_configuration_data.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "include/dvr/dvr_configuration_data.h"
-
-#include <private/dvr/display_client.h>
-
-using android::dvr::display::ConfigFileType;
-using android::dvr::display::DisplayClient;
-
-extern "C" {
-
-int dvrConfigurationDataGet(int config_type, uint8_t** data,
-                            size_t* data_size) {
-  if (!data || !data_size) {
-    return -EINVAL;
-  }
-
-  auto client = DisplayClient::Create();
-  if (!client) {
-    ALOGE("dvrGetGlobalBuffer: Failed to create display client!");
-    return -ECOMM;
-  }
-
-  ConfigFileType config_file_type = static_cast<ConfigFileType>(config_type);
-  auto config_data_status =
-      client->GetConfigurationData(config_file_type);
-
-  if (!config_data_status) {
-    return -config_data_status.error();
-  }
-
-  *data_size = config_data_status.get().size();
-  *data = new uint8_t[*data_size];
-  std::copy_n(config_data_status.get().begin(), *data_size, *data);
-  return 0;
-}
-
-void dvrConfigurationDataDestroy(uint8_t* data) {
-  delete[] data;
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_display_manager.cpp b/libs/vr/libdvr/dvr_display_manager.cpp
deleted file mode 100644
index 7f631e3..0000000
--- a/libs/vr/libdvr/dvr_display_manager.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-#include "include/dvr/dvr_display_manager.h"
-
-#include <dvr/dvr_buffer.h>
-#include <pdx/rpc/variant.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/consumer_buffer.h>
-#include <private/dvr/display_client.h>
-#include <private/dvr/display_manager_client.h>
-
-#include "dvr_internal.h"
-#include "dvr_buffer_queue_internal.h"
-
-using android::dvr::ConsumerBuffer;
-using android::dvr::display::DisplayManagerClient;
-using android::dvr::display::SurfaceAttribute;
-using android::dvr::display::SurfaceAttributes;
-using android::dvr::display::SurfaceState;
-using android::pdx::rpc::EmptyVariant;
-
-namespace {
-
-// Extracts type and value from the attribute Variant and writes them into the
-// respective fields of DvrSurfaceAttribute.
-struct AttributeVisitor {
-  DvrSurfaceAttribute* attribute;
-
-  void operator()(int32_t value) {
-    attribute->value.int32_value = value;
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32;
-  }
-  void operator()(int64_t value) {
-    attribute->value.int64_value = value;
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT64;
-  }
-  void operator()(bool value) {
-    attribute->value.bool_value = value;
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL;
-  }
-  void operator()(float value) {
-    attribute->value.float_value = value;
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT;
-  }
-  void operator()(const std::array<float, 2>& value) {
-    std::copy(value.cbegin(), value.cend(), attribute->value.float2_value);
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2;
-  }
-  void operator()(const std::array<float, 3>& value) {
-    std::copy(value.cbegin(), value.cend(), attribute->value.float3_value);
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3;
-  }
-  void operator()(const std::array<float, 4>& value) {
-    std::copy(value.cbegin(), value.cend(), attribute->value.float4_value);
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4;
-  }
-  void operator()(const std::array<float, 8>& value) {
-    std::copy(value.cbegin(), value.cend(), attribute->value.float8_value);
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8;
-  }
-  void operator()(const std::array<float, 16>& value) {
-    std::copy(value.cbegin(), value.cend(), attribute->value.float16_value);
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16;
-  }
-  void operator()(EmptyVariant) {
-    attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_NONE;
-  }
-};
-
-size_t ConvertSurfaceAttributes(const SurfaceAttributes& surface_attributes,
-                                DvrSurfaceAttribute* attributes,
-                                size_t max_count) {
-  size_t count = 0;
-  for (const auto& attribute : surface_attributes) {
-    if (count >= max_count)
-      break;
-
-    // Copy the key and extract the Variant value using a visitor.
-    attributes[count].key = attribute.first;
-    attribute.second.Visit(AttributeVisitor{&attributes[count]});
-    count++;
-  }
-
-  return count;
-}
-
-}  // anonymous namespace
-
-extern "C" {
-
-struct DvrDisplayManager {
-  std::unique_ptr<DisplayManagerClient> client;
-};
-
-struct DvrSurfaceState {
-  std::vector<SurfaceState> state;
-};
-
-int dvrDisplayManagerCreate(DvrDisplayManager** client_out) {
-  if (!client_out)
-    return -EINVAL;
-
-  auto client = DisplayManagerClient::Create();
-  if (!client) {
-    ALOGE("dvrDisplayManagerCreate: Failed to create display manager client!");
-    return -EIO;
-  }
-
-  *client_out = new DvrDisplayManager{std::move(client)};
-  return 0;
-}
-
-void dvrDisplayManagerDestroy(DvrDisplayManager* client) { delete client; }
-
-int dvrDisplayManagerGetEventFd(DvrDisplayManager* client) {
-  if (!client)
-    return -EINVAL;
-
-  return client->client->event_fd();
-}
-
-int dvrDisplayManagerTranslateEpollEventMask(DvrDisplayManager* client,
-                                             int in_events, int* out_events) {
-  if (!client || !out_events)
-    return -EINVAL;
-
-  auto status = client->client->GetEventMask(in_events);
-  if (!status)
-    return -status.error();
-
-  *out_events = status.get();
-  return 0;
-}
-
-int dvrDisplayManagerGetSurfaceState(DvrDisplayManager* client,
-                                     DvrSurfaceState* state) {
-  if (!client || !state)
-    return -EINVAL;
-
-  auto status = client->client->GetSurfaceState();
-  if (!status)
-    return -status.error();
-
-  state->state = status.take();
-  return 0;
-}
-
-int dvrDisplayManagerGetReadBufferQueue(DvrDisplayManager* client,
-                                        int surface_id, int queue_id,
-                                        DvrReadBufferQueue** queue_out) {
-  if (!client || !queue_out)
-    return -EINVAL;
-
-  auto status = client->client->GetSurfaceQueue(surface_id, queue_id);
-  if (!status) {
-    ALOGE("dvrDisplayManagerGetReadBufferQueue: Failed to get queue: %s",
-          status.GetErrorMessage().c_str());
-    return -status.error();
-  }
-
-  *queue_out = new DvrReadBufferQueue(status.take());
-  return 0;
-}
-
-int dvrSurfaceStateCreate(DvrSurfaceState** surface_state_out) {
-  if (!surface_state_out)
-    return -EINVAL;
-
-  *surface_state_out = new DvrSurfaceState{};
-  return 0;
-}
-
-void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state) {
-  delete surface_state;
-}
-
-int dvrSurfaceStateGetSurfaceCount(DvrSurfaceState* surface_state,
-                                   size_t* count_out) {
-  if (!surface_state)
-    return -EINVAL;
-
-  *count_out = surface_state->state.size();
-  return 0;
-}
-
-int dvrSurfaceStateGetUpdateFlags(DvrSurfaceState* surface_state,
-                                  size_t surface_index,
-                                  DvrSurfaceUpdateFlags* flags_out) {
-  if (!surface_state || surface_index >= surface_state->state.size())
-    return -EINVAL;
-
-  *flags_out = surface_state->state[surface_index].update_flags;
-  return 0;
-}
-
-int dvrSurfaceStateGetSurfaceId(DvrSurfaceState* surface_state,
-                                size_t surface_index, int* surface_id_out) {
-  if (!surface_state || surface_index >= surface_state->state.size())
-    return -EINVAL;
-
-  *surface_id_out = surface_state->state[surface_index].surface_id;
-  return 0;
-}
-
-int dvrSurfaceStateGetProcessId(DvrSurfaceState* surface_state,
-                                size_t surface_index, int* process_id_out) {
-  if (!surface_state || surface_index >= surface_state->state.size())
-    return -EINVAL;
-
-  *process_id_out = surface_state->state[surface_index].process_id;
-  return 0;
-}
-
-int dvrSurfaceStateGetQueueCount(DvrSurfaceState* surface_state,
-                                 size_t surface_index, size_t* count_out) {
-  if (!surface_state || surface_index >= surface_state->state.size())
-    return -EINVAL;
-
-  *count_out = surface_state->state[surface_index].queue_ids.size();
-  return 0;
-}
-
-ssize_t dvrSurfaceStateGetQueueIds(DvrSurfaceState* surface_state,
-                                   size_t surface_index, int* queue_ids,
-                                   size_t max_count) {
-  if (!surface_state || surface_index >= surface_state->state.size())
-    return -EINVAL;
-
-  size_t i;
-  const auto& state = surface_state->state[surface_index];
-  for (i = 0; i < std::min(max_count, state.queue_ids.size()); i++) {
-    queue_ids[i] = state.queue_ids[i];
-  }
-
-  return i;
-}
-
-int dvrSurfaceStateGetZOrder(DvrSurfaceState* surface_state,
-                             size_t surface_index, int* z_order_out) {
-  if (!surface_state || surface_index >= surface_state->state.size() ||
-      !z_order_out) {
-    return -EINVAL;
-  }
-
-  *z_order_out = surface_state->state[surface_index].GetZOrder();
-  return 0;
-}
-
-int dvrSurfaceStateGetVisible(DvrSurfaceState* surface_state,
-                              size_t surface_index, bool* visible_out) {
-  if (!surface_state || surface_index >= surface_state->state.size() ||
-      !visible_out) {
-    return -EINVAL;
-  }
-
-  *visible_out = surface_state->state[surface_index].GetVisible();
-  return 0;
-}
-
-int dvrSurfaceStateGetAttributeCount(DvrSurfaceState* surface_state,
-                                     size_t surface_index, size_t* count_out) {
-  if (!surface_state || surface_index >= surface_state->state.size() ||
-      !count_out) {
-    return -EINVAL;
-  }
-
-  *count_out = surface_state->state[surface_index].surface_attributes.size();
-  return 0;
-}
-
-ssize_t dvrSurfaceStateGetAttributes(DvrSurfaceState* surface_state,
-                                     size_t surface_index,
-                                     DvrSurfaceAttribute* attributes,
-                                     size_t max_count) {
-  if (!surface_state || surface_index >= surface_state->state.size() ||
-      !attributes) {
-    return -EINVAL;
-  }
-
-  return ConvertSurfaceAttributes(
-      surface_state->state[surface_index].surface_attributes, attributes,
-      max_count);
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_hardware_composer_client.cpp b/libs/vr/libdvr/dvr_hardware_composer_client.cpp
deleted file mode 100644
index 4e87cf6..0000000
--- a/libs/vr/libdvr/dvr_hardware_composer_client.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-#include "include/dvr/dvr_hardware_composer_client.h"
-
-#include <android/dvr/IVrComposer.h>
-#include <android/dvr/BnVrComposerCallback.h>
-#include <android/hardware_buffer.h>
-#include <binder/IServiceManager.h>
-#include <private/android/AHardwareBufferHelpers.h>
-
-#include <functional>
-#include <memory>
-#include <mutex>
-
-struct DvrHwcFrame {
-  android::dvr::ComposerView::Frame frame;
-};
-
-namespace {
-
-class HwcCallback : public android::dvr::BnVrComposerCallback {
- public:
-  using CallbackFunction = std::function<int(DvrHwcFrame*)>;
-
-  explicit HwcCallback(const CallbackFunction& callback);
-  ~HwcCallback() override;
-
-  // Reset the callback. This needs to be done early to avoid use after free
-  // accesses from binder thread callbacks.
-  void Shutdown();
-
-  std::unique_ptr<DvrHwcFrame> DequeueFrame();
-
- private:
-  // android::dvr::BnVrComposerCallback:
-  android::binder::Status onNewFrame(
-      const android::dvr::ParcelableComposerFrame& frame,
-      android::dvr::ParcelableUniqueFd* fence) override;
-
-  // Protects the |callback_| from uses from multiple threads. During shutdown
-  // there may be in-flight frame update events. In those cases the callback
-  // access needs to be protected otherwise binder threads may access an invalid
-  // callback.
-  std::mutex mutex_;
-  CallbackFunction callback_;
-
-  HwcCallback(const HwcCallback&) = delete;
-  void operator=(const HwcCallback&) = delete;
-};
-
-HwcCallback::HwcCallback(const CallbackFunction& callback)
-    : callback_(callback) {}
-
-HwcCallback::~HwcCallback() {}
-
-void HwcCallback::Shutdown() {
-  std::lock_guard<std::mutex> guard(mutex_);
-  callback_ = nullptr;
-}
-
-android::binder::Status HwcCallback::onNewFrame(
-    const android::dvr::ParcelableComposerFrame& frame,
-    android::dvr::ParcelableUniqueFd* fence) {
-  std::lock_guard<std::mutex> guard(mutex_);
-
-  if (!callback_) {
-    fence->set_fence(android::base::unique_fd());
-    return android::binder::Status::ok();
-  }
-
-  std::unique_ptr<DvrHwcFrame> dvr_frame(new DvrHwcFrame());
-  dvr_frame->frame = frame.frame();
-
-  fence->set_fence(android::base::unique_fd(callback_(dvr_frame.release())));
-  return android::binder::Status::ok();
-}
-
-}  // namespace
-
-struct DvrHwcClient {
-  android::sp<android::dvr::IVrComposer> composer;
-  android::sp<HwcCallback> callback;
-};
-
-DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback, void* data) {
-  std::unique_ptr<DvrHwcClient> client(new DvrHwcClient());
-
-  android::sp<android::IServiceManager> sm(android::defaultServiceManager());
-  client->composer = android::interface_cast<android::dvr::IVrComposer>(
-      sm->getService(android::dvr::IVrComposer::SERVICE_NAME()));
-  if (!client->composer.get())
-    return nullptr;
-
-  client->callback = new HwcCallback(std::bind(callback, data,
-                                               std::placeholders::_1));
-  android::binder::Status status = client->composer->registerObserver(
-      client->callback);
-  if (!status.isOk())
-    return nullptr;
-
-  return client.release();
-}
-
-void dvrHwcClientDestroy(DvrHwcClient* client) {
-  client->composer->clearObserver();
-
-  // NOTE: Deleting DvrHwcClient* isn't enough since DvrHwcClient::callback is a
-  // shared pointer that could be referenced from a binder thread. But the
-  // client callback isn't valid past this calls so that needs to be reset.
-  client->callback->Shutdown();
-
-  delete client;
-}
-
-void dvrHwcFrameDestroy(DvrHwcFrame* frame) {
-  delete frame;
-}
-
-DvrHwcDisplay dvrHwcFrameGetDisplayId(DvrHwcFrame* frame) {
-  return frame->frame.display_id;
-}
-
-int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame) {
-  return frame->frame.display_width;
-}
-
-int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame) {
-  return frame->frame.display_height;
-}
-
-bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame) {
-  return frame->frame.removed;
-}
-
-size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame) {
-  return frame->frame.layers.size();
-}
-
-uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame) {
-  return static_cast<uint32_t>(frame->frame.active_config);
-}
-
-uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame) {
-  return static_cast<uint32_t>(frame->frame.color_mode);
-}
-
-void dvrHwcFrameGetColorTransform(DvrHwcFrame* frame, float* out_matrix,
-                                  int32_t* out_hint) {
-  *out_hint = frame->frame.color_transform_hint;
-  memcpy(out_matrix, frame->frame.color_transform,
-         sizeof(frame->frame.color_transform));
-}
-
-uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame) {
-  return static_cast<uint32_t>(frame->frame.power_mode);
-}
-
-uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame) {
-  return static_cast<uint32_t>(frame->frame.vsync_enabled);
-}
-
-DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].id;
-}
-
-AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame,
-                                           size_t layer_index) {
-  AHardwareBuffer* buffer = android::AHardwareBuffer_from_GraphicBuffer(
-      frame->frame.layers[layer_index].buffer.get());
-  AHardwareBuffer_acquire(buffer);
-  return buffer;
-}
-
-int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].fence->dup();
-}
-
-DvrHwcRecti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame,
-                                            size_t layer_index) {
-  return DvrHwcRecti{
-    frame->frame.layers[layer_index].display_frame.left,
-    frame->frame.layers[layer_index].display_frame.top,
-    frame->frame.layers[layer_index].display_frame.right,
-    frame->frame.layers[layer_index].display_frame.bottom,
-  };
-}
-
-DvrHwcRectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index) {
-  return DvrHwcRectf{
-    frame->frame.layers[layer_index].crop.left,
-    frame->frame.layers[layer_index].crop.top,
-    frame->frame.layers[layer_index].crop.right,
-    frame->frame.layers[layer_index].crop.bottom,
-  };
-}
-
-DvrHwcBlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame,
-                                             size_t layer_index) {
-  return static_cast<DvrHwcBlendMode>(
-      frame->frame.layers[layer_index].blend_mode);
-}
-
-float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].alpha;
-}
-
-uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].type;
-}
-
-uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
-                                          size_t layer_index) {
-  return frame->frame.layers[layer_index].app_id;
-}
-
-uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].z_order;
-}
-
-void dvrHwcFrameGetLayerCursor(DvrHwcFrame* frame, size_t layer_index,
-                               int32_t* out_x, int32_t* out_y) {
-  *out_x = frame->frame.layers[layer_index].cursor_x;
-  *out_y = frame->frame.layers[layer_index].cursor_y;
-}
-
-uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].transform;
-}
-
-uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index) {
-  return frame->frame.layers[layer_index].dataspace;
-}
-
-uint32_t dvrHwcFrameGetLayerColor(DvrHwcFrame* frame, size_t layer_index) {
-  const auto& color = frame->frame.layers[layer_index].color;
-  return color.r | (static_cast<uint32_t>(color.g) << 8) |
-         (static_cast<uint32_t>(color.b) << 16) |
-         (static_cast<uint32_t>(color.a) << 24);
-}
-
-uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame,
-                                              size_t layer_index) {
-  return frame->frame.layers[layer_index].visible_regions.size();
-}
-
-DvrHwcRecti dvrHwcFrameGetLayerVisibleRegion(DvrHwcFrame* frame,
-                                             size_t layer_index, size_t index) {
-  return DvrHwcRecti{
-      frame->frame.layers[layer_index].visible_regions[index].left,
-      frame->frame.layers[layer_index].visible_regions[index].top,
-      frame->frame.layers[layer_index].visible_regions[index].right,
-      frame->frame.layers[layer_index].visible_regions[index].bottom,
-  };
-}
-
-uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame,
-                                              size_t layer_index) {
-  return frame->frame.layers[layer_index].damaged_regions.size();
-}
-
-DvrHwcRecti dvrHwcFrameGetLayerDamagedRegion(DvrHwcFrame* frame,
-                                             size_t layer_index, size_t index) {
-  return DvrHwcRecti{
-      frame->frame.layers[layer_index].damaged_regions[index].left,
-      frame->frame.layers[layer_index].damaged_regions[index].top,
-      frame->frame.layers[layer_index].damaged_regions[index].right,
-      frame->frame.layers[layer_index].damaged_regions[index].bottom,
-  };
-}
diff --git a/libs/vr/libdvr/dvr_internal.h b/libs/vr/libdvr/dvr_internal.h
deleted file mode 100644
index f845cd8..0000000
--- a/libs/vr/libdvr/dvr_internal.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef ANDROID_DVR_INTERNAL_H_
-#define ANDROID_DVR_INTERNAL_H_
-
-#include <sys/cdefs.h>
-
-#include <memory>
-
-extern "C" {
-
-typedef struct DvrBuffer DvrBuffer;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-
-}  // extern "C"
-
-namespace android {
-namespace dvr {
-
-class IonBuffer;
-
-DvrBuffer* CreateDvrBufferFromIonBuffer(
-    const std::shared_ptr<IonBuffer>& ion_buffer);
-
-}  // namespace dvr
-}  // namespace android
-
-extern "C" {
-
-struct DvrWriteBuffer {
-  // The slot nubmer of the buffer, a valid slot number must be in the range of
-  // [0, android::BufferQueueDefs::NUM_BUFFER_SLOTS). This is only valid for
-  // DvrWriteBuffer acquired from a DvrWriteBufferQueue.
-  int32_t slot = -1;
-
-  std::shared_ptr<android::dvr::ProducerBuffer> write_buffer;
-};
-
-struct DvrReadBuffer {
-  // The slot nubmer of the buffer, a valid slot number must be in the range of
-  // [0, android::BufferQueueDefs::NUM_BUFFER_SLOTS). This is only valid for
-  // DvrReadBuffer acquired from a DvrReadBufferQueue.
-  int32_t slot = -1;
-
-  std::shared_ptr<android::dvr::ConsumerBuffer> read_buffer;
-};
-
-struct DvrBuffer {
-  std::shared_ptr<android::dvr::IonBuffer> buffer;
-};
-
-}  // extern "C"
-
-#endif  // ANDROID_DVR_INTERNAL_H_
diff --git a/libs/vr/libdvr/dvr_performance.cpp b/libs/vr/libdvr/dvr_performance.cpp
deleted file mode 100644
index 599101f..0000000
--- a/libs/vr/libdvr/dvr_performance.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "include/dvr/dvr_performance.h"
-
-#include <private/dvr/performance_client.h>
-
-using android::dvr::PerformanceClient;
-
-extern "C" {
-
-int dvrPerformanceSetSchedulerPolicy(pid_t task_id,
-                                     const char* scheduler_policy) {
-  int error;
-  if (auto client = PerformanceClient::Create(&error))
-    return client->SetSchedulerPolicy(task_id, scheduler_policy);
-  else
-    return error;
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_pose.cpp b/libs/vr/libdvr/dvr_pose.cpp
deleted file mode 100644
index c379ef5..0000000
--- a/libs/vr/libdvr/dvr_pose.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "include/dvr/dvr_pose.h"
-
-#include <memory>
-
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/pose_client_internal.h>
-
-#include "dvr_buffer_queue_internal.h"
-
-using android::dvr::ConsumerQueue;
-
-int dvrPoseClientGetDataReader(DvrPoseClient* client, uint64_t data_type,
-                               DvrReadBufferQueue** queue_out) {
-  if (!client || !queue_out)
-    return -EINVAL;
-
-  ConsumerQueue* consumer_queue;
-  int status = android::dvr::dvrPoseClientGetDataReaderHandle(client,
-                                                              data_type,
-                                                              &consumer_queue);
-  if (status != 0) {
-    ALOGE("dvrPoseClientGetDataReader: Failed to get queue: %d", status);
-    return status;
-  }
-
-  std::shared_ptr<ConsumerQueue> consumer_queue_ptr{consumer_queue};
-  *queue_out = new DvrReadBufferQueue(consumer_queue_ptr);
-  return 0;
-}
diff --git a/libs/vr/libdvr/dvr_surface.cpp b/libs/vr/libdvr/dvr_surface.cpp
deleted file mode 100644
index 0c7ec01..0000000
--- a/libs/vr/libdvr/dvr_surface.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-#include "include/dvr/dvr_surface.h"
-
-#include <inttypes.h>
-
-#include <pdx/rpc/variant.h>
-#include <private/android/AHardwareBufferHelpers.h>
-#include <private/dvr/display_client.h>
-
-#include "dvr_buffer_queue_internal.h"
-#include "dvr_internal.h"
-
-using android::AHardwareBuffer_convertToGrallocUsageBits;
-using android::dvr::display::DisplayClient;
-using android::dvr::display::Surface;
-using android::dvr::display::SurfaceAttributes;
-using android::dvr::display::SurfaceAttributeValue;
-using android::pdx::rpc::EmptyVariant;
-
-namespace {
-
-// Sets the Variant |destination| to the target std::array type and copies the C
-// array into it. Unsupported std::array configurations will fail to compile.
-template <typename T, std::size_t N>
-void ArrayCopy(SurfaceAttributeValue* destination, const T (&source)[N]) {
-  using ArrayType = std::array<T, N>;
-  *destination = ArrayType{};
-  std::copy(std::begin(source), std::end(source),
-            std::get<ArrayType>(*destination).begin());
-}
-
-bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes,
-                              size_t attribute_count,
-                              SurfaceAttributes* surface_attributes,
-                              size_t* error_index) {
-  for (size_t i = 0; i < attribute_count; i++) {
-    SurfaceAttributeValue value;
-    switch (attributes[i].value.type) {
-      case DVR_SURFACE_ATTRIBUTE_TYPE_INT32:
-        value = attributes[i].value.int32_value;
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_INT64:
-        value = attributes[i].value.int64_value;
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL:
-        // bool_value is defined in an extern "C" block, which makes it look
-        // like an int to C++. Use a cast to assign the correct type to the
-        // Variant type SurfaceAttributeValue.
-        value = static_cast<bool>(attributes[i].value.bool_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT:
-        value = attributes[i].value.float_value;
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2:
-        ArrayCopy(&value, attributes[i].value.float2_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3:
-        ArrayCopy(&value, attributes[i].value.float3_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4:
-        ArrayCopy(&value, attributes[i].value.float4_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8:
-        ArrayCopy(&value, attributes[i].value.float8_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16:
-        ArrayCopy(&value, attributes[i].value.float16_value);
-        break;
-      case DVR_SURFACE_ATTRIBUTE_TYPE_NONE:
-        value = EmptyVariant{};
-        break;
-      default:
-        *error_index = i;
-        return false;
-    }
-
-    surface_attributes->emplace(attributes[i].key, value);
-  }
-
-  return true;
-}
-
-}  // anonymous namespace
-
-extern "C" {
-
-struct DvrSurface {
-  std::unique_ptr<Surface> surface;
-};
-
-int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
-                     size_t attribute_count, DvrSurface** out_surface) {
-  if (out_surface == nullptr) {
-    ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface);
-    return -EINVAL;
-  }
-
-  size_t error_index;
-  SurfaceAttributes surface_attributes;
-  if (!ConvertSurfaceAttributes(attributes, attribute_count,
-                                &surface_attributes, &error_index)) {
-    ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64,
-          attributes[error_index].value.type);
-    return -EINVAL;
-  }
-
-  auto status = Surface::CreateSurface(surface_attributes);
-  if (!status) {
-    ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s",
-          status.GetErrorMessage().c_str());
-    return -status.error();
-  }
-
-  *out_surface = new DvrSurface{status.take()};
-  return 0;
-}
-
-void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; }
-
-int dvrSurfaceGetId(DvrSurface* surface) {
-  return surface->surface->surface_id();
-}
-
-int dvrSurfaceSetAttributes(DvrSurface* surface,
-                            const DvrSurfaceAttribute* attributes,
-                            size_t attribute_count) {
-  if (surface == nullptr || attributes == nullptr) {
-    ALOGE(
-        "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p "
-        "attribute_count=%zu",
-        surface, attributes, attribute_count);
-    return -EINVAL;
-  }
-
-  size_t error_index;
-  SurfaceAttributes surface_attributes;
-  if (!ConvertSurfaceAttributes(attributes, attribute_count,
-                                &surface_attributes, &error_index)) {
-    ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64,
-          attributes[error_index].value.type);
-    return -EINVAL;
-  }
-
-  auto status = surface->surface->SetAttributes(surface_attributes);
-  if (!status) {
-    ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s",
-          status.GetErrorMessage().c_str());
-    return -status.error();
-  }
-
-  return 0;
-}
-
-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** out_writer) {
-  if (surface == nullptr || out_writer == nullptr) {
-    ALOGE(
-        "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, "
-        "out_writer=%p.",
-        surface, out_writer);
-    return -EINVAL;
-  }
-
-  auto status = surface->surface->CreateQueue(
-      width, height, layer_count, format, usage, capacity, metadata_size);
-  if (!status) {
-    ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s",
-          status.GetErrorMessage().c_str());
-    return -status.error();
-  }
-
-  *out_writer = new DvrWriteBufferQueue(status.take());
-  return 0;
-}
-
-int dvrSetupGlobalBuffer(DvrGlobalBufferKey key, size_t size, uint64_t usage,
-                         DvrBuffer** buffer_out) {
-  if (!buffer_out)
-    return -EINVAL;
-
-  int error;
-  auto client = DisplayClient::Create(&error);
-  if (!client) {
-    ALOGE("dvrSetupGlobalBuffer: Failed to create display client: %s",
-          strerror(-error));
-    return error;
-  }
-
-  uint64_t gralloc_usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
-
-  auto buffer_status = client->SetupGlobalBuffer(key, size, gralloc_usage);
-  if (!buffer_status) {
-    ALOGE("dvrSetupGlobalBuffer: Failed to setup global buffer: %s",
-          buffer_status.GetErrorMessage().c_str());
-    return -buffer_status.error();
-  }
-
-  *buffer_out = CreateDvrBufferFromIonBuffer(buffer_status.take());
-  return 0;
-}
-
-int dvrDeleteGlobalBuffer(DvrGlobalBufferKey key) {
-  int error;
-  auto client = DisplayClient::Create(&error);
-  if (!client) {
-    ALOGE("dvrDeleteGlobalBuffer: Failed to create display client: %s",
-          strerror(-error));
-    return error;
-  }
-
-  auto buffer_status = client->DeleteGlobalBuffer(key);
-  if (!buffer_status) {
-    ALOGE("dvrDeleteGlobalBuffer: Failed to delete named buffer: %s",
-          buffer_status.GetErrorMessage().c_str());
-    return -buffer_status.error();
-  }
-
-  return 0;
-}
-
-int dvrGetGlobalBuffer(DvrGlobalBufferKey key, DvrBuffer** out_buffer) {
-  if (!out_buffer)
-    return -EINVAL;
-
-  int error;
-  auto client = DisplayClient::Create(&error);
-  if (!client) {
-    ALOGE("dvrGetGlobalBuffer: Failed to create display client: %s",
-          strerror(-error));
-    return error;
-  }
-
-  auto status = client->GetGlobalBuffer(key);
-  if (!status) {
-    return -status.error();
-  }
-  *out_buffer = CreateDvrBufferFromIonBuffer(status.take());
-  return 0;
-}
-
-int dvrGetNativeDisplayMetrics(size_t sizeof_metrics,
-                               DvrNativeDisplayMetrics* metrics) {
-  ALOGE_IF(sizeof_metrics != sizeof(DvrNativeDisplayMetrics),
-           "dvrGetNativeDisplayMetrics: metrics struct mismatch, your dvr api "
-           "header is out of date.");
-
-  auto client = DisplayClient::Create();
-  if (!client) {
-    ALOGE("dvrGetNativeDisplayMetrics: Failed to create display client!");
-    return -ECOMM;
-  }
-
-  if (metrics == nullptr) {
-    ALOGE("dvrGetNativeDisplayMetrics: output metrics buffer must be non-null");
-    return -EINVAL;
-  }
-
-  auto status = client->GetDisplayMetrics();
-
-  if (!status) {
-    return -status.error();
-  }
-
-  if (sizeof_metrics >= 20) {
-    metrics->display_width = status.get().display_width;
-    metrics->display_height = status.get().display_height;
-    metrics->display_x_dpi = status.get().display_x_dpi;
-    metrics->display_y_dpi = status.get().display_y_dpi;
-    metrics->vsync_period_ns = status.get().vsync_period_ns;
-  }
-
-  return 0;
-}
-
-}  // extern "C"
diff --git a/libs/vr/libdvr/dvr_tracking.cpp b/libs/vr/libdvr/dvr_tracking.cpp
deleted file mode 100644
index 73addc9..0000000
--- a/libs/vr/libdvr/dvr_tracking.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "include/dvr/dvr_tracking.h"
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#if !DVR_TRACKING_IMPLEMENTED
-
-extern "C" {
-
-// This file provides the stub implementation of dvrTrackingXXX APIs. On
-// platforms that implement these APIs, set -DDVR_TRACKING_IMPLEMENTED=1 in the
-// build file.
-int dvrTrackingCameraCreate(DvrTrackingCamera**) {
-  ALOGE("dvrTrackingCameraCreate is not implemented.");
-  return -ENOSYS;
-}
-
-void dvrTrackingCameraDestroy(DvrTrackingCamera*) {
-  ALOGE("dvrTrackingCameraDestroy is not implemented.");
-}
-
-int dvrTrackingCameraStart(DvrTrackingCamera*, DvrWriteBufferQueue*) {
-  ALOGE("dvrTrackingCameraCreate is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingCameraStop(DvrTrackingCamera*) {
-  ALOGE("dvrTrackingCameraCreate is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingFeatureExtractorCreate(DvrTrackingFeatureExtractor**) {
-  ALOGE("dvrTrackingFeatureExtractorCreate is not implemented.");
-  return -ENOSYS;
-}
-
-void dvrTrackingFeatureExtractorDestroy(DvrTrackingFeatureExtractor*) {
-  ALOGE("dvrTrackingFeatureExtractorDestroy is not implemented.");
-}
-
-int dvrTrackingFeatureExtractorStart(DvrTrackingFeatureExtractor*,
-                                     DvrTrackingFeatureCallback, void*) {
-  ALOGE("dvrTrackingFeatureExtractorCreate is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingFeatureExtractorStop(DvrTrackingFeatureExtractor*) {
-  ALOGE("dvrTrackingFeatureExtractorCreate is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingFeatureExtractorProcessBuffer(DvrTrackingFeatureExtractor*,
-                                             DvrReadBuffer*,
-                                             const DvrTrackingBufferMetadata*,
-                                             bool*) {
-  ALOGE("dvrTrackingFeatureExtractorProcessBuffer is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingSensorsCreate(DvrTrackingSensors**, const char*) {
-  ALOGE("dvrTrackingSensorsCreate is not implemented.");
-  return -ENOSYS;
-}
-
-void dvrTrackingSensorsDestroy(DvrTrackingSensors*) {
-  ALOGE("dvrTrackingSensorsDestroy is not implemented.");
-}
-
-int dvrTrackingSensorsStart(DvrTrackingSensors*, DvrTrackingSensorEventCallback,
-                            void*) {
-  ALOGE("dvrTrackingStart is not implemented.");
-  return -ENOSYS;
-}
-
-int dvrTrackingSensorsStop(DvrTrackingSensors*) {
-  ALOGE("dvrTrackingStop is not implemented.");
-  return -ENOSYS;
-}
-
-}  // extern "C"
-
-#endif  // DVR_TRACKING_IMPLEMENTED
diff --git a/libs/vr/libdvr/exported_apis.lds b/libs/vr/libdvr/exported_apis.lds
deleted file mode 100644
index 5ecb498..0000000
--- a/libs/vr/libdvr/exported_apis.lds
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  global:
-    # Whitelist the function to load the dvr api.
-    dvrGetApi;
-
-  local:
-    # Hide everything else.
-    *;
-};
diff --git a/libs/vr/libdvr/tests/Android.bp b/libs/vr/libdvr/tests/Android.bp
deleted file mode 100644
index fe7feb8..0000000
--- a/libs/vr/libdvr/tests/Android.bp
+++ /dev/null
@@ -1,113 +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_test {
-    srcs: [
-        "dvr_display_manager-test.cpp",
-        "dvr_named_buffer-test.cpp",
-        "dvr_tracking-test.cpp",
-    ],
-
-    header_libs: ["libdvr_headers"],
-    static_libs: [
-        "libdvr_static.google",
-        "libchrome",
-        "libdvrcommon",
-        "libdisplay",
-        "libbroadcastring",
-    ],
-    shared_libs: [
-        "libbase",
-        "libbinder",
-        "libbufferhubqueue",
-        "libcutils",
-        "libgui",
-        "liblog",
-        "libhardware",
-        "libui",
-        "libutils",
-        "libnativewindow",
-        "libpdx_default_transport",
-    ],
-    cflags: [
-        "-DDVR_TRACKING_IMPLEMENTED=0",
-        "-DLOG_TAG=\"dvr_api-test\"",
-        "-DTRACE=0",
-        "-Wno-missing-field-initializers",
-        "-O0",
-        "-g",
-    ],
-    name: "dvr_api-test",
-}
-
-cc_test {
-    name: "dvr_buffer_queue-test",
-
-    // Includes the dvr_api.h header. Tests should only include "dvr_api.h",
-    // and shall only get access to |dvrGetApi|, as other symbols are hidden
-    // from the library.
-    include_dirs: ["frameworks/native/libs/vr/libdvr/include"],
-
-    srcs: ["dvr_buffer_queue-test.cpp"],
-
-    shared_libs: [
-        "libandroid",
-        "liblog",
-    ],
-
-    cflags: [
-        "-DTRACE=0",
-        "-O2",
-        "-g",
-    ],
-
-    // DTS Should only link to NDK libraries.
-    sdk_version: "26",
-    stl: "c++_static",
-}
-
-cc_test {
-    name: "dvr_display-test",
-
-    include_dirs: [
-        "frameworks/native/libs/vr/libdvr/include",
-        "frameworks/native/libs/nativewindow/include",
-    ],
-
-    srcs: ["dvr_display-test.cpp"],
-
-    shared_libs: [
-        "libandroid",
-        "liblog",
-    ],
-
-    cflags: [
-        "-DTRACE=0",
-        "-O2",
-        "-g",
-    ],
-
-    // DTS Should only link to NDK libraries.
-    sdk_version: "26",
-    stl: "c++_static",
-}
diff --git a/libs/vr/libdvr/tests/dvr_api_test.h b/libs/vr/libdvr/tests/dvr_api_test.h
deleted file mode 100644
index 5d2ec28..0000000
--- a/libs/vr/libdvr/tests/dvr_api_test.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <dlfcn.h>
-#include <dvr/dvr_api.h>
-
-#include <gtest/gtest.h>
-
-/** DvrTestBase loads the libdvr.so at runtime and get the Dvr API version 1. */
-class DvrApiTest : public ::testing::Test {
- protected:
-  void SetUp() override {
-    int flags = RTLD_NOW | RTLD_LOCAL;
-
-    // Here we need to ensure that libdvr is loaded with RTLD_NODELETE flag set
-    // (so that calls to `dlclose` don't actually unload the library). This is a
-    // workaround for an Android NDK bug. See more detail:
-    // https://github.com/android-ndk/ndk/issues/360
-    flags |= RTLD_NODELETE;
-    platform_handle_ = dlopen("libdvr.google.so", flags);
-    ASSERT_NE(nullptr, platform_handle_) << "Dvr shared library missing.";
-
-    auto dvr_get_api = reinterpret_cast<decltype(&dvrGetApi)>(
-        dlsym(platform_handle_, "dvrGetApi"));
-    ASSERT_NE(nullptr, dvr_get_api) << "Platform library missing dvrGetApi.";
-
-    ASSERT_EQ(dvr_get_api(&api_, sizeof(api_), /*version=*/1), 0)
-        << "Unable to find compatible Dvr API.";
-  }
-
-  void TearDown() override {
-    if (platform_handle_ != nullptr) {
-      dlclose(platform_handle_);
-    }
-  }
-
-  void* platform_handle_ = nullptr;
-  DvrApi_v1 api_;
-};
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
deleted file mode 100644
index df06097..0000000
--- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
+++ /dev/null
@@ -1,579 +0,0 @@
-#include <android/log.h>
-#include <android/native_window.h>
-#include <dvr/dvr_api.h>
-#include <dvr/dvr_buffer_queue.h>
-
-#include <gtest/gtest.h>
-
-#include <array>
-#include <unordered_map>
-
-#include "dvr_api_test.h"
-
-#define LOG_TAG "dvr_buffer_queue-test"
-
-#ifndef ALOGD
-#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
-#endif
-
-#ifndef ALOGD_IF
-#define ALOGD_IF(cond, ...) \
-  ((__predict_false(cond)) ? ((void)ALOGD(__VA_ARGS__)) : (void)0)
-#endif
-
-namespace {
-
-static constexpr uint32_t kBufferWidth = 100;
-static constexpr uint32_t kBufferHeight = 1;
-static constexpr uint32_t kLayerCount = 1;
-static constexpr uint32_t kBufferFormat = AHARDWAREBUFFER_FORMAT_BLOB;
-static constexpr uint64_t kBufferUsage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
-static constexpr size_t kQueueCapacity = 3;
-
-class DvrBufferQueueTest : public DvrApiTest {
- public:
-  static void BufferAvailableCallback(void* context) {
-    DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
-    thiz->HandleBufferAvailable();
-  }
-
-  static void BufferRemovedCallback(DvrReadBuffer* buffer, void* context) {
-    DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
-    thiz->HandleBufferRemoved(buffer);
-  }
-
- protected:
-  void TearDown() override {
-    if (write_queue_ != nullptr) {
-      api_.WriteBufferQueueDestroy(write_queue_);
-      write_queue_ = nullptr;
-    }
-    DvrApiTest::TearDown();
-  }
-
-  void HandleBufferAvailable() {
-    buffer_available_count_ += 1;
-    ALOGD_IF(TRACE, "Buffer avaiable, count=%d", buffer_available_count_);
-  }
-
-  void HandleBufferRemoved(DvrReadBuffer* buffer) {
-    buffer_removed_count_ += 1;
-    ALOGD_IF(TRACE, "Buffer removed, buffer=%p, count=%d", buffer,
-             buffer_removed_count_);
-  }
-
-  DvrWriteBufferQueue* write_queue_ = nullptr;
-  int buffer_available_count_{0};
-  int buffer_removed_count_{0};
-};
-
-TEST_F(DvrBufferQueueTest, WriteQueueCreateDestroy) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  api_.WriteBufferQueueDestroy(write_queue_);
-  write_queue_ = nullptr;
-}
-
-TEST_F(DvrBufferQueueTest, WriteQueueGetCapacity) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  size_t capacity = api_.WriteBufferQueueGetCapacity(write_queue_);
-
-  ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity);
-  ASSERT_EQ(kQueueCapacity, capacity);
-}
-
-TEST_F(DvrBufferQueueTest, CreateReadQueueFromWriteQueue) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  DvrReadBufferQueue* read_queue = nullptr;
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, read_queue);
-
-  api_.ReadBufferQueueDestroy(read_queue);
-}
-
-TEST_F(DvrBufferQueueTest, CreateReadQueueFromReadQueue) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  DvrReadBufferQueue* read_queue1 = nullptr;
-  DvrReadBufferQueue* read_queue2 = nullptr;
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue1);
-
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, read_queue1);
-
-  ret = api_.ReadBufferQueueCreateReadQueue(read_queue1, &read_queue2);
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, read_queue2);
-  ASSERT_NE(read_queue1, read_queue2);
-
-  api_.ReadBufferQueueDestroy(read_queue1);
-  api_.ReadBufferQueueDestroy(read_queue2);
-}
-
-TEST_F(DvrBufferQueueTest, GainBuffer) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(ret, 0);
-
-  DvrWriteBuffer* wb = nullptr;
-  EXPECT_FALSE(api_.WriteBufferIsValid(wb));
-
-  DvrNativeBufferMetadata meta;
-  int fence_fd = -1;
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta,
-                                        &fence_fd);
-  ASSERT_EQ(ret, 0);
-  EXPECT_EQ(fence_fd, -1);
-  EXPECT_NE(wb, nullptr);
-  EXPECT_TRUE(api_.WriteBufferIsValid(wb));
-}
-
-TEST_F(DvrBufferQueueTest, AcquirePostGainRelease) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(ret, 0);
-
-  DvrReadBufferQueue* read_queue = nullptr;
-  DvrReadBuffer* rb = nullptr;
-  DvrWriteBuffer* wb = nullptr;
-  DvrNativeBufferMetadata meta1;
-  DvrNativeBufferMetadata meta2;
-  int fence_fd = -1;
-
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
-  ASSERT_EQ(ret, 0);
-  ASSERT_NE(read_queue, nullptr);
-
-  api_.ReadBufferQueueSetBufferAvailableCallback(
-      read_queue, &BufferAvailableCallback, this);
-
-  // Gain buffer for writing.
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb,
-                                        &meta1, &fence_fd);
-  ASSERT_EQ(ret, 0);
-  ASSERT_NE(wb, nullptr);
-  ASSERT_TRUE(api_.WriteBufferIsValid(wb));
-  ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d",
-           wb, fence_fd);
-  close(fence_fd);
-
-  // Post buffer to the read_queue.
-  meta1.timestamp = 42;
-  ret = api_.WriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1);
-  ASSERT_EQ(ret, 0);
-  ASSERT_FALSE(api_.WriteBufferIsValid(wb));
-  wb = nullptr;
-
-  // Acquire buffer for reading.
-  ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb,
-                                          &meta2, &fence_fd);
-  ASSERT_EQ(ret, 0);
-  ASSERT_NE(rb, nullptr);
-
-  // Dequeue is successfully, BufferAvailableCallback should be fired once.
-  ASSERT_EQ(buffer_available_count_, 1);
-  ASSERT_TRUE(api_.ReadBufferIsValid(rb));
-
-  // Metadata should be passed along from producer to consumer properly.
-  ASSERT_EQ(meta1.timestamp, meta2.timestamp);
-
-  ALOGD_IF(TRACE,
-           "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb,
-           fence_fd);
-  close(fence_fd);
-
-  // Release buffer to the write_queue.
-  ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rb, &meta2,
-                                          /*release_fence_fd=*/-1);
-  ASSERT_EQ(ret, 0);
-  ASSERT_FALSE(api_.ReadBufferIsValid(rb));
-  rb = nullptr;
-
-  // TODO(b/34387835) Currently buffer allocation has to happen after all queues
-  // are initialized.
-  size_t capacity = api_.ReadBufferQueueGetCapacity(read_queue);
-
-  ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, capacity=%zu", capacity);
-  ASSERT_EQ(kQueueCapacity, capacity);
-
-  api_.ReadBufferQueueDestroy(read_queue);
-}
-
-TEST_F(DvrBufferQueueTest, GetANativeWindow) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      /*capacity=*/0, /*user_metadata_size=*/0, &write_queue_);
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, write_queue_);
-
-  ANativeWindow* window = nullptr;
-  ret = api_.WriteBufferQueueGetANativeWindow(write_queue_, &window);
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, window);
-
-  uint32_t width = ANativeWindow_getWidth(window);
-  uint32_t height = ANativeWindow_getHeight(window);
-  uint32_t format = ANativeWindow_getFormat(window);
-  ASSERT_EQ(kBufferWidth, width);
-  ASSERT_EQ(kBufferHeight, height);
-  ASSERT_EQ(kBufferFormat, format);
-}
-
-// Create buffer queue of three buffers and dequeue three buffers out of it.
-// Before each dequeue operation, we resize the buffer queue and expect the
-// queue always return buffer with desired dimension.
-TEST_F(DvrBufferQueueTest, ResizeBuffer) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  int fence_fd = -1;
-
-  DvrNativeBufferMetadata meta;
-  DvrReadBufferQueue* read_queue = nullptr;
-  DvrWriteBuffer* wb1 = nullptr;
-  DvrWriteBuffer* wb2 = nullptr;
-  DvrWriteBuffer* wb3 = nullptr;
-  AHardwareBuffer* ahb1 = nullptr;
-  AHardwareBuffer* ahb2 = nullptr;
-  AHardwareBuffer* ahb3 = nullptr;
-  AHardwareBuffer_Desc buffer_desc;
-
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, read_queue);
-
-  api_.ReadBufferQueueSetBufferRemovedCallback(read_queue,
-                                               &BufferRemovedCallback, this);
-
-  // Handle all pending events on the read queue.
-  ret = api_.ReadBufferQueueHandleEvents(read_queue);
-  ASSERT_EQ(0, ret);
-
-  size_t capacity = api_.ReadBufferQueueGetCapacity(read_queue);
-  ALOGD_IF(TRACE, "TestResizeBuffer, capacity=%zu", capacity);
-  ASSERT_EQ(kQueueCapacity, capacity);
-
-  // Resize before dequeuing.
-  constexpr uint32_t w1 = 10;
-  ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w1, kBufferHeight);
-  ASSERT_EQ(0, ret);
-
-  // Gain first buffer for writing. All buffers will be resized.
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb1,
-                                        &meta, &fence_fd);
-  ASSERT_EQ(0, ret);
-  ASSERT_TRUE(api_.WriteBufferIsValid(wb1));
-  ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p", wb1);
-  close(fence_fd);
-
-  // Check the buffer dimension.
-  ret = api_.WriteBufferGetAHardwareBuffer(wb1, &ahb1);
-  ASSERT_EQ(0, ret);
-  AHardwareBuffer_describe(ahb1, &buffer_desc);
-  ASSERT_EQ(w1, buffer_desc.width);
-  ASSERT_EQ(kBufferHeight, buffer_desc.height);
-  AHardwareBuffer_release(ahb1);
-
-  // For the first resize, all buffers are reallocated.
-  int expected_buffer_removed_count = kQueueCapacity;
-  ret = api_.ReadBufferQueueHandleEvents(read_queue);
-  ASSERT_EQ(0, ret);
-  ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
-
-  // Resize the queue. We are testing with blob format, keep height to be 1.
-  constexpr uint32_t w2 = 20;
-  ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w2, kBufferHeight);
-  ASSERT_EQ(0, ret);
-
-  // The next buffer we dequeued should have new width.
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb2,
-                                        &meta, &fence_fd);
-  ASSERT_EQ(0, ret);
-  ASSERT_TRUE(api_.WriteBufferIsValid(wb2));
-  ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb2,
-           fence_fd);
-  close(fence_fd);
-
-  // Check the buffer dimension, should be new width
-  ret = api_.WriteBufferGetAHardwareBuffer(wb2, &ahb2);
-  ASSERT_EQ(0, ret);
-  AHardwareBuffer_describe(ahb2, &buffer_desc);
-  ASSERT_EQ(w2, buffer_desc.width);
-  AHardwareBuffer_release(ahb2);
-
-  // For the second resize, all but one buffers are reallocated.
-  expected_buffer_removed_count += (kQueueCapacity - 1);
-  ret = api_.ReadBufferQueueHandleEvents(read_queue);
-  ASSERT_EQ(0, ret);
-  ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
-
-  // Resize the queue for the third time.
-  constexpr uint32_t w3 = 30;
-  ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w3, kBufferHeight);
-  ASSERT_EQ(0, ret);
-
-  // The next buffer we dequeued should have new width.
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb3,
-                                        &meta, &fence_fd);
-  ASSERT_EQ(0, ret);
-  ASSERT_TRUE(api_.WriteBufferIsValid(wb3));
-  ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb3,
-           fence_fd);
-  close(fence_fd);
-
-  // Check the buffer dimension, should be new width
-  ret = api_.WriteBufferGetAHardwareBuffer(wb3, &ahb3);
-  ASSERT_EQ(0, ret);
-  AHardwareBuffer_describe(ahb3, &buffer_desc);
-  ASSERT_EQ(w3, buffer_desc.width);
-  AHardwareBuffer_release(ahb3);
-
-  // For the third resize, all but two buffers are reallocated.
-  expected_buffer_removed_count += (kQueueCapacity - 2);
-  ret = api_.ReadBufferQueueHandleEvents(read_queue);
-  ASSERT_EQ(0, ret);
-  ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
-
-  api_.ReadBufferQueueDestroy(read_queue);
-}
-
-TEST_F(DvrBufferQueueTest, ReadQueueEventFd) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  DvrReadBufferQueue* read_queue = nullptr;
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
-  ASSERT_EQ(0, ret);
-  ASSERT_NE(nullptr, read_queue);
-
-  int event_fd = api_.ReadBufferQueueGetEventFd(read_queue);
-  ASSERT_GT(event_fd, 0);
-}
-
-// Verifies a Dvr{Read,Write}BufferQueue contains the same set of
-// Dvr{Read,Write}Buffer(s) during their lifecycles. And for the same buffer_id,
-// the corresponding AHardwareBuffer handle stays the same.
-TEST_F(DvrBufferQueueTest, StableBufferIdAndHardwareBuffer) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(0, ret);
-
-  int fence_fd = -1;
-  DvrReadBufferQueue* read_queue = nullptr;
-  EXPECT_EQ(0, api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue));
-
-  // Read buffers.
-  std::array<DvrReadBuffer*, kQueueCapacity> rbs;
-  // Write buffers.
-  std::array<DvrWriteBuffer*, kQueueCapacity> wbs;
-  // Buffer metadata.
-  std::array<DvrNativeBufferMetadata, kQueueCapacity> metas;
-  // Hardware buffers for Read buffers.
-  std::unordered_map<int, AHardwareBuffer*> rhbs;
-  // Hardware buffers for Write buffers.
-  std::unordered_map<int, AHardwareBuffer*> whbs;
-
-  constexpr int kNumTests = 100;
-
-  // This test runs the following operations many many times. Thus we prefer to
-  // use ASSERT_XXX rather than EXPECT_XXX to avoid spamming the output.
-  std::function<void(size_t i)> Gain = [&](size_t i) {
-    int ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/10,
-                                              &wbs[i], &metas[i], &fence_fd);
-    ASSERT_EQ(ret, 0);
-    ASSERT_LT(fence_fd, 0);  // expect invalid fence.
-    ASSERT_TRUE(api_.WriteBufferIsValid(wbs[i]));
-    int buffer_id = api_.WriteBufferGetId(wbs[i]);
-    ASSERT_GT(buffer_id, 0);
-
-    AHardwareBuffer* hb = nullptr;
-    ASSERT_EQ(0, api_.WriteBufferGetAHardwareBuffer(wbs[i], &hb));
-
-    auto whb_it = whbs.find(buffer_id);
-    if (whb_it == whbs.end()) {
-      // If this is a new buffer id, check that total number of unique
-      // hardware buffers won't exceed queue capacity.
-      ASSERT_LT(whbs.size(), kQueueCapacity);
-      whbs.emplace(buffer_id, hb);
-    } else {
-      // If this is a buffer id we have seen before, check that the
-      // buffer_id maps to the same AHardwareBuffer handle.
-      ASSERT_EQ(hb, whb_it->second);
-    }
-  };
-
-  std::function<void(size_t i)> Post = [&](size_t i) {
-    ASSERT_TRUE(api_.WriteBufferIsValid(wbs[i]));
-
-    metas[i].timestamp++;
-    int ret = api_.WriteBufferQueuePostBuffer(write_queue_, wbs[i], &metas[i],
-                                              /*fence=*/-1);
-    ASSERT_EQ(ret, 0);
-  };
-
-  std::function<void(size_t i)> Acquire = [&](size_t i) {
-    int ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10,
-                                                &rbs[i], &metas[i], &fence_fd);
-    ASSERT_EQ(ret, 0);
-    ASSERT_LT(fence_fd, 0);  // expect invalid fence.
-    ASSERT_TRUE(api_.ReadBufferIsValid(rbs[i]));
-
-    int buffer_id = api_.ReadBufferGetId(rbs[i]);
-    ASSERT_GT(buffer_id, 0);
-
-    AHardwareBuffer* hb = nullptr;
-    ASSERT_EQ(0, api_.ReadBufferGetAHardwareBuffer(rbs[i], &hb));
-
-    auto rhb_it = rhbs.find(buffer_id);
-    if (rhb_it == rhbs.end()) {
-      // If this is a new buffer id, check that total number of unique hardware
-      // buffers won't exceed queue capacity.
-      ASSERT_LT(rhbs.size(), kQueueCapacity);
-      rhbs.emplace(buffer_id, hb);
-    } else {
-      // If this is a buffer id we have seen before, check that the buffer_id
-      // maps to the same AHardwareBuffer handle.
-      ASSERT_EQ(hb, rhb_it->second);
-    }
-  };
-
-  std::function<void(size_t i)> Release = [&](size_t i) {
-    ASSERT_TRUE(api_.ReadBufferIsValid(rbs[i]));
-
-    int ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rbs[i], &metas[i],
-                                                /*release_fence_fd=*/-1);
-    ASSERT_EQ(ret, 0);
-  };
-
-  // Scenario one:
-  for (int i = 0; i < kNumTests; i++) {
-    // Gain all write buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Gain(i));
-    }
-    // Post all write buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Post(i));
-    }
-    // Acquire all read buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Acquire(i));
-    }
-    // Release all read buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Release(i));
-    }
-  }
-
-  // Scenario two:
-  for (int i = 0; i < kNumTests; i++) {
-    // Gain and post all write buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Gain(i));
-      ASSERT_NO_FATAL_FAILURE(Post(i));
-    }
-    // Acquire and release all read buffers.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Acquire(i));
-      ASSERT_NO_FATAL_FAILURE(Release(i));
-    }
-  }
-
-  // Scenario three:
-  for (int i = 0; i < kNumTests; i++) {
-    // Gain all write buffers then post them in reversed order.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Gain(i));
-    }
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Post(kQueueCapacity - 1 - i));
-    }
-
-    // Acquire all write buffers then release them in reversed order.
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Acquire(i));
-    }
-    for (size_t i = 0; i < kQueueCapacity; i++) {
-      ASSERT_NO_FATAL_FAILURE(Release(kQueueCapacity - 1 - i));
-    }
-  }
-}
-
-TEST_F(DvrBufferQueueTest, ConsumerReleaseAfterProducerDestroy) {
-  int ret = api_.WriteBufferQueueCreate(
-      kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
-      kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
-  ASSERT_EQ(ret, 0);
-
-  DvrReadBufferQueue* read_queue = nullptr;
-  DvrReadBuffer* rb = nullptr;
-  DvrWriteBuffer* wb = nullptr;
-  DvrNativeBufferMetadata meta1;
-  DvrNativeBufferMetadata meta2;
-  int fence_fd = -1;
-
-  ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-  ASSERT_EQ(ret, 0);
-
-  api_.ReadBufferQueueSetBufferAvailableCallback(
-      read_queue, &BufferAvailableCallback, this);
-
-  // Gain buffer for writing.
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb,
-                                        &meta1, &fence_fd);
-  ASSERT_EQ(ret, 0);
-  close(fence_fd);
-
-  // Post buffer to the read_queue.
-  ret = api_.WriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1);
-  ASSERT_EQ(ret, 0);
-  wb = nullptr;
-
-  // Acquire buffer for reading.
-  ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb,
-                                          &meta2, &fence_fd);
-  ASSERT_EQ(ret, 0);
-  close(fence_fd);
-
-  // Destroy the write buffer queue and make sure the reader queue is picking
-  // these events up.
-  api_.WriteBufferQueueDestroy(write_queue_);
-  ret = api_.ReadBufferQueueHandleEvents(read_queue);
-  ASSERT_EQ(0, ret);
-
-  // Release buffer to the write_queue.
-  ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rb, &meta2,
-                                          /*release_fence_fd=*/-1);
-  ASSERT_EQ(ret, 0);
-  rb = nullptr;
-
-  api_.ReadBufferQueueDestroy(read_queue);
-}
-
-}  // namespace
diff --git a/libs/vr/libdvr/tests/dvr_display-test.cpp b/libs/vr/libdvr/tests/dvr_display-test.cpp
deleted file mode 100644
index c72f940..0000000
--- a/libs/vr/libdvr/tests/dvr_display-test.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-#include <android/hardware_buffer.h>
-#include <android/log.h>
-#include <dvr/dvr_api.h>
-#include <dvr/dvr_display_types.h>
-#include <dvr/dvr_surface.h>
-
-#include <gtest/gtest.h>
-
-#include "dvr_api_test.h"
-
-#define LOG_TAG "dvr_display-test"
-
-#ifndef ALOGD
-#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
-#endif
-
-class DvrDisplayTest : public DvrApiTest {
- protected:
-  void SetUp() override {
-    DvrApiTest::SetUp();
-    int ret = api_.GetNativeDisplayMetrics(sizeof(display_metrics_),
-                                           &display_metrics_);
-    ASSERT_EQ(ret, 0) << "Failed to get display metrics.";
-    ALOGD(
-        "display_width: %d, display_height: %d, display_x_dpi: %d, "
-        "display_y_dpi: %d, vsync_period_ns: %d.",
-        display_metrics_.display_width, display_metrics_.display_height,
-        display_metrics_.display_x_dpi, display_metrics_.display_y_dpi,
-        display_metrics_.vsync_period_ns);
-  }
-
-  void TearDown() override {
-    if (write_queue_ != nullptr) {
-      api_.WriteBufferQueueDestroy(write_queue_);
-      write_queue_ = nullptr;
-    }
-    if (direct_surface_ != nullptr) {
-      api_.SurfaceDestroy(direct_surface_);
-      direct_surface_ = nullptr;
-    }
-    DvrApiTest::TearDown();
-  }
-
-  /* Convert a write buffer to an android hardware buffer and fill in
-   * color_textures evenly to the buffer.
-   * AssertionError if the width of the buffer is not equal to the input width,
-   * AssertionError if the height of the buffer is not equal to the input
-   * height.
-   */
-  void FillWriteBuffer(DvrWriteBuffer* write_buffer,
-                       const std::vector<uint32_t>& color_textures,
-                       uint32_t width, uint32_t height);
-
-  // Write buffer queue properties.
-  static constexpr uint64_t kUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
-                                     AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
-                                     AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
-  uint32_t kFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
-  static constexpr size_t kMetadataSize = 0;
-  static constexpr int kTimeoutMs = 1000;  // Time for getting buffer.
-  uint32_t kLayerCount = 1;
-  DvrWriteBufferQueue* write_queue_ = nullptr;
-  DvrSurface* direct_surface_ = nullptr;
-
-  // Device display properties.
-  DvrNativeDisplayMetrics display_metrics_;
-};
-
-TEST_F(DvrDisplayTest, DisplayWithOneBuffer) {
-  // Create a direct surface.
-  std::vector<DvrSurfaceAttribute> direct_surface_attributes = {
-      {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-      {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
-       .value.int32_value = 10},
-      {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-  };
-  int ret =
-      api_.SurfaceCreate(direct_surface_attributes.data(),
-                         direct_surface_attributes.size(), &direct_surface_);
-  ASSERT_EQ(ret, 0) << "Failed to create direct surface.";
-
-  // Create a buffer queue with the direct surface.
-  constexpr size_t kCapacity = 1;
-  uint32_t width = display_metrics_.display_width;
-  uint32_t height = display_metrics_.display_height;
-  ret = api_.SurfaceCreateWriteBufferQueue(
-      direct_surface_, width, height, kFormat, kLayerCount, kUsage, kCapacity,
-      kMetadataSize, &write_queue_);
-  EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
-  ASSERT_NE(nullptr, write_queue_) << "Write buffer queue should not be null.";
-
-  // Get buffer from WriteBufferQueue.
-  DvrWriteBuffer* write_buffer = nullptr;
-  DvrNativeBufferMetadata out_meta;
-  int out_fence_fd = -1;
-  ret = api_.WriteBufferQueueGainBuffer(write_queue_, kTimeoutMs, &write_buffer,
-                                        &out_meta, &out_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to get the buffer.";
-  ASSERT_NE(nullptr, write_buffer) << "Gained buffer should not be null.";
-
-  // Color the write buffer.
-  FillWriteBuffer(write_buffer,
-                  {0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000},
-                  width, height);
-
-  // Post buffer.
-  int ready_fence_fd = -1;
-  ret = api_.WriteBufferQueuePostBuffer(write_queue_, write_buffer, &out_meta,
-                                        ready_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to post the buffer.";
-
-  sleep(5);  // For visual check on the device under test.
-  // Should observe three primary colors on the screen center.
-}
-
-TEST_F(DvrDisplayTest, DisplayWithDoubleBuffering) {
-  // Create a direct surface.
-  std::vector<DvrSurfaceAttribute> direct_surface_attributes = {
-      {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-      {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
-       .value.int32_value = 10},
-      {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-  };
-  int ret =
-      api_.SurfaceCreate(direct_surface_attributes.data(),
-                         direct_surface_attributes.size(), &direct_surface_);
-  ASSERT_EQ(ret, 0) << "Failed to create direct surface.";
-
-  // Create a buffer queue with the direct surface.
-  constexpr size_t kCapacity = 2;
-  uint32_t width = display_metrics_.display_width;
-  uint32_t height = display_metrics_.display_height;
-  ret = api_.SurfaceCreateWriteBufferQueue(
-      direct_surface_, width, height, kFormat, kLayerCount, kUsage, kCapacity,
-      kMetadataSize, &write_queue_);
-  EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
-  ASSERT_NE(nullptr, write_queue_) << "Write buffer queue should not be null.";
-
-  int num_display_cycles_in_5s = 5 / (display_metrics_.vsync_period_ns / 1e9);
-  ALOGD("The number of display cycles: %d", num_display_cycles_in_5s);
-  int bufferhub_id_prev_write_buffer = -1;
-  for (int i = 0; i < num_display_cycles_in_5s; ++i) {
-    // Get a buffer from the WriteBufferQueue.
-    DvrWriteBuffer* write_buffer = nullptr;
-    DvrNativeBufferMetadata out_meta;
-    int out_fence_fd = -1;
-    ret = api_.WriteBufferQueueGainBuffer(
-        write_queue_, kTimeoutMs, &write_buffer, &out_meta, &out_fence_fd);
-    EXPECT_EQ(0, ret) << "Failed to get the a write buffer.";
-    ASSERT_NE(nullptr, write_buffer) << "The gained buffer should not be null.";
-
-    int bufferhub_id = api_.WriteBufferGetId(write_buffer);
-    ALOGD("Display cycle: %d, bufferhub id of the write buffer: %d", i,
-          bufferhub_id);
-    EXPECT_NE(bufferhub_id_prev_write_buffer, bufferhub_id)
-        << "Double buffering should be using the two buffers in turns, not "
-           "reusing the same write buffer.";
-    bufferhub_id_prev_write_buffer = bufferhub_id;
-
-    // Color the write buffer.
-    if (i % 2) {
-      FillWriteBuffer(write_buffer, {0xffff0000, 0xff00ff00, 0xff0000ff}, width,
-                      height);
-    } else {
-      FillWriteBuffer(write_buffer, {0xff00ff00, 0xff0000ff, 0xffff0000}, width,
-                      height);
-    }
-
-    // Post the write buffer.
-    int ready_fence_fd = -1;
-    ret = api_.WriteBufferQueuePostBuffer(write_queue_, write_buffer, &out_meta,
-                                          ready_fence_fd);
-    EXPECT_EQ(0, ret) << "Failed to post the buffer.";
-  }
-  // Should observe blinking screen in secondary colors
-  // although it is actually displaying primary colors.
-}
-
-TEST_F(DvrDisplayTest, DisplayWithTwoHardwareLayers) {
-  // Create the direct_surface_0 of z order 10 and direct_surface_1 of z
-  // order 11.
-  DvrSurface* direct_surface_0 = nullptr;
-  std::vector<DvrSurfaceAttribute> direct_surface_0_attributes = {
-      {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-      {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
-       .value.int32_value = 10},
-      {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-  };
-  int ret =
-      api_.SurfaceCreate(direct_surface_0_attributes.data(),
-                         direct_surface_0_attributes.size(), &direct_surface_0);
-  EXPECT_EQ(ret, 0) << "Failed to create direct surface.";
-
-  DvrSurface* direct_surface_1 = nullptr;
-  std::vector<DvrSurfaceAttribute> direct_surface_1_attributes = {
-      {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-      {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
-       .value.int32_value = 11},
-      {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
-       .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-       .value.bool_value = true},
-  };
-  ret =
-      api_.SurfaceCreate(direct_surface_1_attributes.data(),
-                         direct_surface_1_attributes.size(), &direct_surface_1);
-  EXPECT_EQ(ret, 0) << "Failed to create direct surface.";
-
-  // Create a buffer queue for each of the direct surfaces.
-  constexpr size_t kCapacity = 1;
-  uint32_t width = display_metrics_.display_width;
-  uint32_t height = display_metrics_.display_height;
-
-  DvrWriteBufferQueue* write_queue_0 = nullptr;
-  ret = api_.SurfaceCreateWriteBufferQueue(
-      direct_surface_0, width, height, kFormat, kLayerCount, kUsage, kCapacity,
-      kMetadataSize, &write_queue_0);
-  EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
-  EXPECT_NE(nullptr, write_queue_0) << "Write buffer queue should not be null.";
-
-  DvrWriteBufferQueue* write_queue_1 = nullptr;
-  ret = api_.SurfaceCreateWriteBufferQueue(
-      direct_surface_1, width, height, kFormat, kLayerCount, kUsage, kCapacity,
-      kMetadataSize, &write_queue_1);
-  EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
-  EXPECT_NE(nullptr, write_queue_1) << "Write buffer queue should not be null.";
-
-  // Get a buffer from each of the write buffer queues.
-  DvrWriteBuffer* write_buffer_0 = nullptr;
-  DvrNativeBufferMetadata out_meta_0;
-  int out_fence_fd = -1;
-  ret = api_.WriteBufferQueueGainBuffer(
-      write_queue_0, kTimeoutMs, &write_buffer_0, &out_meta_0, &out_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to get the buffer.";
-  EXPECT_NE(nullptr, write_buffer_0) << "Gained buffer should not be null.";
-
-  DvrWriteBuffer* write_buffer_1 = nullptr;
-  DvrNativeBufferMetadata out_meta_1;
-  out_fence_fd = -1;
-  ret = api_.WriteBufferQueueGainBuffer(
-      write_queue_1, kTimeoutMs, &write_buffer_1, &out_meta_1, &out_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to get the buffer.";
-  EXPECT_NE(nullptr, write_buffer_1) << "Gained buffer should not be null.";
-
-  // Color the write buffers.
-  FillWriteBuffer(write_buffer_0, {0xffff0000, 0xff00ff00, 0xff0000ff}, width,
-                  height);
-  FillWriteBuffer(write_buffer_1, {0x7f00ff00, 0x7f0000ff, 0x7fff0000}, width,
-                  height);
-
-  // Post buffers.
-  int ready_fence_fd = -1;
-  ret = api_.WriteBufferQueuePostBuffer(write_queue_0, write_buffer_0,
-                                        &out_meta_0, ready_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to post the buffer.";
-
-  ready_fence_fd = -1;
-  ret = api_.WriteBufferQueuePostBuffer(write_queue_1, write_buffer_1,
-                                        &out_meta_1, ready_fence_fd);
-  EXPECT_EQ(0, ret) << "Failed to post the buffer.";
-
-  sleep(5);  // For visual check on the device under test.
-  // Should observe three secondary colors.
-
-  // Test finished. Clean up buffers and surfaces.
-  if (write_queue_0 != nullptr) {
-    api_.WriteBufferQueueDestroy(write_queue_0);
-    write_queue_0 = nullptr;
-  }
-  if (write_queue_1 != nullptr) {
-    api_.WriteBufferQueueDestroy(write_queue_1);
-    write_queue_1 = nullptr;
-  }
-  if (direct_surface_0 != nullptr) {
-    api_.SurfaceDestroy(direct_surface_0);
-  }
-  if (direct_surface_1 != nullptr) {
-    api_.SurfaceDestroy(direct_surface_1);
-  }
-}
-
-void DvrDisplayTest::FillWriteBuffer(
-    DvrWriteBuffer* write_buffer, const std::vector<uint32_t>& color_textures,
-    uint32_t width, uint32_t height) {
-  uint32_t num_colors = color_textures.size();
-  // Convert the first write buffer to an android hardware buffer.
-  AHardwareBuffer* ah_buffer = nullptr;
-  int ret = api_.WriteBufferGetAHardwareBuffer(write_buffer, &ah_buffer);
-  ASSERT_EQ(0, ret) << "Failed to get a hardware buffer from the write buffer.";
-  ASSERT_NE(nullptr, ah_buffer) << "AHardware buffer should not be null.";
-  AHardwareBuffer_Desc ah_buffer_describe;
-  AHardwareBuffer_describe(ah_buffer, &ah_buffer_describe);
-  ASSERT_EQ(ah_buffer_describe.format, kFormat)
-      << "The format of the android hardware buffer is wrong.";
-  ASSERT_EQ(ah_buffer_describe.layers, kLayerCount)
-      << "The obtained android hardware buffer should have 2 layers.";
-  ASSERT_EQ(ah_buffer_describe.width, width)
-      << "The obtained android hardware buffer width is wrong.";
-  ASSERT_EQ(ah_buffer_describe.height, height)
-      << "The obtained android hardware buffer height is wrong.";
-  // Change the content of the android hardware buffer.
-  void* buffer_data = nullptr;
-  int32_t fence = -1;
-  ret = AHardwareBuffer_lock(ah_buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
-                             fence, nullptr, &buffer_data);
-  ASSERT_EQ(0, ret) << "Failed to lock the hardware buffer.";
-  ASSERT_NE(nullptr, buffer_data) << "Buffer data should not be null.";
-
-  uint32_t num_pixels = width * height / num_colors;
-  for (uint32_t color_index = 0; color_index < num_colors - 1; ++color_index) {
-    uint32_t color_texture = color_textures[color_index];
-    for (uint32_t i = 0; i < num_pixels; ++i) {
-      memcpy(reinterpret_cast<void*>(reinterpret_cast<int64_t>(buffer_data) +
-                                     (i + num_pixels * color_index) *
-                                         sizeof(color_texture)),
-             &color_texture, sizeof(color_texture));
-    }
-  }
-  uint32_t color_texture = color_textures[num_colors - 1];
-  uint32_t num_colored_pixels = num_pixels * (num_colors - 1);
-  num_pixels = width * height - num_colored_pixels;
-  for (uint32_t i = 0; i < num_pixels; ++i) {
-    memcpy(reinterpret_cast<void*>(reinterpret_cast<int64_t>(buffer_data) +
-                                   (i + num_colored_pixels) *
-                                       sizeof(color_texture)),
-           &color_texture, sizeof(color_texture));
-  }
-  fence = -1;
-  ret = AHardwareBuffer_unlock(ah_buffer, &fence);
-  EXPECT_EQ(0, ret) << "Failed to unlock the hardware buffer.";
-
-  // Release the android hardware buffer.
-  AHardwareBuffer_release(ah_buffer);
-}
diff --git a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp b/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
deleted file mode 100644
index 07e2121..0000000
--- a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
+++ /dev/null
@@ -1,891 +0,0 @@
-#include <android-base/properties.h>
-#include <base/logging.h>
-#include <cutils/properties.h>
-#include <gtest/gtest.h>
-#include <log/log.h>
-#include <poll.h>
-
-#include <android/hardware_buffer.h>
-
-#include <algorithm>
-#include <array>
-#include <set>
-#include <thread>
-#include <vector>
-
-#include <dvr/dvr_configuration_data.h>
-#include <dvr/dvr_deleter.h>
-#include <dvr/dvr_display_manager.h>
-#include <dvr/dvr_surface.h>
-
-#include <pdx/status.h>
-
-using android::pdx::ErrorStatus;
-using android::pdx::Status;
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-using ::testing::Test;
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, nullptr_t) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_NONE;
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, int32_t value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32;
-  attribute.value.int32_value = value;
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, int64_t value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT64;
-  attribute.value.int64_value = value;
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, bool value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL;
-  attribute.value.bool_value = value;
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, float value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT;
-  attribute.value.float_value = value;
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
-                                  const std::array<float, 2>& value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2;
-  std::copy(value.begin(), value.end(), attribute.value.float2_value);
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
-                                  const std::array<float, 3>& value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3;
-  std::copy(value.begin(), value.end(), attribute.value.float3_value);
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
-                                  const std::array<float, 4>& value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4;
-  std::copy(value.begin(), value.end(), attribute.value.float4_value);
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
-                                  const std::array<float, 8>& value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8;
-  std::copy(value.begin(), value.end(), attribute.value.float8_value);
-  return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
-                                  const std::array<float, 16>& value) {
-  DvrSurfaceAttribute attribute;
-  attribute.key = key;
-  attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16;
-  std::copy(value.begin(), value.end(), attribute.value.float16_value);
-  return attribute;
-}
-
-Status<UniqueDvrSurface> CreateApplicationSurface(bool visible = false,
-                                                  int32_t z_order = 0) {
-  DvrSurface* surface = nullptr;
-  DvrSurfaceAttribute attributes[] = {
-      MakeAttribute(DVR_SURFACE_ATTRIBUTE_Z_ORDER, z_order),
-      MakeAttribute(DVR_SURFACE_ATTRIBUTE_VISIBLE, visible)};
-
-  const int ret = dvrSurfaceCreate(
-      attributes, std::extent<decltype(attributes)>::value, &surface);
-  if (ret < 0)
-    return ErrorStatus(-ret);
-  else
-    return {UniqueDvrSurface(surface)};
-}
-
-Status<UniqueDvrWriteBufferQueue> CreateSurfaceQueue(
-    const UniqueDvrSurface& 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;
-  const int ret = dvrSurfaceCreateWriteBufferQueue(
-      surface.get(), width, height, format, layer_count, usage, capacity,
-      metadata_size, &queue);
-  if (ret < 0)
-    return ErrorStatus(-ret);
-  else
-    return {UniqueDvrWriteBufferQueue(queue)};
-}
-
-Status<std::vector<uint8_t>> GetConfigData(int config_type) {
-  uint8_t* data = nullptr;
-  size_t data_size = 0;
-  int error = dvrConfigurationDataGet(config_type, &data, &data_size);
-  if (error < 0) {
-    return ErrorStatus(-error);
-  }
-
-  if (!data || data_size == 0) {
-    return ErrorStatus(EINVAL);
-  }
-  std::vector<uint8_t> data_result(data, data + data_size);
-  dvrConfigurationDataDestroy(data);
-  std::string s(data, data + data_size);
-  return {std::move(data_result)};
-}
-
-class TestDisplayManager {
- public:
-  TestDisplayManager(UniqueDvrDisplayManager display_manager,
-                     UniqueDvrSurfaceState surface_state)
-      : display_manager_(std::move(display_manager)),
-        surface_state_(std::move(surface_state)) {
-    const int fd = dvrDisplayManagerGetEventFd(display_manager_.get());
-    LOG_IF(INFO, fd < 0) << "Failed to get event fd: " << strerror(-fd);
-    display_manager_event_fd_ = fd;
-  }
-
-  Status<UniqueDvrReadBufferQueue> GetReadBufferQueue(int surface_id,
-                                                      int queue_id) {
-    DvrReadBufferQueue* queue;
-    const int ret = dvrDisplayManagerGetReadBufferQueue(
-        display_manager_.get(), surface_id, queue_id, &queue);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {UniqueDvrReadBufferQueue(queue)};
-  }
-
-  Status<void> UpdateSurfaceState() {
-    const int ret = dvrDisplayManagerGetSurfaceState(display_manager_.get(),
-                                                     surface_state_.get());
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {};
-  }
-
-  enum : int { kTimeoutMs = 10000 };  // 10s
-
-  Status<void> WaitForUpdate(int timeout_ms = kTimeoutMs) {
-    if (display_manager_event_fd_ < 0)
-      return ErrorStatus(-display_manager_event_fd_);
-
-    pollfd pfd = {display_manager_event_fd_, POLLIN, 0};
-    const int count = poll(&pfd, 1, timeout_ms);
-    if (count < 0)
-      return ErrorStatus(errno);
-    else if (count == 0)
-      return ErrorStatus(ETIMEDOUT);
-
-    int events;
-    const int ret = dvrDisplayManagerTranslateEpollEventMask(
-        display_manager_.get(), pfd.revents, &events);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else if (events & POLLIN)
-      return UpdateSurfaceState();
-    else
-      return ErrorStatus(EPROTO);
-  }
-
-  Status<size_t> GetSurfaceCount() {
-    size_t count = 0;
-    const int ret =
-        dvrSurfaceStateGetSurfaceCount(surface_state_.get(), &count);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {count};
-  }
-
-  Status<DvrSurfaceUpdateFlags> GetUpdateFlags(size_t surface_index) {
-    DvrSurfaceUpdateFlags update_flags;
-    const int ret = dvrSurfaceStateGetUpdateFlags(surface_state_.get(),
-                                                  surface_index, &update_flags);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {update_flags};
-  }
-
-  Status<int> GetSurfaceId(size_t surface_index) {
-    int surface_id;
-    const int ret = dvrSurfaceStateGetSurfaceId(surface_state_.get(),
-                                                surface_index, &surface_id);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {surface_id};
-  }
-
-  Status<int> GetProcessId(size_t surface_index) {
-    int process_id;
-    const int ret = dvrSurfaceStateGetProcessId(surface_state_.get(),
-                                                surface_index, &process_id);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-    else
-      return {process_id};
-  }
-
-  Status<std::vector<DvrSurfaceAttribute>> GetAttributes(size_t surface_index) {
-    std::vector<DvrSurfaceAttribute> attributes;
-    size_t count = 0;
-    const int ret = dvrSurfaceStateGetAttributeCount(surface_state_.get(),
-                                                     surface_index, &count);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-
-    attributes.resize(count);
-    const ssize_t return_count = dvrSurfaceStateGetAttributes(
-        surface_state_.get(), surface_index, attributes.data(), count);
-    if (return_count < 0)
-      return ErrorStatus(-return_count);
-
-    attributes.resize(return_count);
-    return {std::move(attributes)};
-  }
-
-  Status<std::vector<int>> GetQueueIds(size_t surface_index) {
-    std::vector<int> queue_ids;
-    size_t count = 0;
-    const int ret = dvrSurfaceStateGetQueueCount(surface_state_.get(),
-                                                 surface_index, &count);
-    if (ret < 0)
-      return ErrorStatus(-ret);
-
-    if (count > 0) {
-      queue_ids.resize(count);
-      const ssize_t return_count = dvrSurfaceStateGetQueueIds(
-          surface_state_.get(), surface_index, queue_ids.data(), count);
-      if (return_count < 0)
-        return ErrorStatus(-return_count);
-
-      queue_ids.resize(return_count);
-    }
-
-    return {std::move(queue_ids)};
-  }
-
- private:
-  UniqueDvrDisplayManager display_manager_;
-  UniqueDvrSurfaceState surface_state_;
-
-  // Owned by object in display_manager_, do not explicitly close.
-  int display_manager_event_fd_;
-
-  TestDisplayManager(const TestDisplayManager&) = delete;
-  void operator=(const TestDisplayManager&) = delete;
-};
-
-class DvrDisplayManagerTest : public Test {
- protected:
-  void SetUp() override {
-    int ret;
-    DvrDisplayManager* display_manager;
-    DvrSurfaceState* surface_state;
-
-    ret = dvrDisplayManagerCreate(&display_manager);
-    ASSERT_EQ(0, ret) << "Failed to create display manager client";
-    ASSERT_NE(nullptr, display_manager);
-
-    ret = dvrSurfaceStateCreate(&surface_state);
-    ASSERT_EQ(0, ret) << "Failed to create surface state object";
-    ASSERT_NE(nullptr, surface_state);
-
-    manager_.reset(
-        new TestDisplayManager(UniqueDvrDisplayManager(display_manager),
-                               UniqueDvrSurfaceState(surface_state)));
-  }
-  void TearDown() override {}
-
-  std::unique_ptr<TestDisplayManager> manager_;
-};
-
-// TODO(eieio): Consider moving these somewhere more central because they are
-// broadly useful.
-
-template <typename T>
-testing::AssertionResult StatusOk(const char* status_expression,
-                                  const Status<T>& status) {
-  if (!status.ok()) {
-    return testing::AssertionFailure()
-           << "(" << status_expression
-           << ") expected to indicate success but actually contains error ("
-           << status.error() << ")";
-  } else {
-    return testing::AssertionSuccess();
-  }
-}
-
-template <typename T>
-testing::AssertionResult StatusError(const char* status_expression,
-                                     const Status<T>& status) {
-  if (status.ok()) {
-    return testing::AssertionFailure()
-           << "(" << status_expression
-           << ") expected to indicate error but instead indicates success.";
-  } else {
-    return testing::AssertionSuccess();
-  }
-}
-
-template <typename T>
-testing::AssertionResult StatusHasError(const char* status_expression,
-                                        const char* /*error_code_expression*/,
-                                        const Status<T>& status,
-                                        int error_code) {
-  if (status.ok()) {
-    return StatusError(status_expression, status);
-  } else if (status.error() != error_code) {
-    return testing::AssertionFailure()
-           << "(" << status_expression << ") expected to indicate error ("
-           << error_code << ") but actually indicates error (" << status.error()
-           << ")";
-  } else {
-    return testing::AssertionSuccess();
-  }
-}
-
-template <typename T, typename U>
-testing::AssertionResult StatusHasValue(const char* status_expression,
-                                        const char* /*value_expression*/,
-                                        const Status<T>& status,
-                                        const U& value) {
-  if (!status.ok()) {
-    return StatusOk(status_expression, status);
-  } else if (status.get() != value) {
-    return testing::AssertionFailure()
-           << "(" << status_expression << ") expected to contain value ("
-           << testing::PrintToString(value) << ") but actually contains value ("
-           << testing::PrintToString(status.get()) << ")";
-  } else {
-    return testing::AssertionSuccess();
-  }
-}
-
-template <typename T, typename Op>
-testing::AssertionResult StatusPred(const char* status_expression,
-                                    const char* pred_expression,
-                                    const Status<T>& status, Op pred) {
-  if (!status.ok()) {
-    return StatusOk(status_expression, status);
-  } else if (!pred(status.get())) {
-    return testing::AssertionFailure()
-           << status_expression << " value ("
-           << testing::PrintToString(status.get())
-           << ") failed to pass predicate " << pred_expression;
-  } else {
-    return testing::AssertionSuccess();
-  }
-}
-
-#define ASSERT_STATUS_OK(status) ASSERT_PRED_FORMAT1(StatusOk, status)
-#define ASSERT_STATUS_ERROR(status) ASSERT_PRED_FORMAT1(StatusError, status)
-
-#define ASSERT_STATUS_ERROR_VALUE(value, status) \
-  ASSERT_PRED_FORMAT2(StatusHasError, status, value)
-
-#define ASSERT_STATUS_EQ(value, status) \
-  ASSERT_PRED_FORMAT2(StatusHasValue, status, value)
-
-#define EXPECT_STATUS_OK(status) EXPECT_PRED_FORMAT1(StatusOk, status)
-#define EXPECT_STATUS_ERROR(status) EXPECT_PRED_FORMAT1(StatusError, status)
-
-#define EXPECT_STATUS_ERROR_VALUE(value, status) \
-  EXPECT_PRED_FORMAT2(StatusHasError, status, value)
-
-#define EXPECT_STATUS_EQ(value, status) \
-  EXPECT_PRED_FORMAT2(StatusHasValue, status, value)
-
-#define EXPECT_STATUS_PRED(pred, status) \
-  EXPECT_PRED_FORMAT2(StatusPred, status, pred)
-
-#if 0
-// Verify utility predicate/macro functionality. This section is commented out
-// because it is designed to fail in some cases to validate the helpers.
-TEST_F(Test, ExpectVoid) {
-  Status<void> status_error{ErrorStatus{EINVAL}};
-  Status<void> status_ok{};
-
-  EXPECT_STATUS_ERROR(status_error);
-  EXPECT_STATUS_ERROR(status_ok);
-  EXPECT_STATUS_OK(status_error);
-  EXPECT_STATUS_OK(status_ok);
-
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error);
-  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error);
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok);
-  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok);
-}
-
-TEST_F(Test, ExpectInt) {
-  Status<int> status_error{ErrorStatus{EINVAL}};
-  Status<int> status_ok{10};
-
-  EXPECT_STATUS_ERROR(status_error);
-  EXPECT_STATUS_ERROR(status_ok);
-  EXPECT_STATUS_OK(status_error);
-  EXPECT_STATUS_OK(status_ok);
-
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error);
-  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error);
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok);
-  EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok);
-
-  EXPECT_STATUS_EQ(10, status_error);
-  EXPECT_STATUS_EQ(20, status_error);
-  EXPECT_STATUS_EQ(10, status_ok);
-  EXPECT_STATUS_EQ(20, status_ok);
-
-  auto pred1 = [](const auto& value) { return value < 15; };
-  auto pred2 = [](const auto& value) { return value > 5; };
-  auto pred3 = [](const auto& value) { return value > 15; };
-  auto pred4 = [](const auto& value) { return value < 5; };
-
-  EXPECT_STATUS_PRED(pred1, status_error);
-  EXPECT_STATUS_PRED(pred2, status_error);
-  EXPECT_STATUS_PRED(pred3, status_error);
-  EXPECT_STATUS_PRED(pred4, status_error);
-  EXPECT_STATUS_PRED(pred1, status_ok);
-  EXPECT_STATUS_PRED(pred2, status_ok);
-  EXPECT_STATUS_PRED(pred3, status_ok);
-  EXPECT_STATUS_PRED(pred4, status_ok);
-}
-#endif
-
-TEST_F(DvrDisplayManagerTest, SurfaceCreateEvent) {
-  // Get surface state and verify there are no surfaces.
-  ASSERT_STATUS_OK(manager_->UpdateSurfaceState());
-  ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount());
-
-  // Get flags for invalid surface index.
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetUpdateFlags(0));
-
-  // Create an application surface.
-  auto surface_status = CreateApplicationSurface();
-  ASSERT_STATUS_OK(surface_status);
-  UniqueDvrSurface surface = surface_status.take();
-  ASSERT_NE(nullptr, surface.get());
-
-  const int surface_id = dvrSurfaceGetId(surface.get());
-  ASSERT_GE(surface_id, 0);
-
-  // Now there should be one new surface.
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  EXPECT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Verify the new surface flag is set.
-  auto check_flags = [](const auto& value) {
-    return value & DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE;
-  };
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  // Verify the surface id matches.
-  EXPECT_STATUS_EQ(surface_id, manager_->GetSurfaceId(0));
-
-  // Verify the owning process of the surface.
-  EXPECT_STATUS_EQ(getpid(), manager_->GetProcessId(0));
-
-  surface.reset();
-
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  EXPECT_STATUS_EQ(0u, manager_->GetSurfaceCount());
-}
-
-TEST_F(DvrDisplayManagerTest, SurfaceAttributeEvent) {
-  // Get surface state and verify there are no surfaces.
-  ASSERT_STATUS_OK(manager_->UpdateSurfaceState());
-  ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount());
-
-  // Get attributes for an invalid surface index.
-  EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetAttributes(0));
-
-  const bool kInitialVisibility = true;
-  const int32_t kInitialZOrder = 10;
-  auto surface_status =
-      CreateApplicationSurface(kInitialVisibility, kInitialZOrder);
-  ASSERT_STATUS_OK(surface_status);
-  auto surface = surface_status.take();
-  ASSERT_NE(nullptr, surface.get());
-
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Check the initial attribute values.
-  auto attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  auto attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), 2u);
-
-  std::set<int32_t> actual_keys;
-  std::set<int32_t> expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-                                     DVR_SURFACE_ATTRIBUTE_VISIBLE};
-
-  // Collect all the keys in attributes that match the expected keys.
-  auto compare_keys = [](const auto& attributes, const auto& expected_keys) {
-    std::set<int32_t> keys;
-    for (const auto& attribute : attributes) {
-      if (expected_keys.find(attribute.key) != expected_keys.end())
-        keys.emplace(attribute.key);
-    }
-    return keys;
-  };
-
-  // If the sets match then attributes contained at least the expected keys,
-  // even if other keys were also present.
-  actual_keys = compare_keys(attributes, expected_keys);
-  EXPECT_EQ(expected_keys, actual_keys);
-
-  std::vector<DvrSurfaceAttribute> attributes_to_set = {
-      MakeAttribute(DVR_SURFACE_ATTRIBUTE_Z_ORDER, 0)};
-
-  // Test invalid args.
-  EXPECT_EQ(-EINVAL, dvrSurfaceSetAttributes(nullptr, attributes_to_set.data(),
-                                             attributes_to_set.size()));
-  EXPECT_EQ(-EINVAL, dvrSurfaceSetAttributes(surface.get(), nullptr,
-                                             attributes_to_set.size()));
-
-  // Test attribute change events.
-  ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
-                                       attributes_to_set.size()));
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-
-  // Verify the attributes changed flag is set.
-  auto check_flags = [](const auto& value) {
-    return value & DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED;
-  };
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), 2u);
-
-  expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-                   DVR_SURFACE_ATTRIBUTE_VISIBLE};
-
-  actual_keys.clear();
-  actual_keys = compare_keys(attributes, expected_keys);
-  EXPECT_EQ(expected_keys, actual_keys);
-
-  // Test setting and then deleting an attribute.
-  const DvrSurfaceAttributeKey kUserKey = 1;
-  attributes_to_set = {MakeAttribute(kUserKey, 1024)};
-
-  ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
-                                       attributes_to_set.size()));
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), 2u);
-
-  expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER, DVR_SURFACE_ATTRIBUTE_VISIBLE,
-                   kUserKey};
-
-  actual_keys.clear();
-  actual_keys = compare_keys(attributes, expected_keys);
-  EXPECT_EQ(expected_keys, actual_keys);
-
-  // Delete the attribute.
-  attributes_to_set = {MakeAttribute(kUserKey, nullptr)};
-
-  ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
-                                       attributes_to_set.size()));
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), 2u);
-
-  expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER, DVR_SURFACE_ATTRIBUTE_VISIBLE,
-                   kUserKey};
-
-  actual_keys.clear();
-  actual_keys = compare_keys(attributes, expected_keys);
-  EXPECT_NE(expected_keys, actual_keys);
-
-  // Test deleting a reserved attribute.
-  attributes_to_set = {MakeAttribute(DVR_SURFACE_ATTRIBUTE_VISIBLE, nullptr)};
-
-  EXPECT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
-                                       attributes_to_set.size()));
-
-  // Failed attribute operations should not trigger update events.
-  const int kTimeoutMs = 100;  // 0.1s
-  EXPECT_STATUS_ERROR_VALUE(ETIMEDOUT, manager_->WaitForUpdate(kTimeoutMs));
-
-  attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), 2u);
-
-  expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER,
-                   DVR_SURFACE_ATTRIBUTE_VISIBLE};
-
-  actual_keys.clear();
-  actual_keys = compare_keys(attributes, expected_keys);
-  EXPECT_EQ(expected_keys, actual_keys);
-}
-
-TEST_F(DvrDisplayManagerTest, SurfaceAttributeTypes) {
-  // Create an application surface.
-  auto surface_status = CreateApplicationSurface();
-  ASSERT_STATUS_OK(surface_status);
-  UniqueDvrSurface surface = surface_status.take();
-  ASSERT_NE(nullptr, surface.get());
-
-  enum : std::int32_t {
-    kInt32Key = 1,
-    kInt64Key,
-    kBoolKey,
-    kFloatKey,
-    kFloat2Key,
-    kFloat3Key,
-    kFloat4Key,
-    kFloat8Key,
-    kFloat16Key,
-  };
-
-  const std::vector<DvrSurfaceAttribute> attributes_to_set = {
-      MakeAttribute(kInt32Key, int32_t{0}),
-      MakeAttribute(kInt64Key, int64_t{0}),
-      MakeAttribute(kBoolKey, false),
-      MakeAttribute(kFloatKey, 0.0f),
-      MakeAttribute(kFloat2Key, std::array<float, 2>{{1.0f, 2.0f}}),
-      MakeAttribute(kFloat3Key, std::array<float, 3>{{3.0f, 4.0f, 5.0f}}),
-      MakeAttribute(kFloat4Key, std::array<float, 4>{{6.0f, 7.0f, 8.0f, 9.0f}}),
-      MakeAttribute(kFloat8Key,
-                    std::array<float, 8>{{10.0f, 11.0f, 12.0f, 13.0f, 14.0f,
-                                          15.0f, 16.0f, 17.0f}}),
-      MakeAttribute(kFloat16Key, std::array<float, 16>{
-                                     {18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f,
-                                      24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f,
-                                      30.0f, 31.0f, 32.0f, 33.0f}})};
-
-  EXPECT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
-                                       attributes_to_set.size()));
-
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  auto attribute_status = manager_->GetAttributes(0);
-  ASSERT_STATUS_OK(attribute_status);
-  auto attributes = attribute_status.take();
-  EXPECT_GE(attributes.size(), attributes_to_set.size());
-
-  auto HasAttribute = [](const auto& attributes,
-                         DvrSurfaceAttributeKey key) -> bool {
-    for (const auto& attribute : attributes) {
-      if (attribute.key == key)
-        return true;
-    }
-    return false;
-  };
-  auto AttributeType =
-      [](const auto& attributes,
-         DvrSurfaceAttributeKey key) -> DvrSurfaceAttributeType {
-    for (const auto& attribute : attributes) {
-      if (attribute.key == key)
-        return attribute.value.type;
-    }
-    return DVR_SURFACE_ATTRIBUTE_TYPE_NONE;
-  };
-
-  ASSERT_TRUE(HasAttribute(attributes, kInt32Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
-            AttributeType(attributes, kInt32Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kInt64Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_INT64,
-            AttributeType(attributes, kInt64Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kBoolKey));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
-            AttributeType(attributes, kBoolKey));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloatKey));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT,
-            AttributeType(attributes, kFloatKey));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloat2Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2,
-            AttributeType(attributes, kFloat2Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloat3Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3,
-            AttributeType(attributes, kFloat3Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloat4Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4,
-            AttributeType(attributes, kFloat4Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloat8Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8,
-            AttributeType(attributes, kFloat8Key));
-
-  ASSERT_TRUE(HasAttribute(attributes, kFloat16Key));
-  EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16,
-            AttributeType(attributes, kFloat16Key));
-}
-
-TEST_F(DvrDisplayManagerTest, SurfaceQueueEvent) {
-  // Create an application surface.
-  auto surface_status = CreateApplicationSurface();
-  ASSERT_STATUS_OK(surface_status);
-  UniqueDvrSurface surface = surface_status.take();
-  ASSERT_NE(nullptr, surface.get());
-
-  const int surface_id = dvrSurfaceGetId(surface.get());
-  ASSERT_GE(surface_id, 0);
-  // Get surface state and verify there is one surface.
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Verify there are no queues for the surface recorded in the state
-  // snapshot.
-  EXPECT_STATUS_EQ(std::vector<int>{}, manager_->GetQueueIds(0));
-
-  // Create a new queue in the surface.
-  auto write_queue_status = CreateSurfaceQueue(
-      surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 1,
-      AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1, 0);
-  ASSERT_STATUS_OK(write_queue_status);
-  UniqueDvrWriteBufferQueue write_queue = write_queue_status.take();
-  ASSERT_NE(nullptr, write_queue.get());
-
-  const int queue_id = dvrWriteBufferQueueGetId(write_queue.get());
-  ASSERT_GE(queue_id, 0);
-
-  // Update surface state.
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Verify the buffers changed flag is set.
-  auto check_flags = [](const auto& value) {
-    return value & DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED;
-  };
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  auto queue_ids_status = manager_->GetQueueIds(0);
-  ASSERT_STATUS_OK(queue_ids_status);
-
-  auto queue_ids = queue_ids_status.take();
-  ASSERT_EQ(1u, queue_ids.size());
-  EXPECT_EQ(queue_id, queue_ids[0]);
-
-  auto read_queue_status = manager_->GetReadBufferQueue(surface_id, queue_id);
-  ASSERT_STATUS_OK(read_queue_status);
-  UniqueDvrReadBufferQueue read_queue = read_queue_status.take();
-  ASSERT_NE(nullptr, read_queue.get());
-  EXPECT_EQ(queue_id, dvrReadBufferQueueGetId(read_queue.get()));
-
-  write_queue.reset();
-
-  // Verify that destroying the queue generates a surface update event.
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Verify that the buffers changed flag is set.
-  EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
-  // Verify that the queue ids reflect the change.
-  queue_ids_status = manager_->GetQueueIds(0);
-  ASSERT_STATUS_OK(queue_ids_status);
-
-  queue_ids = queue_ids_status.take();
-  ASSERT_EQ(0u, queue_ids.size());
-}
-
-TEST_F(DvrDisplayManagerTest, MultiLayerBufferQueue) {
-  // Create an application surface.
-  auto surface_status = CreateApplicationSurface();
-  ASSERT_STATUS_OK(surface_status);
-  UniqueDvrSurface surface = surface_status.take();
-  ASSERT_NE(nullptr, surface.get());
-
-  // Get surface state and verify there is one surface.
-  ASSERT_STATUS_OK(manager_->WaitForUpdate());
-  ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
-  // Create a new queue in the surface.
-  const uint32_t kLayerCount = 3;
-  auto write_queue_status = CreateSurfaceQueue(
-      surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kLayerCount,
-      AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1, 0);
-  ASSERT_STATUS_OK(write_queue_status);
-  UniqueDvrWriteBufferQueue write_queue = write_queue_status.take();
-  ASSERT_NE(nullptr, write_queue.get());
-
-  DvrWriteBuffer* buffer = nullptr;
-  DvrNativeBufferMetadata metadata;
-  int fence_fd = -1;
-  int error = dvrWriteBufferQueueGainBuffer(write_queue.get(), /*timeout=*/1000,
-                                            &buffer, &metadata, &fence_fd);
-  ASSERT_EQ(0, error);
-
-  AHardwareBuffer* hardware_buffer = nullptr;
-  error = dvrWriteBufferGetAHardwareBuffer(buffer, &hardware_buffer);
-  ASSERT_EQ(0, error);
-
-  AHardwareBuffer_Desc desc = {};
-  AHardwareBuffer_describe(hardware_buffer, &desc);
-  ASSERT_EQ(kLayerCount, desc.layers);
-
-  AHardwareBuffer_release(hardware_buffer);
-  dvrWriteBufferDestroy(buffer);
-}
-
-TEST_F(Test, ConfigurationData) {
-  // TODO(hendrikw): Move this test and GetConfigData helper function out of the
-  // display manager tests.
-  auto data1 = GetConfigData(-1);
-  ASSERT_STATUS_ERROR(data1);
-
-  const char kDvrLensMetricsProperty[] = "ro.dvr.lens_metrics";
-
-  // This should be run on devices with and without built in metrics.
-  bool has_metric = !base::GetProperty(kDvrLensMetricsProperty, "").empty();
-  auto data2 = GetConfigData(DVR_CONFIGURATION_DATA_LENS_METRICS);
-  if (has_metric) {
-    ASSERT_STATUS_OK(data2);
-    ASSERT_NE(0u, data2.get().size());
-  } else {
-    ASSERT_STATUS_ERROR(data2);
-  }
-}
-
-}  // namespace
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
deleted file mode 100644
index 5c837e7..0000000
--- a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-#include <android/hardware_buffer.h>
-#include <dvr/dvr_buffer.h>
-#include <dvr/dvr_config.h>
-#include <dvr/dvr_shared_buffers.h>
-#include <dvr/dvr_surface.h>
-#include <system/graphics.h>
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-TEST(DvrGlobalBufferTest, TestGlobalBuffersSameName) {
-  const DvrGlobalBufferKey buffer_key = 101;
-  DvrBuffer* buffer1 = nullptr;
-  int ret1 = dvrSetupGlobalBuffer(buffer_key, 10, 0, &buffer1);
-  ASSERT_EQ(0, ret1);
-  ASSERT_NE(nullptr, buffer1);
-
-  DvrBuffer* buffer2 = nullptr;
-  int ret2 = dvrSetupGlobalBuffer(buffer_key, 10, 0, &buffer2);
-  ASSERT_EQ(0, ret2);
-  ASSERT_NE(nullptr, buffer2);
-
-  AHardwareBuffer* hardware_buffer1 = nullptr;
-  int e1 = dvrBufferGetAHardwareBuffer(buffer1, &hardware_buffer1);
-  ASSERT_EQ(0, e1);
-  ASSERT_NE(nullptr, hardware_buffer1);
-
-  AHardwareBuffer* hardware_buffer2 = nullptr;
-  int e2 = dvrBufferGetAHardwareBuffer(buffer2, &hardware_buffer2);
-  ASSERT_EQ(0, e2);
-  ASSERT_NE(nullptr, hardware_buffer2);
-
-  AHardwareBuffer_Desc desc1 = {};
-  AHardwareBuffer_describe(hardware_buffer1, &desc1);
-  AHardwareBuffer_Desc desc2 = {};
-  AHardwareBuffer_describe(hardware_buffer2, &desc2);
-  ASSERT_EQ(desc1.width, 10u);
-  ASSERT_EQ(desc1.height, 1u);
-  ASSERT_EQ(desc1.layers, 1u);
-  ASSERT_EQ(desc1.format, HAL_PIXEL_FORMAT_BLOB);
-  ASSERT_EQ(desc1.usage, 0u);
-  ASSERT_EQ(desc2.width, 10u);
-  ASSERT_EQ(desc2.height, 1u);
-  ASSERT_EQ(desc2.layers, 1u);
-  ASSERT_EQ(desc2.format, HAL_PIXEL_FORMAT_BLOB);
-  ASSERT_EQ(desc2.usage, 0u);
-
-  dvrBufferDestroy(buffer1);
-  dvrBufferDestroy(buffer2);
-
-  DvrBuffer* buffer3 = nullptr;
-  int e3 = dvrGetGlobalBuffer(buffer_key, &buffer3);
-  ASSERT_NE(nullptr, buffer3);
-  ASSERT_EQ(0, e3);
-
-  AHardwareBuffer* hardware_buffer3 = nullptr;
-  int e4 = dvrBufferGetAHardwareBuffer(buffer3, &hardware_buffer3);
-  ASSERT_EQ(0, e4);
-  ASSERT_NE(nullptr, hardware_buffer3);
-
-  AHardwareBuffer_Desc desc3 = {};
-  AHardwareBuffer_describe(hardware_buffer3, &desc3);
-  ASSERT_EQ(desc3.width, 10u);
-  ASSERT_EQ(desc3.height, 1u);
-  ASSERT_EQ(desc3.layers, 1u);
-  ASSERT_EQ(desc3.format, HAL_PIXEL_FORMAT_BLOB);
-  ASSERT_EQ(desc3.usage, 0u);
-
-  dvrBufferDestroy(buffer3);
-
-  AHardwareBuffer_release(hardware_buffer1);
-  AHardwareBuffer_release(hardware_buffer2);
-  AHardwareBuffer_release(hardware_buffer3);
-}
-
-TEST(DvrGlobalBufferTest, TestMultipleGlobalBuffers) {
-  const DvrGlobalBufferKey buffer_key1 = 102;
-  const DvrGlobalBufferKey buffer_key2 = 103;
-  DvrBuffer* setup_buffer1 = nullptr;
-  int ret1 = dvrSetupGlobalBuffer(buffer_key1, 10, 0, &setup_buffer1);
-  ASSERT_EQ(0, ret1);
-  ASSERT_NE(nullptr, setup_buffer1);
-  dvrBufferDestroy(setup_buffer1);
-
-  DvrBuffer* setup_buffer2 = nullptr;
-  int ret2 = dvrSetupGlobalBuffer(buffer_key2, 10, 0, &setup_buffer2);
-  ASSERT_EQ(0, ret2);
-  ASSERT_NE(nullptr, setup_buffer2);
-  dvrBufferDestroy(setup_buffer2);
-
-  DvrBuffer* buffer1 = nullptr;
-  int e1 = dvrGetGlobalBuffer(buffer_key1, &buffer1);
-  ASSERT_NE(nullptr, buffer1);
-  ASSERT_EQ(0, e1);
-  dvrBufferDestroy(buffer1);
-
-  DvrBuffer* buffer2 = nullptr;
-  int e2 = dvrGetGlobalBuffer(buffer_key2, &buffer2);
-  ASSERT_NE(nullptr, buffer2);
-  ASSERT_EQ(0, e2);
-  dvrBufferDestroy(buffer2);
-}
-
-TEST(DvrGlobalBufferTest, TestGlobalBufferUsage) {
-  const DvrGlobalBufferKey buffer_key = 100;
-
-  // Set usage to AHARDWAREBUFFER_USAGE_VIDEO_ENCODE. We use this because
-  // internally AHARDWAREBUFFER_USAGE_VIDEO_ENCODE is converted to
-  // GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, and these two values are different.
-  // If all is good, when we get the AHardwareBuffer, it should be converted
-  // back to AHARDWAREBUFFER_USAGE_VIDEO_ENCODE.
-  const uint64_t usage = AHARDWAREBUFFER_USAGE_VIDEO_ENCODE;
-
-  DvrBuffer* setup_buffer = nullptr;
-  int e1 = dvrSetupGlobalBuffer(buffer_key, 10, usage, &setup_buffer);
-  ASSERT_NE(nullptr, setup_buffer);
-  ASSERT_EQ(0, e1);
-
-  AHardwareBuffer* hardware_buffer = nullptr;
-  int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
-  ASSERT_EQ(0, e2);
-  ASSERT_NE(nullptr, hardware_buffer);
-
-  AHardwareBuffer_Desc desc = {};
-  AHardwareBuffer_describe(hardware_buffer, &desc);
-  ASSERT_EQ(usage, desc.usage);
-
-  dvrBufferDestroy(setup_buffer);
-  AHardwareBuffer_release(hardware_buffer);
-}
-
-TEST(DvrGlobalBufferTest, TestGlobalBufferCarriesData) {
-  const DvrGlobalBufferKey buffer_name = 110;
-
-  uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
-                   AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
-  constexpr size_t size = 1024 * sizeof(uint64_t);
-  constexpr uint64_t value = 0x123456787654321;
-
-  {
-    // Allocate some data and set it to something.
-    DvrBuffer* setup_buffer = nullptr;
-    int e1 = dvrSetupGlobalBuffer(buffer_name, size, usage, &setup_buffer);
-    ASSERT_NE(nullptr, setup_buffer);
-    ASSERT_EQ(0, e1);
-
-    AHardwareBuffer* hardware_buffer = nullptr;
-    int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
-    ASSERT_EQ(0, e2);
-    ASSERT_NE(nullptr, hardware_buffer);
-
-    void* buffer;
-    int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer);
-    ASSERT_EQ(0, e3);
-    ASSERT_NE(nullptr, buffer);
-    // Verify that the buffer pointer is at least 16 byte aligned.
-    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
-
-    uint64_t* data = static_cast<uint64_t*>(buffer);
-    constexpr size_t num_values = size / sizeof(uint64_t);
-    for (size_t i = 0; i < num_values; ++i) {
-      data[i] = value;
-    }
-
-    int32_t fence = -1;
-    int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence);
-    ASSERT_EQ(0, e4);
-
-    dvrBufferDestroy(setup_buffer);
-    AHardwareBuffer_release(hardware_buffer);
-  }
-
-  {
-    // Get the buffer and check that all the data is still present.
-    DvrBuffer* setup_buffer = nullptr;
-    int e1 = dvrGetGlobalBuffer(buffer_name, &setup_buffer);
-    ASSERT_NE(nullptr, setup_buffer);
-    ASSERT_EQ(0, e1);
-
-    AHardwareBuffer* hardware_buffer = nullptr;
-    int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
-    ASSERT_EQ(0, e2);
-    ASSERT_NE(nullptr, hardware_buffer);
-
-    void* buffer;
-    int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer);
-    ASSERT_EQ(0, e3);
-    ASSERT_NE(nullptr, buffer);
-    // Verify that the buffer pointer is at least 16 byte aligned.
-    ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
-
-    uint64_t* data = static_cast<uint64_t*>(buffer);
-    constexpr size_t num_values = size / sizeof(uint64_t);
-    bool is_equal = true;
-    for (size_t i = 0; i < num_values; ++i) {
-      is_equal &= (data[i] == value);
-    }
-    ASSERT_TRUE(is_equal);
-
-    int32_t fence = -1;
-    int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence);
-    ASSERT_EQ(0, e4);
-
-    dvrBufferDestroy(setup_buffer);
-    AHardwareBuffer_release(hardware_buffer);
-  }
-}
-
-TEST(DvrGlobalBufferTest, TestGlobalBufferZeroed) {
-  const DvrGlobalBufferKey buffer_name = 120;
-
-  // Allocate 1MB and check that it is all zeros.
-  uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
-                   AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
-  constexpr size_t size = 1024 * 1024;
-  DvrBuffer* setup_buffer = nullptr;
-  int e1 = dvrSetupGlobalBuffer(buffer_name, size, usage, &setup_buffer);
-  ASSERT_NE(nullptr, setup_buffer);
-  ASSERT_EQ(0, e1);
-
-  AHardwareBuffer* hardware_buffer = nullptr;
-  int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
-  ASSERT_EQ(0, e2);
-  ASSERT_NE(nullptr, hardware_buffer);
-
-  void* buffer;
-  int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer);
-  ASSERT_EQ(0, e3);
-  ASSERT_NE(nullptr, buffer);
-  // Verify that the buffer pointer is at least 16 byte aligned.
-  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
-
-  uint64_t* data = static_cast<uint64_t*>(buffer);
-  constexpr size_t num_values = size / sizeof(uint64_t);
-  uint64_t zero = 0;
-  for (size_t i = 0; i < num_values; ++i) {
-    zero |= data[i];
-  }
-  ASSERT_EQ(0U, zero);
-
-  int32_t fence = -1;
-  int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence);
-  ASSERT_EQ(0, e4);
-
-  dvrBufferDestroy(setup_buffer);
-  AHardwareBuffer_release(hardware_buffer);
-}
-
-TEST(DvrGlobalBufferTest, TestVrflingerConfigBuffer) {
-  const DvrGlobalBufferKey buffer_name =
-      DvrGlobalBuffers::kVrFlingerConfigBufferKey;
-
-  // First delete any existing buffer so we can test the failure case.
-  dvrDeleteGlobalBuffer(buffer_name);
-
-  const uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
-                         AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY;
-
-  size_t correct_size = DvrConfigRing::MemorySize();
-  size_t wrong_size = DvrConfigRing::MemorySize(0);
-
-  // Setup an invalid config buffer (too small) and assert that it fails.
-  DvrBuffer* setup_buffer = nullptr;
-  int e1 = dvrSetupGlobalBuffer(buffer_name, wrong_size, usage, &setup_buffer);
-  ASSERT_EQ(nullptr, setup_buffer);
-  ASSERT_GT(0, e1);
-
-  // Setup a correct config buffer.
-  int e2 =
-      dvrSetupGlobalBuffer(buffer_name, correct_size, usage, &setup_buffer);
-  ASSERT_NE(nullptr, setup_buffer);
-  ASSERT_EQ(0, e2);
-
-  dvrBufferDestroy(setup_buffer);
-}
-
-}  // namespace
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/vr/libdvr/tests/dvr_tracking-test.cpp b/libs/vr/libdvr/tests/dvr_tracking-test.cpp
deleted file mode 100644
index 3b6d6e1..0000000
--- a/libs/vr/libdvr/tests/dvr_tracking-test.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#include <android/log.h>
-#include <gtest/gtest.h>
-
-#include "dvr_api_test.h"
-
-namespace {
-
-class DvrTrackingTest : public DvrApiTest {};
-
-#if DVR_TRACKING_IMPLEMENTED
-
-TEST_F(DvrTrackingTest, Implemented) {
-  ASSERT_TRUE(api_.TrackingCameraCreate != nullptr);
-  ASSERT_TRUE(api_.TrackingCameraStart != nullptr);
-  ASSERT_TRUE(api_.TrackingCameraStop != nullptr);
-
-  ASSERT_TRUE(api_.TrackingFeatureExtractorCreate != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorDestroy != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorStart != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorStop != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorProcessBuffer != nullptr);
-}
-
-TEST_F(DvrTrackingTest, CameraCreateFailsForInvalidInput) {
-  int ret;
-  ret = api_.TrackingCameraCreate(nullptr);
-  EXPECT_EQ(ret, -EINVAL);
-
-  DvrTrackingCamera* camera = reinterpret_cast<DvrTrackingCamera*>(42);
-  ret = api_.TrackingCameraCreate(&camera);
-  EXPECT_EQ(ret, -EINVAL);
-}
-
-TEST_F(DvrTrackingTest, CameraCreateDestroy) {
-  DvrTrackingCamera* camera = nullptr;
-  int ret = api_.TrackingCameraCreate(&camera);
-
-  EXPECT_EQ(ret, 0);
-  ASSERT_TRUE(camera != nullptr);
-
-  api_.TrackingCameraDestroy(camera);
-}
-
-TEST_F(DvrTrackingTest, FeatureExtractorCreateFailsForInvalidInput) {
-  int ret;
-  ret = api_.TrackingFeatureExtractorCreate(nullptr);
-  EXPECT_EQ(ret, -EINVAL);
-
-  DvrTrackingFeatureExtractor* camera =
-      reinterpret_cast<DvrTrackingFeatureExtractor*>(42);
-  ret = api_.TrackingFeatureExtractorCreate(&camera);
-  EXPECT_EQ(ret, -EINVAL);
-}
-
-TEST_F(DvrTrackingTest, FeatureExtractorCreateDestroy) {
-  DvrTrackingFeatureExtractor* camera = nullptr;
-  int ret = api_.TrackingFeatureExtractorCreate(&camera);
-
-  EXPECT_EQ(ret, 0);
-  ASSERT_TRUE(camera != nullptr);
-
-  api_.TrackingFeatureExtractorDestroy(camera);
-}
-
-#else  // !DVR_TRACKING_IMPLEMENTED
-
-TEST_F(DvrTrackingTest, NotImplemented) {
-  ASSERT_TRUE(api_.TrackingCameraCreate != nullptr);
-  ASSERT_TRUE(api_.TrackingCameraDestroy != nullptr);
-  ASSERT_TRUE(api_.TrackingCameraStart != nullptr);
-  ASSERT_TRUE(api_.TrackingCameraStop != nullptr);
-
-  EXPECT_EQ(api_.TrackingCameraCreate(nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingCameraStart(nullptr, nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingCameraStop(nullptr), -ENOSYS);
-
-  ASSERT_TRUE(api_.TrackingFeatureExtractorCreate != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorDestroy != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorStart != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorStop != nullptr);
-  ASSERT_TRUE(api_.TrackingFeatureExtractorProcessBuffer != nullptr);
-
-  EXPECT_EQ(api_.TrackingFeatureExtractorCreate(nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingFeatureExtractorStart(nullptr, nullptr, nullptr),
-            -ENOSYS);
-  EXPECT_EQ(api_.TrackingFeatureExtractorStop(nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingFeatureExtractorProcessBuffer(nullptr, nullptr,
-                                                       nullptr, nullptr),
-            -ENOSYS);
-
-  ASSERT_TRUE(api_.TrackingSensorsCreate != nullptr);
-  ASSERT_TRUE(api_.TrackingSensorsDestroy != nullptr);
-  ASSERT_TRUE(api_.TrackingSensorsStart != nullptr);
-  ASSERT_TRUE(api_.TrackingSensorsStop != nullptr);
-
-  EXPECT_EQ(api_.TrackingSensorsCreate(nullptr, nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingSensorsStart(nullptr, nullptr, nullptr), -ENOSYS);
-  EXPECT_EQ(api_.TrackingSensorsStop(nullptr), -ENOSYS);
-}
-
-#endif  // DVR_TRACKING_IMPLEMENTED
-
-}  // namespace
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 76fd7f0..dd14bcf 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -207,7 +207,8 @@
     ATRACE_CALL();
     const nsecs_t openTime = systemTime();
 
-    if (should_unload_system_driver(cnx)) {
+    if (!android::GraphicsEnv::getInstance().angleIsSystemDriver() &&
+        should_unload_system_driver(cnx)) {
         unload_system_driver(cnx);
     }
 
@@ -216,8 +217,13 @@
         return cnx->dso;
     }
 
-    // Firstly, try to load ANGLE driver.
-    driver_t* hnd = attempt_to_load_angle(cnx);
+    // Firstly, try to load ANGLE driver, unless we know that we shouldn't.
+    bool shouldForceLegacyDriver = android::GraphicsEnv::getInstance().shouldForceLegacyDriver();
+    driver_t* hnd = nullptr;
+    if (!shouldForceLegacyDriver) {
+        hnd = attempt_to_load_angle(cnx);
+    }
+
     if (!hnd) {
         // Secondly, try to load from driver apk.
         hnd = attempt_to_load_updated_driver(cnx);
@@ -230,21 +236,29 @@
             LOG_ALWAYS_FATAL("couldn't find an OpenGL ES implementation from %s",
                              android::GraphicsEnv::getInstance().getDriverPath().c_str());
         }
-        // Finally, try to load system driver, start by searching for the library name appended by
-        // the system properties of the GLES userspace driver in both locations.
-        // i.e.:
-        //      libGLES_${prop}.so, or:
-        //      libEGL_${prop}.so, libGLESv1_CM_${prop}.so, libGLESv2_${prop}.so
-        for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
-            auto prop = base::GetProperty(key, "");
-            if (prop.empty()) {
-                continue;
-            }
-            hnd = attempt_to_load_system_driver(cnx, prop.c_str(), true);
-            if (hnd) {
-                break;
-            } else if (strcmp(key, DRIVER_SUFFIX_PROPERTY) == 0) {
-                failToLoadFromDriverSuffixProperty = true;
+        // Finally, try to load system driver.  If ANGLE is the system driver
+        // (i.e. we are forcing the legacy system driver instead of ANGLE), use
+        // the driver suffix that was passed down from above.
+        if (shouldForceLegacyDriver) {
+            std::string suffix = android::GraphicsEnv::getInstance().getLegacySuffix();
+            hnd = attempt_to_load_system_driver(cnx, suffix.c_str(), true);
+        } else {
+            // Start by searching for the library name appended by the system
+            // properties of the GLES userspace driver in both locations.
+            // i.e.:
+            //      libGLES_${prop}.so, or:
+            //      libEGL_${prop}.so, libGLESv1_CM_${prop}.so, libGLESv2_${prop}.so
+            for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
+                auto prop = base::GetProperty(key, "");
+                if (prop.empty()) {
+                    continue;
+                }
+                hnd = attempt_to_load_system_driver(cnx, prop.c_str(), true);
+                if (hnd) {
+                    break;
+                } else if (strcmp(key, DRIVER_SUFFIX_PROPERTY) == 0) {
+                    failToLoadFromDriverSuffixProperty = true;
+                }
             }
         }
     }
diff --git a/opengl/libs/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp
index b3d6f74..e0ba946 100644
--- a/opengl/libs/EGL/getProcAddress.cpp
+++ b/opengl/libs/EGL/getProcAddress.cpp
@@ -118,70 +118,27 @@
             : "rax", "cc"                                       \
             );
 
-#elif defined(__mips64)
+#elif defined(__riscv)
+    #define API_ENTRY(_api) __attribute__((noinline)) _api
 
-        #define API_ENTRY(_api) __attribute__((noinline)) _api
-
-        #define CALL_GL_EXTENSION_API(_api, ...)                    \
-            register unsigned int _t0 asm("$12");                   \
-            register unsigned int _fn asm("$25");                   \
-            register unsigned int _tls asm("$3");                   \
-            asm volatile(                                           \
-                ".set  push\n\t"                                    \
-                ".set  noreorder\n\t"                               \
-                "rdhwr %[tls], $29\n\t"                             \
-                "ld    %[t0], %[OPENGL_API](%[tls])\n\t"            \
-                "beqz  %[t0], 1f\n\t"                               \
-                " move %[fn], $ra\n\t"                              \
-                "ld    %[t0], %[API](%[t0])\n\t"                    \
-                "beqz  %[t0], 1f\n\t"                               \
-                " nop\n\t"                                          \
-                "move  %[fn], %[t0]\n\t"                            \
-                "1:\n\t"                                            \
-                "jalr  $0, %[fn]\n\t"                               \
-                " nop\n\t"                                          \
-                ".set  pop\n\t"                                     \
-                : [fn] "=c"(_fn),                                   \
-                  [tls] "=&r"(_tls),                                \
-                  [t0] "=&r"(_t0)                                   \
-                : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),          \
-                  [API] "I"(__builtin_offsetof(gl_hooks_t,          \
-                                          ext.extensions[_api]))    \
-                :                                                   \
-            );
-
-#elif defined(__mips__)
-
-        #define API_ENTRY(_api) __attribute__((noinline)) _api
-
-        #define CALL_GL_EXTENSION_API(_api, ...)                    \
-            register unsigned int _t0 asm("$8");                    \
-            register unsigned int _fn asm("$25");                    \
-            register unsigned int _tls asm("$3");                   \
-            asm volatile(                                           \
-                ".set  push\n\t"                                    \
-                ".set  noreorder\n\t"                               \
-                ".set  mips32r2\n\t"                                \
-                "rdhwr %[tls], $29\n\t"                             \
-                "lw    %[t0], %[OPENGL_API](%[tls])\n\t"            \
-                "beqz  %[t0], 1f\n\t"                               \
-                " move %[fn], $ra\n\t"                              \
-                "lw    %[t0], %[API](%[t0])\n\t"                    \
-                "beqz  %[t0], 1f\n\t"                               \
-                " nop\n\t"                                          \
-                "move  %[fn], %[t0]\n\t"                            \
-                "1:\n\t"                                            \
-                "jalr  $0, %[fn]\n\t"                               \
-                " nop\n\t"                                          \
-                ".set  pop\n\t"                                     \
-                : [fn] "=c"(_fn),                                   \
-                  [tls] "=&r"(_tls),                                \
-                  [t0] "=&r"(_t0)                                   \
-                : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),          \
-                  [API] "I"(__builtin_offsetof(gl_hooks_t,          \
-                                          ext.extensions[_api]))    \
-                :                                                   \
-            );
+    #define CALL_GL_EXTENSION_API(_api)                             \
+        asm volatile(                                               \
+            "mv t0, tp\n"                                           \
+            "li t1, %[tls]\n"                                       \
+            "add t0, t0, t1\n"                                      \
+            "ld t0, 0(t0)\n"                                        \
+            "beqz t0, 1f\n"                                         \
+            "li t1, %[api]\n"                                       \
+            "add t0, t0, t1\n"                                      \
+            "ld t0, 0(t0)\n"                                        \
+            "jalr x0, t0\n"                                         \
+            "1: ret\n"                                              \
+            :                                                       \
+            : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)),      \
+              [api] "i" (__builtin_offsetof(gl_hooks_t,             \
+                                        ext.extensions[_api]))      \
+            : "t0", "t1"                                            \
+        );
 
 #endif
 
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index 65f50f5..5bd5c14 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -191,73 +191,44 @@
             :                              \
         );
 
-#elif defined(__mips64)
+#elif defined(__riscv)
 
     #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    // t0:  $12
-    // fn:  $25
-    // tls: $3
-    // v0:  $2
-    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                  \
-        asm volatile(                                             \
-            ".set  push\n\t"                                      \
-            ".set  noreorder\n\t"                                 \
-            "rdhwr $3, $29\n\t"                                   \
-            "ld    $12, %[OPENGL_API]($3)\n\t"                    \
-            "beqz  $12, 1f\n\t"                                   \
-            " move $25, $ra\n\t"                                  \
-            "ld    $12, %[API]($12)\n\t"                          \
-            "beqz  $12, 1f\n\t"                                   \
-            " nop\n\t"                                            \
-            "move  $25, $12\n\t"                                  \
-            "1:\n\t"                                              \
-            "jalr  $0, $25\n\t"                                   \
-            " move $2, $0\n\t"                                    \
-            ".set  pop\n\t"                                       \
-            :                                                     \
-            : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
-              [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api))  \
-            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",     \
-              "$10", "$11", "$12", "$25"                          \
-        );
-
-    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
-    #define CALL_GL_API_INTERNAL_DO_RETURN
-
-#elif defined(__mips__)
-
-    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
-
-    // t0:  $8
-    // fn:  $25
-    // tls: $3
-    // v0:  $2
     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                 \
         asm volatile(                                            \
-            ".set  push\n\t"                                     \
-            ".set  noreorder\n\t"                                \
-            ".set  mips32r2\n\t"                                 \
-            "rdhwr $3, $29\n\t"                                  \
-            "lw    $3, %[OPENGL_API]($3)\n\t"                    \
-            "beqz  $3, 1f\n\t"                                   \
-            " move $25,$ra\n\t"                                  \
-            "lw    $3, %[API]($3)\n\t"                           \
-            "beqz  $3, 1f\n\t"                                   \
-            " nop\n\t"                                           \
-            "move  $25, $3\n\t"                                  \
-            "1:\n\t"                                             \
-            "jalr  $0, $25\n\t"                                  \
-            " move $2, $0\n\t"                                   \
-            ".set  pop\n\t"                                      \
+            "mv t0, tp\n"                                        \
+            "li t1, %[tls]\n"                                    \
+            "add t0, t0, t1\n"                                   \
+            "ld t0, 0(t0)\n"                                     \
+            "beqz t0, 1f\n"                                      \
+            "li t1, %[api]\n"                                    \
+            "add t0, t0, t1\n"                                   \
+            "ld t0, 0(t0)\n"                                     \
+            "jalr x0, t0\n"                                      \
+            "1:\n"                                               \
             :                                                    \
-            : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),           \
-              [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
-            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25"    \
+            : [tls] "i"(TLS_SLOT_OPENGL_API*sizeof(void *)),     \
+              [api] "i"(__builtin_offsetof(gl_hooks_t, gl._api)) \
+            : "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4",    \
+              "a5", "t6", "t3", "t4", "t5", "t6"                 \
         );
 
-    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
-    #define CALL_GL_API_INTERNAL_DO_RETURN
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        asm volatile(                             \
+            "li a0, 0\n"                          \
+            :                                     \
+            :                                     \
+            : "a0"                                \
+        );
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        asm volatile(                      \
+            "ret\n"                        \
+            :                              \
+            :                              \
+            :                              \
+        );
 
 #endif
 
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index bacd4b4..64c0f97 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -247,73 +247,44 @@
             :                              \
         );
 
-#elif defined(__mips64)
+#elif defined(__riscv)
 
     #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
 
-    // t0:  $12
-    // fn:  $25
-    // tls: $3
-    // v0:  $2
-    #define CALL_GL_API_INTERNAL_CALL(_api, ...)                  \
-        asm volatile(                                             \
-            ".set  push\n\t"                                      \
-            ".set  noreorder\n\t"                                 \
-            "rdhwr $3, $29\n\t"                                   \
-            "ld    $12, %[OPENGL_API]($3)\n\t"                    \
-            "beqz  $12, 1f\n\t"                                   \
-            " move $25, $ra\n\t"                                  \
-            "ld    $12, %[API]($12)\n\t"                          \
-            "beqz  $12, 1f\n\t"                                   \
-            " nop\n\t"                                            \
-            "move  $25, $12\n\t"                                  \
-            "1:\n\t"                                              \
-            "jalr  $0, $25\n\t"                                   \
-            " move $2, $0\n\t"                                    \
-            ".set  pop\n\t"                                       \
-            :                                                     \
-            : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
-              [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api))  \
-            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",     \
-              "$10", "$11", "$12", "$25"                          \
-        );
-
-    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
-    #define CALL_GL_API_INTERNAL_DO_RETURN
-
-#elif defined(__mips__)
-
-    #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
-
-    // t0:  $8
-    // fn:  $25
-    // tls: $3
-    // v0:  $2
     #define CALL_GL_API_INTERNAL_CALL(_api, ...)                 \
         asm volatile(                                            \
-            ".set  push\n\t"                                     \
-            ".set  noreorder\n\t"                                \
-            ".set  mips32r2\n\t"                                 \
-            "rdhwr $3, $29\n\t"                                  \
-            "lw    $3, %[OPENGL_API]($3)\n\t"                    \
-            "beqz  $3, 1f\n\t"                                   \
-            " move $25,$ra\n\t"                                  \
-            "lw    $3, %[API]($3)\n\t"                           \
-            "beqz  $3, 1f\n\t"                                   \
-            " nop\n\t"                                           \
-            "move  $25, $3\n\t"                                  \
-            "1:\n\t"                                             \
-            "jalr  $0, $25\n\t"                                  \
-            " move $2, $0\n\t"                                   \
-            ".set  pop\n\t"                                      \
+            "mv t0, tp\n"                                        \
+            "li t1, %[tls]\n"                                    \
+            "add t0, t0, t1\n"                                   \
+            "ld t0, 0(t0)\n"                                     \
+            "beqz t0, 1f\n"                                      \
+            "li t1, %[api]\n"                                    \
+            "add t0, t0, t1\n"                                   \
+            "ld t0, 0(t0)\n"                                     \
+            "jalr x0, t0\n"                                      \
+            "1:\n"                                               \
             :                                                    \
-            : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4),           \
-              [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
-            : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25"    \
+            : [tls] "i"(TLS_SLOT_OPENGL_API*sizeof(void *)),     \
+              [api] "i"(__builtin_offsetof(gl_hooks_t, gl._api)) \
+            : "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4",    \
+              "a5", "t6", "t3", "t4", "t5", "t6"                 \
         );
 
-    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
-    #define CALL_GL_API_INTERNAL_DO_RETURN
+    #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+        asm volatile(                             \
+            "li a0, 0\n"                          \
+            :                                     \
+            :                                     \
+            : "a0"                                \
+        );
+
+    #define CALL_GL_API_INTERNAL_DO_RETURN \
+        asm volatile(                      \
+            "ret\n"                        \
+            :                              \
+            :                              \
+            :                              \
+        );
 
 #endif
 
diff --git a/services/inputflinger/TEST_MAPPING b/services/inputflinger/TEST_MAPPING
index b4b617e..8d5d883 100644
--- a/services/inputflinger/TEST_MAPPING
+++ b/services/inputflinger/TEST_MAPPING
@@ -15,6 +15,9 @@
       "name": "inputflinger_tests"
     },
     {
+      "name": "libchrome-gestures_test"
+    },
+    {
       "name": "libpalmrejection_test"
     },
     {
diff --git a/services/sensorservice/AidlSensorHalWrapper.cpp b/services/sensorservice/AidlSensorHalWrapper.cpp
index 4d1de96..e75eade 100644
--- a/services/sensorservice/AidlSensorHalWrapper.cpp
+++ b/services/sensorservice/AidlSensorHalWrapper.cpp
@@ -23,6 +23,7 @@
 #include <aidlcommonsupport/NativeHandle.h>
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
+#include <aidl/sensors/convert.h>
 
 using ::aidl::android::hardware::sensors::AdditionalInfo;
 using ::aidl::android::hardware::sensors::DynamicSensorInfo;
@@ -34,469 +35,16 @@
 using ::android::AidlMessageQueue;
 using ::android::hardware::EventFlag;
 using ::android::hardware::sensors::V2_1::implementation::MAX_RECEIVE_BUFFER_EVENT_COUNT;
+using ::android::hardware::sensors::implementation::convertToStatus;
+using ::android::hardware::sensors::implementation::convertToSensor;
+using ::android::hardware::sensors::implementation::convertToSensorEvent;
+using ::android::hardware::sensors::implementation::convertFromSensorEvent;
+
 
 namespace android {
 
 namespace {
 
-status_t convertToStatus(ndk::ScopedAStatus status) {
-    if (status.isOk()) {
-        return OK;
-    } else {
-        switch (status.getExceptionCode()) {
-            case EX_ILLEGAL_ARGUMENT: {
-                return BAD_VALUE;
-            }
-            case EX_SECURITY: {
-                return PERMISSION_DENIED;
-            }
-            case EX_UNSUPPORTED_OPERATION: {
-                return INVALID_OPERATION;
-            }
-            case EX_SERVICE_SPECIFIC: {
-                switch (status.getServiceSpecificError()) {
-                    case ISensors::ERROR_BAD_VALUE: {
-                        return BAD_VALUE;
-                    }
-                    case ISensors::ERROR_NO_MEMORY: {
-                        return NO_MEMORY;
-                    }
-                    default: {
-                        return UNKNOWN_ERROR;
-                    }
-                }
-            }
-            default: {
-                return UNKNOWN_ERROR;
-            }
-        }
-    }
-}
-
-void convertToSensor(const SensorInfo &src, sensor_t *dst) {
-    dst->name = strdup(src.name.c_str());
-    dst->vendor = strdup(src.vendor.c_str());
-    dst->version = src.version;
-    dst->handle = src.sensorHandle;
-    dst->type = (int)src.type;
-    dst->maxRange = src.maxRange;
-    dst->resolution = src.resolution;
-    dst->power = src.power;
-    dst->minDelay = src.minDelayUs;
-    dst->fifoReservedEventCount = src.fifoReservedEventCount;
-    dst->fifoMaxEventCount = src.fifoMaxEventCount;
-    dst->stringType = strdup(src.typeAsString.c_str());
-    dst->requiredPermission = strdup(src.requiredPermission.c_str());
-    dst->maxDelay = src.maxDelayUs;
-    dst->flags = src.flags;
-    dst->reserved[0] = dst->reserved[1] = 0;
-}
-
-void convertToSensorEvent(const Event &src, sensors_event_t *dst) {
-    *dst = {.version = sizeof(sensors_event_t),
-            .sensor = src.sensorHandle,
-            .type = (int32_t)src.sensorType,
-            .reserved0 = 0,
-            .timestamp = src.timestamp};
-
-    switch (src.sensorType) {
-        case SensorType::META_DATA: {
-            // Legacy HALs expect the handle reference in the meta data field.
-            // Copy it over from the handle of the event.
-            dst->meta_data.what = (int32_t)src.payload.get<Event::EventPayload::meta>().what;
-            dst->meta_data.sensor = src.sensorHandle;
-            // Set the sensor handle to 0 to maintain compatibility.
-            dst->sensor = 0;
-            break;
-        }
-
-        case SensorType::ACCELEROMETER:
-        case SensorType::MAGNETIC_FIELD:
-        case SensorType::ORIENTATION:
-        case SensorType::GYROSCOPE:
-        case SensorType::GRAVITY:
-        case SensorType::LINEAR_ACCELERATION: {
-            dst->acceleration.x = src.payload.get<Event::EventPayload::vec3>().x;
-            dst->acceleration.y = src.payload.get<Event::EventPayload::vec3>().y;
-            dst->acceleration.z = src.payload.get<Event::EventPayload::vec3>().z;
-            dst->acceleration.status = (int32_t)src.payload.get<Event::EventPayload::vec3>().status;
-            break;
-        }
-
-        case SensorType::GAME_ROTATION_VECTOR: {
-            dst->data[0] = src.payload.get<Event::EventPayload::vec4>().x;
-            dst->data[1] = src.payload.get<Event::EventPayload::vec4>().y;
-            dst->data[2] = src.payload.get<Event::EventPayload::vec4>().z;
-            dst->data[3] = src.payload.get<Event::EventPayload::vec4>().w;
-            break;
-        }
-
-        case SensorType::ROTATION_VECTOR:
-        case SensorType::GEOMAGNETIC_ROTATION_VECTOR: {
-            dst->data[0] = src.payload.get<Event::EventPayload::data>().values[0];
-            dst->data[1] = src.payload.get<Event::EventPayload::data>().values[1];
-            dst->data[2] = src.payload.get<Event::EventPayload::data>().values[2];
-            dst->data[3] = src.payload.get<Event::EventPayload::data>().values[3];
-            dst->data[4] = src.payload.get<Event::EventPayload::data>().values[4];
-            break;
-        }
-
-        case SensorType::MAGNETIC_FIELD_UNCALIBRATED:
-        case SensorType::GYROSCOPE_UNCALIBRATED:
-        case SensorType::ACCELEROMETER_UNCALIBRATED: {
-            dst->uncalibrated_gyro.x_uncalib = src.payload.get<Event::EventPayload::uncal>().x;
-            dst->uncalibrated_gyro.y_uncalib = src.payload.get<Event::EventPayload::uncal>().y;
-            dst->uncalibrated_gyro.z_uncalib = src.payload.get<Event::EventPayload::uncal>().z;
-            dst->uncalibrated_gyro.x_bias = src.payload.get<Event::EventPayload::uncal>().xBias;
-            dst->uncalibrated_gyro.y_bias = src.payload.get<Event::EventPayload::uncal>().yBias;
-            dst->uncalibrated_gyro.z_bias = src.payload.get<Event::EventPayload::uncal>().zBias;
-            break;
-        }
-
-        case SensorType::HINGE_ANGLE:
-        case SensorType::DEVICE_ORIENTATION:
-        case SensorType::LIGHT:
-        case SensorType::PRESSURE:
-        case SensorType::PROXIMITY:
-        case SensorType::RELATIVE_HUMIDITY:
-        case SensorType::AMBIENT_TEMPERATURE:
-        case SensorType::SIGNIFICANT_MOTION:
-        case SensorType::STEP_DETECTOR:
-        case SensorType::TILT_DETECTOR:
-        case SensorType::WAKE_GESTURE:
-        case SensorType::GLANCE_GESTURE:
-        case SensorType::PICK_UP_GESTURE:
-        case SensorType::WRIST_TILT_GESTURE:
-        case SensorType::STATIONARY_DETECT:
-        case SensorType::MOTION_DETECT:
-        case SensorType::HEART_BEAT:
-        case SensorType::LOW_LATENCY_OFFBODY_DETECT: {
-            dst->data[0] = src.payload.get<Event::EventPayload::scalar>();
-            break;
-        }
-
-        case SensorType::STEP_COUNTER: {
-            dst->u64.step_counter = src.payload.get<Event::EventPayload::stepCount>();
-            break;
-        }
-
-        case SensorType::HEART_RATE: {
-            dst->heart_rate.bpm = src.payload.get<Event::EventPayload::heartRate>().bpm;
-            dst->heart_rate.status =
-                    (int8_t)src.payload.get<Event::EventPayload::heartRate>().status;
-            break;
-        }
-
-        case SensorType::POSE_6DOF: { // 15 floats
-            for (size_t i = 0; i < 15; ++i) {
-                dst->data[i] = src.payload.get<Event::EventPayload::pose6DOF>().values[i];
-            }
-            break;
-        }
-
-        case SensorType::DYNAMIC_SENSOR_META: {
-            dst->dynamic_sensor_meta.connected =
-                    src.payload.get<Event::EventPayload::dynamic>().connected;
-            dst->dynamic_sensor_meta.handle =
-                    src.payload.get<Event::EventPayload::dynamic>().sensorHandle;
-            dst->dynamic_sensor_meta.sensor = NULL; // to be filled in later
-
-            memcpy(dst->dynamic_sensor_meta.uuid,
-                   src.payload.get<Event::EventPayload::dynamic>().uuid.values.data(), 16);
-
-            break;
-        }
-
-        case SensorType::ADDITIONAL_INFO: {
-            const AdditionalInfo &srcInfo = src.payload.get<Event::EventPayload::additional>();
-
-            additional_info_event_t *dstInfo = &dst->additional_info;
-            dstInfo->type = (int32_t)srcInfo.type;
-            dstInfo->serial = srcInfo.serial;
-
-            switch (srcInfo.payload.getTag()) {
-                case AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32: {
-                    const auto &values =
-                            srcInfo.payload.get<AdditionalInfo::AdditionalInfoPayload::dataInt32>()
-                                    .values;
-                    CHECK_EQ(values.size() * sizeof(int32_t), sizeof(dstInfo->data_int32));
-                    memcpy(dstInfo->data_int32, values.data(), sizeof(dstInfo->data_int32));
-                    break;
-                }
-                case AdditionalInfo::AdditionalInfoPayload::Tag::dataFloat: {
-                    const auto &values =
-                            srcInfo.payload.get<AdditionalInfo::AdditionalInfoPayload::dataFloat>()
-                                    .values;
-                    CHECK_EQ(values.size() * sizeof(float), sizeof(dstInfo->data_float));
-                    memcpy(dstInfo->data_float, values.data(), sizeof(dstInfo->data_float));
-                    break;
-                }
-                default: {
-                    ALOGE("Invalid sensor additional info tag: %d", (int)srcInfo.payload.getTag());
-                }
-            }
-            break;
-        }
-
-        case SensorType::HEAD_TRACKER: {
-            const auto &ht = src.payload.get<Event::EventPayload::headTracker>();
-            dst->head_tracker.rx = ht.rx;
-            dst->head_tracker.ry = ht.ry;
-            dst->head_tracker.rz = ht.rz;
-            dst->head_tracker.vx = ht.vx;
-            dst->head_tracker.vy = ht.vy;
-            dst->head_tracker.vz = ht.vz;
-            dst->head_tracker.discontinuity_count = ht.discontinuityCount;
-            break;
-        }
-
-        case SensorType::ACCELEROMETER_LIMITED_AXES:
-        case SensorType::GYROSCOPE_LIMITED_AXES:
-            dst->limited_axes_imu.x = src.payload.get<Event::EventPayload::limitedAxesImu>().x;
-            dst->limited_axes_imu.y = src.payload.get<Event::EventPayload::limitedAxesImu>().y;
-            dst->limited_axes_imu.z = src.payload.get<Event::EventPayload::limitedAxesImu>().z;
-            dst->limited_axes_imu.x_supported =
-                    src.payload.get<Event::EventPayload::limitedAxesImu>().xSupported;
-            dst->limited_axes_imu.y_supported =
-                    src.payload.get<Event::EventPayload::limitedAxesImu>().ySupported;
-            dst->limited_axes_imu.z_supported =
-                    src.payload.get<Event::EventPayload::limitedAxesImu>().zSupported;
-            break;
-
-        case SensorType::ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
-        case SensorType::GYROSCOPE_LIMITED_AXES_UNCALIBRATED:
-            dst->limited_axes_imu_uncalibrated.x_uncalib =
-                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().x;
-            dst->limited_axes_imu_uncalibrated.y_uncalib =
-                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().y;
-            dst->limited_axes_imu_uncalibrated.z_uncalib =
-                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().z;
-            dst->limited_axes_imu_uncalibrated.x_bias =
-                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().xBias;
-            dst->limited_axes_imu_uncalibrated.y_bias =
-                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().yBias;
-            dst->limited_axes_imu_uncalibrated.z_bias =
-                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().zBias;
-            dst->limited_axes_imu_uncalibrated.x_supported =
-                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().xSupported;
-            dst->limited_axes_imu_uncalibrated.y_supported =
-                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().ySupported;
-            dst->limited_axes_imu_uncalibrated.z_supported =
-                    src.payload.get<Event::EventPayload::limitedAxesImuUncal>().zSupported;
-            break;
-
-        case SensorType::HEADING:
-            dst->heading.heading = src.payload.get<Event::EventPayload::heading>().heading;
-            dst->heading.accuracy = src.payload.get<Event::EventPayload::heading>().accuracy;
-            break;
-
-        default: {
-            CHECK_GE((int32_t)src.sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE);
-
-            memcpy(dst->data, src.payload.get<Event::EventPayload::data>().values.data(),
-                   16 * sizeof(float));
-            break;
-        }
-    }
-}
-
-void convertFromSensorEvent(const sensors_event_t &src, Event *dst) {
-    *dst = {
-            .timestamp = src.timestamp,
-            .sensorHandle = src.sensor,
-            .sensorType = (SensorType)src.type,
-    };
-
-    switch (dst->sensorType) {
-        case SensorType::META_DATA: {
-            Event::EventPayload::MetaData meta;
-            meta.what = (Event::EventPayload::MetaData::MetaDataEventType)src.meta_data.what;
-            // Legacy HALs contain the handle reference in the meta data field.
-            // Copy that over to the handle of the event. In legacy HALs this
-            // field was expected to be 0.
-            dst->sensorHandle = src.meta_data.sensor;
-            dst->payload.set<Event::EventPayload::Tag::meta>(meta);
-            break;
-        }
-
-        case SensorType::ACCELEROMETER:
-        case SensorType::MAGNETIC_FIELD:
-        case SensorType::ORIENTATION:
-        case SensorType::GYROSCOPE:
-        case SensorType::GRAVITY:
-        case SensorType::LINEAR_ACCELERATION: {
-            Event::EventPayload::Vec3 vec3;
-            vec3.x = src.acceleration.x;
-            vec3.y = src.acceleration.y;
-            vec3.z = src.acceleration.z;
-            vec3.status = (SensorStatus)src.acceleration.status;
-            dst->payload.set<Event::EventPayload::Tag::vec3>(vec3);
-            break;
-        }
-
-        case SensorType::GAME_ROTATION_VECTOR: {
-            Event::EventPayload::Vec4 vec4;
-            vec4.x = src.data[0];
-            vec4.y = src.data[1];
-            vec4.z = src.data[2];
-            vec4.w = src.data[3];
-            dst->payload.set<Event::EventPayload::Tag::vec4>(vec4);
-            break;
-        }
-
-        case SensorType::ROTATION_VECTOR:
-        case SensorType::GEOMAGNETIC_ROTATION_VECTOR: {
-            Event::EventPayload::Data data;
-            memcpy(data.values.data(), src.data, 5 * sizeof(float));
-            dst->payload.set<Event::EventPayload::Tag::data>(data);
-            break;
-        }
-
-        case SensorType::MAGNETIC_FIELD_UNCALIBRATED:
-        case SensorType::GYROSCOPE_UNCALIBRATED:
-        case SensorType::ACCELEROMETER_UNCALIBRATED: {
-            Event::EventPayload::Uncal uncal;
-            uncal.x = src.uncalibrated_gyro.x_uncalib;
-            uncal.y = src.uncalibrated_gyro.y_uncalib;
-            uncal.z = src.uncalibrated_gyro.z_uncalib;
-            uncal.xBias = src.uncalibrated_gyro.x_bias;
-            uncal.yBias = src.uncalibrated_gyro.y_bias;
-            uncal.zBias = src.uncalibrated_gyro.z_bias;
-            dst->payload.set<Event::EventPayload::Tag::uncal>(uncal);
-            break;
-        }
-
-        case SensorType::DEVICE_ORIENTATION:
-        case SensorType::LIGHT:
-        case SensorType::PRESSURE:
-        case SensorType::PROXIMITY:
-        case SensorType::RELATIVE_HUMIDITY:
-        case SensorType::AMBIENT_TEMPERATURE:
-        case SensorType::SIGNIFICANT_MOTION:
-        case SensorType::STEP_DETECTOR:
-        case SensorType::TILT_DETECTOR:
-        case SensorType::WAKE_GESTURE:
-        case SensorType::GLANCE_GESTURE:
-        case SensorType::PICK_UP_GESTURE:
-        case SensorType::WRIST_TILT_GESTURE:
-        case SensorType::STATIONARY_DETECT:
-        case SensorType::MOTION_DETECT:
-        case SensorType::HEART_BEAT:
-        case SensorType::LOW_LATENCY_OFFBODY_DETECT:
-        case SensorType::HINGE_ANGLE: {
-            dst->payload.set<Event::EventPayload::Tag::scalar>((float)src.data[0]);
-            break;
-        }
-
-        case SensorType::STEP_COUNTER: {
-            dst->payload.set<Event::EventPayload::Tag::stepCount>(src.u64.step_counter);
-            break;
-        }
-
-        case SensorType::HEART_RATE: {
-            Event::EventPayload::HeartRate heartRate;
-            heartRate.bpm = src.heart_rate.bpm;
-            heartRate.status = (SensorStatus)src.heart_rate.status;
-            dst->payload.set<Event::EventPayload::Tag::heartRate>(heartRate);
-            break;
-        }
-
-        case SensorType::POSE_6DOF: { // 15 floats
-            Event::EventPayload::Pose6Dof pose6DOF;
-            for (size_t i = 0; i < 15; ++i) {
-                pose6DOF.values[i] = src.data[i];
-            }
-            dst->payload.set<Event::EventPayload::Tag::pose6DOF>(pose6DOF);
-            break;
-        }
-
-        case SensorType::DYNAMIC_SENSOR_META: {
-            DynamicSensorInfo dynamic;
-            dynamic.connected = src.dynamic_sensor_meta.connected;
-            dynamic.sensorHandle = src.dynamic_sensor_meta.handle;
-
-            memcpy(dynamic.uuid.values.data(), src.dynamic_sensor_meta.uuid, 16);
-            dst->payload.set<Event::EventPayload::Tag::dynamic>(dynamic);
-            break;
-        }
-
-        case SensorType::ADDITIONAL_INFO: {
-            AdditionalInfo info;
-            const additional_info_event_t &srcInfo = src.additional_info;
-            info.type = (AdditionalInfo::AdditionalInfoType)srcInfo.type;
-            info.serial = srcInfo.serial;
-
-            AdditionalInfo::AdditionalInfoPayload::Int32Values data;
-            CHECK_EQ(data.values.size() * sizeof(int32_t), sizeof(srcInfo.data_int32));
-            memcpy(data.values.data(), srcInfo.data_int32, sizeof(srcInfo.data_int32));
-            info.payload.set<AdditionalInfo::AdditionalInfoPayload::Tag::dataInt32>(data);
-
-            dst->payload.set<Event::EventPayload::Tag::additional>(info);
-            break;
-        }
-
-        case SensorType::HEAD_TRACKER: {
-            Event::EventPayload::HeadTracker headTracker;
-            headTracker.rx = src.head_tracker.rx;
-            headTracker.ry = src.head_tracker.ry;
-            headTracker.rz = src.head_tracker.rz;
-            headTracker.vx = src.head_tracker.vx;
-            headTracker.vy = src.head_tracker.vy;
-            headTracker.vz = src.head_tracker.vz;
-            headTracker.discontinuityCount = src.head_tracker.discontinuity_count;
-
-            dst->payload.set<Event::EventPayload::Tag::headTracker>(headTracker);
-            break;
-        }
-
-        case SensorType::ACCELEROMETER_LIMITED_AXES:
-        case SensorType::GYROSCOPE_LIMITED_AXES: {
-            Event::EventPayload::LimitedAxesImu limitedAxesImu;
-            limitedAxesImu.x = src.limited_axes_imu.x;
-            limitedAxesImu.y = src.limited_axes_imu.y;
-            limitedAxesImu.z = src.limited_axes_imu.z;
-            limitedAxesImu.xSupported = src.limited_axes_imu.x_supported;
-            limitedAxesImu.ySupported = src.limited_axes_imu.y_supported;
-            limitedAxesImu.zSupported = src.limited_axes_imu.z_supported;
-            dst->payload.set<Event::EventPayload::Tag::limitedAxesImu>(limitedAxesImu);
-            break;
-        }
-
-        case SensorType::ACCELEROMETER_LIMITED_AXES_UNCALIBRATED:
-        case SensorType::GYROSCOPE_LIMITED_AXES_UNCALIBRATED: {
-            Event::EventPayload::LimitedAxesImuUncal limitedAxesImuUncal;
-            limitedAxesImuUncal.x = src.limited_axes_imu_uncalibrated.x_uncalib;
-            limitedAxesImuUncal.y = src.limited_axes_imu_uncalibrated.y_uncalib;
-            limitedAxesImuUncal.z = src.limited_axes_imu_uncalibrated.z_uncalib;
-            limitedAxesImuUncal.xBias = src.limited_axes_imu_uncalibrated.x_bias;
-            limitedAxesImuUncal.yBias = src.limited_axes_imu_uncalibrated.y_bias;
-            limitedAxesImuUncal.zBias = src.limited_axes_imu_uncalibrated.z_bias;
-            limitedAxesImuUncal.xSupported = src.limited_axes_imu_uncalibrated.x_supported;
-            limitedAxesImuUncal.ySupported = src.limited_axes_imu_uncalibrated.y_supported;
-            limitedAxesImuUncal.zSupported = src.limited_axes_imu_uncalibrated.z_supported;
-            dst->payload.set<Event::EventPayload::Tag::limitedAxesImuUncal>(limitedAxesImuUncal);
-            break;
-        }
-
-        case SensorType::HEADING: {
-            Event::EventPayload::Heading heading;
-            heading.heading = src.heading.heading;
-            heading.accuracy = src.heading.accuracy;
-            dst->payload.set<Event::EventPayload::heading>(heading);
-            break;
-        }
-
-        default: {
-            CHECK_GE((int32_t)dst->sensorType, (int32_t)SensorType::DEVICE_PRIVATE_BASE);
-
-            Event::EventPayload::Data data;
-            memcpy(data.values.data(), src.data, 16 * sizeof(float));
-            dst->payload.set<Event::EventPayload::Tag::data>(data);
-            break;
-        }
-    }
-}
-
 void serviceDied(void *cookie) {
     ALOGW("Sensors HAL died, attempting to reconnect.");
     ((AidlSensorHalWrapper *)cookie)->prepareForReconnect();
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index 3c4f8d9..a2042d6 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -75,6 +75,7 @@
     static_libs: [
         "libaidlcommonsupport",
         "android.hardware.sensors@1.0-convert",
+        "android.hardware.sensors-V1-convert",
         "android.hardware.sensors-V1-ndk",
     ],
 
diff --git a/services/sensorservice/aidl/Android.bp b/services/sensorservice/aidl/Android.bp
new file mode 100644
index 0000000..34d1de7
--- /dev/null
+++ b/services/sensorservice/aidl/Android.bp
@@ -0,0 +1,44 @@
+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 {
+    name: "libsensorserviceaidl",
+    srcs: [
+        "EventQueue.cpp",
+        "DirectReportChannel.cpp",
+        "SensorManager.cpp",
+        "utils.cpp",
+    ],
+    host_supported: true,
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    header_libs: ["jni_headers"],
+    shared_libs: [
+        "libbase",
+        "libutils",
+        "libcutils",
+        "libbinder_ndk",
+        "libsensor",
+        "android.frameworks.sensorservice-V1-ndk",
+        "android.hardware.sensors-V1-ndk",
+    ],
+    export_include_dirs: [
+        "include/",
+    ],
+    static_libs: [
+        "android.hardware.sensors-V1-convert",
+    ],
+
+    export_header_lib_headers: ["jni_headers"],
+    local_include_dirs: [
+        "include/sensorserviceaidl/",
+    ],
+}
diff --git a/services/sensorservice/aidl/DirectReportChannel.cpp b/services/sensorservice/aidl/DirectReportChannel.cpp
new file mode 100644
index 0000000..cab53c1
--- /dev/null
+++ b/services/sensorservice/aidl/DirectReportChannel.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "DirectReportChannel.h"
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+DirectReportChannel::DirectReportChannel(::android::SensorManager& manager, int channelId)
+      : mManager(manager), mId(channelId) {}
+
+DirectReportChannel::~DirectReportChannel() {
+    mManager.destroyDirectChannel(mId);
+}
+
+ndk::ScopedAStatus DirectReportChannel::configure(
+        int32_t sensorHandle, ::aidl::android::hardware::sensors::ISensors::RateLevel rate,
+        int32_t* _aidl_return) {
+    int token = mManager.configureDirectChannel(mId, sensorHandle, static_cast<int>(rate));
+    if (token <= 0) {
+        return ndk::ScopedAStatus::fromServiceSpecificError(token);
+    }
+    *_aidl_return = token;
+    return ndk::ScopedAStatus::ok();
+}
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/DirectReportChannel.h b/services/sensorservice/aidl/DirectReportChannel.h
new file mode 100644
index 0000000..d9ea73d
--- /dev/null
+++ b/services/sensorservice/aidl/DirectReportChannel.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/frameworks/sensorservice/BnDirectReportChannel.h>
+#include <aidl/android/hardware/sensors/ISensors.h>
+#include <sensor/SensorManager.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+class DirectReportChannel final
+      : public ::aidl::android::frameworks::sensorservice::BnDirectReportChannel {
+public:
+    DirectReportChannel(::android::SensorManager& manager, int channelId);
+    ~DirectReportChannel();
+
+    ndk::ScopedAStatus configure(int32_t sensorHandle,
+                                 ::aidl::android::hardware::sensors::ISensors::RateLevel rate,
+                                 int32_t* _aidl_return) override;
+
+private:
+    ::android::SensorManager& mManager;
+    const int mId;
+};
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/EventQueue.cpp b/services/sensorservice/aidl/EventQueue.cpp
new file mode 100644
index 0000000..88ab7a7
--- /dev/null
+++ b/services/sensorservice/aidl/EventQueue.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EventQueue.h"
+#include "utils.h"
+
+#include <android-base/logging.h>
+#include <utils/Looper.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+using ::aidl::android::frameworks::sensorservice::IEventQueueCallback;
+using ::aidl::android::hardware::sensors::Event;
+
+class EventQueueLooperCallback : public ::android::LooperCallback {
+public:
+    EventQueueLooperCallback(sp<::android::SensorEventQueue> queue,
+                             std::shared_ptr<IEventQueueCallback> callback)
+          : mQueue(queue), mCallback(callback) {}
+
+    int handleEvent(int /* fd */, int /* events */, void* /* data */) {
+        ASensorEvent event;
+        ssize_t actual;
+
+        auto internalQueue = mQueue.promote();
+        if (internalQueue == nullptr) {
+            return 1;
+        }
+
+        while ((actual = internalQueue->read(&event, 1)) > 0) {
+            internalQueue->sendAck(&event, actual);
+            ndk::ScopedAStatus ret = mCallback->onEvent(convertEvent(event));
+            if (!ret.isOk()) {
+                LOG(ERROR) << "Failed to envoke EventQueueCallback: " << ret;
+            }
+        }
+
+        return 1; // continue to receive callbacks
+    }
+
+private:
+    wp<::android::SensorEventQueue> mQueue;
+    std::shared_ptr<IEventQueueCallback> mCallback;
+};
+
+EventQueue::EventQueue(std::shared_ptr<IEventQueueCallback> callback, sp<::android::Looper> looper,
+                       sp<::android::SensorEventQueue> internalQueue)
+      : mLooper(looper), mInternalQueue(internalQueue) {
+    mLooper->addFd(internalQueue->getFd(), ALOOPER_POLL_CALLBACK, ALOOPER_EVENT_INPUT,
+                   new EventQueueLooperCallback(internalQueue, callback), nullptr);
+}
+
+// FIXME why was this on onLastStrongRef instead of dtor?
+EventQueue::~EventQueue() {
+    mLooper->removeFd(mInternalQueue->getFd());
+}
+
+ndk::ScopedAStatus EventQueue::enableSensor(int32_t in_sensorHandle, int32_t in_samplingPeriodUs,
+                                            int64_t in_maxBatchReportLatencyUs) {
+    return convertResult(mInternalQueue->enableSensor(in_sensorHandle, in_samplingPeriodUs,
+                                                      in_maxBatchReportLatencyUs, 0));
+}
+
+ndk::ScopedAStatus EventQueue::disableSensor(int32_t in_sensorHandle) {
+    return convertResult(mInternalQueue->disableSensor(in_sensorHandle));
+}
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/EventQueue.h b/services/sensorservice/aidl/EventQueue.h
new file mode 100644
index 0000000..0ae1eba
--- /dev/null
+++ b/services/sensorservice/aidl/EventQueue.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "SensorManagerAidl.h"
+
+#include <aidl/android/frameworks/sensorservice/BnEventQueue.h>
+#include <sensor/SensorManager.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+struct EventQueue final : public aidl::android::frameworks::sensorservice::BnEventQueue {
+    EventQueue(
+            std::shared_ptr<aidl::android::frameworks::sensorservice::IEventQueueCallback> callback,
+            sp<::android::Looper> looper, sp<::android::SensorEventQueue> internalQueue);
+    ~EventQueue();
+
+    ndk::ScopedAStatus enableSensor(int32_t in_sensorHandle, int32_t in_samplingPeriodUs,
+                                    int64_t in_maxBatchReportLatencyUs) override;
+    ndk::ScopedAStatus disableSensor(int32_t sensorHandle) override;
+
+private:
+    friend class EventQueueLooperCallback;
+    sp<::android::Looper> mLooper;
+    sp<::android::SensorEventQueue> mInternalQueue;
+};
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/SensorManager.cpp b/services/sensorservice/aidl/SensorManager.cpp
new file mode 100644
index 0000000..6d8d574
--- /dev/null
+++ b/services/sensorservice/aidl/SensorManager.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// LOG_TAG defined via build flag.
+#ifndef LOG_TAG
+#define LOG_TAG "AidlSensorManager"
+#endif
+
+#include "DirectReportChannel.h"
+#include "EventQueue.h"
+#include "SensorManagerAidl.h"
+#include "utils.h"
+
+#include <aidl/android/hardware/sensors/ISensors.h>
+#include <android-base/logging.h>
+#include <android/binder_ibinder.h>
+#include <sched.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+using ::aidl::android::frameworks::sensorservice::IDirectReportChannel;
+using ::aidl::android::frameworks::sensorservice::IEventQueue;
+using ::aidl::android::frameworks::sensorservice::IEventQueueCallback;
+using ::aidl::android::frameworks::sensorservice::ISensorManager;
+using ::aidl::android::hardware::common::Ashmem;
+using ::aidl::android::hardware::sensors::ISensors;
+using ::aidl::android::hardware::sensors::SensorInfo;
+using ::aidl::android::hardware::sensors::SensorType;
+using ::android::frameworks::sensorservice::implementation::SensorManagerAidl;
+
+static const char* POLL_THREAD_NAME = "aidl_ssvc_poll";
+
+SensorManagerAidl::SensorManagerAidl(JavaVM* vm)
+      : mLooper(new Looper(false)), mStopThread(true), mJavaVm(vm) {}
+SensorManagerAidl::~SensorManagerAidl() {
+    // Stops pollAll inside the thread.
+    std::lock_guard<std::mutex> lock(mThreadMutex);
+
+    mStopThread = true;
+    if (mLooper != nullptr) {
+        mLooper->wake();
+    }
+    if (mPollThread.joinable()) {
+        mPollThread.join();
+    }
+}
+
+ndk::ScopedAStatus createDirectChannel(::android::SensorManager& manager, size_t size, int type,
+                                       const native_handle_t* handle,
+                                       std::shared_ptr<IDirectReportChannel>* chan) {
+    int channelId = manager.createDirectChannel(size, type, handle);
+    if (channelId < 0) {
+        return convertResult(channelId);
+    }
+    if (channelId == 0) {
+        return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_UNKNOWN_ERROR);
+    }
+    *chan = ndk::SharedRefBase::make<DirectReportChannel>(manager, channelId);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus SensorManagerAidl::createAshmemDirectChannel(
+        const Ashmem& in_mem, int64_t in_size,
+        std::shared_ptr<IDirectReportChannel>* _aidl_return) {
+    if (in_size > in_mem.size || in_size < ISensors::DIRECT_REPORT_SENSOR_EVENT_TOTAL_LENGTH) {
+        return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_BAD_VALUE);
+    }
+    native_handle_t* handle = native_handle_create(1, 0);
+    handle->data[0] = dup(in_mem.fd.get());
+
+    auto status = createDirectChannel(getInternalManager(), in_size, SENSOR_DIRECT_MEM_TYPE_ASHMEM,
+                                      handle, _aidl_return);
+    int result = native_handle_close(handle);
+    CHECK(result == 0) << "Failed to close the native_handle_t: " << result;
+    result = native_handle_delete(handle);
+    CHECK(result == 0) << "Failed to delete the native_handle_t: " << result;
+
+    return status;
+}
+
+ndk::ScopedAStatus SensorManagerAidl::createGrallocDirectChannel(
+        const ndk::ScopedFileDescriptor& in_mem, int64_t in_size,
+        std::shared_ptr<IDirectReportChannel>* _aidl_return) {
+    native_handle_t* handle = native_handle_create(1, 0);
+    handle->data[0] = dup(in_mem.get());
+
+    auto status = createDirectChannel(getInternalManager(), in_size, SENSOR_DIRECT_MEM_TYPE_GRALLOC,
+                                      handle, _aidl_return);
+    int result = native_handle_close(handle);
+    CHECK(result == 0) << "Failed to close the native_handle_t: " << result;
+    result = native_handle_delete(handle);
+    CHECK(result == 0) << "Failed to delete the native_handle_t: " << result;
+
+    return status;
+}
+
+ndk::ScopedAStatus SensorManagerAidl::createEventQueue(
+        const std::shared_ptr<IEventQueueCallback>& in_callback,
+        std::shared_ptr<IEventQueue>* _aidl_return) {
+    if (in_callback == nullptr) {
+        return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_BAD_VALUE);
+    }
+
+    sp<::android::Looper> looper = getLooper();
+    if (looper == nullptr) {
+        LOG(ERROR) << "::android::SensorManagerAidl::createEventQueue cannot initialize looper";
+        return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_UNKNOWN_ERROR);
+    }
+
+    String8 package(String8::format("aidl_client_pid_%d", AIBinder_getCallingPid()));
+    sp<::android::SensorEventQueue> internalQueue = getInternalManager().createEventQueue(package);
+    if (internalQueue == nullptr) {
+        LOG(ERROR) << "::android::SensorManagerAidl::createEventQueue returns nullptr.";
+        return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_UNKNOWN_ERROR);
+    }
+
+    *_aidl_return = ndk::SharedRefBase::make<EventQueue>(in_callback, looper, internalQueue);
+
+    return ndk::ScopedAStatus::ok();
+}
+
+SensorInfo convertSensor(Sensor src) {
+    SensorInfo dst;
+    dst.sensorHandle = src.getHandle();
+    dst.name = src.getName();
+    dst.vendor = src.getVendor();
+    dst.version = src.getVersion();
+    dst.type = static_cast<SensorType>(src.getType());
+    dst.typeAsString = src.getStringType();
+    // maxRange uses maxValue because ::android::Sensor wraps the
+    // internal sensor_t in this way.
+    dst.maxRange = src.getMaxValue();
+    dst.resolution = src.getResolution();
+    dst.power = src.getPowerUsage();
+    dst.minDelayUs = src.getMinDelay();
+    dst.fifoReservedEventCount = src.getFifoReservedEventCount();
+    dst.fifoMaxEventCount = src.getFifoMaxEventCount();
+    dst.requiredPermission = src.getRequiredPermission();
+    dst.maxDelayUs = src.getMaxDelay();
+    dst.flags = src.getFlags();
+    return dst;
+}
+
+ndk::ScopedAStatus SensorManagerAidl::getDefaultSensor(SensorType in_type,
+                                                       SensorInfo* _aidl_return) {
+    ::android::Sensor const* sensor =
+            getInternalManager().getDefaultSensor(static_cast<int>(in_type));
+    if (!sensor) {
+        return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_NOT_EXIST);
+    }
+    *_aidl_return = convertSensor(*sensor);
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus SensorManagerAidl::getSensorList(std::vector<SensorInfo>* _aidl_return) {
+    Sensor const* const* list;
+    _aidl_return->clear();
+    ssize_t count = getInternalManager().getSensorList(&list);
+    if (count < 0 || list == nullptr) {
+        LOG(ERROR) << "SensorMAanger::getSensorList failed with count: " << count;
+        return ndk::ScopedAStatus::fromServiceSpecificError(ISensorManager::RESULT_UNKNOWN_ERROR);
+    }
+    _aidl_return->reserve(static_cast<size_t>(count));
+    for (ssize_t i = 0; i < count; ++i) {
+        _aidl_return->push_back(convertSensor(*list[i]));
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+::android::SensorManager& SensorManagerAidl::getInternalManager() {
+    std::lock_guard<std::mutex> lock(mInternalManagerMutex);
+    if (mInternalManager == nullptr) {
+        mInternalManager = &::android::SensorManager::getInstanceForPackage(
+                String16(ISensorManager::descriptor));
+    }
+    return *mInternalManager;
+}
+
+/* One global looper for all event queues created from this SensorManager. */
+sp<Looper> SensorManagerAidl::getLooper() {
+    std::lock_guard<std::mutex> lock(mThreadMutex);
+
+    if (!mPollThread.joinable()) {
+        // if thread not initialized, start thread
+        mStopThread = false;
+        std::thread pollThread{[&stopThread = mStopThread, looper = mLooper, javaVm = mJavaVm] {
+            struct sched_param p = {0};
+            p.sched_priority = 10;
+            if (sched_setscheduler(0 /* current thread*/, SCHED_FIFO, &p) != 0) {
+                LOG(ERROR) << "Could not use SCHED_FIFO for looper thread: " << strerror(errno);
+            }
+
+            // set looper
+            Looper::setForThread(looper);
+
+            // Attach the thread to JavaVM so that pollAll do not crash if the thread
+            // eventually calls into Java.
+            JavaVMAttachArgs args{.version = JNI_VERSION_1_2,
+                                  .name = POLL_THREAD_NAME,
+                                  .group = nullptr};
+            JNIEnv* env;
+            if (javaVm->AttachCurrentThread(&env, &args) != JNI_OK) {
+                LOG(FATAL) << "Cannot attach SensorManager looper thread to Java VM.";
+            }
+
+            LOG(INFO) << POLL_THREAD_NAME << " started.";
+            for (;;) {
+                int pollResult = looper->pollAll(-1 /* timeout */);
+                if (pollResult == Looper::POLL_WAKE) {
+                    if (stopThread == true) {
+                        LOG(INFO) << POLL_THREAD_NAME << ": requested to stop";
+                        break;
+                    } else {
+                        LOG(INFO) << POLL_THREAD_NAME << ": spurious wake up, back to work";
+                    }
+                } else {
+                    LOG(ERROR) << POLL_THREAD_NAME << ": Looper::pollAll returns unexpected "
+                               << pollResult;
+                    break;
+                }
+            }
+
+            if (javaVm->DetachCurrentThread() != JNI_OK) {
+                LOG(ERROR) << "Cannot detach SensorManager looper thread from Java VM.";
+            }
+
+            LOG(INFO) << POLL_THREAD_NAME << " is terminated.";
+        }};
+        mPollThread = std::move(pollThread);
+    }
+    return mLooper;
+}
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/fuzzer/Android.bp b/services/sensorservice/aidl/fuzzer/Android.bp
new file mode 100644
index 0000000..0d6e476
--- /dev/null
+++ b/services/sensorservice/aidl/fuzzer/Android.bp
@@ -0,0 +1,52 @@
+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: "libsensorserviceaidl_fuzzer",
+    defaults: [
+        "service_fuzzer_defaults",
+    ],
+    host_supported: true,
+    static_libs: [
+        "libsensorserviceaidl",
+        "libpermission",
+        "android.frameworks.sensorservice-V1-ndk",
+        "android.hardware.sensors-V1-convert",
+        "android.hardware.sensors-V1-ndk",
+        "android.hardware.common-V2-ndk",
+        "libsensor",
+        "libfakeservicemanager",
+        "libcutils",
+        "liblog",
+    ],
+    srcs: [
+        "fuzzer.cpp",
+    ],
+    fuzz_config: {
+        cc: [
+            "android-sensors@google.com",
+            "devinmoore@google.com",
+        ],
+    },
+    sanitize: {
+        misc_undefined: [
+            "signed-integer-overflow",
+            "unsigned-integer-overflow",
+        ],
+        diag: {
+            misc_undefined: [
+                "signed-integer-overflow",
+                "unsigned-integer-overflow",
+            ],
+        },
+        address: true,
+        integer_overflow: true,
+    },
+
+}
diff --git a/services/sensorservice/aidl/fuzzer/fuzzer.cpp b/services/sensorservice/aidl/fuzzer/fuzzer.cpp
new file mode 100644
index 0000000..1b63d76
--- /dev/null
+++ b/services/sensorservice/aidl/fuzzer/fuzzer.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <ServiceManager.h>
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <fuzzbinder/random_binder.h>
+#include <sensorserviceaidl/SensorManagerAidl.h>
+
+using android::fuzzService;
+using android::frameworks::sensorservice::implementation::SensorManagerAidl;
+using ndk::SharedRefBase;
+
+[[clang::no_destroy]] static std::once_flag gSmOnce;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    static android::sp<android::ServiceManager> fakeServiceManager = new android::ServiceManager();
+    std::call_once(gSmOnce, [&] { setDefaultServiceManager(fakeServiceManager); });
+    fakeServiceManager->clear();
+
+    FuzzedDataProvider fdp(data, size);
+    android::sp<android::IBinder> binder = android::getRandomBinder(&fdp);
+    if (binder == nullptr) {
+        // Nothing to do if we get a null binder. It will cause SensorManager to
+        // hang while trying to get sensorservice.
+        return 0;
+    }
+
+    CHECK(android::NO_ERROR == fakeServiceManager->addService(android::String16("sensorservice"),
+                                   binder));
+
+    std::shared_ptr<SensorManagerAidl> sensorService =
+            ndk::SharedRefBase::make<SensorManagerAidl>(nullptr);
+
+    fuzzService(sensorService->asBinder().get(), std::move(fdp));
+
+    return 0;
+}
diff --git a/services/sensorservice/aidl/include/sensorserviceaidl/SensorManagerAidl.h b/services/sensorservice/aidl/include/sensorserviceaidl/SensorManagerAidl.h
new file mode 100644
index 0000000..c77ee88
--- /dev/null
+++ b/services/sensorservice/aidl/include/sensorserviceaidl/SensorManagerAidl.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/android/frameworks/sensorservice/BnSensorManager.h>
+#include <jni.h>
+#include <sensor/SensorManager.h>
+#include <utils/Looper.h>
+#include <mutex>
+#include <thread>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+class SensorManagerAidl : public ::aidl::android::frameworks::sensorservice::BnSensorManager {
+public:
+    explicit SensorManagerAidl(JavaVM* vm);
+    ~SensorManagerAidl();
+
+    ::ndk::ScopedAStatus createAshmemDirectChannel(
+            const ::aidl::android::hardware::common::Ashmem& in_mem, int64_t in_size,
+            std::shared_ptr<::aidl::android::frameworks::sensorservice::IDirectReportChannel>*
+                    _aidl_return) override;
+    ::ndk::ScopedAStatus createEventQueue(
+            const std::shared_ptr<::aidl::android::frameworks::sensorservice::IEventQueueCallback>&
+                    in_callback,
+            std::shared_ptr<::aidl::android::frameworks::sensorservice::IEventQueue>* _aidl_return)
+            override;
+    ::ndk::ScopedAStatus createGrallocDirectChannel(
+            const ::ndk::ScopedFileDescriptor& in_buffer, int64_t in_size,
+            std::shared_ptr<::aidl::android::frameworks::sensorservice::IDirectReportChannel>*
+                    _aidl_return) override;
+    ::ndk::ScopedAStatus getDefaultSensor(
+            ::aidl::android::hardware::sensors::SensorType in_type,
+            ::aidl::android::hardware::sensors::SensorInfo* _aidl_return) override;
+    ::ndk::ScopedAStatus getSensorList(
+            std::vector<::aidl::android::hardware::sensors::SensorInfo>* _aidl_return) override;
+
+private:
+    // Block until ::android::SensorManager is initialized.
+    ::android::SensorManager& getInternalManager();
+    sp<Looper> getLooper();
+
+    std::mutex mInternalManagerMutex;
+    ::android::SensorManager* mInternalManager = nullptr; // does not own
+    sp<Looper> mLooper;
+
+    volatile bool mStopThread;
+    std::mutex mThreadMutex; // protects mPollThread
+    std::thread mPollThread;
+
+    JavaVM* mJavaVm;
+};
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/utils.cpp b/services/sensorservice/aidl/utils.cpp
new file mode 100644
index 0000000..26bcdc5
--- /dev/null
+++ b/services/sensorservice/aidl/utils.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "utils.h"
+
+#include <aidl/android/frameworks/sensorservice/ISensorManager.h>
+#include <aidl/sensors/convert.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+ndk::ScopedAStatus convertResult(status_t src) {
+    using ::aidl::android::frameworks::sensorservice::ISensorManager;
+
+    int err = 0;
+    switch (src) {
+        case OK:
+            return ndk::ScopedAStatus::ok();
+        case NAME_NOT_FOUND:
+            err = ISensorManager::RESULT_NOT_EXIST;
+            break;
+        case NO_MEMORY:
+            err = ISensorManager::RESULT_NO_MEMORY;
+            break;
+        case NO_INIT:
+            err = ISensorManager::RESULT_NO_INIT;
+            break;
+        case PERMISSION_DENIED:
+            err = ISensorManager::RESULT_PERMISSION_DENIED;
+            break;
+        case BAD_VALUE:
+            err = ISensorManager::RESULT_BAD_VALUE;
+            break;
+        case INVALID_OPERATION:
+            err = ISensorManager::RESULT_INVALID_OPERATION;
+            break;
+        default:
+            err = ISensorManager::RESULT_UNKNOWN_ERROR;
+    }
+    return ndk::ScopedAStatus::fromServiceSpecificError(err);
+}
+
+::aidl::android::hardware::sensors::Event convertEvent(const ::ASensorEvent& src) {
+    ::aidl::android::hardware::sensors::Event dst;
+    ::android::hardware::sensors::implementation::
+            convertFromSensorEvent(reinterpret_cast<const sensors_event_t&>(src), &dst);
+    return dst;
+}
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/sensorservice/aidl/utils.h b/services/sensorservice/aidl/utils.h
new file mode 100644
index 0000000..06ba59e
--- /dev/null
+++ b/services/sensorservice/aidl/utils.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/sensors/Event.h>
+#include <sensor/Sensor.h>
+
+namespace android {
+namespace frameworks {
+namespace sensorservice {
+namespace implementation {
+
+::ndk::ScopedAStatus convertResult(status_t status);
+::aidl::android::hardware::sensors::Event convertEvent(const ::ASensorEvent& event);
+
+} // namespace implementation
+} // namespace sensorservice
+} // namespace frameworks
+} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e9fbf6e..2fa40a5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -328,8 +328,9 @@
         mCompositionEngine(mFactory.createCompositionEngine()),
         mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),
         mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()),
-        mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)),
         mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)),
+        mInternalDisplayDensity(
+                getDensityFromProperty("ro.sf.lcd_density", !mEmulatedDisplayDensity)),
         mPowerAdvisor(std::make_unique<Hwc2::impl::PowerAdvisor>(*this)),
         mWindowInfosListenerInvoker(sp<WindowInfosListenerInvoker>::make(*this)) {
     ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());
@@ -7564,7 +7565,7 @@
     IPCThreadState* ipc = IPCThreadState::self();
     const int pid = ipc->getCallingPid();
     const int uid = ipc->getCallingUid();
-    if ((uid != AID_GRAPHICS) &&
+    if ((uid != AID_GRAPHICS) && (uid != AID_SYSTEM) &&
         !PermissionCache::checkPermission(sControlDisplayBrightness, pid, uid)) {
         ALOGE("Permission Denial: can't control brightness pid=%d, uid=%d", pid, uid);
         return PERMISSION_DENIED;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 46f0e6b..d91aa11 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1374,8 +1374,8 @@
     sp<TunnelModeEnabledReporter> mTunnelModeEnabledReporter;
     ui::DisplayPrimaries mInternalDisplayPrimaries;
 
-    const float mInternalDisplayDensity;
     const float mEmulatedDisplayDensity;
+    const float mInternalDisplayDensity;
 
     // Should only be accessed by the main thread.
     sp<os::IInputFlinger> mInputFlinger;
diff --git a/vulkan/include/vulkan/vk_android_native_buffer.h b/vulkan/include/vulkan/vk_android_native_buffer.h
index ba98696..40cf9fb 100644
--- a/vulkan/include/vulkan/vk_android_native_buffer.h
+++ b/vulkan/include/vulkan/vk_android_native_buffer.h
@@ -49,7 +49,13 @@
  * in VkBindImageMemorySwapchainInfoKHR will be additionally chained to the
  * pNext chain of VkBindImageMemoryInfo and passed down to the driver.
  */
-#define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 8
+/*
+ * NOTE ON VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 9
+ *
+ * This version of the extension is largely designed to clean up the mix of
+ * GrallocUsage and GrallocUsage2
+ */
+#define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 9
 #define VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME "VK_ANDROID_native_buffer"
 
 #define VK_ANDROID_NATIVE_BUFFER_ENUM(type, id) \
@@ -61,6 +67,8 @@
     VK_ANDROID_NATIVE_BUFFER_ENUM(VkStructureType, 1)
 #define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID \
     VK_ANDROID_NATIVE_BUFFER_ENUM(VkStructureType, 2)
+#define VK_STRUCTURE_TYPE_GRALLOC_USAGE_INFO_ANDROID \
+    VK_ANDROID_NATIVE_BUFFER_ENUM(VkStructureType, 3)
 
 /* clang-format off */
 typedef enum VkSwapchainImageUsageFlagBitsANDROID {
@@ -90,6 +98,7 @@
  * format: gralloc format requested when the buffer was allocated
  * usage: gralloc usage requested when the buffer was allocated
  * usage2: gralloc usage requested when the buffer was allocated
+ * usage3: gralloc usage requested when the buffer was allocated
  */
 typedef struct {
     VkStructureType                   sType;
@@ -98,7 +107,8 @@
     int                               stride;
     int                               format;
     int                               usage; /* DEPRECATED in SPEC_VERSION 6 */
-    VkNativeBufferUsage2ANDROID       usage2; /* ADDED in SPEC_VERSION 6 */
+    VkNativeBufferUsage2ANDROID       usage2; /* DEPRECATED in SPEC_VERSION 9 */
+    uint64_t                          usage3; /* ADDED in SPEC_VERSION 9 */
 } VkNativeBufferANDROID;
 
 /*
@@ -127,6 +137,21 @@
     VkBool32                          sharedImage;
 } VkPhysicalDevicePresentationPropertiesANDROID;
 
+/*
+ * struct VkGrallocUsageInfoANDROID
+ *
+ * sType: VK_STRUCTURE_TYPE_GRALLOC_USAGE_INFO_ANDROID
+ * pNext: NULL or a pointer to a structure extending this structure
+ * format: value specifying the format the image will be created with
+ * imageUsage: bitmask of VkImageUsageFlagBits describing intended usage
+ */
+typedef struct {
+    VkStructureType                   sType;
+    const void*                       pNext;
+    VkFormat                          format;
+    VkImageUsageFlags                 imageUsage;
+} VkGrallocUsageInfoANDROID;
+
 /* DEPRECATED in SPEC_VERSION 6 */
 typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsageANDROID)(
     VkDevice                          device,
@@ -134,7 +159,7 @@
     VkImageUsageFlags                 imageUsage,
     int*                              grallocUsage);
 
-/* ADDED in SPEC_VERSION 6 */
+/* DEPRECATED in SPEC_VERSION 9 */
 typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsage2ANDROID)(
     VkDevice                          device,
     VkFormat                          format,
@@ -143,6 +168,12 @@
     uint64_t*                         grallocConsumerUsage,
     uint64_t*                         grallocProducerUsage);
 
+/* ADDED in SPEC_VERSION 9 */
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsage3ANDROID)(
+    VkDevice                          device,
+    const VkGrallocUsageInfoANDROID*  grallocUsageInfo,
+    uint64_t*                         grallocUsage);
+
 typedef VkResult (VKAPI_PTR *PFN_vkAcquireImageANDROID)(
     VkDevice                          device,
     VkImage                           image,
@@ -167,7 +198,7 @@
     int*                              grallocUsage
 );
 
-/* ADDED in SPEC_VERSION 6 */
+/* DEPRECATED in SPEC_VERSION 9 */
 VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage2ANDROID(
     VkDevice                          device,
     VkFormat                          format,
@@ -177,6 +208,13 @@
     uint64_t*                         grallocProducerUsage
 );
 
+/* ADDED in SPEC_VERSION 9 */
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage3ANDROID(
+    VkDevice                          device,
+    const VkGrallocUsageInfoANDROID*  grallocUsageInfo,
+    uint64_t*                         grallocUsage
+);
+
 VKAPI_ATTR VkResult VKAPI_CALL vkAcquireImageANDROID(
     VkDevice                          device,
     VkImage                           image,
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 7664518..4927150 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -1027,6 +1027,39 @@
     }
 }
 
+bool GetAndroidNativeBufferSpecVersion9Support(
+    VkPhysicalDevice physicalDevice) {
+    const InstanceData& data = GetData(physicalDevice);
+
+    // Call to get propertyCount
+    uint32_t propertyCount = 0;
+    ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
+    VkResult result = data.driver.EnumerateDeviceExtensionProperties(
+        physicalDevice, nullptr, &propertyCount, nullptr);
+    ATRACE_END();
+
+    // Call to enumerate properties
+    std::vector<VkExtensionProperties> properties(propertyCount);
+    ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
+    result = data.driver.EnumerateDeviceExtensionProperties(
+        physicalDevice, nullptr, &propertyCount, properties.data());
+    ATRACE_END();
+
+    for (uint32_t i = 0; i < propertyCount; i++) {
+        auto& prop = properties[i];
+
+        if (strcmp(prop.extensionName,
+                   VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME) != 0)
+            continue;
+
+        if (prop.specVersion >= 9) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 VkResult EnumerateDeviceExtensionProperties(
     VkPhysicalDevice physicalDevice,
     const char* pLayerName,
@@ -1061,6 +1094,37 @@
                 VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION});
     }
 
+    // Conditionally add VK_EXT_IMAGE_COMPRESSION_CONTROL* if feature and ANB
+    // support is provided by the driver
+    VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT
+        swapchainCompFeats = {};
+    swapchainCompFeats.sType =
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT;
+    swapchainCompFeats.pNext = nullptr;
+    VkPhysicalDeviceImageCompressionControlFeaturesEXT imageCompFeats = {};
+    imageCompFeats.sType =
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT;
+    imageCompFeats.pNext = &swapchainCompFeats;
+
+    VkPhysicalDeviceFeatures2 feats2 = {};
+    feats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+    feats2.pNext = &imageCompFeats;
+
+    GetPhysicalDeviceFeatures2(physicalDevice, &feats2);
+
+    bool anb9 = GetAndroidNativeBufferSpecVersion9Support(physicalDevice);
+
+    if (anb9 && imageCompFeats.imageCompressionControl) {
+        loader_extensions.push_back(
+            {VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME,
+             VK_EXT_IMAGE_COMPRESSION_CONTROL_SPEC_VERSION});
+    }
+    if (anb9 && swapchainCompFeats.imageCompressionControlSwapchain) {
+        loader_extensions.push_back(
+            {VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME,
+             VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_SPEC_VERSION});
+    }
+
     // enumerate our extensions first
     if (!pLayerName && pProperties) {
         uint32_t count = std::min(
@@ -1254,15 +1318,18 @@
         return VK_ERROR_INCOMPATIBLE_DRIVER;
     }
 
-    // sanity check ANDROID_native_buffer implementation, whose set of
+    // Confirming ANDROID_native_buffer implementation, whose set of
     // entrypoints varies according to the spec version.
     if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
         !data->driver.GetSwapchainGrallocUsageANDROID &&
-        !data->driver.GetSwapchainGrallocUsage2ANDROID) {
-        ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
-              " must expose at least one of "
-              "vkGetSwapchainGrallocUsageANDROID or "
-              "vkGetSwapchainGrallocUsage2ANDROID");
+        !data->driver.GetSwapchainGrallocUsage2ANDROID &&
+        !data->driver.GetSwapchainGrallocUsage3ANDROID) {
+        ALOGE(
+            "Driver's implementation of ANDROID_native_buffer is broken;"
+            " must expose at least one of "
+            "vkGetSwapchainGrallocUsageANDROID or "
+            "vkGetSwapchainGrallocUsage2ANDROID or "
+            "vkGetSwapchainGrallocUsage3ANDROID");
 
         data->driver.DestroyDevice(dev, pAllocator);
         FreeDeviceData(data, data_allocator);
@@ -1441,10 +1508,83 @@
 
     if (driver.GetPhysicalDeviceFeatures2) {
         driver.GetPhysicalDeviceFeatures2(physicalDevice, pFeatures);
+    } else {
+        driver.GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures);
+    }
+
+    // Conditionally add imageCompressionControlSwapchain if
+    // imageCompressionControl is supported Check for imageCompressionControl in
+    // the pChain
+    bool imageCompressionControl = false;
+    bool imageCompressionControlInChain = false;
+    bool imageCompressionControlSwapchainInChain = false;
+    VkPhysicalDeviceFeatures2* pFeats = pFeatures;
+    while (pFeats) {
+        switch (pFeats->sType) {
+            case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT: {
+                const VkPhysicalDeviceImageCompressionControlFeaturesEXT*
+                    compressionFeat = reinterpret_cast<
+                        const VkPhysicalDeviceImageCompressionControlFeaturesEXT*>(
+                        pFeats);
+                imageCompressionControl =
+                    compressionFeat->imageCompressionControl;
+                imageCompressionControlInChain = true;
+            } break;
+
+            case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT: {
+                imageCompressionControlSwapchainInChain = true;
+            } break;
+
+            default:
+                break;
+        }
+        pFeats = reinterpret_cast<VkPhysicalDeviceFeatures2*>(pFeats->pNext);
+    }
+
+    if (!imageCompressionControlSwapchainInChain) {
         return;
     }
 
-    driver.GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures);
+    // If not in pchain, explicitly query for imageCompressionControl
+    if (!imageCompressionControlInChain) {
+        VkPhysicalDeviceImageCompressionControlFeaturesEXT imageCompFeats = {};
+        imageCompFeats.sType =
+            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT;
+        imageCompFeats.pNext = nullptr;
+
+        VkPhysicalDeviceFeatures2 feats2 = {};
+        feats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+        feats2.pNext = &imageCompFeats;
+
+        if (driver.GetPhysicalDeviceFeatures2) {
+            driver.GetPhysicalDeviceFeatures2(physicalDevice, &feats2);
+        } else {
+            driver.GetPhysicalDeviceFeatures2KHR(physicalDevice, &feats2);
+        }
+
+        imageCompressionControl = imageCompFeats.imageCompressionControl;
+    }
+
+    // Only enumerate imageCompressionControlSwapchin if imageCompressionControl
+    if (imageCompressionControl) {
+        pFeats = pFeatures;
+        while (pFeats) {
+            switch (pFeats->sType) {
+                case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT: {
+                    VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*
+                        compressionFeat = reinterpret_cast<
+                            VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*>(
+                            pFeats);
+                    compressionFeat->imageCompressionControlSwapchain = true;
+                } break;
+
+                default:
+                    break;
+            }
+            pFeats =
+                reinterpret_cast<VkPhysicalDeviceFeatures2*>(pFeats->pNext);
+        }
+    }
 }
 
 void GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h
index 14c516b..4d2bbd6 100644
--- a/vulkan/libvulkan/driver.h
+++ b/vulkan/libvulkan/driver.h
@@ -107,6 +107,8 @@
     VkPhysicalDevice physicalDevice,
     VkPhysicalDevicePresentationPropertiesANDROID* presentation_properties);
 
+bool GetAndroidNativeBufferSpecVersion9Support(VkPhysicalDevice physicalDevice);
+
 VKAPI_ATTR PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance,
                                                   const char* pName);
 VKAPI_ATTR PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device,
diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp
index b436db1..de98aa7 100644
--- a/vulkan/libvulkan/driver_gen.cpp
+++ b/vulkan/libvulkan/driver_gen.cpp
@@ -496,6 +496,13 @@
         nullptr,
     },
     {
+        "vkGetSwapchainGrallocUsage3ANDROID",
+        ProcHook::DEVICE,
+        ProcHook::ANDROID_native_buffer,
+        nullptr,
+        nullptr,
+    },
+    {
         "vkGetSwapchainGrallocUsageANDROID",
         ProcHook::DEVICE,
         ProcHook::ANDROID_native_buffer,
@@ -664,6 +671,7 @@
     INIT_PROC(false, dev, GetDeviceQueue2);
     INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsageANDROID);
     INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsage2ANDROID);
+    INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsage3ANDROID);
     INIT_PROC_EXT(ANDROID_native_buffer, true, dev, AcquireImageANDROID);
     INIT_PROC_EXT(ANDROID_native_buffer, true, dev, QueueSignalReleaseImageANDROID);
     // clang-format on
diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h
index 079f9cc..2f60086 100644
--- a/vulkan/libvulkan/driver_gen.h
+++ b/vulkan/libvulkan/driver_gen.h
@@ -123,6 +123,7 @@
     PFN_vkGetDeviceQueue2 GetDeviceQueue2;
     PFN_vkGetSwapchainGrallocUsageANDROID GetSwapchainGrallocUsageANDROID;
     PFN_vkGetSwapchainGrallocUsage2ANDROID GetSwapchainGrallocUsage2ANDROID;
+    PFN_vkGetSwapchainGrallocUsage3ANDROID GetSwapchainGrallocUsage3ANDROID;
     PFN_vkAcquireImageANDROID AcquireImageANDROID;
     PFN_vkQueueSignalReleaseImageANDROID QueueSignalReleaseImageANDROID;
     // clang-format on
diff --git a/vulkan/libvulkan/libvulkan.map.txt b/vulkan/libvulkan/libvulkan.map.txt
index f49e8f3..b189c68 100644
--- a/vulkan/libvulkan/libvulkan.map.txt
+++ b/vulkan/libvulkan/libvulkan.map.txt
@@ -178,6 +178,7 @@
     vkGetImageSparseMemoryRequirements;
     vkGetImageSparseMemoryRequirements2; # introduced=28
     vkGetImageSubresourceLayout;
+    vkGetImageSubresourceLayout2EXT; # introduced=UpsideDownCake
     vkGetInstanceProcAddr;
     vkGetMemoryAndroidHardwareBufferANDROID; # introduced=28
     vkGetPhysicalDeviceExternalBufferProperties; # introduced=28
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 6af2cc1..48a75c5 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -715,6 +715,17 @@
     capabilities->minImageExtent = VkExtent2D{1, 1};
     capabilities->maxImageExtent = VkExtent2D{4096, 4096};
 
+    if (capabilities->maxImageExtent.height <
+        capabilities->currentExtent.height) {
+        capabilities->maxImageExtent.height =
+            capabilities->currentExtent.height;
+    }
+
+    if (capabilities->maxImageExtent.width <
+        capabilities->currentExtent.width) {
+        capabilities->maxImageExtent.width = capabilities->currentExtent.width;
+    }
+
     capabilities->maxImageArrayLayers = 1;
 
     capabilities->supportedTransforms = kSupportedTransforms;
@@ -787,13 +798,14 @@
     std::vector<VkSurfaceFormatKHR> all_formats = {
         {VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
         {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
-        // Also allow to use PASS_THROUGH + HAL_DATASPACE_ARBITRARY
-        {VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_PASS_THROUGH_EXT},
-        {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_PASS_THROUGH_EXT},
     };
 
     if (colorspace_ext) {
         all_formats.emplace_back(VkSurfaceFormatKHR{
+            VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_PASS_THROUGH_EXT});
+        all_formats.emplace_back(VkSurfaceFormatKHR{
+            VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_PASS_THROUGH_EXT});
+        all_formats.emplace_back(VkSurfaceFormatKHR{
             VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_BT709_LINEAR_EXT});
     }
 
@@ -812,16 +824,22 @@
     if (AHardwareBuffer_isSupported(&desc)) {
         all_formats.emplace_back(VkSurfaceFormatKHR{
             VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR});
-        all_formats.emplace_back(VkSurfaceFormatKHR{
-            VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_PASS_THROUGH_EXT});
+        if (colorspace_ext) {
+            all_formats.emplace_back(
+                VkSurfaceFormatKHR{VK_FORMAT_R5G6B5_UNORM_PACK16,
+                                   VK_COLOR_SPACE_PASS_THROUGH_EXT});
+        }
     }
 
     desc.format = AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
     if (AHardwareBuffer_isSupported(&desc)) {
         all_formats.emplace_back(VkSurfaceFormatKHR{
             VK_FORMAT_R16G16B16A16_SFLOAT, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR});
-        all_formats.emplace_back(VkSurfaceFormatKHR{
-            VK_FORMAT_R16G16B16A16_SFLOAT, VK_COLOR_SPACE_PASS_THROUGH_EXT});
+        if (colorspace_ext) {
+            all_formats.emplace_back(
+                VkSurfaceFormatKHR{VK_FORMAT_R16G16B16A16_SFLOAT,
+                                   VK_COLOR_SPACE_PASS_THROUGH_EXT});
+        }
         if (wide_color_support) {
             all_formats.emplace_back(
                 VkSurfaceFormatKHR{VK_FORMAT_R16G16B16A16_SFLOAT,
@@ -837,9 +855,11 @@
         all_formats.emplace_back(
             VkSurfaceFormatKHR{VK_FORMAT_A2B10G10R10_UNORM_PACK32,
                                VK_COLOR_SPACE_SRGB_NONLINEAR_KHR});
-        all_formats.emplace_back(
-            VkSurfaceFormatKHR{VK_FORMAT_A2B10G10R10_UNORM_PACK32,
-                               VK_COLOR_SPACE_PASS_THROUGH_EXT});
+        if (colorspace_ext) {
+            all_formats.emplace_back(
+                VkSurfaceFormatKHR{VK_FORMAT_A2B10G10R10_UNORM_PACK32,
+                                   VK_COLOR_SPACE_PASS_THROUGH_EXT});
+        }
         if (wide_color_support) {
             all_formats.emplace_back(
                 VkSurfaceFormatKHR{VK_FORMAT_A2B10G10R10_UNORM_PACK32,
@@ -849,9 +869,10 @@
 
     desc.format = AHARDWAREBUFFER_FORMAT_R8_UNORM;
     if (AHardwareBuffer_isSupported(&desc)) {
-        all_formats.emplace_back(
-            VkSurfaceFormatKHR{VK_FORMAT_R8_UNORM,
-                               VK_COLOR_SPACE_PASS_THROUGH_EXT});
+        if (colorspace_ext) {
+            all_formats.emplace_back(VkSurfaceFormatKHR{
+                VK_FORMAT_R8_UNORM, VK_COLOR_SPACE_PASS_THROUGH_EXT});
+        }
     }
 
     // NOTE: Any new formats that are added must be coordinated across different
@@ -938,11 +959,60 @@
             surface_formats.data());
 
         if (result == VK_SUCCESS || result == VK_INCOMPLETE) {
+            const auto& driver = GetData(physicalDevice).driver;
+
             // marshal results individually due to stride difference.
-            // completely ignore any chained extension structs.
             uint32_t formats_to_marshal = *pSurfaceFormatCount;
             for (uint32_t i = 0u; i < formats_to_marshal; i++) {
                 pSurfaceFormats[i].surfaceFormat = surface_formats[i];
+
+                // Query the compression properties for the surface format
+                if (pSurfaceFormats[i].pNext) {
+                    VkImageCompressionPropertiesEXT* surfaceCompressionProps =
+                        reinterpret_cast<VkImageCompressionPropertiesEXT*>(
+                            pSurfaceFormats[i].pNext);
+
+                    if (surfaceCompressionProps &&
+                        driver.GetPhysicalDeviceImageFormatProperties2KHR) {
+                        VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = {};
+                        imageFormatInfo.sType =
+                            VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2;
+                        imageFormatInfo.format =
+                            pSurfaceFormats[i].surfaceFormat.format;
+                        imageFormatInfo.pNext = nullptr;
+
+                        VkImageCompressionControlEXT compressionControl = {};
+                        compressionControl.sType =
+                            VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT;
+                        compressionControl.pNext = imageFormatInfo.pNext;
+
+                        imageFormatInfo.pNext = &compressionControl;
+
+                        VkImageCompressionPropertiesEXT compressionProps = {};
+                        compressionProps.sType =
+                            VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT;
+                        compressionProps.pNext = nullptr;
+
+                        VkImageFormatProperties2KHR imageFormatProps = {};
+                        imageFormatProps.sType =
+                            VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR;
+                        imageFormatProps.pNext = &compressionProps;
+
+                        VkResult compressionRes =
+                            driver.GetPhysicalDeviceImageFormatProperties2KHR(
+                                physicalDevice, &imageFormatInfo,
+                                &imageFormatProps);
+                        if (compressionRes == VK_SUCCESS) {
+                            surfaceCompressionProps->imageCompressionFlags =
+                                compressionProps.imageCompressionFlags;
+                            surfaceCompressionProps
+                                ->imageCompressionFixedRateFlags =
+                                compressionProps.imageCompressionFixedRateFlags;
+                        } else {
+                            return compressionRes;
+                        }
+                    }
+                }
             }
         }
 
@@ -1360,8 +1430,48 @@
         num_images = 1;
     }
 
+    void* usage_info_pNext = nullptr;
+    VkImageCompressionControlEXT image_compression = {};
     uint64_t native_usage = 0;
-    if (dispatch.GetSwapchainGrallocUsage2ANDROID) {
+    if (dispatch.GetSwapchainGrallocUsage3ANDROID) {
+        ATRACE_BEGIN("GetSwapchainGrallocUsage3ANDROID");
+        VkGrallocUsageInfoANDROID gralloc_usage_info = {};
+        gralloc_usage_info.sType = VK_STRUCTURE_TYPE_GRALLOC_USAGE_INFO_ANDROID;
+        gralloc_usage_info.format = create_info->imageFormat;
+        gralloc_usage_info.imageUsage = create_info->imageUsage;
+
+        // Look through the pNext chain for an image compression control struct
+        // if one is found AND the appropriate extensions are enabled,
+        // append it to be the gralloc usage pNext chain
+        const VkSwapchainCreateInfoKHR* create_infos = create_info;
+        while (create_infos->pNext) {
+            create_infos = reinterpret_cast<const VkSwapchainCreateInfoKHR*>(
+                create_infos->pNext);
+            switch (create_infos->sType) {
+                case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT: {
+                    const VkImageCompressionControlEXT* compression_infos =
+                        reinterpret_cast<const VkImageCompressionControlEXT*>(
+                            create_infos);
+                    image_compression = *compression_infos;
+                    image_compression.pNext = nullptr;
+                    usage_info_pNext = &image_compression;
+                } break;
+
+                default:
+                    // Ignore all other info structs
+                    break;
+            }
+        }
+        gralloc_usage_info.pNext = usage_info_pNext;
+
+        result = dispatch.GetSwapchainGrallocUsage3ANDROID(
+            device, &gralloc_usage_info, &native_usage);
+        ATRACE_END();
+        if (result != VK_SUCCESS) {
+            ALOGE("vkGetSwapchainGrallocUsage3ANDROID failed: %d", result);
+            return VK_ERROR_SURFACE_LOST_KHR;
+        }
+    } else if (dispatch.GetSwapchainGrallocUsage2ANDROID) {
         uint64_t consumer_usage, producer_usage;
         ATRACE_BEGIN("GetSwapchainGrallocUsage2ANDROID");
         result = dispatch.GetSwapchainGrallocUsage2ANDROID(
@@ -1373,7 +1483,7 @@
             return VK_ERROR_SURFACE_LOST_KHR;
         }
         native_usage =
-            convertGralloc1ToBufferUsage(consumer_usage, producer_usage);
+            convertGralloc1ToBufferUsage(producer_usage, consumer_usage);
     } else if (dispatch.GetSwapchainGrallocUsageANDROID) {
         ATRACE_BEGIN("GetSwapchainGrallocUsageANDROID");
         int32_t legacy_usage = 0;
@@ -1427,7 +1537,7 @@
 #pragma clang diagnostic ignored "-Wold-style-cast"
         .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID,
 #pragma clang diagnostic pop
-        .pNext = nullptr,
+        .pNext = usage_info_pNext,
         .usage = swapchain_image_usage,
     };
     VkNativeBufferANDROID image_native_buffer = {
@@ -1485,6 +1595,7 @@
         android_convertGralloc0To1Usage(int(img.buffer->usage),
             &image_native_buffer.usage2.producer,
             &image_native_buffer.usage2.consumer);
+        image_native_buffer.usage3 = img.buffer->usage;
 
         ATRACE_BEGIN("CreateImage");
         result =
diff --git a/vulkan/nulldrv/null_driver.cpp b/vulkan/nulldrv/null_driver.cpp
index 3c91150..f998b1a 100644
--- a/vulkan/nulldrv/null_driver.cpp
+++ b/vulkan/nulldrv/null_driver.cpp
@@ -948,6 +948,17 @@
     return VK_SUCCESS;
 }
 
+VkResult GetSwapchainGrallocUsage3ANDROID(
+    VkDevice,
+    const VkGrallocUsageInfoANDROID* grallocUsageInfo,
+    uint64_t* grallocUsage) {
+    // The null driver never reads or writes the gralloc buffer
+    ALOGV("TODO: vk%s - grallocUsageInfo->format:%i", __FUNCTION__,
+          grallocUsageInfo->format);
+    *grallocUsage = 0;
+    return VK_SUCCESS;
+}
+
 VkResult AcquireImageANDROID(VkDevice,
                              VkImage,
                              int fence,
diff --git a/vulkan/nulldrv/null_driver_gen.cpp b/vulkan/nulldrv/null_driver_gen.cpp
index f6dcf09..0cb7bd3 100644
--- a/vulkan/nulldrv/null_driver_gen.cpp
+++ b/vulkan/nulldrv/null_driver_gen.cpp
@@ -261,6 +261,7 @@
     {"vkGetRenderAreaGranularity", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetRenderAreaGranularity>(GetRenderAreaGranularity))},
     {"vkGetSemaphoreCounterValue", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetSemaphoreCounterValue>(GetSemaphoreCounterValue))},
     {"vkGetSwapchainGrallocUsage2ANDROID", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetSwapchainGrallocUsage2ANDROID>(GetSwapchainGrallocUsage2ANDROID))},
+    {"vkGetSwapchainGrallocUsage3ANDROID", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetSwapchainGrallocUsage3ANDROID>(GetSwapchainGrallocUsage3ANDROID))},
     {"vkGetSwapchainGrallocUsageANDROID", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkGetSwapchainGrallocUsageANDROID>(GetSwapchainGrallocUsageANDROID))},
     {"vkInvalidateMappedMemoryRanges", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkInvalidateMappedMemoryRanges>(InvalidateMappedMemoryRanges))},
     {"vkMapMemory", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_vkMapMemory>(MapMemory))},
diff --git a/vulkan/nulldrv/null_driver_gen.h b/vulkan/nulldrv/null_driver_gen.h
index 3e003e3..5c7fea0 100644
--- a/vulkan/nulldrv/null_driver_gen.h
+++ b/vulkan/nulldrv/null_driver_gen.h
@@ -209,6 +209,7 @@
 VKAPI_ATTR void GetDescriptorSetLayoutSupport(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport);
 VKAPI_ATTR VkResult GetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage);
 VKAPI_ATTR VkResult GetSwapchainGrallocUsage2ANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, uint64_t* grallocConsumerUsage, uint64_t* grallocProducerUsage);
+VKAPI_ATTR VkResult GetSwapchainGrallocUsage3ANDROID(VkDevice device, const VkGrallocUsageInfoANDROID* grallocUsageInfo, uint64_t* grallocUsage);
 VKAPI_ATTR VkResult AcquireImageANDROID(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence);
 VKAPI_ATTR VkResult QueueSignalReleaseImageANDROID(VkQueue queue, uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image, int* pNativeFenceFd);
 VKAPI_ATTR VkResult CreateRenderPass2(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass);
diff --git a/vulkan/scripts/generator_common.py b/vulkan/scripts/generator_common.py
index 4176509..c25c6cb 100644
--- a/vulkan/scripts/generator_common.py
+++ b/vulkan/scripts/generator_common.py
@@ -69,6 +69,7 @@
 _OPTIONAL_COMMANDS = [
     'vkGetSwapchainGrallocUsageANDROID',
     'vkGetSwapchainGrallocUsage2ANDROID',
+    'vkGetSwapchainGrallocUsage3ANDROID',
 ]
 
 # Dict for mapping dispatch table to a type.