Merge "Adds support for restore dexopt flag" into rvc-dev
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 544e26c..8637a31 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -233,6 +233,7 @@
         { REQ,      "events/filemap/enable" },
     } },
     { "memory",  "Memory", 0, {
+        { OPT,      "events/mm_event/mm_event_record/enable" },
         { OPT,      "events/kmem/rss_stat/enable" },
         { OPT,      "events/kmem/ion_heap_grow/enable" },
         { OPT,      "events/kmem/ion_heap_shrink/enable" },
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 6e460a0..040ddde 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -107,6 +107,8 @@
     chmod 0666 /sys/kernel/tracing/events/kmem/ion_heap_grow/enable
     chmod 0666 /sys/kernel/debug/tracing/events/kmem/ion_heap_shrink/enable
     chmod 0666 /sys/kernel/tracing/events/kmem/ion_heap_shrink/enable
+    chmod 0666 /sys/kernel/debug/tracing/events/mm_event/mm_event_record/enable
+    chmod 0666 /sys/kernel/tracing/events/mm_event/mm_event_record/enable
     chmod 0666 /sys/kernel/debug/tracing/events/signal/signal_generate/enable
     chmod 0666 /sys/kernel/tracing/events/signal/signal_generate/enable
     chmod 0666 /sys/kernel/debug/tracing/events/signal/signal_deliver/enable
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp
index 1824943..bfcc058 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -137,6 +137,8 @@
     ds_info->calling_package = calling_package;
 
     pthread_t thread;
+    // Initialize dumpstate
+    ds_->Initialize();
     status_t err = pthread_create(&thread, nullptr, dumpstate_thread_main, ds_info);
     if (err != 0) {
         delete ds_info;
diff --git a/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl b/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl
index e17f18e..8ff4ca6 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl
@@ -32,7 +32,7 @@
      *
      * @param progress the progress in [0, 100]
      */
-    void onProgress(int progress);
+    oneway void onProgress(int progress);
 
     // NOTE: If you add to or change these error codes, please also change the corresponding enums
     // in system server, in BugreportManager.java.
@@ -54,16 +54,18 @@
 
     /**
      * Called on an error condition with one of the error codes listed above.
+     * This is not an asynchronous method since it can race with dumpstate exiting, thus triggering
+     * death recipient.
      */
     void onError(int errorCode);
 
     /**
      * Called when taking bugreport finishes successfully.
      */
-    void onFinished();
+    oneway void onFinished();
 
     /**
      * Called when screenshot is taken.
      */
-    void onScreenshotTaken(boolean success);
+    oneway void onScreenshotTaken(boolean success);
 }
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 772b9fe..c85c7cf 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -2395,6 +2395,13 @@
     options_ = std::move(options);
 }
 
+void Dumpstate::Initialize() {
+    /* gets the sequential id */
+    uint32_t last_id = android::base::GetIntProperty(PROPERTY_LAST_ID, 0);
+    id_ = ++last_id;
+    android::base::SetProperty(PROPERTY_LAST_ID, std::to_string(last_id));
+}
+
 Dumpstate::RunStatus Dumpstate::Run(int32_t calling_uid, const std::string& calling_package) {
     Dumpstate::RunStatus status = RunInternal(calling_uid, calling_package);
     if (listener_ != nullptr) {
@@ -2505,11 +2512,6 @@
             : "";
     progress_.reset(new Progress(stats_path));
 
-    /* gets the sequential id */
-    uint32_t last_id = android::base::GetIntProperty(PROPERTY_LAST_ID, 0);
-    id_ = ++last_id;
-    android::base::SetProperty(PROPERTY_LAST_ID, std::to_string(last_id));
-
     if (acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME) < 0) {
         MYLOGE("Failed to acquire wake lock: %s\n", strerror(errno));
     } else {
@@ -2675,15 +2677,6 @@
             MYLOGI("User denied consent. Returning\n");
             return status;
         }
-        if (options_->do_screenshot &&
-            options_->screenshot_fd.get() != -1 &&
-            !options_->is_screenshot_copied) {
-            bool copy_succeeded = android::os::CopyFileToFd(screenshot_path_,
-                                                            options_->screenshot_fd.get());
-            if (copy_succeeded) {
-                android::os::UnlinkAndLogOnError(screenshot_path_);
-            }
-        }
         if (status == Dumpstate::RunStatus::USER_CONSENT_TIMED_OUT) {
             MYLOGI(
                 "Did not receive user consent yet."
@@ -2813,6 +2806,16 @@
         bool copy_succeeded = android::os::CopyFileToFd(path_, options_->bugreport_fd.get());
         if (copy_succeeded) {
             android::os::UnlinkAndLogOnError(path_);
+            if (options_->do_screenshot &&
+                options_->screenshot_fd.get() != -1 &&
+                !options_->is_screenshot_copied) {
+                copy_succeeded = android::os::CopyFileToFd(screenshot_path_,
+                                                           options_->screenshot_fd.get());
+                options_->is_screenshot_copied = copy_succeeded;
+                if (copy_succeeded) {
+                    android::os::UnlinkAndLogOnError(screenshot_path_);
+                }
+            }
         }
         return copy_succeeded ? Dumpstate::RunStatus::OK : Dumpstate::RunStatus::ERROR;
     } else if (consent_result == UserConsentResult::UNAVAILABLE) {
@@ -2837,8 +2840,9 @@
         assert(options_->bugreport_fd.get() == -1);
 
         // calling_uid and calling_package are for user consent to share the bugreport with
-        // an app; they are irrelvant here because bugreport is only written to a local
-        // directory, and not shared.
+        // an app; they are irrelevant here because bugreport is triggered via command line.
+        // Update Last ID before calling Run().
+        Initialize();
         status = Run(-1 /* calling_uid */, "" /* calling_package */);
     }
     return status;
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 9ce662b..498f338 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -216,6 +216,9 @@
     /* Checkes whether dumpstate is generating a zipped bugreport. */
     bool IsZipping() const;
 
+    /* Initialize dumpstate fields before starting bugreport generation */
+    void Initialize();
+
     /*
      * Forks a command, waits for it to finish, and returns its status.
      *
@@ -329,7 +332,12 @@
 
     struct DumpOptions;
 
-    /* Main entry point for running a complete bugreport. */
+    /*
+     * Main entry point for running a complete bugreport.
+     *
+     * Initialize() dumpstate before calling this method.
+     *
+     */
     RunStatus Run(int32_t calling_uid, const std::string& calling_package);
 
     RunStatus ParseCommandlineAndRun(int argc, char* argv[]);
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index c9b51b5..ae44d38 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -42,6 +42,7 @@
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/parseint.h>
 #include <android-base/properties.h>
 #include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
@@ -75,6 +76,7 @@
 #define LOG_TAG "installd"
 #endif
 
+using android::base::ParseUint;
 using android::base::StringPrintf;
 using std::endl;
 
@@ -1101,6 +1103,43 @@
     return ok();
 }
 
+binder::Status InstalldNativeService::destroyCeSnapshotsNotSpecified(
+        const std::unique_ptr<std::string> &volumeUuid, const int32_t userId,
+        const std::vector<int32_t>& retainSnapshotIds) {
+    ENFORCE_UID(AID_SYSTEM);
+    CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
+    std::lock_guard<std::recursive_mutex> lock(mLock);
+
+    const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
+
+    auto base_path = create_data_misc_ce_rollback_base_path(volume_uuid, userId);
+
+    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(base_path.c_str()), closedir);
+    if (!dir) {
+        return error(-1, "Failed to open rollback base dir " + base_path);
+    }
+
+    struct dirent* ent;
+    while ((ent = readdir(dir.get()))) {
+        if (ent->d_type != DT_DIR) {
+            continue;
+        }
+
+        uint snapshot_id;
+        bool parse_ok = ParseUint(ent->d_name, &snapshot_id);
+        if (parse_ok &&
+                std::find(retainSnapshotIds.begin(), retainSnapshotIds.end(),
+                          snapshot_id) == retainSnapshotIds.end()) {
+            auto rollback_path = create_data_misc_ce_rollback_path(
+                volume_uuid, userId, snapshot_id);
+            int res = delete_dir_contents_and_dir(rollback_path, true /* ignore_if_missing */);
+            if (res != 0) {
+                return error(res, "Failed clearing snapshot " + rollback_path);
+            }
+        }
+    }
+    return ok();
+}
 
 binder::Status InstalldNativeService::moveCompleteApp(const std::unique_ptr<std::string>& fromUuid,
         const std::unique_ptr<std::string>& toUuid, const std::string& packageName,
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index df01c3c..eb151ca 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -69,6 +69,8 @@
     binder::Status destroyAppDataSnapshot(const std::unique_ptr<std::string> &volumeUuid,
             const std::string& packageName, const int32_t user, const int64_t ceSnapshotInode,
             const int32_t snapshotId, int32_t storageFlags);
+    binder::Status destroyCeSnapshotsNotSpecified(const std::unique_ptr<std::string> &volumeUuid,
+            const int32_t userId, const std::vector<int32_t>& retainSnapshotIds);
 
     binder::Status getAppSize(const std::unique_ptr<std::string>& uuid,
             const std::vector<std::string>& packageNames, int32_t userId, int32_t flags,
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index ca95cb3..5e5af73 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -116,6 +116,9 @@
             int appId, @utf8InCpp String seInfo, int user, int snapshotId, int storageflags);
     void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName,
             int userId, long ceSnapshotInode, int snapshotId, int storageFlags);
+    void destroyCeSnapshotsNotSpecified(@nullable @utf8InCpp String uuid, int userId,
+            in int[] retainSnapshotIds);
+
     void tryMountDataMirror(@nullable @utf8InCpp String volumeUuid);
     void onPrivateVolumeRemoved(@nullable @utf8InCpp String volumeUuid);
 
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 07f8ff0..2944ac5 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -396,6 +396,14 @@
         bool skip_compilation = vold_decrypt == "trigger_restart_min_framework" ||
                                 vold_decrypt == "1";
 
+        std::string updatable_bcp_packages =
+            MapPropertyToArg("dalvik.vm.dex2oat-updatable-bcp-packages-file",
+                             "--updatable-bcp-packages-file=%s");
+        if (updatable_bcp_packages.empty()) {
+          // Make dex2oat fail by providing non-existent file name.
+          updatable_bcp_packages = "--updatable-bcp-packages-file=/nonx/updatable-bcp-packages.txt";
+        }
+
         std::string resolve_startup_string_arg =
                 MapPropertyToArg("persist.device_config.runtime.dex2oat_resolve_startup_strings",
                                  "--resolve-startup-const-strings=%s");
@@ -542,6 +550,7 @@
         AddRuntimeArg(dex2oat_Xms_arg);
         AddRuntimeArg(dex2oat_Xmx_arg);
 
+        AddArg(updatable_bcp_packages);
         AddArg(resolve_startup_string_arg);
         AddArg(image_block_size_arg);
         AddArg(dex2oat_compiler_filter_arg);
diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp
index a31d510..0fb62ae 100644
--- a/cmds/installd/tests/installd_service_test.cpp
+++ b/cmds/installd/tests/installd_service_test.cpp
@@ -641,6 +641,46 @@
           "com.foo", 0, 0, 43, FLAG_STORAGE_DE).isOk());
 }
 
+TEST_F(AppDataSnapshotTest, DestroyCeSnapshotsNotSpecified) {
+  auto rollback_ce_dir_in_1 = create_data_misc_ce_rollback_path("TEST", 0, 1543);
+  auto rollback_ce_dir_in_2 = create_data_misc_ce_rollback_path("TEST", 0, 77);
+  auto rollback_ce_dir_out_1 = create_data_misc_ce_rollback_path("TEST", 0, 1500);
+  auto rollback_ce_dir_out_2 = create_data_misc_ce_rollback_path("TEST", 0, 2);
+
+  // Create snapshots
+  ASSERT_TRUE(mkdirs(rollback_ce_dir_in_1 + "/com.foo/", 0700));
+  ASSERT_TRUE(android::base::WriteStringToFile(
+          "CE_RESTORE_CONTENT", rollback_ce_dir_in_1 + "/com.foo/file1",
+          0700, 10000, 20000, false /* follow_symlinks */));
+
+  ASSERT_TRUE(mkdirs(rollback_ce_dir_in_2 + "/com.foo/", 0700));
+  ASSERT_TRUE(android::base::WriteStringToFile(
+          "CE_RESTORE_CONTENT", rollback_ce_dir_in_2 + "/com.foo/file1",
+          0700, 10000, 20000, false /* follow_symlinks */));
+
+  ASSERT_TRUE(mkdirs(rollback_ce_dir_out_1 + "/com.foo/", 0700));
+  ASSERT_TRUE(android::base::WriteStringToFile(
+          "CE_RESTORE_CONTENT", rollback_ce_dir_out_1 + "/com.foo/file1",
+          0700, 10000, 20000, false /* follow_symlinks */));
+
+  ASSERT_TRUE(mkdirs(rollback_ce_dir_out_2 + "/com.foo/", 0700));
+  ASSERT_TRUE(android::base::WriteStringToFile(
+          "CE_RESTORE_CONTENT", rollback_ce_dir_out_2 + "/com.foo/file1",
+          0700, 10000, 20000, false /* follow_symlinks */));
+
+  ASSERT_TRUE(service->destroyCeSnapshotsNotSpecified(
+          std::make_unique<std::string>("TEST"), 0, { 1543, 77 }).isOk());
+
+  // Check only snapshots not specified are deleted.
+  struct stat sb;
+  ASSERT_EQ(0, stat((rollback_ce_dir_in_1 + "/com.foo").c_str(), &sb));
+  ASSERT_EQ(0, stat((rollback_ce_dir_in_2 + "/com.foo").c_str(), &sb));
+  ASSERT_EQ(-1, stat((rollback_ce_dir_out_1 + "/com.foo").c_str(), &sb));
+  ASSERT_EQ(ENOENT, errno);
+  ASSERT_EQ(-1, stat((rollback_ce_dir_out_2 + "/com.foo").c_str(), &sb));
+  ASSERT_EQ(ENOENT, errno);
+}
+
 TEST_F(AppDataSnapshotTest, RestoreAppDataSnapshot_WrongVolumeUuid) {
   // Setup rollback data to make sure that fails due to wrong volumeUuid being
   // passed, not because of some other reason.
diff --git a/libs/binder/IAppOpsCallback.cpp b/libs/binder/IAppOpsCallback.cpp
index 0ce1dd5..b9eb281 100644
--- a/libs/binder/IAppOpsCallback.cpp
+++ b/libs/binder/IAppOpsCallback.cpp
@@ -39,7 +39,7 @@
         data.writeInterfaceToken(IAppOpsCallback::getInterfaceDescriptor());
         data.writeInt32(op);
         data.writeString16(packageName);
-        remote()->transact(OP_CHANGED_TRANSACTION, data, &reply);
+        remote()->transact(OP_CHANGED_TRANSACTION, data, &reply, IBinder::FLAG_ONEWAY);
     }
 };
 
@@ -58,7 +58,6 @@
             String16 packageName;
             (void)data.readString16(&packageName);
             opChanged(op, packageName);
-            reply->writeNoException();
             return NO_ERROR;
         } break;
         default:
diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp
index 74aece8..6f49aa1 100644
--- a/libs/binder/LazyServiceRegistrar.cpp
+++ b/libs/binder/LazyServiceRegistrar.cpp
@@ -82,12 +82,12 @@
         return false;
     }
 
-    if (!manager->registerClientCallback(name, service, this).isOk()) {
-        ALOGE("Failed to add client callback for service %s", name.c_str());
-        return false;
-    }
-
     if (!reRegister) {
+        if (!manager->registerClientCallback(name, service, this).isOk()) {
+            ALOGE("Failed to add client callback for service %s", name.c_str());
+            return false;
+        }
+
         // Only add this when a service is added for the first time, as it is not removed
         mRegisteredServices[name] = {service, allowIsolated, dumpFlags};
     }
diff --git a/libs/binder/include/binder/AppOpsManager.h b/libs/binder/include/binder/AppOpsManager.h
index 2ee5930..6afcd77 100644
--- a/libs/binder/include/binder/AppOpsManager.h
+++ b/libs/binder/include/binder/AppOpsManager.h
@@ -122,7 +122,16 @@
         OP_LEGACY_STORAGE = 87,
         OP_ACCESS_ACCESSIBILITY = 88,
         OP_READ_DEVICE_IDENTIFIERS = 89,
-        _NUM_OP = 90
+        OP_ACCESS_MEDIA_LOCATION = 90,
+        OP_QUERY_ALL_PACKAGES = 91,
+        OP_MANAGE_EXTERNAL_STORAGE = 92,
+        OP_INTERACT_ACROSS_PROFILES = 93,
+        OP_ACTIVATE_PLATFORM_VPN = 94,
+        OP_LOADER_USAGE_STATS = 95,
+        OP_DEPRECATED_1 = 96,
+        OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 97,
+        OP_AUTO_REVOKE_MANAGED_BY_INSTALLER = 98,
+        _NUM_OP = 99
     };
 
     AppOpsManager();
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 3ee8187..c7b7551 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -40,7 +40,7 @@
     },
 
     srcs: ["binderDriverInterfaceTest.cpp"],
-    test_suites: ["device-tests", "vts-core"],
+    test_suites: ["device-tests", "vts"],
 }
 
 cc_test {
@@ -69,7 +69,7 @@
         "libbinder",
         "libutils",
     ],
-    test_suites: ["device-tests", "vts-core"],
+    test_suites: ["device-tests", "vts"],
     require_root: true,
 }
 
@@ -131,7 +131,7 @@
         "liblog",
         "libutils",
     ],
-    test_suites: ["device-tests", "vts-core"],
+    test_suites: ["device-tests", "vts"],
     require_root: true,
 }
 
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index b2b74dc..fd557b7 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -73,6 +73,7 @@
         "android.hardware.thermal@2.0::IThermal",
         "android.hardware.vr@1.0::IVr",
         "android.hardware.automotive.audiocontrol@1.0::IAudioControl",
+        "android.hardware.automotive.audiocontrol@2.0::IAudioControl",
         "android.hardware.automotive.vehicle@2.0::IVehicle",
         "android.hardware.automotive.evs@1.0::IEvsCamera",
         "android.hardware.neuralnetworks@1.0::IDevice",
diff --git a/libs/gralloc/types/include/gralloctypes/Gralloc4.h b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
index 5ec4d0d..8d12754 100644
--- a/libs/gralloc/types/include/gralloctypes/Gralloc4.h
+++ b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
@@ -25,6 +25,7 @@
 #include <aidl/android/hardware/graphics/common/Interlaced.h>
 #include <aidl/android/hardware/graphics/common/PlaneLayout.h>
 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
 #include <aidl/android/hardware/graphics/common/Smpte2086.h>
 #include <aidl/android/hardware/graphics/common/StandardMetadataType.h>
 #include <aidl/android/hardware/graphics/common/XyColor.h>
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 30e1351..a8384ac 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -110,7 +110,7 @@
         mProducer->setMaxDequeuedBufferCount(2);
     }
     mBufferItemConsumer =
-            new BLASTBufferItemConsumer(mConsumer, AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER, 1, true);
+        new BLASTBufferItemConsumer(mConsumer, GraphicBuffer::USAGE_HW_COMPOSER, 1, true);
     static int32_t id = 0;
     auto name = std::string("BLAST Consumer") + std::to_string(id);
     id++;
@@ -119,7 +119,9 @@
     mBufferItemConsumer->setBufferFreedListener(this);
     mBufferItemConsumer->setDefaultBufferSize(mWidth, mHeight);
     mBufferItemConsumer->setDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888);
+
     mTransformHint = mSurfaceControl->getTransformHint();
+    mBufferItemConsumer->setTransformHint(mTransformHint);
 
     mNumAcquired = 0;
     mNumFrameAvailable = 0;
@@ -130,9 +132,12 @@
 void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, int width, int height) {
     std::unique_lock _lock{mMutex};
     mSurfaceControl = surface;
-    mWidth = width;
-    mHeight = height;
-    mBufferItemConsumer->setDefaultBufferSize(mWidth, mHeight);
+
+    if (mWidth != width || mHeight != height) {
+        mWidth = width;
+        mHeight = height;
+        mBufferItemConsumer->setDefaultBufferSize(mWidth, mHeight);
+    }
 }
 
 static void transactionCallbackThunk(void* context, nsecs_t latchTime,
diff --git a/libs/gui/BufferHubProducer.cpp b/libs/gui/BufferHubProducer.cpp
index 4be014f..489f3c3 100644
--- a/libs/gui/BufferHubProducer.cpp
+++ b/libs/gui/BufferHubProducer.cpp
@@ -19,7 +19,6 @@
 #include <inttypes.h>
 #include <log/log.h>
 #include <system/window.h>
-#include <ui/BufferHubBuffer.h>
 
 namespace android {
 
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 8d79cf8..6fd53cf 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -795,8 +795,7 @@
     }
 
     virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
-                                                      uint8_t componentMask,
-                                                      uint64_t maxFrames) const {
+                                                      uint8_t componentMask, uint64_t maxFrames) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
@@ -1038,7 +1037,7 @@
         return NO_ERROR;
     }
 
-    virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) const {
+    virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (error != NO_ERROR) {
@@ -1145,6 +1144,42 @@
             ALOGE("setFrameRate: failed to transact: %s (%d)", strerror(-err), err);
             return err;
         }
+
+        return reply.readInt32();
+    }
+
+    virtual status_t acquireFrameRateFlexibilityToken(sp<IBinder>* outToken) {
+        if (!outToken) return BAD_VALUE;
+
+        Parcel data, reply;
+        status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        if (err != NO_ERROR) {
+            ALOGE("acquireFrameRateFlexibilityToken: failed writing interface token: %s (%d)",
+                  strerror(-err), -err);
+            return err;
+        }
+
+        err = remote()->transact(BnSurfaceComposer::ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN, data,
+                                 &reply);
+        if (err != NO_ERROR) {
+            ALOGE("acquireFrameRateFlexibilityToken: failed to transact: %s (%d)", strerror(-err),
+                  err);
+            return err;
+        }
+
+        err = reply.readInt32();
+        if (err != NO_ERROR) {
+            ALOGE("acquireFrameRateFlexibilityToken: call failed: %s (%d)", strerror(-err), err);
+            return err;
+        }
+
+        err = reply.readStrongBinder(outToken);
+        if (err != NO_ERROR) {
+            ALOGE("acquireFrameRateFlexibilityToken: failed reading binder token: %s (%d)",
+                  strerror(-err), err);
+            return err;
+        }
+
         return NO_ERROR;
     }
 };
@@ -1945,6 +1980,16 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IBinder> token;
+            status_t result = acquireFrameRateFlexibilityToken(&token);
+            reply->writeInt32(result);
+            if (result == NO_ERROR) {
+                reply->writeStrongBinder(token);
+            }
+            return NO_ERROR;
+        }
         default: {
             return BBinder::onTransact(code, data, reply, flags);
         }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 2307fbf..d9cbeb7 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -241,8 +241,31 @@
 
 // ---------------------------------------------------------------------------
 
-void bufferCacheCallback(void* /*context*/, uint64_t graphicBufferId);
+void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId);
 
+/**
+ * We use the BufferCache to reduce the overhead of exchanging GraphicBuffers with
+ * the server. If we were to simply parcel the GraphicBuffer we would pay two overheads
+ *     1. Cost of sending the FD
+ *     2. Cost of importing the GraphicBuffer with the mapper in the receiving process.
+ * To ease this cost we implement the following scheme of caching buffers to integers,
+ * or said-otherwise, naming them with integers. This is the scheme known as slots in
+ * the legacy BufferQueue system.
+ *     1. When sending Buffers to SurfaceFlinger we look up the Buffer in the cache.
+ *     2. If there is a cache-hit we remove the Buffer from the Transaction and instead
+ *        send the cached integer.
+ *     3. If there is a cache miss, we cache the new buffer and send the integer
+ *        along with the Buffer, SurfaceFlinger on it's side creates a new cache
+ *        entry, and we use the integer for further communication.
+ * A few details about lifetime:
+ *     1. The cache evicts by LRU. The server side cache is keyed by BufferCache::getToken
+ *        which is per process Unique. The server side cache is larger than the client side
+ *        cache so that the server will never evict entries before the client.
+ *     2. When the client evicts an entry it notifies the server via an uncacheBuffer
+ *        transaction.
+ *     3. The client only references the Buffers by ID, and uses buffer->addDeathCallback
+ *        to auto-evict destroyed buffers.
+ */
 class BufferCache : public Singleton<BufferCache> {
 public:
     BufferCache() : token(new BBinder()) {}
@@ -270,7 +293,7 @@
             evictLeastRecentlyUsedBuffer();
         }
 
-        buffer->addDeathCallback(bufferCacheCallback, nullptr);
+        buffer->addDeathCallback(removeDeadBufferCallback, nullptr);
 
         mBuffers[buffer->getId()] = getCounter();
         return buffer->getId();
@@ -318,7 +341,7 @@
 
 ANDROID_SINGLETON_STATIC_INSTANCE(BufferCache);
 
-void bufferCacheCallback(void* /*context*/, uint64_t graphicBufferId) {
+void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId) {
     // GraphicBuffer id's are used as the cache ids.
     BufferCache::getInstance().uncache(graphicBufferId);
 }
@@ -430,6 +453,19 @@
 }
 
 status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const {
+    // If we write the Transaction to a parcel, we want to ensure the Buffers are cached
+    // before crossing the IPC boundary. Otherwise the receiving party will cache the buffers
+    // but is unlikely to use them again as they are owned by the other process.
+    // You may be asking yourself, is this const cast safe? Const cast is safe up
+    // until the point where you try and write to an object that was originally const at which
+    // point we enter undefined behavior. In this case we are safe though, because there are
+    // two possibilities:
+    //    1. The SurfaceComposerClient::Transaction was originally non-const. Safe.
+    //    2. It was originall const! In this case not only was it useless, but it by definition
+    //       contains no composer states and so cacheBuffers will not perform any writes.
+
+    const_cast<SurfaceComposerClient::Transaction*>(this)->cacheBuffers();
+
     parcel->writeUint32(mForceSynchronous);
     parcel->writeUint32(mTransactionNestCount);
     parcel->writeBool(mAnimation);
@@ -507,7 +543,7 @@
 
     mInputWindowCommands.merge(other.mInputWindowCommands);
 
-    mContainsBuffer = other.mContainsBuffer;
+    mContainsBuffer |= other.mContainsBuffer;
     mEarlyWakeup = mEarlyWakeup || other.mEarlyWakeup;
     other.clear();
     return *this;
@@ -547,6 +583,11 @@
         layer_state_t* s = getLayerState(handle);
         if (!(s->what & layer_state_t::eBufferChanged)) {
             continue;
+        } else if (s->what & layer_state_t::eCachedBufferChanged) {
+            // If eBufferChanged and eCachedBufferChanged are both trued then that means
+            // we already cached the buffer in a previous call to cacheBuffers, perhaps
+            // from writeToParcel on a Transaction that was merged in to this one.
+            continue;
         }
 
         // Don't try to cache a null buffer. Sending null buffers is cheap so we shouldn't waste
@@ -558,9 +599,11 @@
         uint64_t cacheId = 0;
         status_t ret = BufferCache::getInstance().getCacheId(s->buffer, &cacheId);
         if (ret == NO_ERROR) {
+            // Cache-hit. Strip the buffer and send only the id.
             s->what &= ~static_cast<uint64_t>(layer_state_t::eBufferChanged);
             s->buffer = nullptr;
         } else {
+            // Cache-miss. Include the buffer and send the new cacheId.
             cacheId = BufferCache::getInstance().cache(s->buffer);
         }
         s->what |= layer_state_t::eCachedBufferChanged;
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 09487ea..b4a3fbe 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -383,7 +383,7 @@
      */
     virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
                                                       uint8_t componentMask,
-                                                      uint64_t maxFrames) const = 0;
+                                                      uint64_t maxFrames) = 0;
 
     /* Returns statistics on the color profile of the last frame displayed for a given display
      *
@@ -468,8 +468,7 @@
      *      BAD_VALUE         if the brightness is invalid, or
      *      INVALID_OPERATION if brightness operations are not supported.
      */
-    virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken,
-                                          float brightness) const = 0;
+    virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) = 0;
 
     /*
      * Sends a power hint to the composer. This function is asynchronous.
@@ -508,6 +507,14 @@
      */
     virtual status_t setFrameRate(const sp<IGraphicBufferProducer>& surface, float frameRate,
                                   int8_t compatibility) = 0;
+
+    /*
+     * Acquire a frame rate flexibility token from SurfaceFlinger. While this token is acquired,
+     * surface flinger will freely switch between frame rates in any way it sees fit, regardless of
+     * the current restrictions applied by DisplayManager. This is useful to get consistent behavior
+     * for tests. Release the token by releasing the returned IBinder reference.
+     */
+    virtual status_t acquireFrameRateFlexibilityToken(sp<IBinder>* outToken) = 0;
 };
 
 // ----------------------------------------------------------------------------
@@ -566,6 +573,7 @@
         GET_GAME_CONTENT_TYPE_SUPPORT,
         SET_GAME_CONTENT_TYPE,
         SET_FRAME_RATE,
+        ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN,
         // Always append new enum to the end.
     };
 
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index a87ccd6..d929a59 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -722,5 +722,8 @@
     ASSERT_EQ(2, events->frameNumber);
     ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
     ASSERT_GE(events->postedTime, postedTimeB);
+
+    // wait for any callbacks that have not been received
+    adapter.waitForCallbacks();
 }
 } // namespace android
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 8c0f8f8..2de6b69 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -804,7 +804,7 @@
     }
     status_t setDisplayContentSamplingEnabled(const sp<IBinder>& /*display*/, bool /*enable*/,
                                               uint8_t /*componentMask*/,
-                                              uint64_t /*maxFrames*/) const override {
+                                              uint64_t /*maxFrames*/) override {
         return NO_ERROR;
     }
     status_t getDisplayedContentSample(const sp<IBinder>& /*display*/, uint64_t /*maxFrames*/,
@@ -822,7 +822,7 @@
         return NO_ERROR;
     }
     status_t setDisplayBrightness(const sp<IBinder>& /*displayToken*/,
-                                  float /*brightness*/) const override {
+                                  float /*brightness*/) override {
         return NO_ERROR;
     }
 
@@ -859,6 +859,8 @@
         return NO_ERROR;
     }
 
+    status_t acquireFrameRateFlexibilityToken(sp<IBinder>* /*outToken*/) { return NO_ERROR; }
+
 protected:
     IBinder* onAsBinder() override { return nullptr; }
 
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index e73f245..36a54a7 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -793,34 +793,66 @@
     // top rectangle and the bottom rectangle, and turn off blending for the middle rectangle.
     FloatRect bounds = layer.geometry.roundedCornersCrop;
 
-    // Firstly, we need to convert the coordination from layer native coordination space to
-    // device coordination space.
-    const auto transformMatrix = display.globalTransform * layer.geometry.positionTransform;
-    const vec4 leftTopCoordinate(bounds.left, bounds.top, 1.0, 1.0);
-    const vec4 rightBottomCoordinate(bounds.right, bounds.bottom, 1.0, 1.0);
-    const vec4 leftTopCoordinateInBuffer = transformMatrix * leftTopCoordinate;
-    const vec4 rightBottomCoordinateInBuffer = transformMatrix * rightBottomCoordinate;
-    bounds = FloatRect(leftTopCoordinateInBuffer[0], leftTopCoordinateInBuffer[1],
-                       rightBottomCoordinateInBuffer[0], rightBottomCoordinateInBuffer[1]);
-
-    // Secondly, if the display is rotated, we need to undo the rotation on coordination and
-    // align the (left, top) and (right, bottom) coordination with the device coordination
-    // space.
+    // Explicitly compute the transform from the clip rectangle to the physical
+    // display. Normally, this is done in glViewport but we explicitly compute
+    // it here so that we can get the scissor bounds correct.
+    const Rect& source = display.clip;
+    const Rect& destination = display.physicalDisplay;
+    // Here we compute the following transform:
+    // 1. Translate the top left corner of the source clip to (0, 0)
+    // 2. Rotate the clip rectangle about the origin in accordance with the
+    // orientation flag
+    // 3. Translate the top left corner back to the origin.
+    // 4. Scale the clip rectangle to the destination rectangle dimensions
+    // 5. Translate the top left corner to the destination rectangle's top left
+    // corner.
+    const mat4 translateSource = mat4::translate(vec4(-source.left, -source.top, 0, 1));
+    mat4 rotation;
+    int displacementX = 0;
+    int displacementY = 0;
+    float destinationWidth = static_cast<float>(destination.getWidth());
+    float destinationHeight = static_cast<float>(destination.getHeight());
+    float sourceWidth = static_cast<float>(source.getWidth());
+    float sourceHeight = static_cast<float>(source.getHeight());
+    const float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f;
     switch (display.orientation) {
         case ui::Transform::ROT_90:
-            std::swap(bounds.left, bounds.right);
+            rotation = mat4::rotate(rot90InRadians, vec3(0, 0, 1));
+            displacementX = source.getHeight();
+            std::swap(sourceHeight, sourceWidth);
             break;
         case ui::Transform::ROT_180:
-            std::swap(bounds.left, bounds.right);
-            std::swap(bounds.top, bounds.bottom);
+            rotation = mat4::rotate(rot90InRadians * 2.0f, vec3(0, 0, 1));
+            displacementY = source.getHeight();
+            displacementX = source.getWidth();
             break;
         case ui::Transform::ROT_270:
-            std::swap(bounds.top, bounds.bottom);
+            rotation = mat4::rotate(rot90InRadians * 3.0f, vec3(0, 0, 1));
+            displacementY = source.getWidth();
+            std::swap(sourceHeight, sourceWidth);
             break;
         default:
             break;
     }
 
+    const mat4 intermediateTranslation = mat4::translate(vec4(displacementX, displacementY, 0, 1));
+    const mat4 scale = mat4::scale(
+            vec4(destinationWidth / sourceWidth, destinationHeight / sourceHeight, 1, 1));
+    const mat4 translateDestination =
+            mat4::translate(vec4(destination.left, destination.top, 0, 1));
+    const mat4 globalTransform =
+            translateDestination * scale * intermediateTranslation * rotation * translateSource;
+
+    const mat4 transformMatrix = globalTransform * layer.geometry.positionTransform;
+    const vec4 leftTopCoordinate(bounds.left, bounds.top, 1.0, 1.0);
+    const vec4 rightBottomCoordinate(bounds.right, bounds.bottom, 1.0, 1.0);
+    const vec4 leftTopCoordinateInBuffer = transformMatrix * leftTopCoordinate;
+    const vec4 rightBottomCoordinateInBuffer = transformMatrix * rightBottomCoordinate;
+    bounds = FloatRect(std::min(leftTopCoordinateInBuffer[0], rightBottomCoordinateInBuffer[0]),
+                       std::min(leftTopCoordinateInBuffer[1], rightBottomCoordinateInBuffer[1]),
+                       std::max(leftTopCoordinateInBuffer[0], rightBottomCoordinateInBuffer[0]),
+                       std::max(leftTopCoordinateInBuffer[1], rightBottomCoordinateInBuffer[1]));
+
     // Finally, we cut the layer into 3 parts, with top and bottom parts having rounded corners
     // and the middle part without rounded corners.
     const int32_t radius = ceil(layer.geometry.roundedCornersRadius);
@@ -1015,8 +1047,8 @@
     setOutputDataSpace(display.outputDataspace);
     setDisplayMaxLuminance(display.maxLuminance);
 
-    mat4 projectionMatrix = mState.projectionMatrix * display.globalTransform;
-    mState.projectionMatrix = projectionMatrix;
+    const mat4 projectionMatrix =
+            ui::Transform(display.orientation).asMatrix4() * mState.projectionMatrix;
     if (!display.clearRegion.isEmpty()) {
         glDisable(GL_BLEND);
         fillRegionWithColor(display.clearRegion, 0.0, 0.0, 0.0, 1.0);
diff --git a/libs/renderengine/gl/filters/BlurFilter.cpp b/libs/renderengine/gl/filters/BlurFilter.cpp
index 6ba78dc..724877b 100644
--- a/libs/renderengine/gl/filters/BlurFilter.cpp
+++ b/libs/renderengine/gl/filters/BlurFilter.cpp
@@ -54,13 +54,13 @@
     static constexpr auto translation = 1.0f;
     const GLfloat vboData[] = {
         // Vertex data
-        translation-size, -translation-size,
-        translation-size, -translation+size,
-        translation+size, -translation+size,
+        translation - size, -translation - size,
+        translation - size, -translation + size,
+        translation + size, -translation + size,
         // UV data
-        0.0f, 0.0f-translation,
-        0.0f, size-translation,
-        size, size-translation
+        0.0f, 0.0f - translation,
+        0.0f, size - translation,
+        size, size - translation
     };
     mMeshBuffer.allocateBuffers(vboData, 12 /* size */);
 }
@@ -69,7 +69,10 @@
     ATRACE_NAME("BlurFilter::setAsDrawTarget");
     mRadius = radius;
 
-    if (!mTexturesAllocated) {
+    if (mDisplayWidth < display.physicalDisplay.width() ||
+        mDisplayHeight < display.physicalDisplay.height()) {
+        ATRACE_NAME("BlurFilter::allocatingTextures");
+
         mDisplayWidth = display.physicalDisplay.width();
         mDisplayHeight = display.physicalDisplay.height();
         mCompositionFbo.allocateBuffers(mDisplayWidth, mDisplayHeight);
@@ -78,7 +81,6 @@
         const uint32_t fboHeight = floorf(mDisplayHeight * kFboScale);
         mPingFbo.allocateBuffers(fboWidth, fboHeight);
         mPongFbo.allocateBuffers(fboWidth, fboHeight);
-        mTexturesAllocated = true;
 
         if (mPingFbo.getStatus() != GL_FRAMEBUFFER_COMPLETE) {
             ALOGE("Invalid ping buffer");
@@ -120,27 +122,35 @@
 
 status_t BlurFilter::prepare() {
     ATRACE_NAME("BlurFilter::prepare");
-    blit(mCompositionFbo, mPingFbo);
 
     // Kawase is an approximation of Gaussian, but it behaves differently from it.
     // A radius transformation is required for approximating them, and also to introduce
     // non-integer steps, necessary to smoothly interpolate large radii.
-    auto radius = mRadius / 6.0f;
+    const auto radius = mRadius / 6.0f;
 
     // Calculate how many passes we'll do, based on the radius.
     // Too many passes will make the operation expensive.
-    auto passes = min(kMaxPasses, (uint32_t)ceil(radius));
+    const auto passes = min(kMaxPasses, (uint32_t)ceil(radius));
 
-    // We'll ping pong between our textures, to accumulate the result of various offsets.
+    const float radiusByPasses = radius / (float)passes;
+    const float stepX = radiusByPasses / (float)mCompositionFbo.getBufferWidth();
+    const float stepY = radiusByPasses / (float)mCompositionFbo.getBufferHeight();
+
+    // Let's start by downsampling and blurring the composited frame simultaneously.
     mBlurProgram.useProgram();
-    GLFramebuffer* read = &mPingFbo;
-    GLFramebuffer* draw = &mPongFbo;
-    float stepX = radius / (float)mCompositionFbo.getBufferWidth() / (float)passes;
-    float stepY = radius / (float)mCompositionFbo.getBufferHeight() / (float)passes;
-    glViewport(0, 0, draw->getBufferWidth(), draw->getBufferHeight());
     glActiveTexture(GL_TEXTURE0);
     glUniform1i(mBTextureLoc, 0);
-    for (auto i = 0; i < passes; i++) {
+    glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName());
+    glUniform2f(mBOffsetLoc, stepX, stepY);
+    glViewport(0, 0, mPingFbo.getBufferWidth(), mPingFbo.getBufferHeight());
+    mPingFbo.bind();
+    drawMesh(mBUvLoc, mBPosLoc);
+
+    // And now we'll ping pong between our textures, to accumulate the result of various offsets.
+    GLFramebuffer* read = &mPingFbo;
+    GLFramebuffer* draw = &mPongFbo;
+    glViewport(0, 0, draw->getBufferWidth(), draw->getBufferHeight());
+    for (auto i = 1; i < passes; i++) {
         ATRACE_NAME("BlurFilter::renderPass");
         draw->bind();
 
@@ -156,9 +166,6 @@
     }
     mLastDrawTarget = read;
 
-    // Cleanup
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
     return NO_ERROR;
 }
 
@@ -177,7 +184,6 @@
         glBlitFramebuffer(0, 0, mLastDrawTarget->getBufferWidth(),
                           mLastDrawTarget->getBufferHeight(), 0, 0, mDisplayWidth, mDisplayHeight,
                           GL_COLOR_BUFFER_BIT, GL_LINEAR);
-        glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
         return NO_ERROR;
     }
 
@@ -256,12 +262,12 @@
 }
 
 void BlurFilter::blit(GLFramebuffer& read, GLFramebuffer& draw) const {
+    ATRACE_NAME("BlurFilter::blit");
     read.bindAsReadBuffer();
     draw.bindAsDrawBuffer();
     glBlitFramebuffer(0, 0, read.getBufferWidth(), read.getBufferHeight(), 0, 0,
                       draw.getBufferWidth(), draw.getBufferHeight(), GL_COLOR_BUFFER_BIT,
                       GL_LINEAR);
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
 } // namespace gl
diff --git a/libs/renderengine/gl/filters/BlurFilter.h b/libs/renderengine/gl/filters/BlurFilter.h
index 3eb5c96..7e0819f 100644
--- a/libs/renderengine/gl/filters/BlurFilter.h
+++ b/libs/renderengine/gl/filters/BlurFilter.h
@@ -38,7 +38,7 @@
     // Downsample FBO to improve performance
     static constexpr float kFboScale = 0.25f;
     // Maximum number of render passes
-    static constexpr uint32_t kMaxPasses = 6;
+    static constexpr uint32_t kMaxPasses = 4;
     // To avoid downscaling artifacts, we interpolate the blurred fbo with the full composited
     // image, up to this radius.
     static constexpr float kMaxCrossFadeRadius = 30.0f;
@@ -67,11 +67,10 @@
     // Frame buffers holding the blur passes.
     GLFramebuffer mPingFbo;
     GLFramebuffer mPongFbo;
-    uint32_t mDisplayWidth;
-    uint32_t mDisplayHeight;
+    uint32_t mDisplayWidth = 0;
+    uint32_t mDisplayHeight = 0;
     // Buffer holding the final blur pass.
     GLFramebuffer* mLastDrawTarget;
-    bool mTexturesAllocated = false;
 
     // VBO containing vertex and uv data of a fullscreen triangle.
     GLVertexBuffer mMeshBuffer;
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index c4a29a9..ca16d2c 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -40,9 +40,6 @@
     // z=1.
     Rect clip = Rect::INVALID_RECT;
 
-    // Global transform to apply to all layers.
-    mat4 globalTransform = mat4();
-
     // Maximum luminance pulled from the display's HDR capabilities.
     float maxLuminance = 1.0f;
 
@@ -55,19 +52,19 @@
     mat4 colorTransform = mat4();
 
     // Region that will be cleared to (0, 0, 0, 1) prior to rendering.
-    // RenderEngine will transform the clearRegion passed in here, by
-    // globalTransform, so that it will be in the same coordinate space as the
-    // rendered layers.
+    // This is specified in layer-stack space.
     Region clearRegion = Region::INVALID_REGION;
 
-    // The orientation of the physical display.
+    // An additional orientation flag to be applied after clipping the output.
+    // By way of example, this may be used for supporting fullscreen screenshot
+    // capture of a device in landscape while the buffer is in portrait
+    // orientation.
     uint32_t orientation = ui::Transform::ROT_0;
 };
 
 static inline bool operator==(const DisplaySettings& lhs, const DisplaySettings& rhs) {
     return lhs.physicalDisplay == rhs.physicalDisplay && lhs.clip == rhs.clip &&
-            lhs.globalTransform == rhs.globalTransform && lhs.maxLuminance == rhs.maxLuminance &&
-            lhs.outputDataspace == rhs.outputDataspace &&
+            lhs.maxLuminance == rhs.maxLuminance && lhs.outputDataspace == rhs.outputDataspace &&
             lhs.colorTransform == rhs.colorTransform &&
             lhs.clearRegion.hasSameRects(rhs.clearRegion) && lhs.orientation == rhs.orientation;
 }
@@ -79,7 +76,6 @@
     PrintTo(settings.physicalDisplay, os);
     *os << "\n    .clip = ";
     PrintTo(settings.clip, os);
-    *os << "\n    .globalTransform = " << settings.globalTransform;
     *os << "\n    .maxLuminance = " << settings.maxLuminance;
     *os << "\n    .outputDataspace = ";
     PrintTo(settings.outputDataspace, os);
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index afcbc50..f5bf014 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -298,7 +298,7 @@
     void fillBufferPhysicalOffset();
 
     template <typename SourceVariant>
-    void fillBufferCheckers(mat4 transform);
+    void fillBufferCheckers(uint32_t rotation);
 
     template <typename SourceVariant>
     void fillBufferCheckersRotate0();
@@ -509,12 +509,12 @@
 }
 
 template <typename SourceVariant>
-void RenderEngineTest::fillBufferCheckers(mat4 transform) {
+void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
     renderengine::DisplaySettings settings;
     settings.physicalDisplay = fullscreenRect();
     // Here logical space is 2x2
     settings.clip = Rect(2, 2);
-    settings.globalTransform = transform;
+    settings.orientation = orientationFlag;
 
     std::vector<const renderengine::LayerSettings*> layers;
 
@@ -545,7 +545,7 @@
 
 template <typename SourceVariant>
 void RenderEngineTest::fillBufferCheckersRotate0() {
-    fillBufferCheckers<SourceVariant>(mat4());
+    fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
     expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
                       255);
     expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
@@ -561,8 +561,7 @@
 
 template <typename SourceVariant>
 void RenderEngineTest::fillBufferCheckersRotate90() {
-    mat4 matrix = mat4(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 1);
-    fillBufferCheckers<SourceVariant>(matrix);
+    fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
     expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
                       255);
     expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
@@ -578,8 +577,7 @@
 
 template <typename SourceVariant>
 void RenderEngineTest::fillBufferCheckersRotate180() {
-    mat4 matrix = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 2, 2, 0, 1);
-    fillBufferCheckers<SourceVariant>(matrix);
+    fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
     expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
                       0);
     expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
@@ -595,8 +593,7 @@
 
 template <typename SourceVariant>
 void RenderEngineTest::fillBufferCheckersRotate270() {
-    mat4 matrix = mat4(0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1);
-    fillBufferCheckers<SourceVariant>(matrix);
+    fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
     expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
                       255);
     expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
@@ -927,8 +924,7 @@
     settings.physicalDisplay = fullscreenRect();
     // Here logical space is 4x4
     settings.clip = Rect(4, 4);
-    settings.globalTransform = mat4::scale(vec4(2, 4, 0, 1));
-    settings.clearRegion = Region(Rect(1, 1));
+    settings.clearRegion = Region(Rect(2, 4));
     std::vector<const renderengine::LayerSettings*> layers;
     // dummy layer, without bounds should not render anything
     renderengine::LayerSettings layer;
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index ba6255d..458ee67 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -36,9 +36,6 @@
 
     srcs: [
         "ColorSpace.cpp",
-        "BufferHubBuffer.cpp",
-        "BufferHubEventFd.cpp",
-        "BufferHubMetadata.cpp",
         "DebugUtils.cpp",
         "Fence.cpp",
         "FenceTime.cpp",
@@ -72,7 +69,6 @@
     //defaults: ["libui-validate-regions-defaults"],
 
     shared_libs: [
-        "android.frameworks.bufferhub@1.0",
         "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.allocator@3.0",
         "android.hardware.graphics.allocator@4.0",
@@ -109,30 +105,20 @@
         vendor: {
             cflags: ["-DLIBUI_IN_VNDK"],
             exclude_srcs: [
-                "BufferHubBuffer.cpp",
-                "BufferHubEventFd.cpp",
-                "BufferHubMetadata.cpp",
             ],
             exclude_header_libs: [
-                "libbufferhub_headers",
-                "libdvr_headers",
             ],
             exclude_shared_libs: [
-                "android.frameworks.bufferhub@1.0",
-                "libpdx_default_transport",
             ],
         },
     },
 
     header_libs: [
         "libbase_headers",
-        "libbufferhub_headers",
-        "libdvr_headers",
         "libnativebase_headers",
         "libnativewindow_headers",
         "libhardware_headers",
         "libui_headers",
-        "libpdx_headers",
     ],
 
     export_static_lib_headers: [
diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp
deleted file mode 100644
index 1dfc1e9..0000000
--- a/libs/ui/BufferHubBuffer.cpp
+++ /dev/null
@@ -1,358 +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 "BufferHubBuffer"
-#include <poll.h>
-
-#include <android-base/unique_fd.h>
-#include <android/frameworks/bufferhub/1.0/IBufferHub.h>
-#include <log/log.h>
-#include <ui/BufferHubBuffer.h>
-#include <ui/BufferHubDefs.h>
-#include <utils/Trace.h>
-
-using ::android::base::unique_fd;
-using ::android::BufferHubDefs::isAnyClientAcquired;
-using ::android::BufferHubDefs::isAnyClientGained;
-using ::android::BufferHubDefs::isClientAcquired;
-using ::android::BufferHubDefs::isClientGained;
-using ::android::BufferHubDefs::isClientPosted;
-using ::android::BufferHubDefs::isClientReleased;
-using ::android::frameworks::bufferhub::V1_0::BufferHubStatus;
-using ::android::frameworks::bufferhub::V1_0::BufferTraits;
-using ::android::frameworks::bufferhub::V1_0::IBufferClient;
-using ::android::frameworks::bufferhub::V1_0::IBufferHub;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::graphics::common::V1_2::HardwareBufferDescription;
-
-namespace android {
-
-std::unique_ptr<BufferHubBuffer> BufferHubBuffer::create(uint32_t width, uint32_t height,
-                                                         uint32_t layerCount, uint32_t format,
-                                                         uint64_t usage, size_t userMetadataSize) {
-    auto buffer = std::unique_ptr<BufferHubBuffer>(
-            new BufferHubBuffer(width, height, layerCount, format, usage, userMetadataSize));
-    return buffer->isValid() ? std::move(buffer) : nullptr;
-}
-
-std::unique_ptr<BufferHubBuffer> BufferHubBuffer::import(const sp<NativeHandle>& token) {
-    if (token == nullptr || token.get() == nullptr) {
-        ALOGE("%s: token cannot be nullptr!", __FUNCTION__);
-        return nullptr;
-    }
-
-    auto buffer = std::unique_ptr<BufferHubBuffer>(new BufferHubBuffer(token));
-    return buffer->isValid() ? std::move(buffer) : nullptr;
-}
-
-BufferHubBuffer::BufferHubBuffer(uint32_t width, uint32_t height, uint32_t layerCount,
-                                 uint32_t format, uint64_t usage, size_t userMetadataSize) {
-    ATRACE_CALL();
-    ALOGD("%s: width=%u height=%u layerCount=%u, format=%u "
-          "usage=%" PRIx64 " mUserMetadataSize=%zu",
-          __FUNCTION__, width, height, layerCount, format, usage, userMetadataSize);
-
-    sp<IBufferHub> bufferhub = IBufferHub::getService();
-    if (bufferhub.get() == nullptr) {
-        ALOGE("%s: BufferHub service not found!", __FUNCTION__);
-        return;
-    }
-
-    AHardwareBuffer_Desc aDesc = {width, height,         layerCount,   format,
-                                  usage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
-    HardwareBufferDescription desc;
-    memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));
-
-    BufferHubStatus ret;
-    sp<IBufferClient> client;
-    BufferTraits bufferTraits;
-    IBufferHub::allocateBuffer_cb allocCb = [&](const auto& status, const auto& outClient,
-                                                const auto& outTraits) {
-        ret = status;
-        client = std::move(outClient);
-        bufferTraits = std::move(outTraits);
-    };
-
-    if (!bufferhub->allocateBuffer(desc, static_cast<uint32_t>(userMetadataSize), allocCb).isOk()) {
-        ALOGE("%s: allocateBuffer transaction failed!", __FUNCTION__);
-        return;
-    } else if (ret != BufferHubStatus::NO_ERROR) {
-        ALOGE("%s: allocateBuffer failed with error %u.", __FUNCTION__, ret);
-        return;
-    } else if (client == nullptr) {
-        ALOGE("%s: allocateBuffer got null BufferClient.", __FUNCTION__);
-        return;
-    }
-
-    const int importRet = initWithBufferTraits(bufferTraits);
-    if (importRet < 0) {
-        ALOGE("%s: Failed to import buffer: %s", __FUNCTION__, strerror(-importRet));
-        client->close();
-    }
-    mBufferClient = std::move(client);
-}
-
-BufferHubBuffer::BufferHubBuffer(const sp<NativeHandle>& token) {
-    sp<IBufferHub> bufferhub = IBufferHub::getService();
-    if (bufferhub.get() == nullptr) {
-        ALOGE("%s: BufferHub service not found!", __FUNCTION__);
-        return;
-    }
-
-    BufferHubStatus ret;
-    sp<IBufferClient> client;
-    BufferTraits bufferTraits;
-    IBufferHub::importBuffer_cb importCb = [&](const auto& status, const auto& outClient,
-                                               const auto& outTraits) {
-        ret = status;
-        client = std::move(outClient);
-        bufferTraits = std::move(outTraits);
-    };
-
-    // hidl_handle(native_handle_t*) simply creates a raw pointer reference withouth ownership
-    // transfer.
-    if (!bufferhub->importBuffer(hidl_handle(token.get()->handle()), importCb).isOk()) {
-        ALOGE("%s: importBuffer transaction failed!", __FUNCTION__);
-        return;
-    } else if (ret != BufferHubStatus::NO_ERROR) {
-        ALOGE("%s: importBuffer failed with error %u.", __FUNCTION__, ret);
-        return;
-    } else if (client == nullptr) {
-        ALOGE("%s: importBuffer got null BufferClient.", __FUNCTION__);
-        return;
-    }
-
-    const int importRet = initWithBufferTraits(bufferTraits);
-    if (importRet < 0) {
-        ALOGE("%s: Failed to import buffer: %s", __FUNCTION__, strerror(-importRet));
-        client->close();
-    }
-    mBufferClient = std::move(client);
-}
-
-BufferHubBuffer::~BufferHubBuffer() {
-    // Close buffer client to avoid possible race condition: user could first duplicate and hold
-    // token with the original buffer gone, and then try to import the token. The close function
-    // will explicitly invalidate the token to avoid this.
-    if (mBufferClient != nullptr) {
-        if (!mBufferClient->close().isOk()) {
-            ALOGE("%s: close BufferClient transaction failed!", __FUNCTION__);
-        }
-    }
-}
-
-int BufferHubBuffer::initWithBufferTraits(const BufferTraits& bufferTraits) {
-    ATRACE_CALL();
-
-    if (bufferTraits.bufferInfo.getNativeHandle() == nullptr) {
-        ALOGE("%s: missing buffer info handle.", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    if (bufferTraits.bufferHandle.getNativeHandle() == nullptr) {
-        ALOGE("%s: missing gralloc handle.", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    // Import fds. Dup fds because hidl_handle owns the fds.
-    unique_fd ashmemFd(fcntl(bufferTraits.bufferInfo->data[0], F_DUPFD_CLOEXEC, 0));
-    mMetadata = BufferHubMetadata::import(std::move(ashmemFd));
-    if (!mMetadata.isValid()) {
-        ALOGE("%s: Received an invalid metadata.", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    mEventFd = BufferHubEventFd(fcntl(bufferTraits.bufferInfo->data[1], F_DUPFD_CLOEXEC, 0));
-    if (!mEventFd.isValid()) {
-        ALOGE("%s: Received ad invalid event fd.", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    int bufferId = bufferTraits.bufferInfo->data[2];
-    if (bufferId < 0) {
-        ALOGE("%s: Received an invalid (negative) id.", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    uint32_t clientBitMask;
-    memcpy(&clientBitMask, &bufferTraits.bufferInfo->data[3], sizeof(clientBitMask));
-    if (clientBitMask == 0U) {
-        ALOGE("%s: Received an invalid client state mask.", __FUNCTION__);
-        return -EINVAL;
-    }
-
-    uint32_t userMetadataSize;
-    memcpy(&userMetadataSize, &bufferTraits.bufferInfo->data[4], sizeof(userMetadataSize));
-    if (mMetadata.userMetadataSize() != userMetadataSize) {
-        ALOGE("%s: user metadata size not match: expected %u, actual %zu.", __FUNCTION__,
-              userMetadataSize, mMetadata.userMetadataSize());
-        return -EINVAL;
-    }
-
-    size_t metadataSize = static_cast<size_t>(mMetadata.metadataSize());
-    if (metadataSize < BufferHubDefs::kMetadataHeaderSize) {
-        ALOGE("%s: metadata too small: %zu", __FUNCTION__, metadataSize);
-        return -EINVAL;
-    }
-
-    // Populate shortcuts to the atomics in metadata.
-    auto metadataHeader = mMetadata.metadataHeader();
-    mBufferState = &metadataHeader->bufferState;
-    mFenceState = &metadataHeader->fenceState;
-    mActiveClientsBitMask = &metadataHeader->activeClientsBitMask;
-    // The C++ standard recommends (but does not require) that lock-free atomic operations are
-    // also address-free, that is, suitable for communication between processes using shared
-    // memory.
-    LOG_ALWAYS_FATAL_IF(!std::atomic_is_lock_free(mBufferState) ||
-                                !std::atomic_is_lock_free(mFenceState) ||
-                                !std::atomic_is_lock_free(mActiveClientsBitMask),
-                        "Atomic variables in ashmen are not lock free.");
-
-    // Import the buffer: We only need to hold on the native_handle_t here so that
-    // GraphicBuffer instance can be created in future.
-    mBufferHandle = std::move(bufferTraits.bufferHandle);
-    memcpy(&mBufferDesc, &bufferTraits.bufferDesc, sizeof(AHardwareBuffer_Desc));
-
-    mId = bufferId;
-    mClientStateMask = clientBitMask;
-
-    // TODO(b/112012161) Set up shared fences.
-    ALOGD("%s: id=%d, mBufferState=%" PRIx32 ".", __FUNCTION__, mId,
-          mBufferState->load(std::memory_order_acquire));
-    return 0;
-}
-
-int BufferHubBuffer::gain() {
-    uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire);
-    if (isClientGained(currentBufferState, mClientStateMask)) {
-        ALOGV("%s: Buffer is already gained by this client %" PRIx32 ".", __FUNCTION__,
-              mClientStateMask);
-        return 0;
-    }
-    do {
-        if (isAnyClientGained(currentBufferState & (~mClientStateMask)) ||
-            isAnyClientAcquired(currentBufferState)) {
-            ALOGE("%s: Buffer is in use, id=%d mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
-                  __FUNCTION__, mId, mClientStateMask, currentBufferState);
-            return -EBUSY;
-        }
-        // Change the buffer state to gained state, whose value happens to be the same as
-        // mClientStateMask.
-    } while (!mBufferState->compare_exchange_weak(currentBufferState, mClientStateMask,
-                                                  std::memory_order_acq_rel,
-                                                  std::memory_order_acquire));
-    // TODO(b/119837586): Update fence state and return GPU fence.
-    return 0;
-}
-
-int BufferHubBuffer::post() {
-    uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire);
-    uint32_t updatedBufferState = (~mClientStateMask) & BufferHubDefs::kHighBitsMask;
-    do {
-        if (!isClientGained(currentBufferState, mClientStateMask)) {
-            ALOGE("%s: Cannot post a buffer that is not gained by this client. buffer_id=%d "
-                  "mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
-                  __FUNCTION__, mId, mClientStateMask, currentBufferState);
-            return -EBUSY;
-        }
-        // Set the producer client buffer state to released, other clients' buffer state to posted.
-        // Post to all existing and non-existing clients.
-    } while (!mBufferState->compare_exchange_weak(currentBufferState, updatedBufferState,
-                                                  std::memory_order_acq_rel,
-                                                  std::memory_order_acquire));
-    // TODO(b/119837586): Update fence state and return GPU fence if needed.
-    return 0;
-}
-
-int BufferHubBuffer::acquire() {
-    uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire);
-    if (isClientAcquired(currentBufferState, mClientStateMask)) {
-        ALOGV("%s: Buffer is already acquired by this client %" PRIx32 ".", __FUNCTION__,
-              mClientStateMask);
-        return 0;
-    }
-    uint32_t updatedBufferState = 0U;
-    do {
-        if (!isClientPosted(currentBufferState, mClientStateMask)) {
-            ALOGE("%s: Cannot acquire a buffer that is not in posted state. buffer_id=%d "
-                  "mClientStateMask=%" PRIx32 " state=%" PRIx32 ".",
-                  __FUNCTION__, mId, mClientStateMask, currentBufferState);
-            return -EBUSY;
-        }
-        // Change the buffer state for this consumer from posted to acquired.
-        updatedBufferState = currentBufferState ^ mClientStateMask;
-    } while (!mBufferState->compare_exchange_weak(currentBufferState, updatedBufferState,
-                                                  std::memory_order_acq_rel,
-                                                  std::memory_order_acquire));
-    // TODO(b/119837586): Update fence state and return GPU fence.
-    return 0;
-}
-
-int BufferHubBuffer::release() {
-    uint32_t currentBufferState = mBufferState->load(std::memory_order_acquire);
-    if (isClientReleased(currentBufferState, mClientStateMask)) {
-        ALOGV("%s: Buffer is already released by this client %" PRIx32 ".", __FUNCTION__,
-              mClientStateMask);
-        return 0;
-    }
-    uint32_t updatedBufferState = 0U;
-    do {
-        updatedBufferState = currentBufferState & (~mClientStateMask);
-    } while (!mBufferState->compare_exchange_weak(currentBufferState, updatedBufferState,
-                                                  std::memory_order_acq_rel,
-                                                  std::memory_order_acquire));
-    // TODO(b/119837586): Update fence state and return GPU fence if needed.
-    return 0;
-}
-
-bool BufferHubBuffer::isReleased() const {
-    return (mBufferState->load(std::memory_order_acquire) &
-            mActiveClientsBitMask->load(std::memory_order_acquire)) == 0;
-}
-
-bool BufferHubBuffer::isValid() const {
-    return mBufferHandle.getNativeHandle() != nullptr && mId >= 0 && mClientStateMask != 0U &&
-            mEventFd.get() >= 0 && mMetadata.isValid() && mBufferClient != nullptr;
-}
-
-sp<NativeHandle> BufferHubBuffer::duplicate() {
-    if (mBufferClient == nullptr) {
-        ALOGE("%s: missing BufferClient!", __FUNCTION__);
-        return nullptr;
-    }
-
-    hidl_handle token;
-    BufferHubStatus ret;
-    IBufferClient::duplicate_cb dupCb = [&](const auto& outToken, const auto& status) {
-        token = std::move(outToken);
-        ret = status;
-    };
-
-    if (!mBufferClient->duplicate(dupCb).isOk()) {
-        ALOGE("%s: duplicate transaction failed!", __FUNCTION__);
-        return nullptr;
-    } else if (ret != BufferHubStatus::NO_ERROR) {
-        ALOGE("%s: duplicate failed with error %u.", __FUNCTION__, ret);
-        return nullptr;
-    } else if (token.getNativeHandle() == nullptr) {
-        ALOGE("%s: duplicate got null token.", __FUNCTION__);
-        return nullptr;
-    }
-
-    return NativeHandle::create(native_handle_clone(token.getNativeHandle()), /*ownsHandle=*/true);
-}
-
-} // namespace android
diff --git a/libs/ui/BufferHubEventFd.cpp b/libs/ui/BufferHubEventFd.cpp
deleted file mode 100644
index bffc2ca..0000000
--- a/libs/ui/BufferHubEventFd.cpp
+++ /dev/null
@@ -1,49 +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.
- */
-
-#include <sys/eventfd.h>
-
-#include <log/log.h>
-#include <ui/BufferHubEventFd.h>
-
-namespace android {
-
-BufferHubEventFd::BufferHubEventFd() : mFd(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)) {}
-
-BufferHubEventFd::BufferHubEventFd(int fd) : mFd(fd) {}
-
-status_t BufferHubEventFd::signal() const {
-    if (!isValid()) {
-        ALOGE("%s: cannot signal an invalid eventfd.", __FUNCTION__);
-        return DEAD_OBJECT;
-    }
-
-    eventfd_write(mFd.get(), 1);
-    return OK;
-}
-
-status_t BufferHubEventFd::clear() const {
-    if (!isValid()) {
-        ALOGE("%s: cannot clear an invalid eventfd.", __FUNCTION__);
-        return DEAD_OBJECT;
-    }
-
-    eventfd_t value;
-    eventfd_read(mFd.get(), &value);
-    return OK;
-}
-
-} // namespace android
diff --git a/libs/ui/BufferHubMetadata.cpp b/libs/ui/BufferHubMetadata.cpp
deleted file mode 100644
index 05bc7dd..0000000
--- a/libs/ui/BufferHubMetadata.cpp
+++ /dev/null
@@ -1,104 +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.
- */
-
-#include <errno.h>
-#include <sys/mman.h>
-#include <limits>
-
-#include <cutils/ashmem.h>
-#include <log/log.h>
-#include <ui/BufferHubMetadata.h>
-
-namespace android {
-
-namespace {
-
-static const int kAshmemProt = PROT_READ | PROT_WRITE;
-
-} // namespace
-
-using BufferHubDefs::kMetadataHeaderSize;
-using BufferHubDefs::MetadataHeader;
-
-/* static */
-BufferHubMetadata BufferHubMetadata::create(size_t userMetadataSize) {
-    // The size the of metadata buffer is used as the "width" parameter during allocation. Thus it
-    // cannot overflow uint32_t.
-    if (userMetadataSize >= (std::numeric_limits<uint32_t>::max() - kMetadataHeaderSize)) {
-        ALOGE("BufferHubMetadata::Create: metadata size too big: %zu.", userMetadataSize);
-        return {};
-    }
-
-    const size_t metadataSize = userMetadataSize + kMetadataHeaderSize;
-    int fd = ashmem_create_region(/*name=*/"BufferHubMetadata", metadataSize);
-    if (fd < 0) {
-        ALOGE("BufferHubMetadata::Create: failed to create ashmem region.");
-        return {};
-    }
-
-    // Hand over the ownership of the fd to a unique_fd immediately after the successful
-    // return of ashmem_create_region. The ashmemFd is going to own the fd and to prevent fd
-    // leaks during error handling.
-    unique_fd ashmemFd{fd};
-
-    if (ashmem_set_prot_region(ashmemFd.get(), kAshmemProt) != 0) {
-        ALOGE("BufferHubMetadata::Create: failed to set protect region.");
-        return {};
-    }
-
-    return BufferHubMetadata::import(std::move(ashmemFd));
-}
-
-/* static */
-BufferHubMetadata BufferHubMetadata::import(unique_fd ashmemFd) {
-    if (!ashmem_valid(ashmemFd.get())) {
-        ALOGE("BufferHubMetadata::Import: invalid ashmem fd.");
-        return {};
-    }
-
-    size_t metadataSize = static_cast<size_t>(ashmem_get_size_region(ashmemFd.get()));
-    size_t userMetadataSize = metadataSize - kMetadataHeaderSize;
-
-    // Note that here the buffer state is mapped from shared memory as an atomic object. The
-    // std::atomic's constructor will not be called so that the original value stored in the memory
-    // region can be preserved.
-    auto metadataHeader = static_cast<MetadataHeader*>(mmap(nullptr, metadataSize, kAshmemProt,
-                                                            MAP_SHARED, ashmemFd.get(),
-                                                            /*offset=*/0));
-    if (metadataHeader == nullptr) {
-        ALOGE("BufferHubMetadata::Import: failed to map region.");
-        return {};
-    }
-
-    return BufferHubMetadata(userMetadataSize, std::move(ashmemFd), metadataHeader);
-}
-
-BufferHubMetadata::BufferHubMetadata(size_t userMetadataSize, unique_fd ashmemFd,
-                                     MetadataHeader* metadataHeader)
-      : mUserMetadataSize(userMetadataSize),
-        mAshmemFd(std::move(ashmemFd)),
-        mMetadataHeader(metadataHeader) {}
-
-BufferHubMetadata::~BufferHubMetadata() {
-    if (mMetadataHeader != nullptr) {
-        int ret = munmap(mMetadataHeader, metadataSize());
-        ALOGE_IF(ret != 0,
-                 "BufferHubMetadata::~BufferHubMetadata: failed to unmap ashmem, error=%d.", errno);
-        mMetadataHeader = nullptr;
-    }
-}
-
-} // namespace android
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index d8e4059..f799ce4 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -203,7 +203,7 @@
     std::vector<ui::PlaneLayout> planeLayouts;
     status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
 
-    if (err != NO_ERROR && !planeLayouts.empty()) {
+    if (err == NO_ERROR && !planeLayouts.empty()) {
         if (outBytesPerPixel) {
             int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
             for (const auto& planeLayout : planeLayouts) {
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 05fc590..3732fee 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -23,10 +23,6 @@
 
 #include <grallocusage/GrallocUsageConversion.h>
 
-#ifndef LIBUI_IN_VNDK
-#include <ui/BufferHubBuffer.h>
-#endif // LIBUI_IN_VNDK
-
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/GraphicBufferMapper.h>
 #include <utils/Trace.h>
@@ -110,22 +106,6 @@
                                 inUsage, inStride);
 }
 
-#ifndef LIBUI_IN_VNDK
-GraphicBuffer::GraphicBuffer(std::unique_ptr<BufferHubBuffer> buffer) : GraphicBuffer() {
-    if (buffer == nullptr) {
-        mInitCheck = BAD_VALUE;
-        return;
-    }
-
-    mInitCheck = initWithHandle(buffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE,
-                                buffer->desc().width, buffer->desc().height,
-                                static_cast<PixelFormat>(buffer->desc().format),
-                                buffer->desc().layers, buffer->desc().usage, buffer->desc().stride);
-    mBufferId = buffer->id();
-    mBufferHubBuffer = std::move(buffer);
-}
-#endif // LIBUI_IN_VNDK
-
 GraphicBuffer::~GraphicBuffer()
 {
     ATRACE_CALL();
@@ -374,29 +354,14 @@
 }
 
 size_t GraphicBuffer::getFlattenedSize() const {
-#ifndef LIBUI_IN_VNDK
-    if (mBufferHubBuffer != nullptr) {
-        return 48;
-    }
-#endif
     return static_cast<size_t>(13 + (handle ? mTransportNumInts : 0)) * sizeof(int);
 }
 
 size_t GraphicBuffer::getFdCount() const {
-#ifndef LIBUI_IN_VNDK
-    if (mBufferHubBuffer != nullptr) {
-        return 0;
-    }
-#endif
     return static_cast<size_t>(handle ? mTransportNumFds : 0);
 }
 
 status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const {
-#ifndef LIBUI_IN_VNDK
-    if (mBufferHubBuffer != nullptr) {
-        return flattenBufferHubBuffer(buffer, size);
-    }
-#endif
     size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
     if (size < sizeNeeded) return NO_MEMORY;
 
@@ -453,12 +418,6 @@
     } else if (buf[0] == 'GBFR') {
         // old version, when usage bits were 32-bits
         flattenWordCount = 12;
-    } else if (buf[0] == 'BHBB') { // BufferHub backed buffer.
-#ifndef LIBUI_IN_VNDK
-        return unflattenBufferHubBuffer(buffer, size);
-#else
-        return BAD_TYPE;
-#endif
     } else {
         return BAD_TYPE;
     }
@@ -565,76 +524,6 @@
     mDeathCallbacks.emplace_back(deathCallback, context);
 }
 
-#ifndef LIBUI_IN_VNDK
-status_t GraphicBuffer::flattenBufferHubBuffer(void*& buffer, size_t& size) const {
-    sp<NativeHandle> tokenHandle = mBufferHubBuffer->duplicate();
-    if (tokenHandle == nullptr || tokenHandle->handle() == nullptr ||
-        tokenHandle->handle()->numFds != 0) {
-        return BAD_VALUE;
-    }
-
-    // Size needed for one label, one number of ints inside the token, one generation number and
-    // the token itself.
-    int numIntsInToken = tokenHandle->handle()->numInts;
-    const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int);
-    if (size < sizeNeeded) {
-        ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__,
-              static_cast<int>(sizeNeeded), static_cast<int>(size));
-        return NO_MEMORY;
-    }
-    size -= sizeNeeded;
-
-    int* buf = static_cast<int*>(buffer);
-    buf[0] = 'BHBB';
-    buf[1] = numIntsInToken;
-    memcpy(buf + 2, tokenHandle->handle()->data, static_cast<size_t>(numIntsInToken) * sizeof(int));
-    buf[2 + numIntsInToken] = static_cast<int32_t>(mGenerationNumber);
-
-    return NO_ERROR;
-}
-
-status_t GraphicBuffer::unflattenBufferHubBuffer(void const*& buffer, size_t& size) {
-    const int* buf = static_cast<const int*>(buffer);
-    int numIntsInToken = buf[1];
-    // Size needed for one label, one number of ints inside the token, one generation number and
-    // the token itself.
-    const size_t sizeNeeded = static_cast<size_t>(3 + numIntsInToken) * sizeof(int);
-    if (size < sizeNeeded) {
-        ALOGE("%s: needed size %d, given size %d. Not enough memory.", __FUNCTION__,
-              static_cast<int>(sizeNeeded), static_cast<int>(size));
-        return NO_MEMORY;
-    }
-    size -= sizeNeeded;
-    native_handle_t* importToken = native_handle_create(/*numFds=*/0, /*numInts=*/numIntsInToken);
-    memcpy(importToken->data, buf + 2, static_cast<size_t>(buf[1]) * sizeof(int));
-    sp<NativeHandle> importTokenHandle = NativeHandle::create(importToken, /*ownHandle=*/true);
-    std::unique_ptr<BufferHubBuffer> bufferHubBuffer = BufferHubBuffer::import(importTokenHandle);
-    if (bufferHubBuffer == nullptr || bufferHubBuffer.get() == nullptr) {
-        return BAD_VALUE;
-    }
-    // Reconstruct this GraphicBuffer object using the new BufferHubBuffer object.
-    if (handle) {
-        free_handle();
-    }
-    mId = 0;
-    mGenerationNumber = static_cast<uint32_t>(buf[2 + numIntsInToken]);
-    mInitCheck =
-            initWithHandle(bufferHubBuffer->duplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE,
-                           bufferHubBuffer->desc().width, bufferHubBuffer->desc().height,
-                           static_cast<PixelFormat>(bufferHubBuffer->desc().format),
-                           bufferHubBuffer->desc().layers, bufferHubBuffer->desc().usage,
-                           bufferHubBuffer->desc().stride);
-    mBufferId = bufferHubBuffer->id();
-    mBufferHubBuffer = std::move(bufferHubBuffer);
-
-    return NO_ERROR;
-}
-
-bool GraphicBuffer::isBufferHubBuffer() const {
-    return mBufferHubBuffer != nullptr;
-}
-#endif // LIBUI_IN_VNDK
-
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/libs/ui/include/ui/BufferHubBuffer.h b/libs/ui/include/ui/BufferHubBuffer.h
deleted file mode 100644
index 5ba189c..0000000
--- a/libs/ui/include/ui/BufferHubBuffer.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_BUFFER_HUB_BUFFER_H_
-#define ANDROID_BUFFER_HUB_BUFFER_H_
-
-#include <android/frameworks/bufferhub/1.0/IBufferClient.h>
-#include <android/hardware_buffer.h>
-#include <cutils/native_handle.h>
-#include <ui/BufferHubDefs.h>
-#include <ui/BufferHubEventFd.h>
-#include <ui/BufferHubMetadata.h>
-#include <utils/NativeHandle.h>
-
-namespace android {
-
-class BufferHubBuffer {
-public:
-    // Allocates a standalone BufferHubBuffer.
-    static std::unique_ptr<BufferHubBuffer> create(uint32_t width, uint32_t height,
-                                                   uint32_t layerCount, uint32_t format,
-                                                   uint64_t usage, size_t userMetadataSize);
-
-    // Imports the given token to a BufferHubBuffer. Not taking ownership of the token.
-    static std::unique_ptr<BufferHubBuffer> import(const sp<NativeHandle>& token);
-
-    BufferHubBuffer(const BufferHubBuffer&) = delete;
-    void operator=(const BufferHubBuffer&) = delete;
-
-    virtual ~BufferHubBuffer();
-
-    // Gets ID of the buffer client. All BufferHubBuffer clients derived from the same buffer in
-    // BufferHub share the same buffer id.
-    int id() const { return mId; }
-
-    // Returns the buffer description, which is guaranteed to be faithful values from BufferHub.
-    const AHardwareBuffer_Desc& desc() const { return mBufferDesc; }
-
-    // Duplicate the underlying Gralloc buffer handle. Caller is responsible to free the handle
-    // after use.
-    native_handle_t* duplicateHandle() {
-        return native_handle_clone(mBufferHandle.getNativeHandle());
-    }
-
-    const BufferHubEventFd& eventFd() const { return mEventFd; }
-
-    // Returns the current value of MetadataHeader::bufferState.
-    uint32_t bufferState() const { return mBufferState->load(std::memory_order_acquire); }
-
-    // A state mask which is unique to a buffer hub client among all its siblings sharing the same
-    // concrete graphic buffer.
-    uint32_t clientStateMask() const { return mClientStateMask; }
-
-    size_t userMetadataSize() const { return mMetadata.userMetadataSize(); }
-
-    // Returns true if the BufferClient is still alive.
-    bool isConnected() const { return mBufferClient->ping().isOk(); }
-
-    // Returns true if the buffer is valid: non-null buffer handle, valid id, valid client bit mask,
-    // valid metadata and valid buffer client
-    bool isValid() const;
-
-    // Gains the buffer for exclusive write permission. Read permission is implied once a buffer is
-    // gained.
-    // The buffer can be gained as long as there is no other client in acquired or gained state.
-    int gain();
-
-    // Posts the gained buffer for other buffer clients to use the buffer.
-    // The buffer can be posted iff the buffer state for this client is gained.
-    // After posting the buffer, this client is put to released state and does not have access to
-    // the buffer for this cycle of the usage of the buffer.
-    int post();
-
-    // Acquires the buffer for shared read permission.
-    // The buffer can be acquired iff the buffer state for this client is posted.
-    int acquire();
-
-    // Releases the buffer.
-    // The buffer can be released from any buffer state.
-    // After releasing the buffer, this client no longer have any permissions to the buffer for the
-    // current cycle of the usage of the buffer.
-    int release();
-
-    // Returns whether the buffer is released by all active clients or not.
-    bool isReleased() const;
-
-    // Creates a token that stands for this BufferHubBuffer client and could be used for Import to
-    // create another BufferHubBuffer. The new BufferHubBuffer will share the same underlying
-    // gralloc buffer and ashmem region for metadata. Not taking ownership of the token.
-    // Returns a valid token on success, nullptr on failure.
-    sp<NativeHandle> duplicate();
-
-private:
-    BufferHubBuffer(uint32_t width, uint32_t height, uint32_t layerCount, uint32_t format,
-                    uint64_t usage, size_t userMetadataSize);
-
-    BufferHubBuffer(const sp<NativeHandle>& token);
-
-    int initWithBufferTraits(const frameworks::bufferhub::V1_0::BufferTraits& bufferTraits);
-
-    // Global id for the buffer that is consistent across processes.
-    int mId = 0;
-
-    // Client state mask of this BufferHubBuffer object. It is unique amoung all
-    // clients/users of the buffer.
-    uint32_t mClientStateMask = 0U;
-
-    // Stores ground truth of the buffer.
-    AHardwareBuffer_Desc mBufferDesc;
-
-    // Wraps the gralloc buffer handle of this buffer.
-    hardware::hidl_handle mBufferHandle;
-
-    // Event fd used for signalling buffer state changes. Shared by all clients of the same buffer.
-    BufferHubEventFd mEventFd;
-
-    // An ashmem-based metadata object. The same shared memory are mapped to the
-    // bufferhubd daemon and all buffer clients.
-    BufferHubMetadata mMetadata;
-    // Shortcuts to the atomics inside the header of mMetadata.
-    std::atomic<uint32_t>* mBufferState = nullptr;
-    std::atomic<uint32_t>* mFenceState = nullptr;
-    std::atomic<uint32_t>* mActiveClientsBitMask = nullptr;
-
-    // HwBinder backend
-    sp<frameworks::bufferhub::V1_0::IBufferClient> mBufferClient;
-};
-
-} // namespace android
-
-#endif // ANDROID_BUFFER_HUB_BUFFER_H_
diff --git a/libs/ui/include/ui/BufferHubEventFd.h b/libs/ui/include/ui/BufferHubEventFd.h
deleted file mode 100644
index 8772304..0000000
--- a/libs/ui/include/ui/BufferHubEventFd.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_BUFFER_HUB_EVENT_FD_H_
-#define ANDROID_BUFFER_HUB_EVENT_FD_H_
-
-#include <android-base/unique_fd.h>
-#include <utils/Errors.h>
-
-namespace android {
-
-class BufferHubEventFd {
-public:
-    /**
-     * Constructs a valid event fd.
-     */
-    BufferHubEventFd();
-
-    /**
-     * Constructs from a valid event fd. Caller is responsible for the validity of the fd. Takes
-     * ownership.
-     */
-    BufferHubEventFd(int fd);
-
-    /**
-     * Returns whether this BufferHubEventFd holds a valid event_fd.
-     */
-    bool isValid() const { return get() >= 0; }
-
-    /**
-     * Returns the fd number of the BufferHubEventFd object. Note that there is no ownership
-     * transfer.
-     */
-    int get() const { return mFd.get(); }
-
-    /**
-     * Signals the eventfd.
-     */
-    status_t signal() const;
-
-    /**
-     * Clears the signal from this eventfd if it is signaled.
-     */
-    status_t clear() const;
-
-private:
-    base::unique_fd mFd;
-};
-
-} // namespace android
-
-#endif // ANDROID_BUFFER_HUB_EVENT_FD_H_
diff --git a/libs/ui/include/ui/BufferHubMetadata.h b/libs/ui/include/ui/BufferHubMetadata.h
deleted file mode 100644
index 3482507..0000000
--- a/libs/ui/include/ui/BufferHubMetadata.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_BUFFER_HUB_METADATA_H_
-#define ANDROID_BUFFER_HUB_METADATA_H_
-
-#include <android-base/unique_fd.h>
-#include <ui/BufferHubDefs.h>
-
-namespace android {
-
-namespace {
-using base::unique_fd;
-} // namespace
-
-class BufferHubMetadata {
-public:
-    // Creates a new BufferHubMetadata backed by an ashmem region.
-    //
-    // @param userMetadataSize Size in bytes of the user defined metadata. The entire metadata
-    //        shared memory region to be allocated is the size of canonical
-    //        BufferHubDefs::MetadataHeader plus userMetadataSize.
-    static BufferHubMetadata create(size_t userMetadataSize);
-
-    // Imports an existing BufferHubMetadata from an ashmem FD.
-    //
-    // @param ashmemFd Ashmem file descriptor representing an ashmem region.
-    static BufferHubMetadata import(unique_fd ashmemFd);
-
-    BufferHubMetadata() = default;
-
-    BufferHubMetadata(BufferHubMetadata&& other) { *this = std::move(other); }
-
-    ~BufferHubMetadata();
-
-    BufferHubMetadata& operator=(BufferHubMetadata&& other) {
-        if (this != &other) {
-            mUserMetadataSize = other.mUserMetadataSize;
-            other.mUserMetadataSize = 0;
-
-            mAshmemFd = std::move(other.mAshmemFd);
-
-            // The old raw mMetadataHeader pointer must be cleared, otherwise the destructor will
-            // automatically mummap() the shared memory.
-            mMetadataHeader = other.mMetadataHeader;
-            other.mMetadataHeader = nullptr;
-        }
-        return *this;
-    }
-
-    // Returns true if the metadata is valid, i.e. the metadata has a valid ashmem fd and the ashmem
-    // has been mapped into virtual address space.
-    bool isValid() const { return mAshmemFd.get() != -1 && mMetadataHeader != nullptr; }
-
-    size_t userMetadataSize() const { return mUserMetadataSize; }
-    size_t metadataSize() const { return mUserMetadataSize + BufferHubDefs::kMetadataHeaderSize; }
-
-    const unique_fd& ashmemFd() const { return mAshmemFd; }
-    BufferHubDefs::MetadataHeader* metadataHeader() { return mMetadataHeader; }
-
-private:
-    BufferHubMetadata(size_t userMetadataSize, unique_fd ashmemFd,
-                      BufferHubDefs::MetadataHeader* metadataHeader);
-
-    BufferHubMetadata(const BufferHubMetadata&) = delete;
-    void operator=(const BufferHubMetadata&) = delete;
-
-    size_t mUserMetadataSize = 0;
-    unique_fd mAshmemFd;
-    BufferHubDefs::MetadataHeader* mMetadataHeader = nullptr;
-};
-
-} // namespace android
-
-#endif // ANDROID_BUFFER_HUB_METADATA_H_
diff --git a/libs/ui/include/ui/DeviceProductInfo.h b/libs/ui/include/ui/DeviceProductInfo.h
index c396e73..af00342 100644
--- a/libs/ui/include/ui/DeviceProductInfo.h
+++ b/libs/ui/include/ui/DeviceProductInfo.h
@@ -31,6 +31,10 @@
 // product information about the intermediate device.
 struct DeviceProductInfo {
     static constexpr size_t TEXT_BUFFER_SIZE = 20;
+    static constexpr size_t RELATIVE_ADDRESS_SIZE = 4;
+
+    using RelativeAddress = std::array<uint8_t, RELATIVE_ADDRESS_SIZE>;
+    static constexpr RelativeAddress NO_RELATIVE_ADDRESS = {0xff, 0xff, 0xff, 0xff};
 
     struct ModelYear {
         uint32_t year;
@@ -54,6 +58,11 @@
 
     using ManufactureOrModelDate = std::variant<ModelYear, ManufactureYear, ManufactureWeekAndYear>;
     ManufactureOrModelDate manufactureOrModelDate;
+
+    // Relative address in the display network. Unavailable address is indicated
+    // by all elements equal to 255.
+    // For example, for HDMI connected device this will be the physical address.
+    RelativeAddress relativeAddress;
 };
 
 } // namespace android
diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h
index c195342..013505a 100644
--- a/libs/ui/include/ui/GraphicBuffer.h
+++ b/libs/ui/include/ui/GraphicBuffer.h
@@ -38,10 +38,6 @@
 
 namespace android {
 
-#ifndef LIBUI_IN_VNDK
-class BufferHubBuffer;
-#endif // LIBUI_IN_VNDK
-
 class GraphicBufferMapper;
 
 using GraphicBufferDeathCallback = std::function<void(void* /*context*/, uint64_t bufferId)>;
@@ -147,11 +143,6 @@
     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
             uint32_t inUsage, std::string requestorName = "<Unknown>");
 
-#ifndef LIBUI_IN_VNDK
-    // Create a GraphicBuffer from an existing BufferHubBuffer.
-    GraphicBuffer(std::unique_ptr<BufferHubBuffer> buffer);
-#endif // LIBUI_IN_VNDK
-
     // return status
     status_t initCheck() const;
 
@@ -163,7 +154,6 @@
     uint32_t getLayerCount() const      { return static_cast<uint32_t>(layerCount); }
     Rect getBounds() const              { return Rect(width, height); }
     uint64_t getId() const              { return mId; }
-    int32_t getBufferId() const { return mBufferId; }
 
     uint32_t getGenerationNumber() const { return mGenerationNumber; }
     void setGenerationNumber(uint32_t generation) {
@@ -225,11 +215,6 @@
 
     void addDeathCallback(GraphicBufferDeathCallback deathCallback, void* context);
 
-#ifndef LIBUI_IN_VNDK
-    // Returns whether this GraphicBuffer is backed by BufferHubBuffer.
-    bool isBufferHubBuffer() const;
-#endif // LIBUI_IN_VNDK
-
 private:
     ~GraphicBuffer();
 
@@ -275,12 +260,6 @@
 
     uint64_t mId;
 
-    // System unique buffer ID. Note that this is different from mId, which is process unique. For
-    // GraphicBuffer backed by BufferHub, the mBufferId is a system unique identifier that stays the
-    // same cross process for the same chunck of underlying memory. Also note that this only applies
-    // to GraphicBuffers that are backed by BufferHub.
-    int32_t mBufferId = -1;
-
     // Stores the generation number of this buffer. If this number does not
     // match the BufferQueue's internal generation number (set through
     // IGBP::setGenerationNumber), attempts to attach the buffer will fail.
@@ -299,22 +278,6 @@
     // and informs SurfaceFlinger that it should drop its strong pointer reference to the buffer.
     std::vector<std::pair<GraphicBufferDeathCallback, void* /*mDeathCallbackContext*/>>
             mDeathCallbacks;
-
-#ifndef LIBUI_IN_VNDK
-    // Flatten this GraphicBuffer object if backed by BufferHubBuffer.
-    status_t flattenBufferHubBuffer(void*& buffer, size_t& size) const;
-
-    // Unflatten into BufferHubBuffer backed GraphicBuffer.
-    // Unflatten will fail if the original GraphicBuffer object is destructed. For instance, a
-    // GraphicBuffer backed by BufferHubBuffer_1 flatten in process/thread A, transport the token
-    // to process/thread B through a socket, BufferHubBuffer_1 dies and bufferhub invalidated the
-    // token. Race condition occurs between the invalidation of the token in bufferhub process and
-    // process/thread B trying to unflatten and import the buffer with that token.
-    status_t unflattenBufferHubBuffer(void const*& buffer, size_t& size);
-
-    // Stores a BufferHubBuffer that handles buffer signaling, identification.
-    std::unique_ptr<BufferHubBuffer> mBufferHubBuffer;
-#endif // LIBUI_IN_VNDK
 };
 
 }; // namespace android
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index 605c5a9..b53342c 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -31,7 +31,6 @@
 cc_test {
     name: "GraphicBufferAllocator_test",
     header_libs: [
-        "libdvr_headers",
         "libnativewindow_headers",
     ],
     static_libs: [
@@ -52,11 +51,9 @@
 cc_test {
     name: "GraphicBuffer_test",
     header_libs: [
-        "libdvr_headers",
         "libnativewindow_headers",
     ],
     shared_libs: [
-        "android.frameworks.bufferhub@1.0",
         "libcutils",
         "libhidlbase",
         "libui",
@@ -71,11 +68,7 @@
     name: "GraphicBufferOverBinder_test",
     srcs: ["GraphicBufferOverBinder_test.cpp"],
     cflags: ["-Wall", "-Werror"],
-    header_libs: [
-        "libdvr_headers",
-    ],
     shared_libs: [
-        "android.frameworks.bufferhub@1.0",
         "libbinder",
         "libgui",
         "liblog",
@@ -85,31 +78,6 @@
 }
 
 cc_test {
-    name: "BufferHub_test",
-    header_libs: [
-        "libdvr_headers",
-        "libnativewindow_headers",
-    ],
-    static_libs: [
-        "libgmock",
-    ],
-    shared_libs: [
-        "android.frameworks.bufferhub@1.0",
-        "libcutils",
-        "libhidlbase",
-        "liblog",
-        "libui",
-        "libutils"
-    ],
-    srcs: [
-        "BufferHubBuffer_test.cpp",
-        "BufferHubEventFd_test.cpp",
-        "BufferHubMetadata_test.cpp",
-    ],
-    cflags: ["-Wall", "-Werror"],
-}
-
-cc_test {
     name: "Size_test",
     test_suites: ["device-tests"],
     shared_libs: ["libui"],
diff --git a/libs/ui/tests/BufferHubBuffer_test.cpp b/libs/ui/tests/BufferHubBuffer_test.cpp
deleted file mode 100644
index 0c73a72..0000000
--- a/libs/ui/tests/BufferHubBuffer_test.cpp
+++ /dev/null
@@ -1,477 +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.
- */
-
-#define LOG_TAG "BufferHubBufferTest"
-
-#include <errno.h>
-#include <sys/epoll.h>
-
-#include <android/frameworks/bufferhub/1.0/IBufferHub.h>
-#include <android/hardware_buffer.h>
-#include <cutils/native_handle.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <hidl/ServiceManagement.h>
-#include <hwbinder/IPCThreadState.h>
-#include <ui/BufferHubBuffer.h>
-#include <ui/BufferHubEventFd.h>
-
-namespace android {
-
-namespace {
-
-using ::android::BufferHubDefs::isAnyClientAcquired;
-using ::android::BufferHubDefs::isAnyClientGained;
-using ::android::BufferHubDefs::isAnyClientPosted;
-using ::android::BufferHubDefs::isClientAcquired;
-using ::android::BufferHubDefs::isClientGained;
-using ::android::BufferHubDefs::isClientPosted;
-using ::android::BufferHubDefs::isClientReleased;
-using ::android::BufferHubDefs::kMetadataHeaderSize;
-using ::android::frameworks::bufferhub::V1_0::IBufferHub;
-using ::testing::IsNull;
-using ::testing::NotNull;
-
-const int kWidth = 640;
-const int kHeight = 480;
-const int kLayerCount = 1;
-const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-const int kUsage = 0;
-const AHardwareBuffer_Desc kDesc = {kWidth, kHeight,        kLayerCount,  kFormat,
-                                    kUsage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
-const size_t kUserMetadataSize = 1;
-
-class BufferHubBufferTest : public ::testing::Test {
-protected:
-    void SetUp() override {
-        android::hardware::ProcessState::self()->startThreadPool();
-
-        if (!BufferHubServiceRunning()) {
-            // TODO(b/112940221): Enforce the test cross all devices once BufferHub lands in Android
-            // R for all Android varieties.
-            GTEST_SKIP() << "Skip test as the BufferHub service is not running.";
-        }
-    }
-
-    bool BufferHubServiceRunning() {
-        sp<IBufferHub> bufferhub = IBufferHub::getService();
-        return bufferhub.get() != nullptr;
-    }
-};
-
-bool cmpAHardwareBufferDesc(const AHardwareBuffer_Desc& desc, const AHardwareBuffer_Desc& other) {
-    // Not comparing stride because it's unknown before allocation
-    return desc.format == other.format && desc.height == other.height &&
-            desc.layers == other.layers && desc.usage == other.usage && desc.width == other.width;
-}
-
-class BufferHubBufferStateTransitionTest : public BufferHubBufferTest {
-protected:
-    void SetUp() override {
-        BufferHubBufferTest::SetUp();
-
-        if (IsSkipped()) {
-            // If the base class' SetUp() stated the test should be skipped, we should short
-            // circuit this sub-class' logic.
-            return;
-        }
-
-        CreateTwoClientsOfABuffer();
-    }
-
-    std::unique_ptr<BufferHubBuffer> b1;
-    uint32_t b1ClientMask = 0U;
-    std::unique_ptr<BufferHubBuffer> b2;
-    uint32_t b2ClientMask = 0U;
-
-private:
-    // Creates b1 and b2 as the clients of the same buffer for testing.
-    void CreateTwoClientsOfABuffer();
-};
-
-void BufferHubBufferStateTransitionTest::CreateTwoClientsOfABuffer() {
-    b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize);
-    ASSERT_THAT(b1, NotNull());
-    b1ClientMask = b1->clientStateMask();
-    ASSERT_NE(b1ClientMask, 0U);
-
-    sp<NativeHandle> token = b1->duplicate();
-    ASSERT_THAT(token, NotNull());
-
-    b2 = BufferHubBuffer::import(token);
-    ASSERT_THAT(b2, NotNull());
-
-    b2ClientMask = b2->clientStateMask();
-    ASSERT_NE(b2ClientMask, 0U);
-    ASSERT_NE(b2ClientMask, b1ClientMask);
-}
-
-TEST_F(BufferHubBufferTest, CreateBufferFails) {
-    // Buffer Creation will fail: BLOB format requires height to be 1.
-    auto b1 = BufferHubBuffer::create(kWidth, /*height=*/2, kLayerCount,
-                                      /*format=*/HAL_PIXEL_FORMAT_BLOB, kUsage, kUserMetadataSize);
-
-    EXPECT_THAT(b1, IsNull());
-
-    // Buffer Creation will fail: user metadata size too large.
-    auto b2 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
-                                      /*userMetadataSize=*/std::numeric_limits<size_t>::max());
-
-    EXPECT_THAT(b2, IsNull());
-
-    // Buffer Creation will fail: user metadata size too large.
-    const size_t userMetadataSize = std::numeric_limits<size_t>::max() - kMetadataHeaderSize;
-    auto b3 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
-                                      userMetadataSize);
-
-    EXPECT_THAT(b3, IsNull());
-}
-
-TEST_F(BufferHubBufferTest, CreateBuffer) {
-    auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
-                                      kUserMetadataSize);
-    ASSERT_THAT(b1, NotNull());
-    EXPECT_TRUE(b1->isConnected());
-    EXPECT_TRUE(b1->isValid());
-    EXPECT_TRUE(cmpAHardwareBufferDesc(b1->desc(), kDesc));
-    EXPECT_EQ(b1->userMetadataSize(), kUserMetadataSize);
-}
-
-TEST_F(BufferHubBufferTest, DuplicateAndImportBuffer) {
-    auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
-                                      kUserMetadataSize);
-    ASSERT_THAT(b1, NotNull());
-    EXPECT_TRUE(b1->isValid());
-
-    sp<NativeHandle> token = b1->duplicate();
-    ASSERT_THAT(token, NotNull());
-
-    // The detached buffer should still be valid.
-    EXPECT_TRUE(b1->isConnected());
-    EXPECT_TRUE(b1->isValid());
-
-    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
-
-    ASSERT_THAT(b2, NotNull());
-    EXPECT_TRUE(b2->isValid());
-
-    EXPECT_TRUE(cmpAHardwareBufferDesc(b1->desc(), b2->desc()));
-    EXPECT_EQ(b1->userMetadataSize(), b2->userMetadataSize());
-
-    // These two buffer instances are based on the same physical buffer under the
-    // hood, so they should share the same id.
-    EXPECT_EQ(b1->id(), b2->id());
-    // We use clientStateMask() to tell those two instances apart.
-    EXPECT_NE(b1->clientStateMask(), b2->clientStateMask());
-
-    // Both buffer instances should be in released state currently.
-    EXPECT_TRUE(b1->isReleased());
-    EXPECT_TRUE(b2->isReleased());
-
-    // The event fd should behave like duped event fds.
-    const BufferHubEventFd& eventFd1 = b1->eventFd();
-    ASSERT_GE(eventFd1.get(), 0);
-    const BufferHubEventFd& eventFd2 = b2->eventFd();
-    ASSERT_GE(eventFd2.get(), 0);
-
-    base::unique_fd epollFd(epoll_create(64));
-    ASSERT_GE(epollFd.get(), 0);
-
-    // Add eventFd1 to epoll set, and signal eventFd2.
-    epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd1.get(), &e), 0) << strerror(errno);
-
-    std::array<epoll_event, 1> events;
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-
-    eventFd2.signal();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-
-    // The epoll fd is edge triggered, so it only responds to the eventFd once.
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-
-    eventFd2.signal();
-    eventFd2.clear();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-}
-
-TEST_F(BufferHubBufferTest, ImportFreedBuffer) {
-    auto b1 = BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
-                                      kUserMetadataSize);
-    ASSERT_THAT(b1, NotNull());
-    EXPECT_TRUE(b1->isValid());
-
-    sp<NativeHandle> token = b1->duplicate();
-    ASSERT_THAT(token, NotNull());
-
-    // Explicitly destroy b1. Backend buffer should be freed and token becomes invalid
-    b1.reset();
-
-    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
-
-    // Import should fail with INVALID_TOKEN
-    EXPECT_THAT(b2, IsNull());
-}
-
-// nullptr must not crash the service
-TEST_F(BufferHubBufferTest, ImportNullToken) {
-    auto b1 = BufferHubBuffer::import(nullptr);
-    EXPECT_THAT(b1, IsNull());
-}
-
-TEST_F(BufferHubBufferTest, ImportInvalidToken) {
-    native_handle_t* token = native_handle_create(/*numFds=*/0, /*numInts=*/1);
-    token->data[0] = 0;
-
-    sp<NativeHandle> tokenHandle = NativeHandle::create(token, /*ownHandle=*/true);
-    auto b1 = BufferHubBuffer::import(tokenHandle);
-
-    EXPECT_THAT(b1, IsNull());
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromReleasedState) {
-    ASSERT_TRUE(b1->isReleased());
-
-    // Successful gaining the buffer should change the buffer state bit of b1 to
-    // gained state, other client state bits to released state.
-    EXPECT_EQ(b1->gain(), 0);
-    EXPECT_TRUE(isClientGained(b1->bufferState(), b1ClientMask));
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromGainedState) {
-    ASSERT_EQ(b1->gain(), 0);
-    auto currentBufferState = b1->bufferState();
-    ASSERT_TRUE(isClientGained(currentBufferState, b1ClientMask));
-
-    // Gaining from gained state by the same client should not return error.
-    EXPECT_EQ(b1->gain(), 0);
-
-    // Gaining from gained state by another client should return error.
-    EXPECT_EQ(b2->gain(), -EBUSY);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromAcquiredState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_EQ(b1->post(), 0);
-    ASSERT_EQ(b2->acquire(), 0);
-    ASSERT_TRUE(isAnyClientAcquired(b1->bufferState()));
-
-    // Gaining from acquired state should fail.
-    EXPECT_EQ(b1->gain(), -EBUSY);
-    EXPECT_EQ(b2->gain(), -EBUSY);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromOtherClientInPostedState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_EQ(b1->post(), 0);
-    ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
-
-    // Gaining a buffer who has other posted client should succeed.
-    EXPECT_EQ(b1->gain(), 0);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, GainBuffer_fromSelfInPostedState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_EQ(b1->post(), 0);
-    ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
-
-    // A posted client should be able to gain the buffer when there is no other clients in
-    // acquired state.
-    EXPECT_EQ(b2->gain(), 0);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromOtherInGainedState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_TRUE(isClientGained(b1->bufferState(), b1ClientMask));
-
-    EXPECT_EQ(b2->post(), -EBUSY);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromSelfInGainedState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_TRUE(isClientGained(b1->bufferState(), b1ClientMask));
-
-    EXPECT_EQ(b1->post(), 0);
-    auto currentBufferState = b1->bufferState();
-    EXPECT_TRUE(isClientReleased(currentBufferState, b1ClientMask));
-    EXPECT_TRUE(isClientPosted(currentBufferState, b2ClientMask));
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromPostedState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_EQ(b1->post(), 0);
-    ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
-
-    // Post from posted state should fail.
-    EXPECT_EQ(b1->post(), -EBUSY);
-    EXPECT_EQ(b2->post(), -EBUSY);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromAcquiredState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_EQ(b1->post(), 0);
-    ASSERT_EQ(b2->acquire(), 0);
-    ASSERT_TRUE(isAnyClientAcquired(b1->bufferState()));
-
-    // Posting from acquired state should fail.
-    EXPECT_EQ(b1->post(), -EBUSY);
-    EXPECT_EQ(b2->post(), -EBUSY);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, PostBuffer_fromReleasedState) {
-    ASSERT_TRUE(b1->isReleased());
-
-    // Posting from released state should fail.
-    EXPECT_EQ(b1->post(), -EBUSY);
-    EXPECT_EQ(b2->post(), -EBUSY);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromSelfInPostedState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_EQ(b1->post(), 0);
-    ASSERT_TRUE(isClientPosted(b1->bufferState(), b2ClientMask));
-
-    // Acquire from posted state should pass.
-    EXPECT_EQ(b2->acquire(), 0);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromOtherInPostedState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_EQ(b1->post(), 0);
-    ASSERT_TRUE(isClientPosted(b1->bufferState(), b2ClientMask));
-
-    // Acquire from released state should fail, although there are other clients
-    // in posted state.
-    EXPECT_EQ(b1->acquire(), -EBUSY);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromSelfInAcquiredState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_EQ(b1->post(), 0);
-    ASSERT_EQ(b2->acquire(), 0);
-    auto currentBufferState = b1->bufferState();
-    ASSERT_TRUE(isClientAcquired(currentBufferState, b2ClientMask));
-
-    // Acquiring from acquired state by the same client should not error out.
-    EXPECT_EQ(b2->acquire(), 0);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromReleasedState) {
-    ASSERT_TRUE(b1->isReleased());
-
-    // Acquiring form released state should fail.
-    EXPECT_EQ(b1->acquire(), -EBUSY);
-    EXPECT_EQ(b2->acquire(), -EBUSY);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, AcquireBuffer_fromGainedState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_TRUE(isAnyClientGained(b1->bufferState()));
-
-    // Acquiring from gained state should fail.
-    EXPECT_EQ(b1->acquire(), -EBUSY);
-    EXPECT_EQ(b2->acquire(), -EBUSY);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInReleasedState) {
-    ASSERT_TRUE(b1->isReleased());
-
-    EXPECT_EQ(b1->release(), 0);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInGainedState) {
-    ASSERT_TRUE(b1->isReleased());
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_TRUE(isAnyClientGained(b1->bufferState()));
-
-    EXPECT_EQ(b1->release(), 0);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInPostedState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_EQ(b1->post(), 0);
-    ASSERT_TRUE(isAnyClientPosted(b1->bufferState()));
-
-    EXPECT_EQ(b2->release(), 0);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, ReleaseBuffer_fromSelfInAcquiredState) {
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_EQ(b1->post(), 0);
-    ASSERT_EQ(b2->acquire(), 0);
-    ASSERT_TRUE(isAnyClientAcquired(b1->bufferState()));
-
-    EXPECT_EQ(b2->release(), 0);
-}
-
-TEST_F(BufferHubBufferStateTransitionTest, BasicUsage) {
-    // 1 producer buffer and 1 consumer buffer initialised in testcase setup.
-    // Test if this set of basic operation succeed:
-    // Producer post three times to the consumer, and released by consumer.
-    for (int i = 0; i < 3; ++i) {
-        ASSERT_EQ(b1->gain(), 0);
-        ASSERT_EQ(b1->post(), 0);
-        ASSERT_EQ(b2->acquire(), 0);
-        ASSERT_EQ(b2->release(), 0);
-    }
-}
-
-TEST_F(BufferHubBufferTest, createNewConsumerAfterGain) {
-    // Create a poducer buffer and gain.
-    std::unique_ptr<BufferHubBuffer> b1 =
-            BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
-                                    kUserMetadataSize);
-    ASSERT_THAT(b1, NotNull());
-    ASSERT_EQ(b1->gain(), 0);
-
-    // Create a consumer of the buffer and test if the consumer can acquire the
-    // buffer if producer posts.
-    sp<NativeHandle> token = b1->duplicate();
-    ASSERT_THAT(token, NotNull());
-
-    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
-
-    ASSERT_THAT(b2, NotNull());
-    ASSERT_NE(b1->clientStateMask(), b2->clientStateMask());
-
-    ASSERT_EQ(b1->post(), 0);
-    EXPECT_EQ(b2->acquire(), 0);
-}
-
-TEST_F(BufferHubBufferTest, createNewConsumerAfterPost) {
-    // Create a poducer buffer and post.
-    std::unique_ptr<BufferHubBuffer> b1 =
-            BufferHubBuffer::create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
-                                    kUserMetadataSize);
-    ASSERT_EQ(b1->gain(), 0);
-    ASSERT_EQ(b1->post(), 0);
-
-    // Create a consumer of the buffer and test if the consumer can acquire the
-    // buffer if producer posts.
-    sp<NativeHandle> token = b1->duplicate();
-    ASSERT_THAT(token, NotNull());
-
-    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::import(token);
-
-    ASSERT_THAT(b2, NotNull());
-    ASSERT_NE(b1->clientStateMask(), b2->clientStateMask());
-
-    EXPECT_EQ(b2->acquire(), 0);
-}
-
-} // namespace
-
-} // namespace android
diff --git a/libs/ui/tests/BufferHubEventFd_test.cpp b/libs/ui/tests/BufferHubEventFd_test.cpp
deleted file mode 100644
index ef1781f..0000000
--- a/libs/ui/tests/BufferHubEventFd_test.cpp
+++ /dev/null
@@ -1,428 +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.
- */
-
-#define LOG_TAG "BufferHubEventFdTest"
-
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-
-#include <array>
-#include <condition_variable>
-#include <mutex>
-#include <thread>
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <log/log.h>
-#include <ui/BufferHubEventFd.h>
-
-namespace android {
-
-namespace {
-
-const int kTimeout = 100;
-const std::chrono::milliseconds kTimeoutMs(kTimeout);
-const int kTestRuns = 5;
-
-using ::testing::Contains;
-using BufferHubEventFdTest = ::testing::Test;
-
-} // namespace
-
-TEST_F(BufferHubEventFdTest, EventFd_testSingleEpollFd) {
-    BufferHubEventFd eventFd;
-    ASSERT_TRUE(eventFd.isValid());
-
-    base::unique_fd epollFd(epoll_create(64));
-    ASSERT_GE(epollFd.get(), 0);
-
-    epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
-
-    std::array<epoll_event, 1> events;
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-
-    eventFd.signal();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-
-    // The epoll fd is edge triggered, so it only responds to the eventFd once.
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-
-    // Check that it can receive consecutive signal.
-    eventFd.signal();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-
-    // Check that it can receive consecutive signal from a duplicated eventfd.
-    BufferHubEventFd dupEventFd(dup(eventFd.get()));
-    ASSERT_TRUE(dupEventFd.isValid());
-    dupEventFd.signal();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-    dupEventFd.signal();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-}
-
-TEST_F(BufferHubEventFdTest, EventFd_testCreateEpollFdAndAddSignaledEventFd) {
-    BufferHubEventFd eventFd;
-    ASSERT_TRUE(eventFd.isValid());
-    eventFd.signal();
-
-    base::unique_fd epollFd(epoll_create(64));
-    ASSERT_GE(epollFd.get(), 0);
-
-    // Make sure that the epoll set has not been signal yet.
-    std::array<epoll_event, 1> events;
-    ASSERT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-
-    // Check that adding an signaled fd into this epoll set will trigger the epoll set.
-    epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-
-    // The epoll fd is edge triggered, so it only responds to the eventFd once.
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-}
-
-TEST_F(BufferHubEventFdTest, EventFd_testAddSignaledEventFdToEpollFd) {
-    BufferHubEventFd eventFd;
-    ASSERT_TRUE(eventFd.isValid());
-
-    base::unique_fd epollFd(epoll_create(64));
-    ASSERT_GE(epollFd.get(), 0);
-
-    eventFd.signal();
-
-    epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
-
-    std::array<epoll_event, 1> events;
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-
-    // The epoll fd is edge triggered, so it only responds to the eventFd once.
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-}
-
-TEST_F(BufferHubEventFdTest, EventFd_testConsecutiveSignalsFromAEventFd) {
-    BufferHubEventFd eventFd;
-    ASSERT_TRUE(eventFd.isValid());
-    base::unique_fd epollFd(epoll_create(64));
-    ASSERT_GE(epollFd.get(), 0);
-    epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
-
-    std::array<epoll_event, 1> events;
-    for (int i = 0; i < kTestRuns; ++i) {
-        eventFd.signal();
-        EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-        EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-    }
-}
-
-TEST_F(BufferHubEventFdTest, EventFd_testConsecutiveSignalsFromADuplicatedEventFd) {
-    BufferHubEventFd eventFd;
-    ASSERT_TRUE(eventFd.isValid());
-    base::unique_fd epollFd(epoll_create(64));
-    ASSERT_GE(epollFd.get(), 0);
-    epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
-
-    BufferHubEventFd dupEventFd(dup(eventFd.get()));
-    ASSERT_TRUE(dupEventFd.isValid());
-
-    std::array<epoll_event, 1> events;
-    for (int i = 0; i < kTestRuns; ++i) {
-        dupEventFd.signal();
-        EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-        EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-    }
-}
-
-TEST_F(BufferHubEventFdTest, EventFd_testClear) {
-    BufferHubEventFd eventFd;
-    ASSERT_TRUE(eventFd.isValid());
-
-    base::unique_fd epollFd(epoll_create(64));
-    epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
-
-    ASSERT_GE(epollFd.get(), 0);
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
-
-    eventFd.signal();
-    eventFd.clear();
-
-    std::array<epoll_event, 1> events;
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-}
-
-TEST_F(BufferHubEventFdTest, EventFd_testDupEventFd) {
-    BufferHubEventFd eventFd;
-    ASSERT_TRUE(eventFd.isValid());
-
-    base::unique_fd epollFd(epoll_create(64));
-    epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
-
-    ASSERT_GE(epollFd.get(), 0);
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
-
-    // Technically, the dupliated eventFd and the original eventFd are pointing
-    // to the same kernel object. This test signals the duplicated eventFd but epolls the origianl
-    // eventFd.
-    BufferHubEventFd dupedEventFd(dup(eventFd.get()));
-    ASSERT_GE(dupedEventFd.get(), 0);
-
-    std::array<epoll_event, 1> events;
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-
-    dupedEventFd.signal();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-
-    // The epoll fd is edge triggered, so it only responds to the eventFd once.
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-
-    dupedEventFd.signal();
-
-    dupedEventFd.clear();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-}
-
-TEST_F(BufferHubEventFdTest, EventFd_testTwoEpollFds) {
-    BufferHubEventFd eventFd;
-    ASSERT_TRUE(eventFd.isValid());
-
-    base::unique_fd epollFd1(epoll_create(64));
-    base::unique_fd epollFd2(epoll_create(64));
-    epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
-
-    ASSERT_GE(epollFd1.get(), 0);
-    ASSERT_GE(epollFd2.get(), 0);
-
-    // Register the same eventFd to two EpollFds.
-    ASSERT_EQ(epoll_ctl(epollFd1.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
-    ASSERT_EQ(epoll_ctl(epollFd2.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
-
-    std::array<epoll_event, 1> events;
-    EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0);
-    EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0);
-
-    eventFd.signal();
-    EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 1);
-    EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 1);
-
-    // The epoll fd is edge triggered, so it only responds to the eventFd once.
-    EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0);
-    EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0);
-
-    eventFd.signal();
-    EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 1);
-
-    eventFd.clear();
-    EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0);
-    EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0);
-}
-
-TEST_F(BufferHubEventFdTest, EventFd_testTwoEventFds) {
-    BufferHubEventFd eventFd1;
-    BufferHubEventFd eventFd2;
-
-    ASSERT_TRUE(eventFd1.isValid());
-    ASSERT_TRUE(eventFd2.isValid());
-
-    base::unique_fd epollFd(epoll_create(64));
-    epoll_event e1 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 1}};
-    epoll_event e2 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 2}};
-
-    ASSERT_GE(epollFd.get(), 0);
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd1.get(), &e1), 0);
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd2.get(), &e2), 0);
-
-    std::array<epoll_event, 2> events;
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-
-    // Signal one by one.
-    eventFd1.signal();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-    EXPECT_EQ(events[0].data.u32, e1.data.u32);
-
-    eventFd2.signal();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-    EXPECT_EQ(events[0].data.u32, e2.data.u32);
-
-    // Signal both.
-    eventFd1.signal();
-    eventFd2.signal();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 2);
-
-    uint32_t u32s[] = {events[0].data.u32, events[1].data.u32};
-    EXPECT_THAT(u32s, Contains(e1.data.u32));
-    EXPECT_THAT(u32s, Contains(e2.data.u32));
-
-    // The epoll fd is edge triggered, so it only responds to the eventFd once.
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
-
-    eventFd1.signal();
-    eventFd2.signal();
-    eventFd2.clear();
-    EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
-}
-
-TEST_F(BufferHubEventFdTest, EventFd_testPollingThreadWithTwoEventFds) {
-    BufferHubEventFd eventFd1;
-    BufferHubEventFd eventFd2;
-
-    ASSERT_TRUE(eventFd1.isValid());
-    ASSERT_TRUE(eventFd2.isValid());
-
-    base::unique_fd epollFd(epoll_create(64));
-    epoll_event e1 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 1}};
-    epoll_event e2 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 2}};
-
-    ASSERT_GE(epollFd.get(), 0);
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd1.get(), &e1), 0);
-    ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd2.get(), &e2), 0);
-
-    int countEvent1 = 0;
-    int countEvent2 = 0;
-    std::atomic<bool> stop{false};
-    std::mutex mx;
-    std::condition_variable cv;
-
-    std::thread pollingThread([&] {
-        std::array<epoll_event, 2> events;
-        while (true) {
-            if (stop.load()) {
-                break;
-            }
-            int ret = epoll_wait(epollFd.get(), events.data(), events.size(), kTimeout);
-            ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed.");
-
-            std::lock_guard<std::mutex> lock(mx);
-            for (int i = 0; i < ret; i++) {
-                if (events[i].data.u32 == e1.data.u32) {
-                    countEvent1++;
-                    cv.notify_one();
-                } else if (events[i].data.u32 == e2.data.u32) {
-                    countEvent2++;
-                    cv.notify_one();
-                }
-            }
-        }
-    });
-
-    {
-        std::unique_lock<std::mutex> lock(mx);
-
-        eventFd1.signal();
-        EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 1; }));
-
-        eventFd1.signal();
-        EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 2; }));
-
-        eventFd2.signal();
-        EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent2 == 1; }));
-
-        eventFd1.clear();
-        eventFd2.clear();
-        EXPECT_EQ(countEvent1, 2);
-        EXPECT_EQ(countEvent2, 1);
-
-        eventFd1.signal();
-        EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 3; }));
-
-        eventFd2.signal();
-        EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent2 == 2; }));
-    }
-
-    stop.store(true);
-    pollingThread.join();
-}
-
-TEST_F(BufferHubEventFdTest, EventFd_testTwoPollingThreads) {
-    BufferHubEventFd eventFd;
-    ASSERT_TRUE(eventFd.isValid());
-
-    base::unique_fd epollFd1(epoll_create(64));
-    base::unique_fd epollFd2(epoll_create(64));
-    epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
-
-    ASSERT_GE(epollFd1.get(), 0);
-    ASSERT_GE(epollFd2.get(), 0);
-
-    // Register the same eventFd to two EpollFds.
-    ASSERT_EQ(epoll_ctl(epollFd1.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
-    ASSERT_EQ(epoll_ctl(epollFd2.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
-
-    int countEpoll1 = 0;
-    int countEpoll2 = 0;
-    std::atomic<bool> stop{false};
-    std::mutex mx;
-    std::condition_variable cv;
-
-    std::thread pollingThread1([&] {
-        std::array<epoll_event, 1> events;
-        while (!stop.load()) {
-            int ret = epoll_wait(epollFd1.get(), events.data(), events.size(), kTimeout);
-            ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed.");
-
-            if (ret > 0) {
-                std::lock_guard<std::mutex> lock(mx);
-                countEpoll1++;
-                cv.notify_one();
-            }
-        }
-    });
-
-    std::thread pollingThread2([&] {
-        std::array<epoll_event, 1> events;
-        while (!stop.load()) {
-            int ret = epoll_wait(epollFd2.get(), events.data(), events.size(), kTimeout);
-            ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed.");
-
-            if (ret > 0) {
-                std::lock_guard<std::mutex> lock(mx);
-                countEpoll2++;
-                cv.notify_one();
-            }
-        }
-    });
-
-    {
-        std::unique_lock<std::mutex> lock(mx);
-
-        eventFd.signal();
-        EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 1; }));
-        EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 1; }));
-
-        eventFd.signal();
-        EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 2; }));
-        EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 2; }));
-
-        eventFd.clear();
-        EXPECT_EQ(countEpoll1, 2);
-        EXPECT_EQ(countEpoll2, 2);
-
-        eventFd.signal();
-        EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 3; }));
-        EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 3; }));
-    }
-
-    stop.store(true);
-    pollingThread1.join();
-    pollingThread2.join();
-}
-
-} // namespace android
diff --git a/libs/ui/tests/BufferHubMetadata_test.cpp b/libs/ui/tests/BufferHubMetadata_test.cpp
deleted file mode 100644
index eb978ca..0000000
--- a/libs/ui/tests/BufferHubMetadata_test.cpp
+++ /dev/null
@@ -1,98 +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.
- */
-
-#include <gtest/gtest.h>
-#include <ui/BufferHubMetadata.h>
-
-namespace android {
-namespace dvr {
-
-constexpr size_t kEmptyUserMetadataSize = 0;
-
-class BufferHubMetadataTest : public ::testing::Test {};
-
-TEST_F(BufferHubMetadataTest, Create_UserMetdataSizeTooBig) {
-    BufferHubMetadata m1 = BufferHubMetadata::create(std::numeric_limits<uint32_t>::max());
-    EXPECT_FALSE(m1.isValid());
-}
-
-TEST_F(BufferHubMetadataTest, Create_Success) {
-    BufferHubMetadata m1 = BufferHubMetadata::create(kEmptyUserMetadataSize);
-    EXPECT_TRUE(m1.isValid());
-    EXPECT_NE(m1.metadataHeader(), nullptr);
-}
-
-TEST_F(BufferHubMetadataTest, Import_Success) {
-    BufferHubMetadata m1 = BufferHubMetadata::create(kEmptyUserMetadataSize);
-    EXPECT_TRUE(m1.isValid());
-    EXPECT_NE(m1.metadataHeader(), nullptr);
-
-    unique_fd h2 = unique_fd(dup(m1.ashmemFd().get()));
-    EXPECT_NE(h2.get(), -1);
-
-    BufferHubMetadata m2 = BufferHubMetadata::import(std::move(h2));
-    EXPECT_EQ(h2.get(), -1);
-    EXPECT_TRUE(m1.isValid());
-    BufferHubDefs::MetadataHeader* mh1 = m1.metadataHeader();
-    EXPECT_NE(mh1, nullptr);
-
-    // Check if the newly allocated buffer is initialized in released state (i.e.
-    // state equals to 0U).
-    EXPECT_TRUE(mh1->bufferState.load() == 0U);
-
-    EXPECT_TRUE(m2.isValid());
-    BufferHubDefs::MetadataHeader* mh2 = m2.metadataHeader();
-    EXPECT_NE(mh2, nullptr);
-
-    // Check if the newly allocated buffer is initialized in released state (i.e.
-    // state equals to 0U).
-    EXPECT_TRUE(mh2->bufferState.load() == 0U);
-}
-
-TEST_F(BufferHubMetadataTest, MoveMetadataInvalidatesOldOne) {
-    BufferHubMetadata m1 = BufferHubMetadata::create(sizeof(int));
-    EXPECT_TRUE(m1.isValid());
-    EXPECT_NE(m1.metadataHeader(), nullptr);
-    EXPECT_NE(m1.ashmemFd().get(), -1);
-    EXPECT_EQ(m1.userMetadataSize(), sizeof(int));
-
-    BufferHubMetadata m2 = std::move(m1);
-
-    // After the move, the metadata header (a raw pointer) should be reset in the older buffer.
-    EXPECT_EQ(m1.metadataHeader(), nullptr);
-    EXPECT_NE(m2.metadataHeader(), nullptr);
-
-    EXPECT_EQ(m1.ashmemFd().get(), -1);
-    EXPECT_NE(m2.ashmemFd().get(), -1);
-
-    EXPECT_EQ(m1.userMetadataSize(), 0U);
-    EXPECT_EQ(m2.userMetadataSize(), sizeof(int));
-
-    BufferHubMetadata m3{std::move(m2)};
-
-    // After the move, the metadata header (a raw pointer) should be reset in the older buffer.
-    EXPECT_EQ(m2.metadataHeader(), nullptr);
-    EXPECT_NE(m3.metadataHeader(), nullptr);
-
-    EXPECT_EQ(m2.ashmemFd().get(), -1);
-    EXPECT_NE(m3.ashmemFd().get(), -1);
-
-    EXPECT_EQ(m2.userMetadataSize(), 0U);
-    EXPECT_EQ(m3.userMetadataSize(), sizeof(int));
-}
-
-}  // namespace dvr
-}  // namespace android
diff --git a/libs/ui/tests/GraphicBufferOverBinder_test.cpp b/libs/ui/tests/GraphicBufferOverBinder_test.cpp
index 7c0a44a..126a945 100644
--- a/libs/ui/tests/GraphicBufferOverBinder_test.cpp
+++ b/libs/ui/tests/GraphicBufferOverBinder_test.cpp
@@ -23,7 +23,6 @@
 #include <gui/BufferQueue.h>
 #include <gui/IGraphicBufferConsumer.h>
 #include <gui/IGraphicBufferProducer.h>
-#include <ui/BufferHubBuffer.h>
 #include <ui/GraphicBuffer.h>
 #include <utils/Log.h>
 
@@ -37,7 +36,6 @@
 static const String16 kTestServiceName = String16("GraphicBufferOverBinderTestService");
 enum GraphicBufferOverBinderTestServiceCode {
     GRAPHIC_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
-    GRAPHIC_BUFFER_FROM_BUFFER_HUB_BUFFER,
 };
 
 class GraphicBufferOverBinderTestService : public BBinder {
@@ -46,21 +44,6 @@
         // GraphicBuffer
         mGraphicBuffer = new GraphicBuffer(kTestWidth, kTestHeight, kTestFormat, kTestLayerCount,
                                            kTestUsage);
-        ALOGI("mGraphicBuffer id %" PRIi32, mGraphicBuffer->getBufferId());
-
-        // BufferHub-backed GraphicBuffer
-        std::unique_ptr<BufferHubBuffer> bufferHubBuffer =
-                BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
-                                        kTestUsage, /*userMetadataSize=*/0);
-        mBufferhubBackedGraphicBuffer = new GraphicBuffer(std::move(bufferHubBuffer));
-        if (!mBufferhubBackedGraphicBuffer->isBufferHubBuffer()) {
-            ALOGE("Failed to back GraphicBuffer with BufferHub.");
-        }
-        if (bufferHubBuffer != nullptr) {
-            ALOGE("Failed to move BufferHubBuffer to GraphicBuffer");
-        }
-        ALOGI("mBufferhubBackedGraphicBuffer id %" PRIi32,
-              mBufferhubBackedGraphicBuffer->getBufferId());
     }
 
     ~GraphicBufferOverBinderTestService() = default;
@@ -71,9 +54,6 @@
             case GRAPHIC_BUFFER: {
                 return reply->write(*mGraphicBuffer);
             }
-            case GRAPHIC_BUFFER_FROM_BUFFER_HUB_BUFFER: {
-                return reply->write(*mBufferhubBackedGraphicBuffer);
-            }
             default:
                 return UNKNOWN_TRANSACTION;
         };
@@ -81,7 +61,6 @@
 
 protected:
     sp<GraphicBuffer> mGraphicBuffer;
-    sp<GraphicBuffer> mBufferhubBackedGraphicBuffer;
 };
 
 static int runBinderServer() {
@@ -138,17 +117,6 @@
     sp<GraphicBuffer> gb;
     EXPECT_EQ(GetGraphicBuffer(&gb, GRAPHIC_BUFFER), OK);
     EXPECT_NE(gb, nullptr);
-    EXPECT_FALSE(gb->isBufferHubBuffer());
-    void* vaddr;
-    EXPECT_EQ(gb->lock(kTestUsage, &vaddr), OK);
-    EXPECT_EQ(gb->unlock(), OK);
-}
-
-TEST_F(GraphicBufferOverBinderTest, SendGraphicBufferFromBufferHubBufferOverBinder) {
-    sp<GraphicBuffer> gb;
-    EXPECT_EQ(GetGraphicBuffer(&gb, GRAPHIC_BUFFER_FROM_BUFFER_HUB_BUFFER), NO_ERROR);
-    EXPECT_NE(gb, nullptr);
-    EXPECT_TRUE(gb->isBufferHubBuffer());
     void* vaddr;
     EXPECT_EQ(gb->lock(kTestUsage, &vaddr), OK);
     EXPECT_EQ(gb->unlock(), OK);
diff --git a/libs/ui/tests/GraphicBuffer_test.cpp b/libs/ui/tests/GraphicBuffer_test.cpp
index 5e0b094..19551b3 100644
--- a/libs/ui/tests/GraphicBuffer_test.cpp
+++ b/libs/ui/tests/GraphicBuffer_test.cpp
@@ -16,7 +16,6 @@
 
 #define LOG_TAG "GraphicBufferTest"
 
-#include <ui/BufferHubBuffer.h>
 #include <ui/GraphicBuffer.h>
 
 #include <gtest/gtest.h>
@@ -27,7 +26,6 @@
 
 constexpr uint32_t kTestWidth = 1024;
 constexpr uint32_t kTestHeight = 1;
-constexpr uint32_t kTestFormat = HAL_PIXEL_FORMAT_BLOB;
 constexpr uint32_t kTestLayerCount = 1;
 constexpr uint64_t kTestUsage = GraphicBuffer::USAGE_SW_WRITE_OFTEN;
 
@@ -68,88 +66,4 @@
     ASSERT_EQ(BAD_VALUE, gb2->initCheck());
 }
 
-TEST_F(GraphicBufferTest, CreateFromBufferHubBuffer) {
-    std::unique_ptr<BufferHubBuffer> b1 =
-            BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
-                                    kTestUsage, /*userMetadataSize=*/0);
-    ASSERT_NE(b1, nullptr);
-    EXPECT_TRUE(b1->isValid());
-
-    sp<GraphicBuffer> gb(new GraphicBuffer(std::move(b1)));
-    EXPECT_TRUE(gb->isBufferHubBuffer());
-
-    EXPECT_EQ(gb->getWidth(), kTestWidth);
-    EXPECT_EQ(gb->getHeight(), kTestHeight);
-    EXPECT_EQ(static_cast<uint32_t>(gb->getPixelFormat()), kTestFormat);
-    EXPECT_EQ(gb->getUsage(), kTestUsage);
-    EXPECT_EQ(gb->getLayerCount(), kTestLayerCount);
-}
-
-TEST_F(GraphicBufferTest, InvalidBufferIdForNoneBufferHubBuffer) {
-    sp<GraphicBuffer> gb(
-            new GraphicBuffer(kTestWidth, kTestHeight, kTestFormat, kTestLayerCount, kTestUsage));
-    EXPECT_FALSE(gb->isBufferHubBuffer());
-    EXPECT_EQ(gb->getBufferId(), -1);
-}
-
-TEST_F(GraphicBufferTest, BufferIdMatchesBufferHubBufferId) {
-    std::unique_ptr<BufferHubBuffer> b1 =
-            BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
-                                    kTestUsage, /*userMetadataSize=*/0);
-    EXPECT_NE(b1, nullptr);
-    EXPECT_TRUE(b1->isValid());
-
-    int b1_id = b1->id();
-    EXPECT_GE(b1_id, 0);
-
-    sp<GraphicBuffer> gb(new GraphicBuffer(std::move(b1)));
-    EXPECT_TRUE(gb->isBufferHubBuffer());
-    EXPECT_EQ(gb->getBufferId(), b1_id);
-}
-
-TEST_F(GraphicBufferTest, flattenAndUnflatten) {
-    std::unique_ptr<BufferHubBuffer> b1 =
-            BufferHubBuffer::create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
-                                    kTestUsage, /*userMetadataSize=*/0);
-    ASSERT_NE(b1, nullptr);
-    sp<GraphicBuffer> gb1(new GraphicBuffer(std::move(b1)));
-    gb1->setGenerationNumber(42);
-
-    size_t flattenedSize = gb1->getFlattenedSize();
-    EXPECT_EQ(flattenedSize, 48);
-    size_t fdCount = gb1->getFdCount();
-    EXPECT_EQ(fdCount, 0);
-
-    int data[flattenedSize];
-    int fds[0];
-
-    // Make copies of needed items since flatten modifies them.
-    size_t flattenedSizeCopy = flattenedSize;
-    size_t fdCountCopy = fdCount;
-    void* dataStart = data;
-    int* fdsStart = fds;
-    status_t err = gb1->flatten(dataStart, flattenedSizeCopy, fdsStart, fdCountCopy);
-    ASSERT_EQ(err, NO_ERROR);
-    EXPECT_EQ(flattenedSizeCopy, 0);
-    EXPECT_EQ(fdCountCopy, 0);
-
-    size_t unflattenSize = flattenedSize;
-    size_t unflattenFdCount = fdCount;
-    const void* unflattenData = static_cast<const void*>(dataStart);
-    const int* unflattenFdData = static_cast<const int*>(fdsStart);
-
-    GraphicBuffer* gb2 = new GraphicBuffer();
-    err = gb2->unflatten(unflattenData, unflattenSize, unflattenFdData, unflattenFdCount);
-    ASSERT_EQ(err, NO_ERROR);
-    EXPECT_TRUE(gb2->isBufferHubBuffer());
-
-    EXPECT_EQ(gb2->getWidth(), kTestWidth);
-    EXPECT_EQ(gb2->getHeight(), kTestHeight);
-    EXPECT_EQ(static_cast<uint32_t>(gb2->getPixelFormat()), kTestFormat);
-    EXPECT_EQ(gb2->getUsage(), kTestUsage);
-    EXPECT_EQ(gb2->getLayerCount(), kTestLayerCount);
-    EXPECT_EQ(gb1->getBufferId(), gb2->getBufferId());
-    EXPECT_EQ(gb2->getGenerationNumber(), 42);
-}
-
 } // namespace android
diff --git a/services/bufferhub/Android.bp b/services/bufferhub/Android.bp
deleted file mode 100644
index 2bb6aef..0000000
--- a/services/bufferhub/Android.bp
+++ /dev/null
@@ -1,77 +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.
-//
-
-cc_library_shared {
-    name: "libbufferhubservice",
-    cflags: [
-        "-DLOG_TAG=\"libbufferhubservice\"",
-        "-Wall",
-        "-Werror",
-        "-Wextra",
-    ],
-    srcs: [
-        "BufferClient.cpp",
-        "BufferHubIdGenerator.cpp",
-        "BufferHubService.cpp",
-        "BufferNode.cpp",
-    ],
-    header_libs: [
-        "libdvr_headers",
-        "libnativewindow_headers",
-    ],
-    shared_libs: [
-        "android.frameworks.bufferhub@1.0",
-        "libcrypto",
-        "libcutils",
-        "libhidlbase",
-        "liblog",
-        "libui",
-        "libutils",
-    ],
-    export_include_dirs: [
-        "include"
-    ],
-}
-
-cc_binary {
-    name: "android.frameworks.bufferhub@1.0-service",
-    relative_install_path: "hw",
-    srcs: [
-        "main_bufferhub.cpp"
-    ],
-    header_libs: [
-        "libdvr_headers",
-        "libnativewindow_headers",
-    ],
-    shared_libs: [
-        "android.frameworks.bufferhub@1.0",
-        "libbufferhubservice",
-        "libcrypto",
-        "libcutils",
-        "libhidlbase",
-        "liblog",
-        "libui",
-        "libutils",
-    ],
-    cflags: [
-        "-DLOG_TAG=\"bufferhub\"",
-        "-Wall",
-        "-Werror",
-        "-Wextra",
-    ],
-    init_rc: ["android.frameworks.bufferhub@1.0-service.rc"],
-    vintf_fragments: ["android.frameworks.bufferhub@1.0-service.xml"],
-}
diff --git a/services/bufferhub/BufferClient.cpp b/services/bufferhub/BufferClient.cpp
deleted file mode 100644
index ec7e535..0000000
--- a/services/bufferhub/BufferClient.cpp
+++ /dev/null
@@ -1,100 +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.
- */
-
-#include <bufferhub/BufferClient.h>
-#include <bufferhub/BufferHubService.h>
-#include <hidl/HidlSupport.h>
-#include <log/log.h>
-
-namespace android {
-namespace frameworks {
-namespace bufferhub {
-namespace V1_0 {
-namespace implementation {
-
-using hardware::hidl_handle;
-using hardware::Void;
-
-BufferClient* BufferClient::create(BufferHubService* service,
-                                   const std::shared_ptr<BufferNode>& node) {
-    if (!service) {
-        ALOGE("%s: service cannot be nullptr.", __FUNCTION__);
-        return nullptr;
-    } else if (!node) {
-        ALOGE("%s: node cannot be nullptr.", __FUNCTION__);
-        return nullptr;
-    }
-    return new BufferClient(service, node);
-}
-
-BufferClient::~BufferClient() {
-    {
-        std::lock_guard<std::mutex> lock(mClosedMutex);
-        if (!mClosed) {
-            ALOGW("%s: client of buffer #%d destroyed without close. Closing it now.", __FUNCTION__,
-                  mBufferNode->id());
-        }
-    }
-
-    close();
-}
-
-Return<BufferHubStatus> BufferClient::close() {
-    std::lock_guard<std::mutex> lock(mClosedMutex);
-    if (mClosed) {
-        return BufferHubStatus::CLIENT_CLOSED;
-    }
-
-    getService()->onClientClosed(this);
-    mBufferNode.reset();
-    mClosed = true;
-    return BufferHubStatus::NO_ERROR;
-}
-
-Return<void> BufferClient::duplicate(duplicate_cb _hidl_cb) {
-    std::lock_guard<std::mutex> lock(mClosedMutex);
-    if (mClosed) {
-        _hidl_cb(/*token=*/hidl_handle(), /*status=*/BufferHubStatus::CLIENT_CLOSED);
-        return Void();
-    }
-
-    if (!mBufferNode) {
-        // Should never happen
-        ALOGE("%s: node is missing.", __FUNCTION__);
-        _hidl_cb(/*token=*/hidl_handle(), /*status=*/BufferHubStatus::BUFFER_FREED);
-        return Void();
-    }
-
-    const hidl_handle token = getService()->registerToken(this);
-    _hidl_cb(/*token=*/token, /*status=*/BufferHubStatus::NO_ERROR);
-    return Void();
-}
-
-sp<BufferHubService> BufferClient::getService() {
-    sp<BufferHubService> service = mService.promote();
-    if (service == nullptr) {
-        // Should never happen. Kill the process.
-        LOG_FATAL("%s: service died.", __FUNCTION__);
-    }
-
-    return service;
-}
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace bufferhub
-} // namespace frameworks
-} // namespace android
\ No newline at end of file
diff --git a/services/bufferhub/BufferHubIdGenerator.cpp b/services/bufferhub/BufferHubIdGenerator.cpp
deleted file mode 100644
index 2c12f0e..0000000
--- a/services/bufferhub/BufferHubIdGenerator.cpp
+++ /dev/null
@@ -1,59 +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.
- */
-
-#include <bufferhub/BufferHubIdGenerator.h>
-#include <log/log.h>
-
-namespace android {
-namespace frameworks {
-namespace bufferhub {
-namespace V1_0 {
-namespace implementation {
-
-BufferHubIdGenerator& BufferHubIdGenerator::getInstance() {
-    static BufferHubIdGenerator generator;
-
-    return generator;
-}
-
-int BufferHubIdGenerator::getId() {
-    std::lock_guard<std::mutex> lock(mIdsInUseMutex);
-
-    do {
-        if (++mLastId >= std::numeric_limits<int>::max()) {
-            mLastId = 0;
-        }
-    } while (mIdsInUse.find(mLastId) != mIdsInUse.end());
-
-    mIdsInUse.insert(mLastId);
-    return mLastId;
-}
-
-void BufferHubIdGenerator::freeId(int id) {
-    std::lock_guard<std::mutex> lock(mIdsInUseMutex);
-    auto iter = mIdsInUse.find(id);
-    if (iter != mIdsInUse.end()) {
-        mIdsInUse.erase(iter);
-    } else {
-        ALOGW("%s: Cannot free nonexistent id #%d", __FUNCTION__, id);
-    }
-}
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace bufferhub
-} // namespace frameworks
-} // namespace android
diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
deleted file mode 100644
index 7a3472f..0000000
--- a/services/bufferhub/BufferHubService.cpp
+++ /dev/null
@@ -1,401 +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.
- */
-
-#include <array>
-#include <iomanip>
-#include <random>
-#include <sstream>
-
-#include <android/hardware_buffer.h>
-#include <bufferhub/BufferHubService.h>
-#include <cutils/native_handle.h>
-#include <log/log.h>
-#include <openssl/hmac.h>
-#include <system/graphics-base.h>
-#include <ui/BufferHubDefs.h>
-
-using ::android::BufferHubDefs::MetadataHeader;
-using ::android::hardware::Void;
-
-namespace android {
-namespace frameworks {
-namespace bufferhub {
-namespace V1_0 {
-namespace implementation {
-
-BufferHubService::BufferHubService() {
-    std::mt19937_64 randomEngine;
-    randomEngine.seed(time(nullptr));
-
-    mKey = randomEngine();
-}
-
-Return<void> BufferHubService::allocateBuffer(const HardwareBufferDescription& description,
-                                              const uint32_t userMetadataSize,
-                                              allocateBuffer_cb _hidl_cb) {
-    AHardwareBuffer_Desc desc;
-    memcpy(&desc, &description, sizeof(AHardwareBuffer_Desc));
-
-    std::shared_ptr<BufferNode> node =
-            std::make_shared<BufferNode>(desc.width, desc.height, desc.layers, desc.format,
-                                         desc.usage, userMetadataSize,
-                                         BufferHubIdGenerator::getInstance().getId());
-    if (node == nullptr || !node->isValid()) {
-        ALOGE("%s: creating BufferNode failed.", __FUNCTION__);
-        _hidl_cb(/*status=*/BufferHubStatus::ALLOCATION_FAILED, /*bufferClient=*/nullptr,
-                 /*bufferTraits=*/{});
-        return Void();
-    }
-
-    sp<BufferClient> client = BufferClient::create(this, node);
-    // Add it to list for bookkeeping and dumpsys.
-    std::lock_guard<std::mutex> lock(mClientSetMutex);
-    mClientSet.emplace(client);
-
-    // Allocate memory for bufferInfo of type hidl_handle on the stack. See
-    // http://aosp/286282 for the usage of NATIVE_HANDLE_DECLARE_STORAGE.
-    NATIVE_HANDLE_DECLARE_STORAGE(bufferInfoStorage, BufferHubDefs::kBufferInfoNumFds,
-                                  BufferHubDefs::kBufferInfoNumInts);
-    hidl_handle bufferInfo =
-            buildBufferInfo(bufferInfoStorage, node->id(), node->addNewActiveClientsBitToMask(),
-                            node->userMetadataSize(), node->metadata().ashmemFd(),
-                            node->eventFd().get());
-    // During the gralloc allocation carried out by BufferNode, gralloc allocator will populate the
-    // fields of its HardwareBufferDescription (i.e. strides) according to the actual
-    // gralloc implementation. We need to read those fields back and send them to the client via
-    // BufferTraits.
-    HardwareBufferDescription allocatedBufferDesc;
-    memcpy(&allocatedBufferDesc, &node->bufferDesc(), sizeof(AHardwareBuffer_Desc));
-    BufferTraits bufferTraits = {/*bufferDesc=*/allocatedBufferDesc,
-                                 /*bufferHandle=*/hidl_handle(node->bufferHandle()),
-                                 /*bufferInfo=*/std::move(bufferInfo)};
-
-    _hidl_cb(/*status=*/BufferHubStatus::NO_ERROR, /*bufferClient=*/client,
-             /*bufferTraits=*/std::move(bufferTraits));
-    return Void();
-}
-
-Return<void> BufferHubService::importBuffer(const hidl_handle& tokenHandle,
-                                            importBuffer_cb _hidl_cb) {
-    if (!tokenHandle.getNativeHandle() || tokenHandle->numFds != 0 || tokenHandle->numInts <= 1) {
-        // nullptr handle or wrong format
-        _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr,
-                 /*bufferTraits=*/{});
-        return Void();
-    }
-
-    int tokenId = tokenHandle->data[0];
-
-    wp<BufferClient> originClientWp;
-    {
-        std::lock_guard<std::mutex> lock(mTokenMutex);
-        auto iter = mTokenMap.find(tokenId);
-        if (iter == mTokenMap.end()) {
-            // Token Id not exist
-            ALOGD("%s: token #%d not found.", __FUNCTION__, tokenId);
-            _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr,
-                     /*bufferTraits=*/{});
-            return Void();
-        }
-
-        const std::vector<uint8_t>& tokenHMAC = iter->second.first;
-
-        int numIntsForHMAC = (int)ceil(tokenHMAC.size() * sizeof(uint8_t) / (double)sizeof(int));
-        if (tokenHandle->numInts - 1 != numIntsForHMAC) {
-            // HMAC size not match
-            ALOGD("%s: token #%d HMAC size not match. Expected: %d Actual: %d", __FUNCTION__,
-                  tokenId, numIntsForHMAC, tokenHandle->numInts - 1);
-            _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr,
-                     /*bufferTraits=*/{});
-            return Void();
-        }
-
-        size_t hmacSize = tokenHMAC.size() * sizeof(uint8_t);
-        if (memcmp(tokenHMAC.data(), &tokenHandle->data[1], hmacSize) != 0) {
-            // HMAC not match
-            ALOGD("%s: token #%d HMAC not match.", __FUNCTION__, tokenId);
-            _hidl_cb(/*status=*/BufferHubStatus::INVALID_TOKEN, /*bufferClient=*/nullptr,
-                     /*bufferTraits=*/{});
-            return Void();
-        }
-
-        originClientWp = iter->second.second;
-        mTokenMap.erase(iter);
-    }
-
-    // Check if original client is dead
-    sp<BufferClient> originClient = originClientWp.promote();
-    if (!originClient) {
-        // Should not happen since token should be removed if already gone
-        ALOGE("%s: original client %p gone!", __FUNCTION__, originClientWp.unsafe_get());
-        _hidl_cb(/*status=*/BufferHubStatus::BUFFER_FREED, /*bufferClient=*/nullptr,
-                 /*bufferTraits=*/{});
-        return Void();
-    }
-
-    sp<BufferClient> client = new BufferClient(*originClient);
-    uint32_t clientStateMask = client->getBufferNode()->addNewActiveClientsBitToMask();
-    if (clientStateMask == 0U) {
-        // Reach max client count
-        ALOGE("%s: import failed, BufferNode#%u reached maximum clients.", __FUNCTION__,
-              client->getBufferNode()->id());
-        _hidl_cb(/*status=*/BufferHubStatus::MAX_CLIENT, /*bufferClient=*/nullptr,
-                 /*bufferTraits=*/{});
-        return Void();
-    }
-
-    std::lock_guard<std::mutex> lock(mClientSetMutex);
-    mClientSet.emplace(client);
-
-    std::shared_ptr<BufferNode> node = client->getBufferNode();
-
-    HardwareBufferDescription bufferDesc;
-    memcpy(&bufferDesc, &node->bufferDesc(), sizeof(HardwareBufferDescription));
-
-    // Allocate memory for bufferInfo of type hidl_handle on the stack. See
-    // http://aosp/286282 for the usage of NATIVE_HANDLE_DECLARE_STORAGE.
-    NATIVE_HANDLE_DECLARE_STORAGE(bufferInfoStorage, BufferHubDefs::kBufferInfoNumFds,
-                                  BufferHubDefs::kBufferInfoNumInts);
-    hidl_handle bufferInfo = buildBufferInfo(bufferInfoStorage, node->id(), clientStateMask,
-                                             node->userMetadataSize(), node->metadata().ashmemFd(),
-                                             node->eventFd().get());
-    BufferTraits bufferTraits = {/*bufferDesc=*/bufferDesc,
-                                 /*bufferHandle=*/hidl_handle(node->bufferHandle()),
-                                 /*bufferInfo=*/std::move(bufferInfo)};
-
-    _hidl_cb(/*status=*/BufferHubStatus::NO_ERROR, /*bufferClient=*/client,
-             /*bufferTraits=*/std::move(bufferTraits));
-    return Void();
-}
-
-Return<void> BufferHubService::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
-    if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
-        ALOGE("%s: missing fd for writing.", __FUNCTION__);
-        return Void();
-    }
-
-    FILE* out = fdopen(dup(fd->data[0]), "w");
-
-    if (args.size() != 0) {
-        fprintf(out,
-                "Note: lshal bufferhub currently does not support args. Input arguments are "
-                "ignored.\n");
-    }
-
-    std::ostringstream stream;
-
-    // Get the number of clients of each buffer.
-    // Map from bufferId to bufferNode_clientCount pair.
-    std::map<int, std::pair<const std::shared_ptr<BufferNode>, uint32_t>> clientCount;
-    {
-        std::lock_guard<std::mutex> lock(mClientSetMutex);
-        for (auto iter = mClientSet.begin(); iter != mClientSet.end(); ++iter) {
-            sp<BufferClient> client = iter->promote();
-            if (client != nullptr) {
-                const std::shared_ptr<BufferNode> node = client->getBufferNode();
-                auto mapIter = clientCount.find(node->id());
-                if (mapIter != clientCount.end()) {
-                    ++mapIter->second.second;
-                } else {
-                    clientCount.emplace(node->id(),
-                                        std::pair<std::shared_ptr<BufferNode>, uint32_t>(node, 1U));
-                }
-            }
-        }
-    }
-
-    stream << "Active Buffers:\n";
-    stream << std::right;
-    stream << std::setw(6) << "Id";
-    stream << " ";
-    stream << std::setw(9) << "#Clients";
-    stream << " ";
-    stream << std::setw(14) << "Geometry";
-    stream << " ";
-    stream << std::setw(6) << "Format";
-    stream << " ";
-    stream << std::setw(10) << "Usage";
-    stream << " ";
-    stream << std::setw(10) << "State";
-    stream << " ";
-    stream << std::setw(8) << "Index";
-    stream << std::endl;
-
-    for (auto iter = clientCount.begin(); iter != clientCount.end(); ++iter) {
-        const std::shared_ptr<BufferNode> node = std::move(iter->second.first);
-        const uint32_t clientCount = iter->second.second;
-        AHardwareBuffer_Desc desc = node->bufferDesc();
-
-        MetadataHeader* metadataHeader =
-                const_cast<BufferHubMetadata*>(&node->metadata())->metadataHeader();
-        const uint32_t state = metadataHeader->bufferState.load(std::memory_order_acquire);
-        const uint64_t index = metadataHeader->queueIndex;
-
-        stream << std::right;
-        stream << std::setw(6) << /*Id=*/node->id();
-        stream << " ";
-        stream << std::setw(9) << /*#Clients=*/clientCount;
-        stream << " ";
-        if (desc.format == HAL_PIXEL_FORMAT_BLOB) {
-            std::string size = std::to_string(desc.width) + " B";
-            stream << std::setw(14) << /*Geometry=*/size;
-        } else {
-            std::string dimensions = std::to_string(desc.width) + "x" +
-                    std::to_string(desc.height) + "x" + std::to_string(desc.layers);
-            stream << std::setw(14) << /*Geometry=*/dimensions;
-        }
-        stream << " ";
-        stream << std::setw(6) << /*Format=*/desc.format;
-        stream << " ";
-        stream << "0x" << std::hex << std::setfill('0');
-        stream << std::setw(8) << /*Usage=*/desc.usage;
-        stream << std::dec << std::setfill(' ');
-        stream << " ";
-        stream << "0x" << std::hex << std::setfill('0');
-        stream << std::setw(8) << /*State=*/state;
-        stream << std::dec << std::setfill(' ');
-        stream << " ";
-        stream << std::setw(8) << /*Index=*/index;
-        stream << std::endl;
-    }
-
-    stream << std::endl;
-
-    // Get the number of tokens of each buffer.
-    // Map from bufferId to tokenCount
-    std::map<int, uint32_t> tokenCount;
-    {
-        std::lock_guard<std::mutex> lock(mTokenMutex);
-        for (auto iter = mTokenMap.begin(); iter != mTokenMap.end(); ++iter) {
-            sp<BufferClient> client = iter->second.second.promote();
-            if (client != nullptr) {
-                const std::shared_ptr<BufferNode> node = client->getBufferNode();
-                auto mapIter = tokenCount.find(node->id());
-                if (mapIter != tokenCount.end()) {
-                    ++mapIter->second;
-                } else {
-                    tokenCount.emplace(node->id(), 1U);
-                }
-            }
-        }
-    }
-
-    stream << "Unused Tokens:\n";
-    stream << std::right;
-    stream << std::setw(8) << "Buffer Id";
-    stream << " ";
-    stream << std::setw(7) << "#Tokens";
-    stream << std::endl;
-
-    for (auto iter = tokenCount.begin(); iter != tokenCount.end(); ++iter) {
-        stream << std::right;
-        stream << std::setw(8) << /*Buffer Id=*/iter->first;
-        stream << " ";
-        stream << std::setw(7) << /*#Tokens=*/iter->second;
-        stream << std::endl;
-    }
-
-    fprintf(out, "%s", stream.str().c_str());
-
-    fclose(out);
-    return Void();
-}
-
-hidl_handle BufferHubService::registerToken(const wp<BufferClient>& client) {
-    // Find next available token id
-    std::lock_guard<std::mutex> lock(mTokenMutex);
-    do {
-        ++mLastTokenId;
-    } while (mTokenMap.find(mLastTokenId) != mTokenMap.end());
-
-    std::array<uint8_t, EVP_MAX_MD_SIZE> hmac;
-    uint32_t hmacSize = 0U;
-
-    HMAC(/*evp_md=*/EVP_sha256(), /*key=*/&mKey, /*key_len=*/kKeyLen,
-         /*data=*/(uint8_t*)&mLastTokenId, /*data_len=*/mTokenIdSize,
-         /*out=*/hmac.data(), /*out_len=*/&hmacSize);
-
-    int numIntsForHMAC = (int)ceil(hmacSize / (double)sizeof(int));
-    native_handle_t* handle = native_handle_create(/*numFds=*/0, /*numInts=*/1 + numIntsForHMAC);
-    handle->data[0] = mLastTokenId;
-    // Set all the the bits of last int to 0 since it might not be fully overwritten
-    handle->data[numIntsForHMAC] = 0;
-    memcpy(&handle->data[1], hmac.data(), hmacSize);
-
-    // returnToken owns the native_handle_t* thus doing lifecycle management
-    hidl_handle returnToken;
-    returnToken.setTo(handle, /*shoudOwn=*/true);
-
-    std::vector<uint8_t> hmacVec;
-    hmacVec.resize(hmacSize);
-    memcpy(hmacVec.data(), hmac.data(), hmacSize);
-    mTokenMap.emplace(mLastTokenId, std::pair(hmacVec, client));
-
-    return returnToken;
-}
-
-void BufferHubService::onClientClosed(const BufferClient* client) {
-    removeTokenByClient(client);
-
-    std::lock_guard<std::mutex> lock(mClientSetMutex);
-    auto iter = std::find(mClientSet.begin(), mClientSet.end(), client);
-    if (iter != mClientSet.end()) {
-        mClientSet.erase(iter);
-    }
-}
-
-// Implementation of this function should be consistent with the definition of bufferInfo handle in
-// ui/BufferHubDefs.h.
-hidl_handle BufferHubService::buildBufferInfo(char* bufferInfoStorage, int bufferId,
-                                              uint32_t clientBitMask, uint32_t userMetadataSize,
-                                              int metadataFd, int eventFd) {
-    native_handle_t* infoHandle =
-            native_handle_init(bufferInfoStorage, BufferHubDefs::kBufferInfoNumFds,
-                               BufferHubDefs::kBufferInfoNumInts);
-
-    infoHandle->data[0] = metadataFd;
-    infoHandle->data[1] = eventFd;
-    infoHandle->data[2] = bufferId;
-    // Use memcpy to convert to int without missing digit.
-    // TOOD(b/121345852): use bit_cast to unpack bufferInfo when C++20 becomes available.
-    memcpy(&infoHandle->data[3], &clientBitMask, sizeof(clientBitMask));
-    memcpy(&infoHandle->data[4], &userMetadataSize, sizeof(userMetadataSize));
-
-    hidl_handle bufferInfo;
-    bufferInfo.setTo(infoHandle, /*shouldOwn=*/false);
-
-    return bufferInfo;
-}
-
-void BufferHubService::removeTokenByClient(const BufferClient* client) {
-    std::lock_guard<std::mutex> lock(mTokenMutex);
-    auto iter = mTokenMap.begin();
-    while (iter != mTokenMap.end()) {
-        if (iter->second.second == client) {
-            auto oldIter = iter;
-            ++iter;
-            mTokenMap.erase(oldIter);
-        } else {
-            ++iter;
-        }
-    }
-}
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace bufferhub
-} // namespace frameworks
-} // namespace android
diff --git a/services/bufferhub/BufferNode.cpp b/services/bufferhub/BufferNode.cpp
deleted file mode 100644
index 04ca649..0000000
--- a/services/bufferhub/BufferNode.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-#include <errno.h>
-
-#include <bufferhub/BufferHubService.h>
-#include <bufferhub/BufferNode.h>
-#include <log/log.h>
-#include <ui/GraphicBufferAllocator.h>
-
-namespace android {
-namespace frameworks {
-namespace bufferhub {
-namespace V1_0 {
-namespace implementation {
-
-void BufferNode::initializeMetadata() {
-    // Using placement new here to reuse shared memory instead of new allocation
-    // Initialize the atomic variables to zero.
-    BufferHubDefs::MetadataHeader* metadataHeader = mMetadata.metadataHeader();
-    mBufferState = new (&metadataHeader->bufferState) std::atomic<uint32_t>(0);
-    mFenceState = new (&metadataHeader->fenceState) std::atomic<uint32_t>(0);
-    mActiveClientsBitMask = new (&metadataHeader->activeClientsBitMask) std::atomic<uint32_t>(0);
-    // The C++ standard recommends (but does not require) that lock-free atomic operations are
-    // also address-free, that is, suitable for communication between processes using shared
-    // memory.
-    LOG_ALWAYS_FATAL_IF(!std::atomic_is_lock_free(mBufferState) ||
-                                !std::atomic_is_lock_free(mFenceState) ||
-                                !std::atomic_is_lock_free(mActiveClientsBitMask),
-                        "Atomic variables in ashmen are not lock free.");
-}
-
-// Allocates a new BufferNode.
-BufferNode::BufferNode(uint32_t width, uint32_t height, uint32_t layerCount, uint32_t format,
-                       uint64_t usage, size_t userMetadataSize, int id)
-      : mId(id) {
-    uint32_t outStride = 0;
-    // graphicBufferId is not used in GraphicBufferAllocator::allocate
-    // TODO(b/112338294) After move to the service folder, stop using the
-    // hardcoded service name "bufferhub".
-    int ret = GraphicBufferAllocator::get().allocate(width, height, format, layerCount, usage,
-                                                     const_cast<const native_handle_t**>(
-                                                             &mBufferHandle),
-                                                     &outStride,
-                                                     /*graphicBufferId=*/0,
-                                                     /*requestor=*/"bufferhub");
-
-    if (ret != OK || mBufferHandle == nullptr) {
-        ALOGE("%s: Failed to allocate buffer: %s", __FUNCTION__, strerror(-ret));
-        return;
-    }
-
-    mBufferDesc.width = width;
-    mBufferDesc.height = height;
-    mBufferDesc.layers = layerCount;
-    mBufferDesc.format = format;
-    mBufferDesc.usage = usage;
-    mBufferDesc.stride = outStride;
-
-    mMetadata = BufferHubMetadata::create(userMetadataSize);
-    if (!mMetadata.isValid()) {
-        ALOGE("%s: Failed to allocate metadata.", __FUNCTION__);
-        return;
-    }
-    initializeMetadata();
-}
-
-BufferNode::~BufferNode() {
-    // Free the handle
-    if (mBufferHandle != nullptr) {
-        status_t ret = GraphicBufferAllocator::get().free(mBufferHandle);
-        if (ret != OK) {
-            ALOGE("%s: Failed to free handle; Got error: %d", __FUNCTION__, ret);
-        }
-    }
-
-    // Free the id, if valid
-    if (mId >= 0) {
-        BufferHubIdGenerator::getInstance().freeId(mId);
-    }
-}
-
-uint32_t BufferNode::getActiveClientsBitMask() const {
-    return mActiveClientsBitMask->load(std::memory_order_acquire);
-}
-
-uint32_t BufferNode::addNewActiveClientsBitToMask() {
-    uint32_t currentActiveClientsBitMask = getActiveClientsBitMask();
-    uint32_t clientStateMask = 0U;
-    uint32_t updatedActiveClientsBitMask = 0U;
-    do {
-        clientStateMask =
-                BufferHubDefs::findNextAvailableClientStateMask(currentActiveClientsBitMask);
-        if (clientStateMask == 0U) {
-            ALOGE("%s: reached the maximum number of channels per buffer node: %d.", __FUNCTION__,
-                  BufferHubDefs::kMaxNumberOfClients);
-            errno = E2BIG;
-            return 0U;
-        }
-        updatedActiveClientsBitMask = currentActiveClientsBitMask | clientStateMask;
-    } while (!(mActiveClientsBitMask->compare_exchange_weak(currentActiveClientsBitMask,
-                                                            updatedActiveClientsBitMask,
-                                                            std::memory_order_acq_rel,
-                                                            std::memory_order_acquire)));
-    return clientStateMask;
-}
-
-void BufferNode::removeClientsBitFromMask(const uint32_t& value) {
-    mActiveClientsBitMask->fetch_and(~value);
-}
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace bufferhub
-} // namespace frameworks
-} // namespace android
diff --git a/services/bufferhub/android.frameworks.bufferhub@1.0-service.rc b/services/bufferhub/android.frameworks.bufferhub@1.0-service.rc
deleted file mode 100644
index 36fbede..0000000
--- a/services/bufferhub/android.frameworks.bufferhub@1.0-service.rc
+++ /dev/null
@@ -1,6 +0,0 @@
-service system_bufferhub /system/bin/hw/android.frameworks.bufferhub@1.0-service
-  class hal animation
-  user system
-  group system graphics
-  onrestart restart surfaceflinger
-  writepid /dev/cpuset/system-background/tasks
diff --git a/services/bufferhub/android.frameworks.bufferhub@1.0-service.xml b/services/bufferhub/android.frameworks.bufferhub@1.0-service.xml
deleted file mode 100644
index bd958d3..0000000
--- a/services/bufferhub/android.frameworks.bufferhub@1.0-service.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest version="1.0" type="framework">
-    <hal>
-        <name>android.frameworks.bufferhub</name>
-        <transport>hwbinder</transport>
-        <version>1.0</version>
-        <interface>
-            <name>IBufferHub</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-</manifest>
diff --git a/services/bufferhub/include/bufferhub/BufferClient.h b/services/bufferhub/include/bufferhub/BufferClient.h
deleted file mode 100644
index 644b403..0000000
--- a/services/bufferhub/include/bufferhub/BufferClient.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_CLIENT_H
-#define ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_CLIENT_H
-
-#include <mutex>
-
-#include <android/frameworks/bufferhub/1.0/IBufferClient.h>
-#include <bufferhub/BufferNode.h>
-
-namespace android {
-namespace frameworks {
-namespace bufferhub {
-namespace V1_0 {
-namespace implementation {
-
-using hardware::hidl_handle;
-using hardware::Return;
-
-// Forward declaration to avoid circular dependency
-class BufferHubService;
-
-class BufferClient : public IBufferClient {
-public:
-    // Creates a server-side buffer client from an existing BufferNode. Note that
-    // this function takes ownership of the shared_ptr.
-    // Returns a raw pointer to the BufferClient on success, nullptr on failure.
-    static BufferClient* create(BufferHubService* service, const std::shared_ptr<BufferNode>& node);
-
-    // Creates a BufferClient from an existing BufferClient. Will share the same BufferNode.
-    explicit BufferClient(const BufferClient& other)
-          : mService(other.mService), mBufferNode(other.mBufferNode) {}
-    ~BufferClient();
-
-    Return<BufferHubStatus> close() override;
-    Return<void> duplicate(duplicate_cb _hidl_cb) override;
-
-    // Non-binder functions
-    const std::shared_ptr<BufferNode>& getBufferNode() const { return mBufferNode; }
-
-private:
-    BufferClient(wp<BufferHubService> service, const std::shared_ptr<BufferNode>& node)
-          : mService(service), mBufferNode(node) {}
-
-    sp<BufferHubService> getService();
-
-    wp<BufferHubService> mService;
-
-    std::mutex mClosedMutex;
-    bool mClosed GUARDED_BY(mClosedMutex) = false;
-
-    std::shared_ptr<BufferNode> mBufferNode;
-};
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace bufferhub
-} // namespace frameworks
-} // namespace android
-
-#endif
diff --git a/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h b/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h
deleted file mode 100644
index ef7c077..0000000
--- a/services/bufferhub/include/bufferhub/BufferHubIdGenerator.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_ID_GENERATOR_H
-#define ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_ID_GENERATOR_H
-
-#include <mutex>
-#include <set>
-
-#include <utils/Mutex.h>
-
-namespace android {
-namespace frameworks {
-namespace bufferhub {
-namespace V1_0 {
-namespace implementation {
-
-// A thread-safe, non-negative, incremental, int id generator.
-class BufferHubIdGenerator {
-public:
-    // Get the singleton instance of this class
-    static BufferHubIdGenerator& getInstance();
-
-    // Gets next available id. If next id is greater than std::numeric_limits<int32_t>::max(), it
-    // will try to get an id start from 0 again.
-    int getId();
-
-    // Free a specific id.
-    void freeId(int id);
-
-private:
-    BufferHubIdGenerator() = default;
-    ~BufferHubIdGenerator() = default;
-
-    // Start from -1 so all valid ids will be >= 0
-    int mLastId = -1;
-
-    std::mutex mIdsInUseMutex;
-    std::set<int> mIdsInUse GUARDED_BY(mIdsInUseMutex);
-};
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace bufferhub
-} // namespace frameworks
-} // namespace android
-
-#endif // ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_ID_GENERATOR_H
diff --git a/services/bufferhub/include/bufferhub/BufferHubService.h b/services/bufferhub/include/bufferhub/BufferHubService.h
deleted file mode 100644
index edad20b..0000000
--- a/services/bufferhub/include/bufferhub/BufferHubService.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_HUB_SERVICE_H
-#define ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_HUB_SERVICE_H
-
-#include <map>
-#include <mutex>
-#include <set>
-#include <vector>
-
-#include <android/frameworks/bufferhub/1.0/IBufferHub.h>
-#include <bufferhub/BufferClient.h>
-#include <bufferhub/BufferHubIdGenerator.h>
-#include <utils/Mutex.h>
-
-namespace android {
-namespace frameworks {
-namespace bufferhub {
-namespace V1_0 {
-namespace implementation {
-
-using hardware::hidl_handle;
-using hardware::hidl_string;
-using hardware::hidl_vec;
-using hardware::Return;
-using hardware::graphics::common::V1_2::HardwareBufferDescription;
-
-class BufferHubService : public IBufferHub {
-public:
-    BufferHubService();
-
-    Return<void> allocateBuffer(const HardwareBufferDescription& description,
-                                const uint32_t userMetadataSize,
-                                allocateBuffer_cb _hidl_cb) override;
-    Return<void> importBuffer(const hidl_handle& tokenHandle, importBuffer_cb _hidl_cb) override;
-
-    Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
-
-    // Non-binder functions
-    // Internal help function for IBufferClient::duplicate.
-    hidl_handle registerToken(const wp<BufferClient>& client);
-
-    void onClientClosed(const BufferClient* client);
-
-private:
-    // Helper function to build BufferTraits.bufferInfo handle
-    hidl_handle buildBufferInfo(char* bufferInfoStorage, int bufferId, uint32_t clientBitMask,
-                                uint32_t userMetadataSize, int metadataFd, int eventFd);
-
-    // Helper function to remove all the token belongs to a specific client.
-    void removeTokenByClient(const BufferClient* client);
-
-    // List of active BufferClient for bookkeeping.
-    std::mutex mClientSetMutex;
-    std::set<wp<BufferClient>> mClientSet GUARDED_BY(mClientSetMutex);
-
-    // Token generation related
-    // A random number used as private key for HMAC
-    uint64_t mKey;
-    static constexpr size_t kKeyLen = sizeof(uint64_t);
-
-    std::mutex mTokenMutex;
-    // The first TokenId will be 1. TokenId could be negative.
-    int mLastTokenId GUARDED_BY(mTokenMutex) = 0;
-    static constexpr size_t mTokenIdSize = sizeof(int);
-    // A map from token id to the token-buffer_client pair. Using token id as the key to reduce
-    // looking up time
-    std::map<int, std::pair<std::vector<uint8_t>, const wp<BufferClient>>> mTokenMap
-            GUARDED_BY(mTokenMutex);
-};
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace bufferhub
-} // namespace frameworks
-} // namespace android
-
-#endif // ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_HUB_SERVICE_H
diff --git a/services/bufferhub/include/bufferhub/BufferNode.h b/services/bufferhub/include/bufferhub/BufferNode.h
deleted file mode 100644
index 62a8d63..0000000
--- a/services/bufferhub/include/bufferhub/BufferNode.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_NODE_H_
-#define ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_NODE_H_
-
-#include <android/hardware_buffer.h>
-#include <bufferhub/BufferHubIdGenerator.h>
-#include <cutils/native_handle.h>
-#include <ui/BufferHubEventFd.h>
-#include <ui/BufferHubMetadata.h>
-
-namespace android {
-namespace frameworks {
-namespace bufferhub {
-namespace V1_0 {
-namespace implementation {
-
-class BufferNode {
-public:
-    // Allocates a new BufferNode.
-    BufferNode(uint32_t width, uint32_t height, uint32_t layerCount, uint32_t format,
-               uint64_t usage, size_t userMetadataSize, int id = -1);
-
-    ~BufferNode();
-
-    // Returns whether the object holds a valid metadata.
-    bool isValid() const { return mMetadata.isValid(); }
-
-    int id() const { return mId; }
-
-    size_t userMetadataSize() const { return mMetadata.userMetadataSize(); }
-
-    // Accessors of the buffer description and handle
-    const native_handle_t* bufferHandle() const { return mBufferHandle; }
-    const AHardwareBuffer_Desc& bufferDesc() const { return mBufferDesc; }
-
-    // Accessor of event fd.
-    const BufferHubEventFd& eventFd() const { return mEventFd; }
-
-    // Accessors of mMetadata.
-    const BufferHubMetadata& metadata() const { return mMetadata; }
-
-    // Gets the current value of mActiveClientsBitMask in mMetadata with
-    // std::memory_order_acquire, so that all previous releases of
-    // mActiveClientsBitMask from all threads will be returned here.
-    uint32_t getActiveClientsBitMask() const;
-
-    // Find and add a new client state mask to mActiveClientsBitMask in
-    // mMetadata.
-    // Return the new client state mask that is added to mActiveClientsBitMask.
-    // Return 0U if there are already 16 clients of the buffer.
-    uint32_t addNewActiveClientsBitToMask();
-
-    // Removes the value from active_clients_bit_mask in mMetadata with
-    // std::memory_order_release, so that the change will be visible to any
-    // acquire of mActiveClientsBitMask in any threads after the succeed of
-    // this operation.
-    void removeClientsBitFromMask(const uint32_t& value);
-
-private:
-    // Helper method for constructors to initialize atomic metadata header
-    // variables in shared memory.
-    void initializeMetadata();
-
-    // Gralloc buffer handles.
-    native_handle_t* mBufferHandle;
-    AHardwareBuffer_Desc mBufferDesc;
-
-    // Eventfd used for signalling buffer events among the clients of the buffer.
-    BufferHubEventFd mEventFd;
-
-    // Metadata in shared memory.
-    BufferHubMetadata mMetadata;
-
-    // A system-unique id generated by bufferhub from 0 to std::numeric_limits<int>::max().
-    // BufferNodes not created by bufferhub will have id < 0, meaning "not specified".
-    // TODO(b/118891412): remove default id = -1 and update comments after pdx is no longer in use
-    const int mId = -1;
-
-    // The following variables are atomic variables in mMetadata that are visible
-    // to Bn object and Bp objects. Please find more info in
-    // BufferHubDefs::MetadataHeader.
-
-    // mBufferState tracks the state of the buffer. Buffer can be in one of these
-    // four states: gained, posted, acquired, released.
-    std::atomic<uint32_t>* mBufferState = nullptr;
-
-    // TODO(b/112012161): add comments to mFenceState.
-    std::atomic<uint32_t>* mFenceState = nullptr;
-
-    // mActiveClientsBitMask tracks all the bp clients of the buffer. It is the
-    // union of all client_state_mask of all bp clients.
-    std::atomic<uint32_t>* mActiveClientsBitMask = nullptr;
-};
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace bufferhub
-} // namespace frameworks
-} // namespace android
-
-#endif // ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_NODE_H_
diff --git a/services/bufferhub/main_bufferhub.cpp b/services/bufferhub/main_bufferhub.cpp
deleted file mode 100644
index 084460d..0000000
--- a/services/bufferhub/main_bufferhub.cpp
+++ /dev/null
@@ -1,37 +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.
- */
-
-#include <bufferhub/BufferHubService.h>
-#include <hidl/HidlTransportSupport.h>
-#include <hwbinder/IPCThreadState.h>
-#include <log/log.h>
-
-using android::sp;
-using android::frameworks::bufferhub::V1_0::IBufferHub;
-using android::frameworks::bufferhub::V1_0::implementation::BufferHubService;
-
-int main(int /*argc*/, char** /*argv*/) {
-    ALOGI("Bootstrap bufferhub HIDL service.");
-
-    android::hardware::configureRpcThreadpool(/*numThreads=*/1, /*willJoin=*/true);
-
-    sp<IBufferHub> service = new BufferHubService();
-    LOG_ALWAYS_FATAL_IF(service->registerAsService() != android::OK, "Failed to register service");
-
-    android::hardware::joinRpcThreadpool();
-
-    return 0;
-}
diff --git a/services/bufferhub/tests/Android.bp b/services/bufferhub/tests/Android.bp
deleted file mode 100644
index 3033e70..0000000
--- a/services/bufferhub/tests/Android.bp
+++ /dev/null
@@ -1,26 +0,0 @@
-cc_test {
-    name: "BufferHubServer_test",
-    srcs: [
-        "BufferNode_test.cpp",
-        "BufferHubIdGenerator_test.cpp",
-    ],
-    cflags: [
-        "-DLOG_TAG=\"BufferHubServer_test\"",
-        "-DTRACE=0",
-        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
-        "-Wall",
-        "-Werror",
-    ],
-    compile_multilib: "first",
-    header_libs: [
-        "libdvr_headers",
-        "libnativewindow_headers",
-    ],
-    shared_libs: [
-        "libbufferhubservice",
-        "libui",
-    ],
-    static_libs: [
-        "libgmock",
-    ],
-}
diff --git a/services/bufferhub/tests/BufferHubIdGenerator_test.cpp b/services/bufferhub/tests/BufferHubIdGenerator_test.cpp
deleted file mode 100644
index fb6de0d..0000000
--- a/services/bufferhub/tests/BufferHubIdGenerator_test.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <bufferhub/BufferHubIdGenerator.h>
-#include <gtest/gtest.h>
-
-namespace android {
-namespace frameworks {
-namespace bufferhub {
-namespace V1_0 {
-namespace implementation {
-
-namespace {
-
-class BufferHubIdGeneratorTest : public testing::Test {
-protected:
-    BufferHubIdGenerator* mIdGenerator = &BufferHubIdGenerator::getInstance();
-};
-
-TEST_F(BufferHubIdGeneratorTest, TestGenerateAndFreeID) {
-    int id = mIdGenerator->getId();
-    EXPECT_GE(id, 0);
-
-    mIdGenerator->freeId(id);
-}
-
-TEST_F(BufferHubIdGeneratorTest, TestGenerateUniqueIncrementalID) {
-    // 10 IDs should not overflow the UniqueIdGenerator to cause a roll back to start, so the
-    // resulting IDs should still keep incresing.
-    const int kTestSize = 10;
-    int ids[kTestSize];
-    for (int i = 0; i < kTestSize; ++i) {
-        ids[i] = mIdGenerator->getId();
-        EXPECT_GE(ids[i], 0);
-        if (i >= 1) {
-            EXPECT_GT(ids[i], ids[i - 1]);
-        }
-    }
-
-    for (int i = 0; i < kTestSize; ++i) {
-        mIdGenerator->freeId(ids[i]);
-    }
-}
-
-} // namespace
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace bufferhub
-} // namespace frameworks
-} // namespace android
\ No newline at end of file
diff --git a/services/bufferhub/tests/BufferNode_test.cpp b/services/bufferhub/tests/BufferNode_test.cpp
deleted file mode 100644
index 2dfd4fc..0000000
--- a/services/bufferhub/tests/BufferNode_test.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-#include <errno.h>
-
-#include <bufferhub/BufferNode.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <ui/BufferHubDefs.h>
-#include <ui/GraphicBufferMapper.h>
-
-namespace android {
-namespace frameworks {
-namespace bufferhub {
-namespace V1_0 {
-namespace implementation {
-
-namespace {
-
-using testing::NotNull;
-
-const uint32_t kWidth = 640;
-const uint32_t kHeight = 480;
-const uint32_t kLayerCount = 1;
-const uint32_t kFormat = 1;
-const uint64_t kUsage = 0;
-const size_t kUserMetadataSize = 0;
-
-class BufferNodeTest : public ::testing::Test {
-protected:
-    void SetUp() override {
-        mBufferNode =
-                new BufferNode(kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize);
-        ASSERT_TRUE(mBufferNode->isValid());
-    }
-
-    void TearDown() override {
-        if (mBufferNode != nullptr) {
-            delete mBufferNode;
-        }
-    }
-
-    BufferNode* mBufferNode = nullptr;
-};
-
-TEST_F(BufferNodeTest, TestCreateBufferNode) {
-    EXPECT_EQ(mBufferNode->userMetadataSize(), kUserMetadataSize);
-    // Test the handle just allocated is good (i.e. able to be imported)
-    GraphicBufferMapper& mapper = GraphicBufferMapper::get();
-    const native_handle_t* outHandle;
-    status_t ret =
-            mapper.importBuffer(mBufferNode->bufferHandle(), mBufferNode->bufferDesc().width,
-                                mBufferNode->bufferDesc().height, mBufferNode->bufferDesc().layers,
-                                mBufferNode->bufferDesc().format, mBufferNode->bufferDesc().usage,
-                                mBufferNode->bufferDesc().stride, &outHandle);
-    EXPECT_EQ(ret, OK);
-    EXPECT_THAT(outHandle, NotNull());
-}
-
-TEST_F(BufferNodeTest, TestaddNewActiveClientsBitToMask_twoNewClients) {
-    uint32_t newClientStateMask1 = mBufferNode->addNewActiveClientsBitToMask();
-    EXPECT_EQ(mBufferNode->getActiveClientsBitMask(), newClientStateMask1);
-
-    // Request and add a new client_state_mask again.
-    // Active clients bit mask should be the union of the two new
-    // client_state_masks.
-    uint32_t newClientStateMask2 = mBufferNode->addNewActiveClientsBitToMask();
-    EXPECT_EQ(mBufferNode->getActiveClientsBitMask(), newClientStateMask1 | newClientStateMask2);
-}
-
-TEST_F(BufferNodeTest, TestaddNewActiveClientsBitToMask_32NewClients) {
-    uint32_t newClientStateMask = 0U;
-    uint32_t currentMask = 0U;
-    uint32_t expectedMask = 0U;
-
-    for (int i = 0; i < BufferHubDefs::kMaxNumberOfClients; ++i) {
-        newClientStateMask = mBufferNode->addNewActiveClientsBitToMask();
-        EXPECT_NE(newClientStateMask, 0U);
-        EXPECT_FALSE(newClientStateMask & currentMask);
-        expectedMask = currentMask | newClientStateMask;
-        currentMask = mBufferNode->getActiveClientsBitMask();
-        EXPECT_EQ(currentMask, expectedMask);
-    }
-
-    // Method should fail upon requesting for more than maximum allowable clients.
-    newClientStateMask = mBufferNode->addNewActiveClientsBitToMask();
-    EXPECT_EQ(newClientStateMask, 0U);
-    EXPECT_EQ(errno, E2BIG);
-}
-
-TEST_F(BufferNodeTest, TestRemoveActiveClientsBitFromMask) {
-    mBufferNode->addNewActiveClientsBitToMask();
-    uint32_t currentMask = mBufferNode->getActiveClientsBitMask();
-    uint32_t newClientStateMask = mBufferNode->addNewActiveClientsBitToMask();
-    EXPECT_NE(mBufferNode->getActiveClientsBitMask(), currentMask);
-
-    mBufferNode->removeClientsBitFromMask(newClientStateMask);
-    EXPECT_EQ(mBufferNode->getActiveClientsBitMask(), currentMask);
-
-    // Remove the test_mask again to the active client bit mask should not modify
-    // the value of active clients bit mask.
-    mBufferNode->removeClientsBitFromMask(newClientStateMask);
-    EXPECT_EQ(mBufferNode->getActiveClientsBitMask(), currentMask);
-}
-
-} // namespace
-
-} // namespace implementation
-} // namespace V1_0
-} // namespace bufferhub
-} // namespace frameworks
-} // namespace android
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index fc771a2..e68946d 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -111,8 +111,10 @@
         handlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>());
         handlesPerDisplay[info.displayId].push_back(new BinderWindowHandle(info));
     }
-    for (auto const& i : handlesPerDisplay) {
-        mDispatcher->setInputWindows(i.second, i.first, setInputWindowsListener);
+    mDispatcher->setInputWindows(handlesPerDisplay);
+
+    if (setInputWindowsListener) {
+        setInputWindowsListener->onSetInputWindowsFinished();
     }
 }
 
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index 3b18813..7c5c9c5 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -252,7 +252,7 @@
     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
     sp<FakeWindowHandle> window = new FakeWindowHandle(application, dispatcher, "Fake Window");
 
-    dispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    dispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     NotifyMotionArgs motionArgs = generateMotionArgs();
 
@@ -288,7 +288,7 @@
     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
     sp<FakeWindowHandle> window = new FakeWindowHandle(application, dispatcher, "Fake Window");
 
-    dispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    dispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     for (auto _ : state) {
         MotionEvent event = generateMotionEvent();
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 308d19b..4ec61b0 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3621,6 +3621,18 @@
     mWindowHandlesByDisplay[displayId] = newHandles;
 }
 
+void InputDispatcher::setInputWindows(
+        const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
+    { // acquire lock
+        std::scoped_lock _l(mLock);
+        for (auto const& i : handlesPerDisplay) {
+            setInputWindowsLocked(i.second, i.first);
+        }
+    }
+    // Wake up poll loop since it may need to make new input dispatching choices.
+    mLooper->wake();
+}
+
 /**
  * Called from InputManagerService, update window handle list by displayId that can receive input.
  * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
@@ -3628,9 +3640,8 @@
  * For focused handle, check if need to change and send a cancel event to previous one.
  * For removed handle, check if need to send a cancel event if already in touch.
  */
-void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
-                                      int32_t displayId,
-                                      const sp<ISetInputWindowsListener>& setInputWindowsListener) {
+void InputDispatcher::setInputWindowsLocked(
+        const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
     if (DEBUG_FOCUS) {
         std::string windowList;
         for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
@@ -3638,109 +3649,97 @@
         }
         ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
     }
-    { // acquire lock
-        std::scoped_lock _l(mLock);
 
-        // Copy old handles for release if they are no longer present.
-        const std::vector<sp<InputWindowHandle>> oldWindowHandles =
-                getWindowHandlesLocked(displayId);
+    // Copy old handles for release if they are no longer present.
+    const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
 
-        updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
+    updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
 
-        sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
-        bool foundHoveredWindow = false;
-        for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
-            // Set newFocusedWindowHandle to the top most focused window instead of the last one
-            if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
-                windowHandle->getInfo()->visible) {
-                newFocusedWindowHandle = windowHandle;
+    sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
+    bool foundHoveredWindow = false;
+    for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
+        // Set newFocusedWindowHandle to the top most focused window instead of the last one
+        if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
+            windowHandle->getInfo()->visible) {
+            newFocusedWindowHandle = windowHandle;
+        }
+        if (windowHandle == mLastHoverWindowHandle) {
+            foundHoveredWindow = true;
+        }
+    }
+
+    if (!foundHoveredWindow) {
+        mLastHoverWindowHandle = nullptr;
+    }
+
+    sp<InputWindowHandle> oldFocusedWindowHandle =
+            getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
+
+    if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
+        if (oldFocusedWindowHandle != nullptr) {
+            if (DEBUG_FOCUS) {
+                ALOGD("Focus left window: %s in display %" PRId32,
+                      oldFocusedWindowHandle->getName().c_str(), displayId);
             }
-            if (windowHandle == mLastHoverWindowHandle) {
-                foundHoveredWindow = true;
+            sp<InputChannel> focusedInputChannel =
+                    getInputChannelLocked(oldFocusedWindowHandle->getToken());
+            if (focusedInputChannel != nullptr) {
+                CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
+                                           "focus left window");
+                synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
+                enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
             }
+            mFocusedWindowHandlesByDisplay.erase(displayId);
+        }
+        if (newFocusedWindowHandle != nullptr) {
+            if (DEBUG_FOCUS) {
+                ALOGD("Focus entered window: %s in display %" PRId32,
+                      newFocusedWindowHandle->getName().c_str(), displayId);
+            }
+            mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
+            enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
         }
 
-        if (!foundHoveredWindow) {
-            mLastHoverWindowHandle = nullptr;
+        if (mFocusedDisplayId == displayId) {
+            onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
         }
+    }
 
-        sp<InputWindowHandle> oldFocusedWindowHandle =
-                getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
-
-        if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
-            if (oldFocusedWindowHandle != nullptr) {
+    ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
+    if (stateIndex >= 0) {
+        TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
+        for (size_t i = 0; i < state.windows.size();) {
+            TouchedWindow& touchedWindow = state.windows[i];
+            if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
                 if (DEBUG_FOCUS) {
-                    ALOGD("Focus left window: %s in display %" PRId32,
-                          oldFocusedWindowHandle->getName().c_str(), displayId);
+                    ALOGD("Touched window was removed: %s in display %" PRId32,
+                          touchedWindow.windowHandle->getName().c_str(), displayId);
                 }
-                sp<InputChannel> focusedInputChannel =
-                        getInputChannelLocked(oldFocusedWindowHandle->getToken());
-                if (focusedInputChannel != nullptr) {
-                    CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
-                                               "focus left window");
-                    synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
-                    enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
+                sp<InputChannel> touchedInputChannel =
+                        getInputChannelLocked(touchedWindow.windowHandle->getToken());
+                if (touchedInputChannel != nullptr) {
+                    CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
+                                               "touched window was removed");
+                    synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
                 }
-                mFocusedWindowHandlesByDisplay.erase(displayId);
-            }
-            if (newFocusedWindowHandle != nullptr) {
-                if (DEBUG_FOCUS) {
-                    ALOGD("Focus entered window: %s in display %" PRId32,
-                          newFocusedWindowHandle->getName().c_str(), displayId);
-                }
-                mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
-                enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
-            }
-
-            if (mFocusedDisplayId == displayId) {
-                onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
+                state.windows.erase(state.windows.begin() + i);
+            } else {
+                ++i;
             }
         }
+    }
 
-        ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
-        if (stateIndex >= 0) {
-            TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
-            for (size_t i = 0; i < state.windows.size();) {
-                TouchedWindow& touchedWindow = state.windows[i];
-                if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
-                    if (DEBUG_FOCUS) {
-                        ALOGD("Touched window was removed: %s in display %" PRId32,
-                              touchedWindow.windowHandle->getName().c_str(), displayId);
-                    }
-                    sp<InputChannel> touchedInputChannel =
-                            getInputChannelLocked(touchedWindow.windowHandle->getToken());
-                    if (touchedInputChannel != nullptr) {
-                        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
-                                                   "touched window was removed");
-                        synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
-                                                                         options);
-                    }
-                    state.windows.erase(state.windows.begin() + i);
-                } else {
-                    ++i;
-                }
+    // Release information for windows that are no longer present.
+    // This ensures that unused input channels are released promptly.
+    // Otherwise, they might stick around until the window handle is destroyed
+    // which might not happen until the next GC.
+    for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
+        if (!hasWindowHandleLocked(oldWindowHandle)) {
+            if (DEBUG_FOCUS) {
+                ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
             }
+            oldWindowHandle->releaseChannel();
         }
-
-        // Release information for windows that are no longer present.
-        // This ensures that unused input channels are released promptly.
-        // Otherwise, they might stick around until the window handle is destroyed
-        // which might not happen until the next GC.
-        for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
-            if (!hasWindowHandleLocked(oldWindowHandle)) {
-                if (DEBUG_FOCUS) {
-                    ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
-                }
-                oldWindowHandle->releaseChannel();
-            }
-        }
-    } // release lock
-
-    // Wake up poll loop since it may need to make new input dispatching choices.
-    mLooper->wake();
-
-    if (setInputWindowsListener) {
-        setInputWindowsListener->onSetInputWindowsFinished();
     }
 }
 
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 4aa47f8..cbba7e1 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -109,8 +109,8 @@
     virtual std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) override;
 
     virtual void setInputWindows(
-            const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId,
-            const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) override;
+            const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
+                    handlesPerDisplay) override;
     virtual void setFocusedApplication(
             int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) override;
     virtual void setFocusedDisplay(int32_t displayId) override;
@@ -278,6 +278,8 @@
 
     std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay
             GUARDED_BY(mLock);
+    void setInputWindowsLocked(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
+                               int32_t displayId) REQUIRES(mLock);
     // Get window handles by display, return an empty vector if not found.
     std::vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const
             REQUIRES(mLock);
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 6e98676..09dc92c 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -19,6 +19,7 @@
 
 #include <InputListener.h>
 #include <input/ISetInputWindowsListener.h>
+#include <unordered_map>
 
 namespace android {
 
@@ -99,13 +100,13 @@
      */
     virtual std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) = 0;
 
-    /* Sets the list of input windows.
+    /* Sets the list of input windows per display.
      *
      * This method may be called on any thread (usually by the input manager).
      */
     virtual void setInputWindows(
-            const std::vector<sp<InputWindowHandle> >& inputWindowHandles, int32_t displayId,
-            const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) = 0;
+            const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
+                    handlesPerDisplay) = 0;
 
     /* Sets the focused application on the given display.
      *
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index bbc8e53..99a572a 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -160,8 +160,8 @@
       : InputMapper(deviceContext),
         mSource(0),
         mDeviceMode(DEVICE_MODE_DISABLED),
-        mSurfaceWidth(-1),
-        mSurfaceHeight(-1),
+        mRawSurfaceWidth(-1),
+        mRawSurfaceHeight(-1),
         mSurfaceLeft(0),
         mSurfaceTop(0),
         mPhysicalWidth(-1),
@@ -680,7 +680,7 @@
                     naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
                     naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
                     naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
-                    naturalPhysicalLeft = mViewport.deviceHeight - naturalPhysicalWidth;
+                    naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
                     naturalPhysicalTop = mViewport.physicalLeft;
                     naturalDeviceWidth = mViewport.deviceHeight;
                     naturalDeviceHeight = mViewport.deviceWidth;
@@ -701,7 +701,7 @@
                     naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
                     naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
                     naturalPhysicalLeft = mViewport.physicalTop;
-                    naturalPhysicalTop = mViewport.deviceWidth - naturalPhysicalHeight;
+                    naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
                     naturalDeviceWidth = mViewport.deviceHeight;
                     naturalDeviceHeight = mViewport.deviceWidth;
                     break;
@@ -729,10 +729,12 @@
             mPhysicalLeft = naturalPhysicalLeft;
             mPhysicalTop = naturalPhysicalTop;
 
-            mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
-            mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
+            mRawSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
+            mRawSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
             mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
             mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
+            mSurfaceRight = mSurfaceLeft + naturalLogicalWidth;
+            mSurfaceBottom = mSurfaceTop + naturalLogicalHeight;
 
             mSurfaceOrientation =
                     mParameters.orientationAware ? mViewport.orientation : DISPLAY_ORIENTATION_0;
@@ -742,8 +744,8 @@
             mPhysicalLeft = 0;
             mPhysicalTop = 0;
 
-            mSurfaceWidth = rawWidth;
-            mSurfaceHeight = rawHeight;
+            mRawSurfaceWidth = rawWidth;
+            mRawSurfaceHeight = rawHeight;
             mSurfaceLeft = 0;
             mSurfaceTop = 0;
             mSurfaceOrientation = DISPLAY_ORIENTATION_0;
@@ -769,12 +771,12 @@
     if (viewportChanged || deviceModeChanged) {
         ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
               "display id %d",
-              getDeviceId(), getDeviceName().c_str(), mSurfaceWidth, mSurfaceHeight,
+              getDeviceId(), getDeviceName().c_str(), mRawSurfaceWidth, mRawSurfaceHeight,
               mSurfaceOrientation, mDeviceMode, mViewport.displayId);
 
         // Configure X and Y factors.
-        mXScale = float(mSurfaceWidth) / rawWidth;
-        mYScale = float(mSurfaceHeight) / rawHeight;
+        mXScale = float(mRawSurfaceWidth) / rawWidth;
+        mYScale = float(mRawSurfaceHeight) / rawHeight;
         mXTranslate = -mSurfaceLeft;
         mYTranslate = -mSurfaceTop;
         mXPrecision = 1.0f / mXScale;
@@ -793,7 +795,7 @@
         mGeometricScale = avg(mXScale, mYScale);
 
         // Size of diagonal axis.
-        float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
+        float diagonalSize = hypotf(mRawSurfaceWidth, mRawSurfaceHeight);
 
         // Size factors.
         if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
@@ -956,13 +958,13 @@
                 mOrientedYPrecision = mXPrecision;
 
                 mOrientedRanges.x.min = mYTranslate;
-                mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
+                mOrientedRanges.x.max = mRawSurfaceHeight + mYTranslate - 1;
                 mOrientedRanges.x.flat = 0;
                 mOrientedRanges.x.fuzz = 0;
                 mOrientedRanges.x.resolution = mRawPointerAxes.y.resolution * mYScale;
 
                 mOrientedRanges.y.min = mXTranslate;
-                mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
+                mOrientedRanges.y.max = mRawSurfaceWidth + mXTranslate - 1;
                 mOrientedRanges.y.flat = 0;
                 mOrientedRanges.y.fuzz = 0;
                 mOrientedRanges.y.resolution = mRawPointerAxes.x.resolution * mXScale;
@@ -973,13 +975,13 @@
                 mOrientedYPrecision = mYPrecision;
 
                 mOrientedRanges.x.min = mXTranslate;
-                mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
+                mOrientedRanges.x.max = mRawSurfaceWidth + mXTranslate - 1;
                 mOrientedRanges.x.flat = 0;
                 mOrientedRanges.x.fuzz = 0;
                 mOrientedRanges.x.resolution = mRawPointerAxes.x.resolution * mXScale;
 
                 mOrientedRanges.y.min = mYTranslate;
-                mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
+                mOrientedRanges.y.max = mRawSurfaceHeight + mYTranslate - 1;
                 mOrientedRanges.y.flat = 0;
                 mOrientedRanges.y.fuzz = 0;
                 mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale;
@@ -992,7 +994,7 @@
         if (mDeviceMode == DEVICE_MODE_POINTER) {
             // Compute pointer gesture detection parameters.
             float rawDiagonal = hypotf(rawWidth, rawHeight);
-            float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
+            float displayDiagonal = hypotf(mRawSurfaceWidth, mRawSurfaceHeight);
 
             // Scale movements such that one whole swipe of the touch pad covers a
             // given area relative to the diagonal size of the display when no acceleration
@@ -1027,10 +1029,12 @@
 
 void TouchInputMapper::dumpSurface(std::string& dump) {
     dump += StringPrintf(INDENT3 "%s\n", mViewport.toString().c_str());
-    dump += StringPrintf(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
-    dump += StringPrintf(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
+    dump += StringPrintf(INDENT3 "RawSurfaceWidth: %dpx\n", mRawSurfaceWidth);
+    dump += StringPrintf(INDENT3 "RawSurfaceHeight: %dpx\n", mRawSurfaceHeight);
     dump += StringPrintf(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
     dump += StringPrintf(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
+    dump += StringPrintf(INDENT3 "SurfaceRight: %d\n", mSurfaceRight);
+    dump += StringPrintf(INDENT3 "SurfaceBottom: %d\n", mSurfaceBottom);
     dump += StringPrintf(INDENT3 "PhysicalWidth: %dpx\n", mPhysicalWidth);
     dump += StringPrintf(INDENT3 "PhysicalHeight: %dpx\n", mPhysicalHeight);
     dump += StringPrintf(INDENT3 "PhysicalLeft: %d\n", mPhysicalLeft);
@@ -1074,16 +1078,16 @@
         int32_t halfHeight = virtualKeyDefinition.height / 2;
 
         virtualKey.hitLeft =
-                (virtualKeyDefinition.centerX - halfWidth) * touchScreenWidth / mSurfaceWidth +
+                (virtualKeyDefinition.centerX - halfWidth) * touchScreenWidth / mRawSurfaceWidth +
                 touchScreenLeft;
         virtualKey.hitRight =
-                (virtualKeyDefinition.centerX + halfWidth) * touchScreenWidth / mSurfaceWidth +
+                (virtualKeyDefinition.centerX + halfWidth) * touchScreenWidth / mRawSurfaceWidth +
                 touchScreenLeft;
-        virtualKey.hitTop =
-                (virtualKeyDefinition.centerY - halfHeight) * touchScreenHeight / mSurfaceHeight +
+        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight) * touchScreenHeight /
+                        mRawSurfaceHeight +
                 touchScreenTop;
-        virtualKey.hitBottom =
-                (virtualKeyDefinition.centerY + halfHeight) * touchScreenHeight / mSurfaceHeight +
+        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight) * touchScreenHeight /
+                        mRawSurfaceHeight +
                 touchScreenTop;
         mVirtualKeys.push_back(virtualKey);
     }
@@ -2188,13 +2192,10 @@
         rotateAndScale(xTransformed, yTransformed);
 
         // Adjust X, Y, and coverage coords for surface orientation.
-        float x, y;
         float left, top, right, bottom;
 
         switch (mSurfaceOrientation) {
             case DISPLAY_ORIENTATION_90:
-                x = yTransformed + mYTranslate;
-                y = xTransformed + mXTranslate;
                 left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
                 right = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
                 bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
@@ -2207,8 +2208,6 @@
                 }
                 break;
             case DISPLAY_ORIENTATION_180:
-                x = xTransformed + mXTranslate;
-                y = yTransformed + mYTranslate;
                 left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
                 right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
                 bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
@@ -2221,8 +2220,6 @@
                 }
                 break;
             case DISPLAY_ORIENTATION_270:
-                x = yTransformed + mYTranslate;
-                y = xTransformed + mXTranslate;
                 left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
                 right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
                 bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
@@ -2235,8 +2232,6 @@
                 }
                 break;
             default:
-                x = xTransformed + mXTranslate;
-                y = yTransformed + mYTranslate;
                 left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
                 right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
                 bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
@@ -2247,8 +2242,8 @@
         // Write output coords.
         PointerCoords& out = mCurrentCookedState.cookedPointerData.pointerCoords[i];
         out.clear();
-        out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
-        out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+        out.setAxisValue(AMOTION_EVENT_AXIS_X, xTransformed);
+        out.setAxisValue(AMOTION_EVENT_AXIS_Y, yTransformed);
         out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
         out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
         out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
@@ -3624,34 +3619,47 @@
     abortTouches(when, 0 /* policyFlags*/);
 }
 
+// Transform raw coordinate to surface coordinate
 void TouchInputMapper::rotateAndScale(float& x, float& y) {
+    // Scale to surface coordinate.
+    const float xScaled = float(x - mRawPointerAxes.x.minValue) * mXScale;
+    const float yScaled = float(y - mRawPointerAxes.y.minValue) * mYScale;
+
+    // Rotate to surface coordinate.
+    // 0 - no swap and reverse.
+    // 90 - swap x/y and reverse y.
+    // 180 - reverse x, y.
+    // 270 - swap x/y and reverse x.
     switch (mSurfaceOrientation) {
+        case DISPLAY_ORIENTATION_0:
+            x = xScaled + mXTranslate;
+            y = yScaled + mYTranslate;
+            break;
         case DISPLAY_ORIENTATION_90:
-            x = float(mRawPointerAxes.x.maxValue - x) * mXScale;
-            y = float(y - mRawPointerAxes.y.minValue) * mYScale;
+            y = mSurfaceRight - xScaled;
+            x = yScaled + mYTranslate;
             break;
         case DISPLAY_ORIENTATION_180:
-            x = float(mRawPointerAxes.x.maxValue - x) * mXScale;
-            y = float(mRawPointerAxes.y.maxValue - y) * mYScale;
+            x = mSurfaceRight - xScaled;
+            y = mSurfaceBottom - yScaled;
             break;
         case DISPLAY_ORIENTATION_270:
-            x = float(x - mRawPointerAxes.x.minValue) * mXScale;
-            y = float(mRawPointerAxes.y.maxValue - y) * mYScale;
+            y = xScaled + mXTranslate;
+            x = mSurfaceBottom - yScaled;
             break;
         default:
-            x = float(x - mRawPointerAxes.x.minValue) * mXScale;
-            y = float(y - mRawPointerAxes.y.minValue) * mYScale;
-            break;
+            assert(false);
     }
 }
 
 bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
-    float xTransformed = x, yTransformed = y;
-    rotateAndScale(xTransformed, yTransformed);
+    const float xScaled = (x - mRawPointerAxes.x.minValue) * mXScale;
+    const float yScaled = (y - mRawPointerAxes.y.minValue) * mYScale;
+
     return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue &&
-            xTransformed >= mSurfaceLeft && xTransformed <= mSurfaceLeft + mSurfaceWidth &&
+            xScaled >= mSurfaceLeft && xScaled <= mSurfaceRight &&
             y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue &&
-            yTransformed >= mSurfaceTop && yTransformed <= mSurfaceTop + mSurfaceHeight;
+            yScaled >= mSurfaceTop && yScaled <= mSurfaceBottom;
 }
 
 const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(int32_t x, int32_t y) {
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.h b/services/inputflinger/reader/mapper/TouchInputMapper.h
index e21a33a..58bfc5c 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.h
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.h
@@ -407,12 +407,16 @@
     // The surface orientation, width and height set by configureSurface().
     // The width and height are derived from the viewport but are specified
     // in the natural orientation.
+    // They could be used for calculating diagonal, scaling factors, and virtual keys.
+    int32_t mRawSurfaceWidth;
+    int32_t mRawSurfaceHeight;
+
     // The surface origin specifies how the surface coordinates should be translated
     // to align with the logical display coordinate space.
-    int32_t mSurfaceWidth;
-    int32_t mSurfaceHeight;
     int32_t mSurfaceLeft;
     int32_t mSurfaceTop;
+    int32_t mSurfaceRight;
+    int32_t mSurfaceBottom;
 
     // Similar to the surface coordinates, but in the raw display coordinate space rather than in
     // the logical coordinate space.
diff --git a/services/inputflinger/tests/EventHub_test.cpp b/services/inputflinger/tests/EventHub_test.cpp
index be2e19e..71731b0 100644
--- a/services/inputflinger/tests/EventHub_test.cpp
+++ b/services/inputflinger/tests/EventHub_test.cpp
@@ -34,6 +34,7 @@
 using android::sp;
 using android::UinputHomeKey;
 using std::chrono_literals::operator""ms;
+using std::chrono_literals::operator""s;
 
 static constexpr bool DEBUG = false;
 
@@ -70,11 +71,12 @@
         mEventHub = std::make_unique<EventHub>();
         consumeInitialDeviceAddedEvents();
         mKeyboard = createUinputDevice<UinputHomeKey>();
-        mDeviceId = waitForDeviceCreation();
+        ASSERT_NO_FATAL_FAILURE(mDeviceId = waitForDeviceCreation());
     }
     virtual void TearDown() override {
         mKeyboard.reset();
         waitForDeviceClose(mDeviceId);
+        assertNoMoreEvents();
     }
 
     /**
@@ -83,21 +85,38 @@
     int32_t waitForDeviceCreation();
     void waitForDeviceClose(int32_t deviceId);
     void consumeInitialDeviceAddedEvents();
-    std::vector<RawEvent> getEvents(std::chrono::milliseconds timeout = 5ms);
+    void assertNoMoreEvents();
+    /**
+     * Read events from the EventHub.
+     *
+     * If expectedEvents is set, wait for a significant period of time to try and ensure that
+     * the expected number of events has been read. The number of returned events
+     * may be smaller (if timeout has been reached) or larger than expectedEvents.
+     *
+     * If expectedEvents is not set, return all of the immediately available events.
+     */
+    std::vector<RawEvent> getEvents(std::optional<size_t> expectedEvents = std::nullopt);
 };
 
-std::vector<RawEvent> EventHubTest::getEvents(std::chrono::milliseconds timeout) {
+std::vector<RawEvent> EventHubTest::getEvents(std::optional<size_t> expectedEvents) {
     static constexpr size_t EVENT_BUFFER_SIZE = 256;
     std::array<RawEvent, EVENT_BUFFER_SIZE> eventBuffer;
     std::vector<RawEvent> events;
 
     while (true) {
-        size_t count =
+        std::chrono::milliseconds timeout = 0s;
+        if (expectedEvents) {
+            timeout = 2s;
+        }
+        const size_t count =
                 mEventHub->getEvents(timeout.count(), eventBuffer.data(), eventBuffer.size());
         if (count == 0) {
             break;
         }
         events.insert(events.end(), eventBuffer.begin(), eventBuffer.begin() + count);
+        if (expectedEvents && events.size() >= *expectedEvents) {
+            break;
+        }
     }
     if (DEBUG) {
         dumpEvents(events);
@@ -111,7 +130,7 @@
  * it will return a lot of "device added" type of events.
  */
 void EventHubTest::consumeInitialDeviceAddedEvents() {
-    std::vector<RawEvent> events = getEvents(0ms);
+    std::vector<RawEvent> events = getEvents();
     std::set<int32_t /*deviceId*/> existingDevices;
     // All of the events should be DEVICE_ADDED type, except the last one.
     for (size_t i = 0; i < events.size() - 1; i++) {
@@ -128,8 +147,11 @@
 
 int32_t EventHubTest::waitForDeviceCreation() {
     // Wait a little longer than usual, to ensure input device has time to be created
-    std::vector<RawEvent> events = getEvents(20ms);
-    EXPECT_EQ(2U, events.size()); // Using "expect" because the function is non-void.
+    std::vector<RawEvent> events = getEvents(2);
+    if (events.size() != 2) {
+        ADD_FAILURE() << "Instead of 2 events, received " << events.size();
+        return 0; // this value is unused
+    }
     const RawEvent& deviceAddedEvent = events[0];
     EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_ADDED), deviceAddedEvent.type);
     InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceAddedEvent.deviceId);
@@ -142,7 +164,7 @@
 }
 
 void EventHubTest::waitForDeviceClose(int32_t deviceId) {
-    std::vector<RawEvent> events = getEvents(20ms);
+    std::vector<RawEvent> events = getEvents(2);
     ASSERT_EQ(2U, events.size());
     const RawEvent& deviceRemovedEvent = events[0];
     EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_REMOVED), deviceRemovedEvent.type);
@@ -152,6 +174,11 @@
               finishedDeviceScanEvent.type);
 }
 
+void EventHubTest::assertNoMoreEvents() {
+    std::vector<RawEvent> events = getEvents();
+    ASSERT_TRUE(events.empty());
+}
+
 /**
  * Ensure that input_events are generated with monotonic clock.
  * That means input_event should receive a timestamp that is in the future of the time
@@ -162,7 +189,7 @@
     nsecs_t lastEventTime = systemTime(SYSTEM_TIME_MONOTONIC);
     ASSERT_NO_FATAL_FAILURE(mKeyboard->pressAndReleaseHomeKey());
 
-    std::vector<RawEvent> events = getEvents();
+    std::vector<RawEvent> events = getEvents(4);
     ASSERT_EQ(4U, events.size()) << "Expected to receive 2 keys and 2 syncs, total of 4 events";
     for (const RawEvent& event : events) {
         // Cannot use strict comparison because the events may happen too quickly
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 1f283b1..e0d32a0 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -491,7 +491,7 @@
 
 // --- InputDispatcherTest SetInputWindowTest ---
 static constexpr int32_t INJECT_EVENT_TIMEOUT = 500;
-static constexpr int32_t DISPATCHING_TIMEOUT = 100;
+static constexpr nsecs_t DISPATCHING_TIMEOUT = seconds_to_nanoseconds(5);
 
 class FakeApplicationHandle : public InputApplicationHandle {
 public:
@@ -871,7 +871,7 @@
     sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
             ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
             AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
@@ -888,7 +888,7 @@
     sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
             ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
             AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
@@ -910,7 +910,7 @@
 
     // Display should have only one focused window
     windowSecond->setFocus(true);
-    mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
 
     windowSecond->consumeFocusEvent(true);
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
@@ -935,7 +935,7 @@
     windowTop->setFocus(true);
     windowSecond->setFocus(true);
 
-    mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
     windowTop->consumeFocusEvent(true);
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
             << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
@@ -960,7 +960,7 @@
     windowSecond->setFocus(true);
     // Release channel for window is no longer valid.
     windowTop->releaseChannel();
-    mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
     windowSecond->consumeFocusEvent(true);
 
     // Test inject a key down, should dispatch to a valid window.
@@ -986,7 +986,7 @@
 
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
 
-    mDispatcher->setInputWindows({windowLeft, windowRight}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
 
     // Inject an event with coordinate in the area of right window, with mouse cursor in the area of
     // left window. This event should be dispatched to the left window.
@@ -1003,7 +1003,7 @@
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
     window->setFocus(true);
 
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(true);
 
     NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
@@ -1025,7 +1025,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     NotifyMotionArgs motionArgs =
             generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -1053,7 +1053,7 @@
             "Second Window", ADISPLAY_ID_DEFAULT);
 
     // Add the windows to the dispatcher
-    mDispatcher->setInputWindows({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
 
     // Send down to the first window
     NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
@@ -1090,7 +1090,7 @@
             "Second Window", ADISPLAY_ID_DEFAULT);
 
     // Add the windows to the dispatcher
-    mDispatcher->setInputWindows({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
 
     // Send down to the first window
     NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
@@ -1152,7 +1152,7 @@
             | InputWindowInfo::FLAG_SPLIT_TOUCH);
 
     // Add the windows to the dispatcher
-    mDispatcher->setInputWindows({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
 
     PointF pointInFirst = {300, 200};
     PointF pointInSecond = {300, 600};
@@ -1204,7 +1204,7 @@
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
     window->setFocus(true);
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     window->consumeFocusEvent(true);
 
@@ -1220,7 +1220,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
     mDispatcher->notifyKey(&keyArgs);
@@ -1235,7 +1235,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     // Send key
     NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
@@ -1289,7 +1289,7 @@
     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
                                                       true /*isGestureMonitor*/);
@@ -1309,7 +1309,7 @@
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
     window->setFocus(true);
 
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(true);
 
     FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
@@ -1325,7 +1325,7 @@
     sp<FakeApplicationHandle> application = new FakeApplicationHandle();
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
                                                       true /*isGestureMonitor*/);
@@ -1351,7 +1351,7 @@
     sp<FakeWindowHandle> window =
             new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     NotifyMotionArgs motionArgs =
             generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -1387,29 +1387,29 @@
     window->setFocus(true);
 
     SCOPED_TRACE("Check default value of touch mode");
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
 
     SCOPED_TRACE("Remove the window to trigger focus loss");
     window->setFocus(false);
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);
 
     SCOPED_TRACE("Disable touch mode");
     mDispatcher->setInTouchMode(false);
     window->setFocus(true);
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/);
 
     SCOPED_TRACE("Remove the window to trigger focus loss");
     window->setFocus(false);
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);
 
     SCOPED_TRACE("Enable touch mode again");
     mDispatcher->setInTouchMode(true);
     window->setFocus(true);
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
 
     window->assertNoEvents();
@@ -1423,7 +1423,7 @@
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
     window->setFocus(true);
 
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
     window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
 
     NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
@@ -1459,7 +1459,7 @@
 
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
 
-    mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     NotifyMotionArgs motionArgs =
             generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -1512,7 +1512,7 @@
         mWindow = new FakeWindowHandle(mApp, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
 
         mWindow->setFocus(true);
-        mDispatcher->setInputWindows({mWindow}, ADISPLAY_ID_DEFAULT);
+        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
 
         mWindow->consumeFocusEvent(true);
     }
@@ -1602,7 +1602,7 @@
         // Set focus window for primary display, but focused display would be second one.
         mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
         windowInPrimary->setFocus(true);
-        mDispatcher->setInputWindows({windowInPrimary}, ADISPLAY_ID_DEFAULT);
+        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary}}});
         windowInPrimary->consumeFocusEvent(true);
 
         application2 = new FakeApplicationHandle();
@@ -1614,7 +1614,7 @@
         // Set focus window for second display.
         mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
         windowInSecondary->setFocus(true);
-        mDispatcher->setInputWindows({windowInSecondary}, SECOND_DISPLAY_ID);
+        mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}});
         windowInSecondary->consumeFocusEvent(true);
     }
 
@@ -1664,7 +1664,7 @@
     windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
 
     // Remove all windows in secondary display.
-    mDispatcher->setInputWindows({}, SECOND_DISPLAY_ID);
+    mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
 
     // Expect old focus should receive a cancel event.
     windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
@@ -1828,7 +1828,7 @@
         mFocusedWindow->setFocus(true);
 
         // Expect one focus window exist in display.
-        mDispatcher->setInputWindows({mUnfocusedWindow, mFocusedWindow}, ADISPLAY_ID_DEFAULT);
+        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
         mFocusedWindow->consumeFocusEvent(true);
     }
 
@@ -1852,6 +1852,7 @@
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
             AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT, 20, 20))
             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+    mUnfocusedWindow->consumeMotionDown();
 
     ASSERT_TRUE(mDispatcher->waitForIdle());
     mFakePolicy->assertOnPointerDownEquals(mUnfocusedWindow->getToken());
@@ -1864,6 +1865,7 @@
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
             AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, 20, 20))
             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+    mFocusedWindow->consumeMotionDown();
 
     ASSERT_TRUE(mDispatcher->waitForIdle());
     mFakePolicy->assertOnPointerDownWasNotCalled();
@@ -1874,6 +1876,7 @@
 TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
     ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
             << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+    mFocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
 
     ASSERT_TRUE(mDispatcher->waitForIdle());
     mFakePolicy->assertOnPointerDownWasNotCalled();
@@ -1888,6 +1891,7 @@
               injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
                                mFocusedWindowTouchPoint, mFocusedWindowTouchPoint))
             << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+    mFocusedWindow->consumeMotionDown();
 
     ASSERT_TRUE(mDispatcher->waitForIdle());
     mFakePolicy->assertOnPointerDownWasNotCalled();
@@ -1916,7 +1920,7 @@
         mWindow2->setId(1);
         mWindow2->setFrame(Rect(100, 100, 200, 200));
 
-        mDispatcher->setInputWindows({mWindow1, mWindow2}, ADISPLAY_ID_DEFAULT);
+        mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
     }
 
 protected:
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 618aefc..96d86b6 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -6990,51 +6990,7 @@
     ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
 }
 
-/**
- * Test touch should not work if outside of surface.
- */
-TEST_F(MultiTouchInputMapperTest, Viewports_SurfaceRange) {
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION);
-    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
 
-    // Touch on left-top area should work.
-    int32_t rawX = DISPLAY_WIDTH / 2 - 1;
-    int32_t rawY = DISPLAY_HEIGHT / 2 - 1;
-    processPosition(mapper, rawX, rawY);
-    processSync(mapper);
-
-    NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-
-    // Reset.
-    mapper.reset(ARBITRARY_TIME);
-
-    // Let logical display be different to physical display and rotate 90-degrees.
-    std::optional<DisplayViewport> internalViewport =
-            mFakePolicy->getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL);
-    internalViewport->orientation = DISPLAY_ORIENTATION_90;
-    internalViewport->logicalLeft = 0;
-    internalViewport->logicalTop = 0;
-    internalViewport->logicalRight = DISPLAY_HEIGHT;
-    internalViewport->logicalBottom = DISPLAY_WIDTH / 2;
-
-    internalViewport->physicalLeft = DISPLAY_HEIGHT;
-    internalViewport->physicalTop = DISPLAY_WIDTH / 2;
-    internalViewport->physicalRight = DISPLAY_HEIGHT;
-    internalViewport->physicalBottom = DISPLAY_WIDTH;
-
-    internalViewport->deviceWidth = DISPLAY_HEIGHT;
-    internalViewport->deviceHeight = DISPLAY_WIDTH;
-    mFakePolicy->updateViewport(internalViewport.value());
-    configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
-
-    // Display align to right-top after rotate 90-degrees, touch on left-top area should not work.
-    processPosition(mapper, rawX, rawY);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-}
 
 TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleSingleTouch) {
     addConfigurationProperty("touch.deviceType", "touchScreen");
@@ -7161,4 +7117,130 @@
     ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
     ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
 }
+
+/**
+ * Test touch should not work if outside of surface.
+ */
+class MultiTouchInputMapperTest_SurfaceRange : public MultiTouchInputMapperTest {
+protected:
+    void halfDisplayToCenterHorizontal(int32_t orientation) {
+        std::optional<DisplayViewport> internalViewport =
+                mFakePolicy->getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL);
+
+        // Half display to (width/4, 0, width * 3/4, height) to make display has offset.
+        internalViewport->orientation = orientation;
+        if (orientation == DISPLAY_ORIENTATION_90 || orientation == DISPLAY_ORIENTATION_270) {
+            internalViewport->logicalLeft = 0;
+            internalViewport->logicalTop = 0;
+            internalViewport->logicalRight = DISPLAY_HEIGHT;
+            internalViewport->logicalBottom = DISPLAY_WIDTH / 2;
+
+            internalViewport->physicalLeft = 0;
+            internalViewport->physicalTop = DISPLAY_WIDTH / 4;
+            internalViewport->physicalRight = DISPLAY_HEIGHT;
+            internalViewport->physicalBottom = DISPLAY_WIDTH * 3 / 4;
+
+            internalViewport->deviceWidth = DISPLAY_HEIGHT;
+            internalViewport->deviceHeight = DISPLAY_WIDTH;
+        } else {
+            internalViewport->logicalLeft = 0;
+            internalViewport->logicalTop = 0;
+            internalViewport->logicalRight = DISPLAY_WIDTH / 2;
+            internalViewport->logicalBottom = DISPLAY_HEIGHT;
+
+            internalViewport->physicalLeft = DISPLAY_WIDTH / 4;
+            internalViewport->physicalTop = 0;
+            internalViewport->physicalRight = DISPLAY_WIDTH * 3 / 4;
+            internalViewport->physicalBottom = DISPLAY_HEIGHT;
+
+            internalViewport->deviceWidth = DISPLAY_WIDTH;
+            internalViewport->deviceHeight = DISPLAY_HEIGHT;
+        }
+
+        mFakePolicy->updateViewport(internalViewport.value());
+        configureDevice(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+    }
+
+    void processPositionAndVerify(MultiTouchInputMapper& mapper, int32_t xInside, int32_t yInside,
+                                  int32_t xOutside, int32_t yOutside, int32_t xExpected,
+                                  int32_t yExpected) {
+        // touch on outside area should not work.
+        processPosition(mapper, toRawX(xOutside), toRawY(yOutside));
+        processSync(mapper);
+        ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+
+        // touch on inside area should receive the event.
+        NotifyMotionArgs args;
+        processPosition(mapper, toRawX(xInside), toRawY(yInside));
+        processSync(mapper);
+        ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+        ASSERT_NEAR(xExpected, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
+        ASSERT_NEAR(yExpected, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
+
+        // Reset.
+        mapper.reset(ARBITRARY_TIME);
+    }
+};
+
+TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange) {
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION);
+    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
+
+    // Touch on center of normal display should work.
+    const int32_t x = DISPLAY_WIDTH / 4;
+    const int32_t y = DISPLAY_HEIGHT / 2;
+    processPosition(mapper, toRawX(x), toRawY(y));
+    processSync(mapper);
+    NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], x, y, 1.0f, 0.0f, 0.0f, 0.0f,
+                                                0.0f, 0.0f, 0.0f, 0.0f));
+    // Reset.
+    mapper.reset(ARBITRARY_TIME);
+
+    // Let physical display be different to device, and make surface and physical could be 1:1.
+    halfDisplayToCenterHorizontal(DISPLAY_ORIENTATION_0);
+
+    const int32_t xExpected = (x + 1) - (DISPLAY_WIDTH / 4);
+    const int32_t yExpected = y;
+    processPositionAndVerify(mapper, x - 1, y, x + 1, y, xExpected, yExpected);
+}
+
+TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_90) {
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION);
+    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
+
+    // Half display to (width/4, 0, width * 3/4, height) and rotate 90-degrees.
+    halfDisplayToCenterHorizontal(DISPLAY_ORIENTATION_90);
+
+    const int32_t x = DISPLAY_WIDTH / 4;
+    const int32_t y = DISPLAY_HEIGHT / 2;
+
+    // expect x/y = swap x/y then reverse y.
+    const int32_t xExpected = y;
+    const int32_t yExpected = (DISPLAY_WIDTH * 3 / 4) - (x + 1);
+    processPositionAndVerify(mapper, x - 1, y, x + 1, y, xExpected, yExpected);
+}
+
+TEST_F(MultiTouchInputMapperTest_SurfaceRange, Viewports_SurfaceRange_270) {
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    prepareDisplay(DISPLAY_ORIENTATION_0);
+    prepareAxes(POSITION);
+    MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
+
+    // Half display to (width/4, 0, width * 3/4, height) and rotate 270-degrees.
+    halfDisplayToCenterHorizontal(DISPLAY_ORIENTATION_270);
+
+    const int32_t x = DISPLAY_WIDTH / 4;
+    const int32_t y = DISPLAY_HEIGHT / 2;
+
+    // expect x/y = swap x/y then reverse x.
+    constexpr int32_t xExpected = DISPLAY_HEIGHT - y;
+    constexpr int32_t yExpected = (x + 1) - DISPLAY_WIDTH / 4;
+    processPositionAndVerify(mapper, x - 1, y, x + 1, y, xExpected, yExpected);
+}
 } // namespace android
diff --git a/services/inputflinger/tests/UinputDevice.cpp b/services/inputflinger/tests/UinputDevice.cpp
index 99480b7..10e7293 100644
--- a/services/inputflinger/tests/UinputDevice.cpp
+++ b/services/inputflinger/tests/UinputDevice.cpp
@@ -44,9 +44,7 @@
     device.id.product = 0x01;
     device.id.version = 1;
 
-    // Using EXPECT instead of ASSERT to allow the device creation to continue even when
-    // some failures are reported when configuring the device.
-    EXPECT_NO_FATAL_FAILURE(configureDevice(mDeviceFd, &device));
+    ASSERT_NO_FATAL_FAILURE(configureDevice(mDeviceFd, &device));
 
     if (write(mDeviceFd, &device, sizeof(device)) < 0) {
         FAIL() << "Could not write uinput_user_dev struct into uinput file descriptor: "
@@ -70,7 +68,7 @@
                                              " with value %" PRId32 " : %s",
                                              type, code, value, strerror(errno));
         ALOGE("%s", msg.c_str());
-        ADD_FAILURE() << msg.c_str();
+        FAIL() << msg.c_str();
     }
 }
 
@@ -82,41 +80,41 @@
 void UinputKeyboard::configureDevice(int fd, uinput_user_dev* device) {
     // enable key press/release event
     if (ioctl(fd, UI_SET_EVBIT, EV_KEY)) {
-        ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_KEY: " << strerror(errno);
+        FAIL() << "Error in ioctl : UI_SET_EVBIT : EV_KEY: " << strerror(errno);
     }
 
     // enable set of KEY events
     std::for_each(mKeys.begin(), mKeys.end(), [fd](int key) {
         if (ioctl(fd, UI_SET_KEYBIT, key)) {
-            ADD_FAILURE() << "Error in ioctl : UI_SET_KEYBIT : " << key << " : " << strerror(errno);
+            FAIL() << "Error in ioctl : UI_SET_KEYBIT : " << key << " : " << strerror(errno);
         }
     });
 
     // enable synchronization event
     if (ioctl(fd, UI_SET_EVBIT, EV_SYN)) {
-        ADD_FAILURE() << "Error in ioctl : UI_SET_EVBIT : EV_SYN: " << strerror(errno);
+        FAIL() << "Error in ioctl : UI_SET_EVBIT : EV_SYN: " << strerror(errno);
     }
 }
 
 void UinputKeyboard::pressKey(int key) {
     if (mKeys.find(key) == mKeys.end()) {
-        ADD_FAILURE() << mName << ": Cannot inject key press: Key not found: " << key;
+        FAIL() << mName << ": Cannot inject key press: Key not found: " << key;
     }
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, key, 1));
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
+    injectEvent(EV_KEY, key, 1);
+    injectEvent(EV_SYN, SYN_REPORT, 0);
 }
 
 void UinputKeyboard::releaseKey(int key) {
     if (mKeys.find(key) == mKeys.end()) {
-        ADD_FAILURE() << mName << ": Cannot inject key release: Key not found: " << key;
+        FAIL() << mName << ": Cannot inject key release: Key not found: " << key;
     }
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, key, 0));
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
+    injectEvent(EV_KEY, key, 0);
+    injectEvent(EV_SYN, SYN_REPORT, 0);
 }
 
 void UinputKeyboard::pressAndReleaseKey(int key) {
-    EXPECT_NO_FATAL_FAILURE(pressKey(key));
-    EXPECT_NO_FATAL_FAILURE(releaseKey(key));
+    pressKey(key);
+    releaseKey(key);
 }
 
 // --- UinputHomeKey ---
@@ -124,7 +122,7 @@
 UinputHomeKey::UinputHomeKey() : UinputKeyboard({KEY_HOME}) {}
 
 void UinputHomeKey::pressAndReleaseHomeKey() {
-    EXPECT_NO_FATAL_FAILURE(pressAndReleaseKey(KEY_HOME));
+    pressAndReleaseKey(KEY_HOME);
 }
 
 // --- UinputTouchScreen ---
@@ -158,35 +156,35 @@
 }
 
 void UinputTouchScreen::sendSlot(int32_t slot) {
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_SLOT, slot));
+    injectEvent(EV_ABS, ABS_MT_SLOT, slot);
 }
 
 void UinputTouchScreen::sendTrackingId(int32_t trackingId) {
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_TRACKING_ID, trackingId));
+    injectEvent(EV_ABS, ABS_MT_TRACKING_ID, trackingId);
 }
 
 void UinputTouchScreen::sendDown(const Point& point) {
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, BTN_TOUCH, 1));
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x));
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y));
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
+    injectEvent(EV_KEY, BTN_TOUCH, 1);
+    injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x);
+    injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y);
+    injectEvent(EV_SYN, SYN_REPORT, 0);
 }
 
 void UinputTouchScreen::sendMove(const Point& point) {
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x));
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y));
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
+    injectEvent(EV_ABS, ABS_MT_POSITION_X, point.x);
+    injectEvent(EV_ABS, ABS_MT_POSITION_Y, point.y);
+    injectEvent(EV_SYN, SYN_REPORT, 0);
 }
 
 void UinputTouchScreen::sendUp() {
     sendTrackingId(0xffffffff);
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_KEY, BTN_TOUCH, 0));
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
+    injectEvent(EV_KEY, BTN_TOUCH, 0);
+    injectEvent(EV_SYN, SYN_REPORT, 0);
 }
 
 void UinputTouchScreen::sendToolType(int32_t toolType) {
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_ABS, ABS_MT_TOOL_TYPE, toolType));
-    EXPECT_NO_FATAL_FAILURE(injectEvent(EV_SYN, SYN_REPORT, 0));
+    injectEvent(EV_ABS, ABS_MT_TOOL_TYPE, toolType);
+    injectEvent(EV_SYN, SYN_REPORT, 0);
 }
 
 // Get the center x, y base on the range definition.
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 9a13c00..e799372 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -91,11 +91,11 @@
     result.appendFormat("\t %s | WakeLockRefCount %d | uid %d | cache size %d | "
             "max cache size %d\n", mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize,
             mMaxCacheSize);
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
+    for (auto& it : mSensorInfo) {
+        const FlushInfo& flushInfo = it.second;
         result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
-                            mService->getSensorName(mSensorInfo.keyAt(i)).string(),
-                            mSensorInfo.keyAt(i),
+                            mService->getSensorName(it.first).string(),
+                            it.first,
                             flushInfo.mFirstFlushPending ? "First flush pending" :
                                                            "active",
                             flushInfo.mPendingFlushEventsToSend);
@@ -135,12 +135,12 @@
     proto->write(UID, int32_t(mUid));
     proto->write(CACHE_SIZE, int32_t(mCacheSize));
     proto->write(MAX_CACHE_SIZE, int32_t(mMaxCacheSize));
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
+    for (auto& it : mSensorInfo) {
+        const FlushInfo& flushInfo = it.second;
         const uint64_t token = proto->start(FLUSH_INFOS);
         proto->write(FlushInfoProto::SENSOR_NAME,
-                std::string(mService->getSensorName(mSensorInfo.keyAt(i))));
-        proto->write(FlushInfoProto::SENSOR_HANDLE, mSensorInfo.keyAt(i));
+                std::string(mService->getSensorName(it.first)));
+        proto->write(FlushInfoProto::SENSOR_HANDLE, it.first);
         proto->write(FlushInfoProto::FIRST_FLUSH_PENDING, flushInfo.mFirstFlushPending);
         proto->write(FlushInfoProto::PENDING_FLUSH_EVENTS_TO_SEND,
                 flushInfo.mPendingFlushEventsToSend);
@@ -162,24 +162,33 @@
     sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
     if (si == nullptr ||
         !canAccessSensor(si->getSensor(), "Tried adding", mOpPackageName) ||
-        mSensorInfo.indexOfKey(handle) >= 0) {
+        mSensorInfo.count(handle) > 0) {
         return false;
     }
-    mSensorInfo.add(handle, FlushInfo());
+    mSensorInfo[handle] = FlushInfo();
     return true;
 }
 
 bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
     Mutex::Autolock _l(mConnectionLock);
-    if (mSensorInfo.removeItem(handle) >= 0) {
+    if (mSensorInfo.erase(handle) >= 0) {
         return true;
     }
     return false;
 }
 
+std::vector<int32_t> SensorService::SensorEventConnection::getActiveSensorHandles() const {
+    Mutex::Autolock _l(mConnectionLock);
+    std::vector<int32_t> list;
+    for (auto& it : mSensorInfo) {
+        list.push_back(it.first);
+    }
+    return list;
+}
+
 bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
     Mutex::Autolock _l(mConnectionLock);
-    return mSensorInfo.indexOfKey(handle) >= 0;
+    return mSensorInfo.count(handle) > 0;
 }
 
 bool SensorService::SensorEventConnection::hasAnySensor() const {
@@ -189,8 +198,8 @@
 
 bool SensorService::SensorEventConnection::hasOneShotSensors() const {
     Mutex::Autolock _l(mConnectionLock);
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const int handle = mSensorInfo.keyAt(i);
+    for (auto &it : mSensorInfo) {
+        const int handle = it.first;
         sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
         if (si != nullptr && si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
             return true;
@@ -206,9 +215,8 @@
 void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
                                 bool value) {
     Mutex::Autolock _l(mConnectionLock);
-    ssize_t index = mSensorInfo.indexOfKey(handle);
-    if (index >= 0) {
-        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+    if (mSensorInfo.count(handle) > 0) {
+        FlushInfo& flushInfo = mSensorInfo[handle];
         flushInfo.mFirstFlushPending = value;
     }
 }
@@ -233,8 +241,8 @@
     int looper_flags = 0;
     if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
     if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const int handle = mSensorInfo.keyAt(i);
+    for (auto& it : mSensorInfo) {
+        const int handle = it.first;
         sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
         if (si != nullptr && si->getSensor().isWakeUpSensor()) {
             looper_flags |= ALOOPER_EVENT_INPUT;
@@ -266,9 +274,8 @@
 
 void SensorService::SensorEventConnection::incrementPendingFlushCount(int32_t handle) {
     Mutex::Autolock _l(mConnectionLock);
-    ssize_t index = mSensorInfo.indexOfKey(handle);
-    if (index >= 0) {
-        FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+    if (mSensorInfo.count(handle) > 0) {
+        FlushInfo& flushInfo = mSensorInfo[handle];
         flushInfo.mPendingFlushEventsToSend++;
     }
 }
@@ -296,15 +303,14 @@
                 sensor_handle = buffer[i].meta_data.sensor;
             }
 
-            ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
             // Check if this connection has registered for this sensor. If not continue to the
             // next sensor_event.
-            if (index < 0) {
+            if (mSensorInfo.count(sensor_handle) == 0) {
                 ++i;
                 continue;
             }
 
-            FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+            FlushInfo& flushInfo = mSensorInfo[sensor_handle];
             // Check if there is a pending flush_complete event for this sensor on this connection.
             if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
                     mapFlushEventsToConnections[i] == this) {
@@ -522,14 +528,14 @@
     flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
     // Loop through all the sensors for this connection and check if there are any pending
     // flush complete events to be sent.
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        const int handle = mSensorInfo.keyAt(i);
+    for (auto& it : mSensorInfo) {
+        const int handle = it.first;
         sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
         if (si == nullptr) {
             continue;
         }
 
-        FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
+        FlushInfo& flushInfo = it.second;
         while (flushInfo.mPendingFlushEventsToSend > 0) {
             flushCompleteEvent.meta_data.sensor = handle;
             bool wakeUpSensor = si->getSensor().isWakeUpSensor();
@@ -615,14 +621,13 @@
     // separately before the next batch of events.
     for (int j = 0; j < numEventsDropped; ++j) {
         if (scratch[j].type == SENSOR_TYPE_META_DATA) {
-            ssize_t index = mSensorInfo.indexOfKey(scratch[j].meta_data.sensor);
-            if (index < 0) {
+            if (mSensorInfo.count(scratch[j].meta_data.sensor) == 0) {
                 ALOGW("%s: sensor 0x%x is not found in connection",
                       __func__, scratch[j].meta_data.sensor);
                 continue;
             }
 
-            FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+            FlushInfo& flushInfo = mSensorInfo[scratch[j].meta_data.sensor];
             flushInfo.mPendingFlushEventsToSend++;
             ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
                      flushInfo.mPendingFlushEventsToSend);
@@ -764,8 +769,8 @@
 int SensorService::SensorEventConnection::computeMaxCacheSizeLocked() const {
     size_t fifoWakeUpSensors = 0;
     size_t fifoNonWakeUpSensors = 0;
-    for (size_t i = 0; i < mSensorInfo.size(); ++i) {
-        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(mSensorInfo.keyAt(i));
+    for (auto& it : mSensorInfo) {
+        sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(it.first);
         if (si == nullptr) {
             continue;
         }
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index caf5d7c..1ca35c0 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -23,7 +23,6 @@
 
 #include <utils/Vector.h>
 #include <utils/SortedVector.h>
-#include <utils/KeyedVector.h>
 #include <utils/threads.h>
 #include <utils/AndroidThreads.h>
 #include <utils/RefBase.h>
@@ -60,6 +59,7 @@
     bool hasOneShotSensors() const;
     bool addSensor(int32_t handle);
     bool removeSensor(int32_t handle);
+    std::vector<int32_t> getActiveSensorHandles() const;
     void setFirstFlushPending(int32_t handle, bool value);
     void dump(String8& result);
     void dump(util::ProtoOutputStream* proto) const;
@@ -169,8 +169,8 @@
 
         FlushInfo() : mPendingFlushEventsToSend(0), mFirstFlushPending(false) {}
     };
-    // protected by SensorService::mLock. Key for this vector is the sensor handle.
-    KeyedVector<int, FlushInfo> mSensorInfo;
+    // protected by SensorService::mLock. Key for this map is the sensor handle.
+    std::unordered_map<int32_t, FlushInfo> mSensorInfo;
 
     sensors_event_t *mEventCache;
     int mCacheSize, mMaxCacheSize;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 22a15c6..5fdc74f 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -1740,8 +1740,7 @@
     status_t err(NO_ERROR);
     Mutex::Autolock _l(mLock);
     // Loop through all sensors for this connection and call flush on each of them.
-    for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) {
-        const int handle = connection->mSensorInfo.keyAt(i);
+    for (int handle : connection->getActiveSensorHandles()) {
         sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
         if (sensor == nullptr) {
             continue;
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index e4d754c..54cd04f 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -272,7 +272,7 @@
     // pixel format is HDR Y410 masquerading as RGBA_1010102
     return (mBufferInfo.mDataspace == ui::Dataspace::BT2020_ITU_PQ &&
             mBufferInfo.mApi == NATIVE_WINDOW_API_MEDIA &&
-            mBufferInfo.mBuffer->getPixelFormat() == HAL_PIXEL_FORMAT_RGBA_1010102);
+            mBufferInfo.mPixelFormat == HAL_PIXEL_FORMAT_RGBA_1010102);
 }
 
 sp<compositionengine::LayerFE> BufferLayer::getCompositionEngineLayerFE() const {
@@ -294,6 +294,7 @@
     auto* compositionState = editCompositionState();
     if (compositionState->sidebandStream.get()) {
         compositionState->compositionType = Hwc2::IComposerClient::Composition::SIDEBAND;
+        return;
     } else {
         // Normal buffer layers
         compositionState->hdrMetadata = mBufferInfo.mHdrMetadata;
@@ -301,6 +302,12 @@
                 ? Hwc2::IComposerClient::Composition::CURSOR
                 : Hwc2::IComposerClient::Composition::DEVICE;
     }
+
+    compositionState->buffer = mBufferInfo.mBuffer;
+    compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
+            ? 0
+            : mBufferInfo.mBufferSlot;
+    compositionState->acquireFence = mBufferInfo.mFence;
 }
 
 bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
@@ -374,6 +381,12 @@
     return true;
 }
 
+void BufferLayer::gatherBufferInfo() {
+    mBufferInfo.mPixelFormat =
+            !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->format;
+    mBufferInfo.mFrameLatencyNeeded = true;
+}
+
 bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
                               nsecs_t expectedPresentTime) {
     ATRACE_CALL();
@@ -434,7 +447,6 @@
     gatherBufferInfo();
 
     mRefreshPending = true;
-    mBufferInfo.mFrameLatencyNeeded = true;
     if (oldBufferInfo.mBuffer == nullptr) {
         // the first time we receive a buffer, we need to trigger a
         // geometry invalidation.
@@ -613,6 +625,39 @@
             sourceCrop.getWidth() != displayFrame.getWidth();
 }
 
+bool BufferLayer::needsFilteringForScreenshots(const sp<const DisplayDevice>& displayDevice,
+                                               const ui::Transform& inverseParentTransform) const {
+    // If we are not capturing based on the state of a known display device,
+    // just return false.
+    if (displayDevice == nullptr) {
+        return false;
+    }
+
+    const auto outputLayer = findOutputLayerForDisplay(displayDevice);
+    if (outputLayer == nullptr) {
+        return false;
+    }
+
+    // We need filtering if the sourceCrop rectangle size does not match the
+    // viewport rectangle size (not a 1:1 render)
+    const auto& compositionState = outputLayer->getState();
+    const ui::Transform& displayTransform = displayDevice->getTransform();
+    const ui::Transform inverseTransform = inverseParentTransform * displayTransform.inverse();
+    // Undo the transformation of the displayFrame so that we're back into
+    // layer-stack space.
+    const Rect frame = inverseTransform.transform(compositionState.displayFrame);
+    const FloatRect sourceCrop = compositionState.sourceCrop;
+
+    int32_t frameHeight = frame.getHeight();
+    int32_t frameWidth = frame.getWidth();
+    // If the display transform had a rotational component then undo the
+    // rotation so that the orientation matches the source crop.
+    if (displayTransform.getOrientation() & ui::Transform::ROT_90) {
+        std::swap(frameHeight, frameWidth);
+    }
+    return sourceCrop.getHeight() != frameHeight || sourceCrop.getWidth() != frameWidth;
+}
+
 uint64_t BufferLayer::getHeadFrameNumber(nsecs_t expectedPresentTime) const {
     if (hasFrameUpdate()) {
         return getFrameNumber(expectedPresentTime);
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index f678910..56bab1b 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -161,7 +161,7 @@
         Region mSurfaceDamage;
         HdrMetadata mHdrMetadata;
         int mApi;
-        PixelFormat mPixelFormat;
+        PixelFormat mPixelFormat{PIXEL_FORMAT_NONE};
         bool mTransformToDisplayInverse{false};
 
         sp<GraphicBuffer> mBuffer;
@@ -208,6 +208,8 @@
 private:
     // Returns true if this layer requires filtering
     bool needsFiltering(const sp<const DisplayDevice>& displayDevice) const override;
+    bool needsFilteringForScreenshots(const sp<const DisplayDevice>& displayDevice,
+                                      const ui::Transform& inverseParentTransform) const override;
 
     // BufferStateLayers can return Rect::INVALID_RECT if the layer does not have a display frame
     // and its parent layer is not bounded
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 4e5c593..f4e630e 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -365,21 +365,6 @@
     return NO_ERROR;
 }
 
-void BufferQueueLayer::preparePerFrameCompositionState() {
-    BufferLayer::preparePerFrameCompositionState();
-
-    auto* compositionState = editCompositionState();
-    if (compositionState->compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) {
-        return;
-    }
-
-    compositionState->buffer = mBufferInfo.mBuffer;
-    compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
-            ? 0
-            : mBufferInfo.mBufferSlot;
-    compositionState->acquireFence = mBufferInfo.mFence;
-}
-
 // -----------------------------------------------------------------------
 // Interface implementation for BufferLayerConsumer::ContentsChangedListener
 // -----------------------------------------------------------------------
@@ -525,8 +510,6 @@
         return BAD_VALUE;
     }
 
-    mFormat = format;
-
     setDefaultBufferSize(w, h);
     mConsumer->setDefaultBufferFormat(format);
     mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
@@ -550,6 +533,8 @@
 }
 
 void BufferQueueLayer::gatherBufferInfo() {
+    BufferLayer::gatherBufferInfo();
+
     mBufferInfo.mDesiredPresentTime = mConsumer->getTimestamp();
     mBufferInfo.mFenceTime = mConsumer->getCurrentFenceTime();
     mBufferInfo.mFence = mConsumer->getCurrentFence();
@@ -560,7 +545,6 @@
     mBufferInfo.mSurfaceDamage = mConsumer->getSurfaceDamage();
     mBufferInfo.mHdrMetadata = mConsumer->getCurrentHdrMetadata();
     mBufferInfo.mApi = mConsumer->getCurrentApi();
-    mBufferInfo.mPixelFormat = mFormat;
     mBufferInfo.mTransformToDisplayInverse = mConsumer->getTransformToDisplayInverse();
 }
 
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index 5f7587c..16b4b6e 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -82,7 +82,6 @@
     status_t updateActiveBuffer() override;
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
-    void preparePerFrameCompositionState() override;
     sp<Layer> createClone() override;
 
     void onFrameAvailable(const BufferItem& item);
@@ -132,8 +131,6 @@
     sp<BufferLayerConsumer> mConsumer;
     sp<IGraphicBufferProducer> mProducer;
 
-    PixelFormat mFormat{PIXEL_FORMAT_NONE};
-
     bool mUpdateTexImageFailed{false};
 
     uint64_t mPreviousBufferId = 0;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 3ed6889..a121ce0 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -631,19 +631,6 @@
     return NO_ERROR;
 }
 
-void BufferStateLayer::preparePerFrameCompositionState() {
-    BufferLayer::preparePerFrameCompositionState();
-
-    auto* compositionState = editCompositionState();
-    if (compositionState->compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) {
-        return;
-    }
-
-    compositionState->buffer = mBufferInfo.mBuffer;
-    compositionState->bufferSlot = mBufferInfo.mBufferSlot;
-    compositionState->acquireFence = mBufferInfo.mFence;
-}
-
 void BufferStateLayer::HwcSlotGenerator::bufferErased(const client_cache_t& clientCacheId) {
     std::lock_guard lock(mMutex);
     if (!clientCacheId.isValid()) {
@@ -718,8 +705,9 @@
 }
 
 void BufferStateLayer::gatherBufferInfo() {
-    const State& s(getDrawingState());
+    BufferLayer::gatherBufferInfo();
 
+    const State& s(getDrawingState());
     mBufferInfo.mDesiredPresentTime = s.desiredPresentTime;
     mBufferInfo.mFenceTime = std::make_shared<FenceTime>(s.acquireFence);
     mBufferInfo.mFence = s.acquireFence;
@@ -730,8 +718,6 @@
     mBufferInfo.mSurfaceDamage = s.surfaceDamageRegion;
     mBufferInfo.mHdrMetadata = s.hdrMetadata;
     mBufferInfo.mApi = s.api;
-    mBufferInfo.mPixelFormat =
-            !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->format;
     mBufferInfo.mTransformToDisplayInverse = s.transformToDisplayInverse;
     mBufferInfo.mBufferSlot = mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId);
 }
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 753a742..5873a73 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -138,7 +138,6 @@
     status_t updateActiveBuffer() override;
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
-    void preparePerFrameCompositionState() override;
     sp<Layer> createClone() override;
 
     // Crop that applies to the buffer
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index c345405..308ec5a 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -268,12 +268,9 @@
 }
 
 bool Display::getSkipColorTransform() const {
-    if (!mId) {
-        return false;
-    }
-
-    auto& hwc = getCompositionEngine().getHwComposer();
-    return hwc.hasDisplayCapability(*mId, HWC2::DisplayCapability::SkipClientColorTransform);
+    const auto& hwc = getCompositionEngine().getHwComposer();
+    return mId ? hwc.hasDisplayCapability(*mId, HWC2::DisplayCapability::SkipClientColorTransform)
+               : hwc.hasCapability(HWC2::Capability::SkipClientColorTransform);
 }
 
 bool Display::anyLayersRequireClientComposition() const {
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 248933e..34d0cb2 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -829,7 +829,6 @@
     renderengine::DisplaySettings clientCompositionDisplay;
     clientCompositionDisplay.physicalDisplay = outputState.destinationClip;
     clientCompositionDisplay.clip = outputState.sourceClip;
-    clientCompositionDisplay.globalTransform = outputState.transform.asMatrix4();
     clientCompositionDisplay.orientation = outputState.orientation;
     clientCompositionDisplay.outputDataspace = mDisplayColorProfile->hasWideColorGamut()
             ? outputState.dataspace
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 88f2686..f73a6f7 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -681,15 +681,17 @@
 
 using DisplayGetSkipColorTransformTest = DisplayWithLayersTestCommon;
 
-TEST_F(DisplayGetSkipColorTransformTest, doesNothingIfNonHwcDisplay) {
+TEST_F(DisplayGetSkipColorTransformTest, checksCapabilityIfNonHwcDisplay) {
+    EXPECT_CALL(mHwComposer, hasCapability(HWC2::Capability::SkipClientColorTransform))
+            .WillOnce(Return(true));
     auto args = getDisplayCreationArgsForNonHWCVirtualDisplay();
     auto nonHwcDisplay{impl::createDisplay(mCompositionEngine, args)};
-    EXPECT_FALSE(nonHwcDisplay->getSkipColorTransform());
+    EXPECT_TRUE(nonHwcDisplay->getSkipColorTransform());
 }
 
-TEST_F(DisplayGetSkipColorTransformTest, checksHwcCapability) {
+TEST_F(DisplayGetSkipColorTransformTest, checksDisplayCapability) {
     EXPECT_CALL(mHwComposer,
-                hasDisplayCapability(std::make_optional(DEFAULT_DISPLAY_ID),
+                hasDisplayCapability(DEFAULT_DISPLAY_ID,
                                      HWC2::DisplayCapability::SkipClientColorTransform))
             .WillOnce(Return(true));
     EXPECT_TRUE(mDisplay->getSkipColorTransform());
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 02226ab..52bd6a1 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -40,11 +40,11 @@
     MOCK_CONST_METHOD3(getDisplayIdentificationData,
                        bool(hwc2_display_t, uint8_t*, DisplayIdentificationData*));
     MOCK_CONST_METHOD1(hasCapability, bool(HWC2::Capability));
-    MOCK_CONST_METHOD2(hasDisplayCapability,
-                       bool(const std::optional<DisplayId>&, HWC2::DisplayCapability));
+    MOCK_CONST_METHOD2(hasDisplayCapability, bool(DisplayId, HWC2::DisplayCapability));
 
     MOCK_METHOD3(allocateVirtualDisplay,
                  std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*));
+    MOCK_METHOD2(allocatePhysicalDisplay, void(hwc2_display_t, DisplayId));
     MOCK_METHOD1(createLayer, HWC2::Layer*(DisplayId));
     MOCK_METHOD2(destroyLayer, void(DisplayId, HWC2::Layer*));
     MOCK_METHOD3(getDeviceCompositionChanges,
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 63bb459..1c9cd9c 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3100,9 +3100,8 @@
             .andIfUsesHdr(true)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
-                                            mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
-                                            mat4(), Region::INVALID_REGION,
-                                            kDefaultOutputOrientation})
+                                            kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+                                            Region::INVALID_REGION, kDefaultOutputOrientation})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3112,9 +3111,8 @@
             .andIfUsesHdr(false)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
-                                            mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
-                                            mat4(), Region::INVALID_REGION,
-                                            kDefaultOutputOrientation})
+                                            kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+                                            Region::INVALID_REGION, kDefaultOutputOrientation})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3124,7 +3122,7 @@
             .andIfUsesHdr(true)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
-                                            mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
+                                            kDefaultMaxLuminance, kDefaultOutputDataspace,
                                             kDefaultColorTransformMat, Region::INVALID_REGION,
                                             kDefaultOutputOrientation})
             .execute()
@@ -3136,7 +3134,7 @@
             .andIfUsesHdr(false)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
-                                            mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
+                                            kDefaultMaxLuminance, kDefaultOutputDataspace,
                                             kDefaultColorTransformMat, Region::INVALID_REGION,
                                             kDefaultOutputOrientation})
             .execute()
@@ -3149,9 +3147,8 @@
             .andIfUsesHdr(true)
             .andIfSkipColorTransform(true)
             .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
-                                            mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
-                                            mat4(), Region::INVALID_REGION,
-                                            kDefaultOutputOrientation})
+                                            kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+                                            Region::INVALID_REGION, kDefaultOutputOrientation})
             .execute()
             .expectAFenceWasReturned();
 }
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index b72214d..b81eb18 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -220,13 +220,11 @@
     const bool needsFiltering =
             (!globalTransform.preserveRects() || (type >= ui::Transform::SCALE));
 
-    Rect sourceClip = globalTransform.transform(viewport);
-    if (sourceClip.isEmpty()) {
-        sourceClip = displayBounds;
+    const Rect& sourceClip = viewport;
+    Rect destinationClip = globalTransform.transform(viewport);
+    if (destinationClip.isEmpty()) {
+        destinationClip = displayBounds;
     }
-    // For normal display use we always set the source and destination clip
-    // rectangles to the same values.
-    const Rect& destinationClip = sourceClip;
 
     uint32_t transformOrientation;
 
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index fb6c817..e670d78 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -183,9 +183,10 @@
     struct Physical {
         DisplayId id;
         DisplayConnectionType type;
+        hwc2_display_t hwcDisplayId;
 
         bool operator==(const Physical& other) const {
-            return id == other.id && type == other.type;
+            return id == other.id && type == other.type && hwcDisplayId == other.hwcDisplayId;
         }
     };
 
@@ -243,14 +244,12 @@
                       uint32_t reqHeight, ui::Dataspace reqDataSpace, RotationFlags rotation,
                       bool allowSecureLayers = true)
           : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, reqDataSpace,
-                       display->getViewport(),
-                       applyInversePhysicalOrientation(rotation,
-                                                       display->getPhysicalOrientation())),
+                       display->getViewport(), applyDeviceOrientation(rotation, display)),
             mDisplay(std::move(display)),
             mSourceCrop(sourceCrop),
             mAllowSecureLayers(allowSecureLayers) {}
 
-    const ui::Transform& getTransform() const override { return mDisplay->getTransform(); }
+    const ui::Transform& getTransform() const override { return mTransform; }
     Rect getBounds() const override { return mDisplay->getBounds(); }
     int getHeight() const override { return mDisplay->getHeight(); }
     int getWidth() const override { return mDisplay->getWidth(); }
@@ -258,15 +257,9 @@
     sp<const DisplayDevice> getDisplayDevice() const override { return mDisplay; }
 
     bool needsFiltering() const override {
-        // check if the projection from the logical display to the physical
-        // display needs filtering
-        if (mDisplay->needsFiltering()) {
-            return true;
-        }
-
-        // check if the projection from the logical render area (i.e., the
-        // physical display) to the physical render area requires filtering
-        const Rect sourceCrop = getSourceCrop();
+        // check if the projection from the logical render area
+        // to the physical render area requires filtering
+        const Rect& sourceCrop = getSourceCrop();
         int width = sourceCrop.width();
         int height = sourceCrop.height();
         if (getRotationFlags() & ui::Transform::ROT_90) {
@@ -281,36 +274,44 @@
             return mDisplay->getSourceClip();
         }
 
-        // Recompute the device transformation for the source crop.
+        // If there is a source crop provided then it is assumed that the device
+        // was in portrait orientation. This may not logically be true, so
+        // correct for the orientation error by undoing the rotation
+
+        ui::Rotation logicalOrientation = mDisplay->getOrientation();
+        if (logicalOrientation == ui::Rotation::Rotation90) {
+            logicalOrientation = ui::Rotation::Rotation270;
+        } else if (logicalOrientation == ui::Rotation::Rotation270) {
+            logicalOrientation = ui::Rotation::Rotation90;
+        }
+
+        const auto flags = ui::Transform::toRotationFlags(logicalOrientation);
+        int width = mDisplay->getSourceClip().getWidth();
+        int height = mDisplay->getSourceClip().getHeight();
         ui::Transform rotation;
-        ui::Transform translatePhysical;
-        ui::Transform translateLogical;
-        ui::Transform scale;
-        const Rect& viewport = mDisplay->getViewport();
-        const Rect& sourceClip = mDisplay->getSourceClip();
-        const Rect& frame = mDisplay->getFrame();
-
-        const auto flags = ui::Transform::toRotationFlags(mDisplay->getPhysicalOrientation());
-        rotation.set(flags, getWidth(), getHeight());
-
-        translateLogical.set(-viewport.left, -viewport.top);
-        translatePhysical.set(sourceClip.left, sourceClip.top);
-        scale.set(frame.getWidth() / float(viewport.getWidth()), 0, 0,
-                  frame.getHeight() / float(viewport.getHeight()));
-        const ui::Transform finalTransform =
-                rotation * translatePhysical * scale * translateLogical;
-        return finalTransform.transform(mSourceCrop);
+        rotation.set(flags, width, height);
+        return rotation.transform(mSourceCrop);
     }
 
 private:
-    static RotationFlags applyInversePhysicalOrientation(RotationFlags orientation,
-                                                         ui::Rotation physicalOrientation) {
+    static RotationFlags applyDeviceOrientation(RotationFlags orientationFlag,
+                                                const sp<const DisplayDevice>& device) {
         uint32_t inverseRotate90 = 0;
         uint32_t inverseReflect = 0;
 
-        switch (physicalOrientation) {
+        // Reverse the logical orientation.
+        ui::Rotation logicalOrientation = device->getOrientation();
+        if (logicalOrientation == ui::Rotation::Rotation90) {
+            logicalOrientation = ui::Rotation::Rotation270;
+        } else if (logicalOrientation == ui::Rotation::Rotation270) {
+            logicalOrientation = ui::Rotation::Rotation90;
+        }
+
+        const ui::Rotation orientation = device->getPhysicalOrientation() + logicalOrientation;
+
+        switch (orientation) {
             case ui::ROTATION_0:
-                return orientation;
+                return orientationFlag;
 
             case ui::ROTATION_90:
                 inverseRotate90 = ui::Transform::ROT_90;
@@ -326,8 +327,8 @@
                 break;
         }
 
-        const uint32_t rotate90 = orientation & ui::Transform::ROT_90;
-        uint32_t reflect = orientation & ui::Transform::ROT_180;
+        const uint32_t rotate90 = orientationFlag & ui::Transform::ROT_90;
+        uint32_t reflect = orientationFlag & ui::Transform::ROT_180;
 
         // Apply reflection for double rotation.
         if (rotate90 & inverseRotate90) {
@@ -341,6 +342,7 @@
     const sp<const DisplayDevice> mDisplay;
     const Rect mSourceCrop;
     const bool mAllowSecureLayers;
+    const ui::Transform mTransform = ui::Transform();
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp b/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
index f24f314..4dfc743 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
@@ -35,6 +35,7 @@
 
 using byte_view = std::basic_string_view<uint8_t>;
 
+constexpr size_t kEdidBlockSize = 128;
 constexpr size_t kEdidHeaderLength = 5;
 
 constexpr uint16_t kFallbackEdidManufacturerId = 0;
@@ -95,9 +96,66 @@
         info.manufactureOrModelDate = date;
     }
 
+    if (edid.cea861Block && edid.cea861Block->hdmiVendorDataBlock) {
+        const auto& address = edid.cea861Block->hdmiVendorDataBlock->physicalAddress;
+        info.relativeAddress = {address.a, address.b, address.c, address.d};
+    } else {
+        info.relativeAddress = DeviceProductInfo::NO_RELATIVE_ADDRESS;
+    }
     return info;
 }
 
+Cea861ExtensionBlock parseCea861Block(const byte_view& block) {
+    Cea861ExtensionBlock cea861Block;
+
+    constexpr size_t kRevisionNumberOffset = 1;
+    cea861Block.revisionNumber = block[kRevisionNumberOffset];
+
+    constexpr size_t kDetailedTimingDescriptorsOffset = 2;
+    const size_t dtdStart =
+            std::min(kEdidBlockSize, static_cast<size_t>(block[kDetailedTimingDescriptorsOffset]));
+
+    // Parse data blocks.
+    for (size_t dataBlockOffset = 4; dataBlockOffset < dtdStart;) {
+        const uint8_t header = block[dataBlockOffset];
+        const uint8_t tag = header >> 5;
+        const size_t bodyLength = header & 0b11111;
+        constexpr size_t kDataBlockHeaderSize = 1;
+        const size_t dataBlockSize = bodyLength + kDataBlockHeaderSize;
+
+        if (block.size() < dataBlockOffset + dataBlockSize) {
+            ALOGW("Invalid EDID: CEA 861 data block is truncated.");
+            break;
+        }
+
+        const byte_view dataBlock(block.data() + dataBlockOffset, dataBlockSize);
+        constexpr uint8_t kVendorSpecificDataBlockTag = 0x3;
+
+        if (tag == kVendorSpecificDataBlockTag) {
+            const uint32_t ieeeRegistrationId =
+                    dataBlock[1] | (dataBlock[2] << 8) | (dataBlock[3] << 16);
+            constexpr uint32_t kHdmiIeeeRegistrationId = 0xc03;
+
+            if (ieeeRegistrationId == kHdmiIeeeRegistrationId) {
+                const uint8_t a = dataBlock[4] >> 4;
+                const uint8_t b = dataBlock[4] & 0b1111;
+                const uint8_t c = dataBlock[5] >> 4;
+                const uint8_t d = dataBlock[5] & 0b1111;
+                cea861Block.hdmiVendorDataBlock =
+                        HdmiVendorDataBlock{.physicalAddress = HdmiPhysicalAddress{a, b, c, d}};
+            } else {
+                ALOGV("Ignoring vendor specific data block for vendor with IEEE OUI %x",
+                      ieeeRegistrationId);
+            }
+        } else {
+            ALOGV("Ignoring CEA-861 data block with tag %x", tag);
+        }
+        dataBlockOffset += bodyLength + kDataBlockHeaderSize;
+    }
+
+    return cea861Block;
+}
+
 } // namespace
 
 uint16_t DisplayId::manufacturerId() const {
@@ -115,13 +173,12 @@
 }
 
 std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) {
-    constexpr size_t kMinLength = 128;
-    if (edid.size() < kMinLength) {
+    if (edid.size() < kEdidBlockSize) {
         ALOGW("Invalid EDID: structure is truncated.");
         // Attempt parsing even if EDID is malformed.
     } else {
-        ALOGW_IF(edid[126] != 0, "EDID extensions are currently unsupported.");
-        ALOGW_IF(std::accumulate(edid.begin(), edid.begin() + kMinLength, static_cast<uint8_t>(0)),
+        ALOGW_IF(std::accumulate(edid.begin(), edid.begin() + kEdidBlockSize,
+                                 static_cast<uint8_t>(0)),
                  "Invalid EDID: structure does not checksum.");
     }
 
@@ -227,13 +284,43 @@
     // have been observed to change on some displays with multiple inputs.
     const auto modelHash = static_cast<uint32_t>(std::hash<std::string_view>()(modelString));
 
+    // Parse extension blocks.
+    std::optional<Cea861ExtensionBlock> cea861Block;
+    if (edid.size() < kEdidBlockSize) {
+        ALOGW("Invalid EDID: block 0 is truncated.");
+    } else {
+        constexpr size_t kNumExtensionsOffset = 126;
+        const size_t numExtensions = edid[kNumExtensionsOffset];
+        view = byte_view(edid.data(), edid.size());
+        for (size_t blockNumber = 1; blockNumber <= numExtensions; blockNumber++) {
+            view.remove_prefix(kEdidBlockSize);
+            if (view.size() < kEdidBlockSize) {
+                ALOGW("Invalid EDID: block %zu is truncated.", blockNumber);
+                break;
+            }
+
+            const byte_view block(view.data(), kEdidBlockSize);
+            ALOGW_IF(std::accumulate(block.begin(), block.end(), static_cast<uint8_t>(0)),
+                     "Invalid EDID: block %zu does not checksum.", blockNumber);
+            const uint8_t tag = block[0];
+
+            constexpr uint8_t kCea861BlockTag = 0x2;
+            if (tag == kCea861BlockTag) {
+                cea861Block = parseCea861Block(block);
+            } else {
+                ALOGV("Ignoring block number %zu with tag %x.", blockNumber, tag);
+            }
+        }
+    }
+
     return Edid{.manufacturerId = manufacturerId,
                 .productId = productId,
                 .pnpId = *pnpId,
                 .modelHash = modelHash,
                 .displayName = displayName,
+                .manufactureOrModelYear = manufactureOrModelYear,
                 .manufactureWeek = manufactureWeek,
-                .manufactureOrModelYear = manufactureOrModelYear};
+                .cea861Block = cea861Block};
 }
 
 std::optional<PnpId> getPnpId(uint16_t manufacturerId) {
diff --git a/services/surfaceflinger/DisplayHardware/DisplayIdentification.h b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
index d91b957..9e6c549 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
@@ -57,6 +57,26 @@
     std::optional<DeviceProductInfo> deviceProductInfo;
 };
 
+struct ExtensionBlock {
+    uint8_t tag;
+    uint8_t revisionNumber;
+};
+
+struct HdmiPhysicalAddress {
+    // The address describes the path from the display sink in the network of connected HDMI
+    // devices. The format of the address is "a.b.c.d". For example, address 2.1.0.0 means we are
+    // connected to port 1 of a device which is connected to port 2 of the sink.
+    uint8_t a, b, c, d;
+};
+
+struct HdmiVendorDataBlock {
+    HdmiPhysicalAddress physicalAddress;
+};
+
+struct Cea861ExtensionBlock : ExtensionBlock {
+    std::optional<HdmiVendorDataBlock> hdmiVendorDataBlock;
+};
+
 struct Edid {
     uint16_t manufacturerId;
     uint16_t productId;
@@ -65,6 +85,7 @@
     std::string_view displayName;
     uint8_t manufactureOrModelYear;
     uint8_t manufactureWeek;
+    std::optional<Cea861ExtensionBlock> cea861Block;
 };
 
 bool isEdid(const DisplayIdentificationData&);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 1c1e113..f30d662 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -190,71 +190,22 @@
     return mCapabilities.count(capability) > 0;
 }
 
-bool HWComposer::hasDisplayCapability(const std::optional<DisplayId>& displayId,
+bool HWComposer::hasDisplayCapability(DisplayId displayId,
                                       HWC2::DisplayCapability capability) const {
-    if (!displayId) {
-        // Checkout global capabilities for displays without a corresponding HWC display.
-        if (capability == HWC2::DisplayCapability::SkipClientColorTransform) {
-            return hasCapability(HWC2::Capability::SkipClientColorTransform);
-        }
-        return false;
-    }
-    RETURN_IF_INVALID_DISPLAY(*displayId, false);
-    return mDisplayData.at(*displayId).hwcDisplay->getCapabilities().count(capability) > 0;
+    RETURN_IF_INVALID_DISPLAY(displayId, false);
+    return mDisplayData.at(displayId).hwcDisplay->getCapabilities().count(capability) > 0;
 }
 
 std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hwc2_display_t hwcDisplayId,
                                                                HWC2::Connection connection) {
-    std::optional<DisplayIdentificationInfo> info;
-
-    if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
-        info = DisplayIdentificationInfo{.id = *displayId,
-                                         .name = std::string(),
-                                         .deviceProductInfo = std::nullopt};
-    } else {
-        if (connection == HWC2::Connection::Disconnected) {
-            ALOGE("Ignoring disconnection of invalid HWC display %" PRIu64, hwcDisplayId);
+    switch (connection) {
+        case HWC2::Connection::Connected:
+            return onHotplugConnect(hwcDisplayId);
+        case HWC2::Connection::Disconnected:
+            return onHotplugDisconnect(hwcDisplayId);
+        case HWC2::Connection::Invalid:
             return {};
-        }
-
-        info = onHotplugConnect(hwcDisplayId);
-        if (!info) return {};
     }
-
-    ALOGV("%s: %s %s display %s with HWC ID %" PRIu64, __FUNCTION__, to_string(connection).c_str(),
-          hwcDisplayId == mInternalHwcDisplayId ? "internal" : "external",
-          to_string(info->id).c_str(), hwcDisplayId);
-
-    if (connection == HWC2::Connection::Connected) {
-        auto& displayData = mDisplayData[info->id];
-        // If we get a hotplug connected event for a display we already have,
-        // destroy the display and recreate it. This will force us to requery
-        // the display params and recreate all layers on that display.
-        if (displayData.hwcDisplay != nullptr && displayData.hwcDisplay->isConnected()) {
-            ALOGI("Hotplug connecting an already connected display."
-                  " Clearing old display state.");
-        }
-        displayData.hwcDisplay.reset();
-        auto newDisplay =
-                std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId,
-                                                      HWC2::DisplayType::Physical);
-        newDisplay->setConnected(true);
-        displayData.hwcDisplay = std::move(newDisplay);
-        mPhysicalDisplayIdMap[hwcDisplayId] = info->id;
-    } else if (connection == HWC2::Connection::Disconnected) {
-        // The display will later be destroyed by a call to
-        // destroyDisplay(). For now we just mark it disconnected.
-        auto& displayData = mDisplayData[info->id];
-        if (displayData.hwcDisplay) {
-            displayData.hwcDisplay->setConnected(false);
-        } else {
-            ALOGW("Attempted to disconnect unknown display %" PRIu64, hwcDisplayId);
-        }
-        // The cleanup of Disconnect is handled through HWComposer::disconnectDisplay
-        // via SurfaceFlinger's onHotplugReceived callback handling
-    }
-
-    return info;
 }
 
 bool HWComposer::onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) {
@@ -337,6 +288,22 @@
     return displayId;
 }
 
+void HWComposer::allocatePhysicalDisplay(hwc2_display_t hwcDisplayId, DisplayId displayId) {
+    if (!mInternalHwcDisplayId) {
+        mInternalHwcDisplayId = hwcDisplayId;
+    } else if (mInternalHwcDisplayId != hwcDisplayId && !mExternalHwcDisplayId) {
+        mExternalHwcDisplayId = hwcDisplayId;
+    }
+
+    auto& displayData = mDisplayData[displayId];
+    auto newDisplay =
+            std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId,
+                                                  HWC2::DisplayType::Physical);
+    newDisplay->setConnected(true);
+    displayData.hwcDisplay = std::move(newDisplay);
+    mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
+}
+
 HWC2::Layer* HWComposer::createLayer(DisplayId displayId) {
     RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
 
@@ -911,52 +878,93 @@
     return {};
 }
 
-std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(hwc2_display_t hwcDisplayId) {
+bool HWComposer::shouldIgnoreHotplugConnect(hwc2_display_t hwcDisplayId,
+                                            bool hasDisplayIdentificationData) const {
     if (isUsingVrComposer() && mInternalHwcDisplayId) {
         ALOGE("Ignoring connection of external display %" PRIu64 " in VR mode", hwcDisplayId);
-        return {};
+        return true;
     }
 
-    uint8_t port;
-    DisplayIdentificationData data;
-    const bool hasMultiDisplaySupport = getDisplayIdentificationData(hwcDisplayId, &port, &data);
-
-    if (mPhysicalDisplayIdMap.empty()) {
-        mHasMultiDisplaySupport = hasMultiDisplaySupport;
-        ALOGI("Switching to %s multi-display mode",
-              hasMultiDisplaySupport ? "generalized" : "legacy");
-    } else if (mHasMultiDisplaySupport && !hasMultiDisplaySupport) {
+    if (mHasMultiDisplaySupport && !hasDisplayIdentificationData) {
         ALOGE("Ignoring connection of display %" PRIu64 " without identification data",
               hwcDisplayId);
-        return {};
+        return true;
     }
 
-    std::optional<DisplayIdentificationInfo> info;
-
-    if (mHasMultiDisplaySupport) {
-        info = parseDisplayIdentificationData(port, data);
-        ALOGE_IF(!info, "Failed to parse identification data for display %" PRIu64, hwcDisplayId);
-    } else if (mInternalHwcDisplayId && mExternalHwcDisplayId) {
+    if (!mHasMultiDisplaySupport && mInternalHwcDisplayId && mExternalHwcDisplayId) {
         ALOGE("Ignoring connection of tertiary display %" PRIu64, hwcDisplayId);
-        return {};
+        return true;
+    }
+
+    return false;
+}
+
+std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(hwc2_display_t hwcDisplayId) {
+    std::optional<DisplayIdentificationInfo> info;
+    if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
+        info = DisplayIdentificationInfo{.id = *displayId,
+                                         .name = std::string(),
+                                         .deviceProductInfo = std::nullopt};
     } else {
-        ALOGW_IF(hasMultiDisplaySupport, "Ignoring identification data for display %" PRIu64,
-                 hwcDisplayId);
-        port = mInternalHwcDisplayId ? HWC_DISPLAY_EXTERNAL : HWC_DISPLAY_PRIMARY;
+        uint8_t port;
+        DisplayIdentificationData data;
+        const bool hasDisplayIdentificationData =
+                getDisplayIdentificationData(hwcDisplayId, &port, &data);
+        if (mPhysicalDisplayIdMap.empty()) {
+            mHasMultiDisplaySupport = hasDisplayIdentificationData;
+            ALOGI("Switching to %s multi-display mode",
+                  mHasMultiDisplaySupport ? "generalized" : "legacy");
+        }
+
+        if (shouldIgnoreHotplugConnect(hwcDisplayId, hasDisplayIdentificationData)) {
+            return {};
+        }
+
+        info = [this, hwcDisplayId, &port, &data, hasDisplayIdentificationData] {
+            const bool isPrimary = !mInternalHwcDisplayId;
+            if (mHasMultiDisplaySupport) {
+                if (const auto info = parseDisplayIdentificationData(port, data)) {
+                    return *info;
+                }
+                ALOGE("Failed to parse identification data for display %" PRIu64, hwcDisplayId);
+            } else {
+                ALOGW_IF(hasDisplayIdentificationData,
+                         "Ignoring identification data for display %" PRIu64, hwcDisplayId);
+                port = isPrimary ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL;
+            }
+
+            return DisplayIdentificationInfo{.id = getFallbackDisplayId(port),
+                                             .name = isPrimary ? "Internal display"
+                                                               : "External display",
+                                             .deviceProductInfo = std::nullopt};
+        }();
     }
 
-    if (!mInternalHwcDisplayId) {
-        mInternalHwcDisplayId = hwcDisplayId;
-    } else if (!mExternalHwcDisplayId) {
-        mExternalHwcDisplayId = hwcDisplayId;
+    if (!isConnected(info->id)) {
+        allocatePhysicalDisplay(hwcDisplayId, info->id);
+    }
+    return info;
+}
+
+std::optional<DisplayIdentificationInfo> HWComposer::onHotplugDisconnect(
+        hwc2_display_t hwcDisplayId) {
+    const auto displayId = toPhysicalDisplayId(hwcDisplayId);
+    if (!displayId) {
+        ALOGE("Ignoring disconnection of invalid HWC display %" PRIu64, hwcDisplayId);
+        return {};
     }
 
-    if (info) return info;
-
-    return DisplayIdentificationInfo{.id = getFallbackDisplayId(port),
-                                     .name = hwcDisplayId == mInternalHwcDisplayId
-                                             ? "Internal display"
-                                             : "External display",
+    // The display will later be destroyed by a call to
+    // destroyDisplay(). For now we just mark it disconnected.
+    if (isConnected(*displayId)) {
+        mDisplayData[*displayId].hwcDisplay->setConnected(false);
+    } else {
+        ALOGW("Attempted to disconnect unknown display %" PRIu64, hwcDisplayId);
+    }
+    // The cleanup of Disconnect is handled through HWComposer::disconnectDisplay
+    // via SurfaceFlinger's onHotplugReceived callback handling
+    return DisplayIdentificationInfo{.id = *displayId,
+                                     .name = std::string(),
                                      .deviceProductInfo = std::nullopt};
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 41db501..e18419a 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -70,13 +70,15 @@
                                               DisplayIdentificationData* outData) const = 0;
 
     virtual bool hasCapability(HWC2::Capability capability) const = 0;
-    virtual bool hasDisplayCapability(const std::optional<DisplayId>& displayId,
+    virtual bool hasDisplayCapability(DisplayId displayId,
                                       HWC2::DisplayCapability capability) const = 0;
 
     // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
     virtual std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
                                                             ui::PixelFormat* format) = 0;
 
+    virtual void allocatePhysicalDisplay(hwc2_display_t hwcDisplayId, DisplayId displayId) = 0;
+
     // Attempts to create a new layer on this display
     virtual HWC2::Layer* createLayer(DisplayId displayId) = 0;
     // Destroy a previously created layer
@@ -164,6 +166,7 @@
 
     // Returns stable display ID (and display name on connection of new or previously disconnected
     // display), or std::nullopt if hotplug event was ignored.
+    // This function is called from SurfaceFlinger.
     virtual std::optional<DisplayIdentificationInfo> onHotplug(hwc2_display_t hwcDisplayId,
                                                                HWC2::Connection connection) = 0;
 
@@ -231,13 +234,16 @@
                                       DisplayIdentificationData* outData) const override;
 
     bool hasCapability(HWC2::Capability capability) const override;
-    bool hasDisplayCapability(const std::optional<DisplayId>& displayId,
+    bool hasDisplayCapability(DisplayId displayId,
                               HWC2::DisplayCapability capability) const override;
 
     // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
     std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
                                                     ui::PixelFormat* format) override;
 
+    // Called from SurfaceFlinger, when the state for a new physical display needs to be recreated.
+    void allocatePhysicalDisplay(hwc2_display_t hwcDisplayId, DisplayId displayId) override;
+
     // Attempts to create a new layer on this display
     HWC2::Layer* createLayer(DisplayId displayId) override;
     // Destroy a previously created layer
@@ -361,6 +367,10 @@
     friend TestableSurfaceFlinger;
 
     std::optional<DisplayIdentificationInfo> onHotplugConnect(hwc2_display_t hwcDisplayId);
+    std::optional<DisplayIdentificationInfo> onHotplugDisconnect(hwc2_display_t hwcDisplayId);
+    bool shouldIgnoreHotplugConnect(hwc2_display_t hwcDisplayId,
+                                    bool hasDisplayIdentificationData) const;
+
     void loadCapabilities();
     void loadLayerMetadataSupport();
     uint32_t getMaxVirtualDisplayCount() const;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3d67a6b..5039761 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2134,10 +2134,12 @@
     writeToProtoDrawingState(layerProto, traceFlags);
     writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, traceFlags);
 
-    // Only populate for the primary display.
-    if (device) {
-        const Hwc2::IComposerClient::Composition compositionType = getCompositionType(device);
-        layerProto->set_hwc_composition_type(static_cast<HwcCompositionType>(compositionType));
+    if (traceFlags & SurfaceTracing::TRACE_COMPOSITION) {
+        // Only populate for the primary display.
+        if (device) {
+            const Hwc2::IComposerClient::Composition compositionType = getCompositionType(device);
+            layerProto->set_hwc_composition_type(static_cast<HwcCompositionType>(compositionType));
+        }
     }
 
     for (const sp<Layer>& layer : mDrawingChildren) {
@@ -2180,8 +2182,10 @@
         LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
                                                [&]() { return layerInfo->mutable_position(); });
         LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); });
-        LayerProtoHelper::writeToProto(debugGetVisibleRegionOnDefaultDisplay(),
-                                       [&]() { return layerInfo->mutable_visible_region(); });
+        if (traceFlags & SurfaceTracing::TRACE_COMPOSITION) {
+            LayerProtoHelper::writeToProto(debugGetVisibleRegionOnDefaultDisplay(),
+                                           [&]() { return layerInfo->mutable_visible_region(); });
+        }
         LayerProtoHelper::writeToProto(surfaceDamageRegion,
                                        [&]() { return layerInfo->mutable_damage_region(); });
 
@@ -2191,15 +2195,13 @@
         }
     }
 
-    if (traceFlags & SurfaceTracing::TRACE_EXTRA) {
-        LayerProtoHelper::writeToProto(mSourceBounds,
-                                       [&]() { return layerInfo->mutable_source_bounds(); });
-        LayerProtoHelper::writeToProto(mScreenBounds,
-                                       [&]() { return layerInfo->mutable_screen_bounds(); });
-        LayerProtoHelper::writeToProto(getRoundedCornerState().cropRect,
-                                       [&]() { return layerInfo->mutable_corner_radius_crop(); });
-        layerInfo->set_shadow_radius(mEffectiveShadowRadius);
-    }
+    LayerProtoHelper::writeToProto(mSourceBounds,
+                                   [&]() { return layerInfo->mutable_source_bounds(); });
+    LayerProtoHelper::writeToProto(mScreenBounds,
+                                   [&]() { return layerInfo->mutable_screen_bounds(); });
+    LayerProtoHelper::writeToProto(getRoundedCornerState().cropRect,
+                                   [&]() { return layerInfo->mutable_corner_radius_crop(); });
+    layerInfo->set_shadow_radius(mEffectiveShadowRadius);
 }
 
 void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet stateSet,
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index be80f78..92ac015 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -535,6 +535,19 @@
     }
     virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; }
     virtual bool needsFiltering(const sp<const DisplayDevice>&) const { return false; }
+    // True if this layer requires filtering
+    // This method is distinct from needsFiltering() in how the filter
+    // requirement is computed. needsFiltering() compares displayFrame and crop,
+    // where as this method transforms the displayFrame to layer-stack space
+    // first. This method should be used if there is no physical display to
+    // project onto when taking screenshots, as the filtering requirements are
+    // different.
+    // If the parent transform needs to be undone when capturing the layer, then
+    // the inverse parent transform is also required.
+    virtual bool needsFilteringForScreenshots(const sp<const DisplayDevice>&,
+                                              const ui::Transform&) const {
+        return false;
+    }
 
     // This layer is not a clone, but it's the parent to the cloned hierarchy. The
     // variable mClonedChild represents the top layer that will be cloned so this
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index c675971..0a0f2f1 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -170,7 +170,7 @@
 void RefreshRateOverlay::primeCache() {
     auto& allRefreshRates = mFlinger.mRefreshRateConfigs->getAllRefreshRates();
     if (allRefreshRates.size() == 1) {
-        auto fps = allRefreshRates.begin()->second->fps;
+        auto fps = allRefreshRates.begin()->second->getFps();
         half4 color = {LOW_FPS_COLOR, ALPHA};
         mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color));
         return;
@@ -179,7 +179,7 @@
     std::vector<uint32_t> supportedFps;
     supportedFps.reserve(allRefreshRates.size());
     for (auto& [ignored, refreshRate] : allRefreshRates) {
-        supportedFps.push_back(refreshRate->fps);
+        supportedFps.push_back(refreshRate->getFps());
     }
 
     std::sort(supportedFps.begin(), supportedFps.end());
@@ -207,7 +207,7 @@
     const int32_t right = left + display->getWidth() / 8;
     const int32_t buttom = top + display->getHeight() / 32;
 
-    auto buffer = mBufferCache[refreshRate.fps];
+    auto buffer = mBufferCache[refreshRate.getFps()];
     mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {});
 
     mLayer->setFrame(Rect(left, top, right, buttom));
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index 9b3a9f4..6b0455a 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -61,10 +61,9 @@
     // render area.  It can be larger than the logical render area.  It can
     // also be optionally rotated.
     //
-    // Layers are first clipped to the source crop (in addition to being
-    // clipped to the logical render area already).  The source crop and the
-    // layers are then rotated around the center of the source crop, and
-    // scaled to the physical render area linearly.
+    // The source crop is specified in layer space (when rendering a layer and
+    // its children), or in layer-stack space (when rendering all layers visible
+    // on the display).
     virtual Rect getSourceCrop() const = 0;
 
     // Returns the rotation of the source crop and the layers.
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 0d6a92e..8347650 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -429,7 +429,13 @@
                     ALOGW("Faking VSYNC due to driver stall for thread %s", mThreadName);
                     std::string debugInfo = "VsyncSource debug info:\n";
                     mVSyncSource->dump(debugInfo);
-                    ALOGW("%s", debugInfo.c_str());
+                    // Log the debug info line-by-line to avoid logcat overflow
+                    auto pos = debugInfo.find('\n');
+                    while (pos != std::string::npos) {
+                        ALOGW("%s", debugInfo.substr(0, pos).c_str());
+                        debugInfo = debugInfo.substr(pos + 1);
+                        pos = debugInfo.find('\n');
+                    }
                 }
 
                 LOG_FATAL_IF(!mVSyncState);
diff --git a/services/surfaceflinger/Scheduler/HwcStrongTypes.h b/services/surfaceflinger/Scheduler/HwcStrongTypes.h
index cfbbdfe..8ba4f20 100644
--- a/services/surfaceflinger/Scheduler/HwcStrongTypes.h
+++ b/services/surfaceflinger/Scheduler/HwcStrongTypes.h
@@ -22,6 +22,5 @@
 
 // Strong types for the different indexes as they are referring to a different base.
 using HwcConfigIndexType = StrongTyping<int, struct HwcConfigIndexTypeTag, Compare, Add, Hash>;
-using HwcConfigGroupType = StrongTyping<int, struct HwcConfigGroupTypeTag, Compare>;
 
 } // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
index 43883fb..d9aaa05 100644
--- a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
+++ b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
@@ -43,7 +43,7 @@
     refreshRates.reserve(allRefreshRates.size());
 
     for (const auto& [ignored, refreshRate] : allRefreshRates) {
-        refreshRates.emplace_back(refreshRate->fps);
+        refreshRates.emplace_back(refreshRate->getFps());
     }
 
     return refreshRates;
@@ -59,7 +59,7 @@
 
 PhaseOffsets::PhaseOffsets(const scheduler::RefreshRateConfigs& refreshRateConfigs)
       : PhaseOffsets(getRefreshRatesFromConfigs(refreshRateConfigs),
-                     refreshRateConfigs.getCurrentRefreshRate().fps,
+                     refreshRateConfigs.getCurrentRefreshRate().getFps(),
                      // Below defines the threshold when an offset is considered to be negative,
                      // i.e. targeting for the N+2 vsync instead of N+1. This means that: For offset
                      // < threshold, SF wake up (vsync_duration - offset) before HW vsync. For
@@ -275,7 +275,7 @@
 
 PhaseDurations::PhaseDurations(const scheduler::RefreshRateConfigs& refreshRateConfigs)
       : PhaseDurations(getRefreshRatesFromConfigs(refreshRateConfigs),
-                       refreshRateConfigs.getCurrentRefreshRate().fps,
+                       refreshRateConfigs.getCurrentRefreshRate().getFps(),
                        getProperty("debug.sf.late.sf.duration").value_or(-1),
                        getProperty("debug.sf.late.app.duration").value_or(-1),
                        getProperty("debug.sf.early.sf.duration").value_or(mSfDuration),
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 02d0b53..5634adb 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -53,7 +53,7 @@
     if (explicitContentFramerate != 0) {
         contentFramerate = explicitContentFramerate;
     } else if (contentFramerate == 0) {
-        contentFramerate = round<int>(mMaxSupportedRefreshRate->fps);
+        contentFramerate = round<int>(mMaxSupportedRefreshRate->getFps());
     }
     ATRACE_INT("ContentFPS", contentFramerate);
 
@@ -177,7 +177,7 @@
                 continue;
             }
 
-            const auto displayPeriod = scores[i].first->vsyncPeriod;
+            const auto displayPeriod = scores[i].first->hwcConfig->getVsyncPeriod();
             const auto layerPeriod = round<nsecs_t>(1e9f / layer.desiredRefreshRate);
             if (layer.vote == LayerVoteType::ExplicitDefault) {
                 const auto layerScore = [&]() {
@@ -301,7 +301,7 @@
                   mCurrentRefreshRate) != mAvailableRefreshRates.end()) {
         return *mCurrentRefreshRate;
     }
-    return *mRefreshRates.at(mDefaultConfig);
+    return *mRefreshRates.at(getCurrentPolicyLocked()->defaultConfig);
 }
 
 void RefreshRateConfigs::setCurrentConfigId(HwcConfigIndexType configId) {
@@ -309,55 +309,85 @@
     mCurrentRefreshRate = mRefreshRates.at(configId).get();
 }
 
-RefreshRateConfigs::RefreshRateConfigs(const std::vector<InputConfig>& configs,
-                                       HwcConfigIndexType currentHwcConfig) {
-    init(configs, currentHwcConfig);
-}
-
 RefreshRateConfigs::RefreshRateConfigs(
         const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs,
         HwcConfigIndexType currentConfigId) {
-    std::vector<InputConfig> inputConfigs;
-    for (size_t configId = 0; configId < configs.size(); ++configId) {
-        auto configGroup = HwcConfigGroupType(configs[configId]->getConfigGroup());
-        inputConfigs.push_back({HwcConfigIndexType(static_cast<int>(configId)), configGroup,
-                                configs[configId]->getVsyncPeriod()});
+    LOG_ALWAYS_FATAL_IF(configs.empty());
+    LOG_ALWAYS_FATAL_IF(currentConfigId.value() >= configs.size());
+
+    for (auto configId = HwcConfigIndexType(0); configId.value() < configs.size(); configId++) {
+        const auto& config = configs.at(static_cast<size_t>(configId.value()));
+        const float fps = 1e9f / config->getVsyncPeriod();
+        mRefreshRates.emplace(configId,
+                              std::make_unique<RefreshRate>(configId, config,
+                                                            base::StringPrintf("%2.ffps", fps), fps,
+                                                            RefreshRate::ConstructorTag(0)));
+        if (configId == currentConfigId) {
+            mCurrentRefreshRate = mRefreshRates.at(configId).get();
+        }
     }
-    init(inputConfigs, currentConfigId);
+
+    std::vector<const RefreshRate*> sortedConfigs;
+    getSortedRefreshRateList([](const RefreshRate&) { return true; }, &sortedConfigs);
+    mDisplayManagerPolicy.defaultConfig = currentConfigId;
+    mMinSupportedRefreshRate = sortedConfigs.front();
+    mMaxSupportedRefreshRate = sortedConfigs.back();
+    constructAvailableRefreshRates();
 }
 
-status_t RefreshRateConfigs::setPolicy(HwcConfigIndexType defaultConfigId, float minRefreshRate,
-                                       float maxRefreshRate, bool* outPolicyChanged) {
+bool RefreshRateConfigs::isPolicyValid(const Policy& policy) {
+    // defaultConfig must be a valid config, and within the given refresh rate range.
+    auto iter = mRefreshRates.find(policy.defaultConfig);
+    if (iter == mRefreshRates.end()) {
+        return false;
+    }
+    const RefreshRate& refreshRate = *iter->second;
+    if (!refreshRate.inPolicy(policy.minRefreshRate, policy.maxRefreshRate)) {
+        return false;
+    }
+    return true;
+}
+
+status_t RefreshRateConfigs::setDisplayManagerPolicy(const Policy& policy) {
     std::lock_guard lock(mLock);
-    bool policyChanged = defaultConfigId != mDefaultConfig ||
-            minRefreshRate != mMinRefreshRateFps || maxRefreshRate != mMaxRefreshRateFps;
-    if (outPolicyChanged) {
-        *outPolicyChanged = policyChanged;
-    }
-    if (!policyChanged) {
-        return NO_ERROR;
-    }
-    // defaultConfigId must be a valid config ID, and within the given refresh rate range.
-    if (mRefreshRates.count(defaultConfigId) == 0) {
+    if (!isPolicyValid(policy)) {
         return BAD_VALUE;
     }
-    const RefreshRate& refreshRate = *mRefreshRates.at(defaultConfigId);
-    if (!refreshRate.inPolicy(minRefreshRate, maxRefreshRate)) {
-        return BAD_VALUE;
+    Policy previousPolicy = *getCurrentPolicyLocked();
+    mDisplayManagerPolicy = policy;
+    if (*getCurrentPolicyLocked() == previousPolicy) {
+        return CURRENT_POLICY_UNCHANGED;
     }
-    mDefaultConfig = defaultConfigId;
-    mMinRefreshRateFps = minRefreshRate;
-    mMaxRefreshRateFps = maxRefreshRate;
     constructAvailableRefreshRates();
     return NO_ERROR;
 }
 
-void RefreshRateConfigs::getPolicy(HwcConfigIndexType* defaultConfigId, float* minRefreshRate,
-                                   float* maxRefreshRate) const {
+status_t RefreshRateConfigs::setOverridePolicy(const std::optional<Policy>& policy) {
     std::lock_guard lock(mLock);
-    *defaultConfigId = mDefaultConfig;
-    *minRefreshRate = mMinRefreshRateFps;
-    *maxRefreshRate = mMaxRefreshRateFps;
+    if (policy && !isPolicyValid(*policy)) {
+        return BAD_VALUE;
+    }
+    Policy previousPolicy = *getCurrentPolicyLocked();
+    mOverridePolicy = policy;
+    if (*getCurrentPolicyLocked() == previousPolicy) {
+        return CURRENT_POLICY_UNCHANGED;
+    }
+    constructAvailableRefreshRates();
+    return NO_ERROR;
+}
+
+const RefreshRateConfigs::Policy* RefreshRateConfigs::getCurrentPolicyLocked() const {
+    return mOverridePolicy ? &mOverridePolicy.value() : &mDisplayManagerPolicy;
+}
+
+RefreshRateConfigs::Policy RefreshRateConfigs::getCurrentPolicy() const {
+    std::lock_guard lock(mLock);
+    return *getCurrentPolicyLocked();
+}
+
+RefreshRateConfigs::Policy RefreshRateConfigs::getDisplayManagerPolicy() const {
+    std::lock_guard lock(mLock);
+    return mDisplayManagerPolicy;
 }
 
 bool RefreshRateConfigs::isConfigAllowed(HwcConfigIndexType config) const {
@@ -385,19 +415,35 @@
 
     std::sort(outRefreshRates->begin(), outRefreshRates->end(),
               [](const auto refreshRate1, const auto refreshRate2) {
-                  return refreshRate1->vsyncPeriod > refreshRate2->vsyncPeriod;
+                  if (refreshRate1->hwcConfig->getVsyncPeriod() !=
+                      refreshRate2->hwcConfig->getVsyncPeriod()) {
+                      return refreshRate1->hwcConfig->getVsyncPeriod() >
+                              refreshRate2->hwcConfig->getVsyncPeriod();
+                  } else {
+                      return refreshRate1->hwcConfig->getConfigGroup() >
+                              refreshRate2->hwcConfig->getConfigGroup();
+                  }
               });
 }
 
 void RefreshRateConfigs::constructAvailableRefreshRates() {
     // Filter configs based on current policy and sort based on vsync period
-    HwcConfigGroupType group = mRefreshRates.at(mDefaultConfig)->configGroup;
+    const Policy* policy = getCurrentPolicyLocked();
+    const auto& defaultConfig = mRefreshRates.at(policy->defaultConfig)->hwcConfig;
     ALOGV("constructAvailableRefreshRates: default %d group %d min %.2f max %.2f",
-          mDefaultConfig.value(), group.value(), mMinRefreshRateFps, mMaxRefreshRateFps);
+          policy->defaultConfig.value(), defaultConfig->getConfigGroup(), policy->minRefreshRate,
+          policy->maxRefreshRate);
     getSortedRefreshRateList(
             [&](const RefreshRate& refreshRate) REQUIRES(mLock) {
-                return refreshRate.configGroup == group &&
-                        refreshRate.inPolicy(mMinRefreshRateFps, mMaxRefreshRateFps);
+                const auto& hwcConfig = refreshRate.hwcConfig;
+
+                return hwcConfig->getHeight() == defaultConfig->getHeight() &&
+                        hwcConfig->getWidth() == defaultConfig->getWidth() &&
+                        hwcConfig->getDpiX() == defaultConfig->getDpiX() &&
+                        hwcConfig->getDpiY() == defaultConfig->getDpiY() &&
+                        (policy->allowGroupSwitching ||
+                         hwcConfig->getConfigGroup() == defaultConfig->getConfigGroup()) &&
+                        refreshRate.inPolicy(policy->minRefreshRate, policy->maxRefreshRate);
             },
             &mAvailableRefreshRates);
 
@@ -409,33 +455,8 @@
     ALOGV("Available refresh rates: %s", availableRefreshRates.c_str());
     LOG_ALWAYS_FATAL_IF(mAvailableRefreshRates.empty(),
                         "No compatible display configs for default=%d min=%.0f max=%.0f",
-                        mDefaultConfig.value(), mMinRefreshRateFps, mMaxRefreshRateFps);
-}
-
-// NO_THREAD_SAFETY_ANALYSIS since this is called from the constructor
-void RefreshRateConfigs::init(const std::vector<InputConfig>& configs,
-                              HwcConfigIndexType currentHwcConfig) NO_THREAD_SAFETY_ANALYSIS {
-    LOG_ALWAYS_FATAL_IF(configs.empty());
-    LOG_ALWAYS_FATAL_IF(currentHwcConfig.value() >= configs.size());
-
-    for (const auto& config : configs) {
-        const float fps = 1e9f / config.vsyncPeriod;
-        mRefreshRates.emplace(config.configId,
-                              std::make_unique<RefreshRate>(config.configId, config.vsyncPeriod,
-                                                            config.configGroup,
-                                                            base::StringPrintf("%2.ffps", fps),
-                                                            fps));
-        if (config.configId == currentHwcConfig) {
-            mCurrentRefreshRate = mRefreshRates.at(config.configId).get();
-        }
-    }
-
-    std::vector<const RefreshRate*> sortedConfigs;
-    getSortedRefreshRateList([](const RefreshRate&) { return true; }, &sortedConfigs);
-    mDefaultConfig = currentHwcConfig;
-    mMinSupportedRefreshRate = sortedConfigs.front();
-    mMaxSupportedRefreshRate = sortedConfigs.back();
-    constructAvailableRefreshRates();
+                        policy->defaultConfig.value(), policy->minRefreshRate,
+                        policy->maxRefreshRate);
 }
 
 } // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 87d4389..dea7e90 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -20,6 +20,7 @@
 
 #include <algorithm>
 #include <numeric>
+#include <optional>
 #include <type_traits>
 
 #include "DisplayHardware/HWComposer.h"
@@ -28,6 +29,8 @@
 #include "Scheduler/StrongTyping.h"
 
 namespace android::scheduler {
+class RefreshRateConfigsTest;
+
 using namespace std::chrono_literals;
 
 enum class RefreshRateConfigEvent : unsigned { None = 0b0, Changed = 0b1 };
@@ -48,30 +51,27 @@
     static constexpr nsecs_t MARGIN_FOR_PERIOD_CALCULATION =
         std::chrono::nanoseconds(800us).count();
 
-    struct RefreshRate {
-        // The tolerance within which we consider FPS approximately equals.
-        static constexpr float FPS_EPSILON = 0.001f;
+    class RefreshRate {
+    private:
+        // Effectively making the constructor private while allowing
+        // std::make_unique to create the object
+        struct ConstructorTag {
+            explicit ConstructorTag(int) {}
+        };
 
-        RefreshRate(HwcConfigIndexType configId, nsecs_t vsyncPeriod,
-                    HwcConfigGroupType configGroup, std::string name, float fps)
-              : configId(configId),
-                vsyncPeriod(vsyncPeriod),
-                configGroup(configGroup),
-                name(std::move(name)),
-                fps(fps) {}
+    public:
+        RefreshRate(HwcConfigIndexType configId,
+                    std::shared_ptr<const HWC2::Display::Config> config, std::string name,
+                    float fps, ConstructorTag)
+              : configId(configId), hwcConfig(config), name(std::move(name)), fps(fps) {}
 
         RefreshRate(const RefreshRate&) = delete;
-        // This config ID corresponds to the position of the config in the vector that is stored
-        // on the device.
-        const HwcConfigIndexType configId;
-        // Vsync period in nanoseconds.
-        const nsecs_t vsyncPeriod;
-        // This configGroup for the config.
-        const HwcConfigGroupType configGroup;
-        // Human readable name of the refresh rate.
-        const std::string name;
-        // Refresh rate in frames per second
-        const float fps = 0;
+
+        HwcConfigIndexType getConfigId() const { return configId; }
+        nsecs_t getVsyncPeriod() const { return hwcConfig->getVsyncPeriod(); }
+        int32_t getConfigGroup() const { return hwcConfig->getConfigGroup(); }
+        const std::string& getName() const { return name; }
+        float getFps() const { return fps; }
 
         // Checks whether the fps of this RefreshRate struct is within a given min and max refresh
         // rate passed in. FPS_EPSILON is applied to the boundaries for approximation.
@@ -80,24 +80,73 @@
         }
 
         bool operator!=(const RefreshRate& other) const {
-            return configId != other.configId || vsyncPeriod != other.vsyncPeriod ||
-                    configGroup != other.configGroup;
+            return configId != other.configId || hwcConfig != other.hwcConfig;
         }
 
         bool operator==(const RefreshRate& other) const { return !(*this != other); }
+
+    private:
+        friend RefreshRateConfigs;
+        friend RefreshRateConfigsTest;
+
+        // The tolerance within which we consider FPS approximately equals.
+        static constexpr float FPS_EPSILON = 0.001f;
+
+        // This config ID corresponds to the position of the config in the vector that is stored
+        // on the device.
+        const HwcConfigIndexType configId;
+        // The config itself
+        std::shared_ptr<const HWC2::Display::Config> hwcConfig;
+        // Human readable name of the refresh rate.
+        const std::string name;
+        // Refresh rate in frames per second
+        const float fps = 0;
     };
 
     using AllRefreshRatesMapType =
             std::unordered_map<HwcConfigIndexType, std::unique_ptr<const RefreshRate>>;
 
-    // Sets the current policy to choose refresh rates. Returns NO_ERROR if the requested policy is
-    // valid, or a negative error value otherwise. policyChanged, if non-null, will be set to true
-    // if the new policy is different from the old policy.
-    status_t setPolicy(HwcConfigIndexType defaultConfigId, float minRefreshRate,
-                       float maxRefreshRate, bool* policyChanged) EXCLUDES(mLock);
-    // Gets the current policy.
-    void getPolicy(HwcConfigIndexType* defaultConfigId, float* minRefreshRate,
-                   float* maxRefreshRate) const EXCLUDES(mLock);
+    struct Policy {
+        // The default config, used to ensure we only initiate display config switches within the
+        // same config group as defaultConfigId's group.
+        HwcConfigIndexType defaultConfig;
+        // The min and max FPS allowed by the policy.
+        float minRefreshRate = 0;
+        float maxRefreshRate = std::numeric_limits<float>::max();
+        // Whether or not we switch config groups to get the best frame rate. Only used by tests.
+        bool allowGroupSwitching = false;
+
+        bool operator==(const Policy& other) const {
+            return defaultConfig == other.defaultConfig && minRefreshRate == other.minRefreshRate &&
+                    maxRefreshRate == other.maxRefreshRate &&
+                    allowGroupSwitching == other.allowGroupSwitching;
+        }
+
+        bool operator!=(const Policy& other) const { return !(*this == other); }
+    };
+
+    // Return code set*Policy() to indicate the current policy is unchanged.
+    static constexpr int CURRENT_POLICY_UNCHANGED = 1;
+
+    // We maintain the display manager policy and the override policy separately. The override
+    // policy is used by CTS tests to get a consistent device state for testing. While the override
+    // policy is set, it takes precedence over the display manager policy. Once the override policy
+    // is cleared, we revert to using the display manager policy.
+
+    // Sets the display manager policy to choose refresh rates. The return value will be:
+    //   - A negative value if the policy is invalid or another error occurred.
+    //   - NO_ERROR if the policy was successfully updated, and the current policy is different from
+    //     what it was before the call.
+    //   - CURRENT_POLICY_UNCHANGED if the policy was successfully updated, but the current policy
+    //     is the same as it was before the call.
+    status_t setDisplayManagerPolicy(const Policy& policy) EXCLUDES(mLock);
+    // Sets the override policy. See setDisplayManagerPolicy() for the meaning of the return value.
+    status_t setOverridePolicy(const std::optional<Policy>& policy) EXCLUDES(mLock);
+    // Gets the current policy, which will be the override policy if active, and the display manager
+    // policy otherwise.
+    Policy getCurrentPolicy() const EXCLUDES(mLock);
+    // Gets the display manager policy, regardless of whether an override policy is active.
+    Policy getDisplayManagerPolicy() const EXCLUDES(mLock);
 
     // Returns true if config is allowed by the current policy.
     bool isConfigAllowed(HwcConfigIndexType config) const EXCLUDES(mLock);
@@ -174,20 +223,10 @@
     // Stores the current configId the device operates at
     void setCurrentConfigId(HwcConfigIndexType configId) EXCLUDES(mLock);
 
-    struct InputConfig {
-        HwcConfigIndexType configId = HwcConfigIndexType(0);
-        HwcConfigGroupType configGroup = HwcConfigGroupType(0);
-        nsecs_t vsyncPeriod = 0;
-    };
-
-    RefreshRateConfigs(const std::vector<InputConfig>& configs,
-                       HwcConfigIndexType currentHwcConfig);
     RefreshRateConfigs(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs,
                        HwcConfigIndexType currentConfigId);
 
 private:
-    void init(const std::vector<InputConfig>& configs, HwcConfigIndexType currentHwcConfig);
-
     void constructAvailableRefreshRates() REQUIRES(mLock);
 
     void getSortedRefreshRateList(
@@ -208,6 +247,9 @@
     // the policy.
     const RefreshRate& getCurrentRefreshRateByPolicyLocked() const REQUIRES(mLock);
 
+    const Policy* getCurrentPolicyLocked() const REQUIRES(mLock);
+    bool isPolicyValid(const Policy& policy);
+
     // The list of refresh rates, indexed by display config ID. This must not change after this
     // object is initialized.
     AllRefreshRatesMapType mRefreshRates;
@@ -220,14 +262,10 @@
     // the main thread, and read by the Scheduler (and other objects) on other threads.
     const RefreshRate* mCurrentRefreshRate GUARDED_BY(mLock);
 
-    // The default config. This will change at runtime. This is set by SurfaceFlinger on
-    // the main thread, and read by the Scheduler (and other objects) on other threads.
-    HwcConfigIndexType mDefaultConfig GUARDED_BY(mLock);
-
-    // The min and max FPS allowed by the policy. This will change at runtime and set by
-    // SurfaceFlinger on the main thread.
-    float mMinRefreshRateFps GUARDED_BY(mLock) = 0;
-    float mMaxRefreshRateFps GUARDED_BY(mLock) = std::numeric_limits<float>::max();
+    // The policy values will change at runtime. They're set by SurfaceFlinger on the main thread,
+    // and read by the Scheduler (and other objects) on other threads.
+    Policy mDisplayManagerPolicy GUARDED_BY(mLock);
+    std::optional<Policy> mOverridePolicy GUARDED_BY(mLock);
 
     // The min and max refresh rates supported by the device.
     // This will not change at runtime.
diff --git a/services/surfaceflinger/Scheduler/RefreshRateStats.h b/services/surfaceflinger/Scheduler/RefreshRateStats.h
index e44cd52..66d4a03 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateStats.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateStats.h
@@ -78,10 +78,10 @@
         // Multiple configs may map to the same name, e.g. "60fps". Add the
         // times for such configs together.
         for (const auto& [configId, time] : mConfigModesTotalTime) {
-            totalTime[mRefreshRateConfigs.getRefreshRateFromConfigId(configId).name] = 0;
+            totalTime[mRefreshRateConfigs.getRefreshRateFromConfigId(configId).getName()] = 0;
         }
         for (const auto& [configId, time] : mConfigModesTotalTime) {
-            totalTime[mRefreshRateConfigs.getRefreshRateFromConfigId(configId).name] += time;
+            totalTime[mRefreshRateConfigs.getRefreshRateFromConfigId(configId).getName()] += time;
         }
         totalTime["ScreenOff"] = mScreenOffTime;
         return totalTime;
@@ -115,7 +115,7 @@
             }
             mConfigModesTotalTime[mCurrentConfigMode] += timeElapsedMs;
             fps = static_cast<uint32_t>(std::round(
-                    mRefreshRateConfigs.getRefreshRateFromConfigId(mCurrentConfigMode).fps));
+                    mRefreshRateConfigs.getRefreshRateFromConfigId(mCurrentConfigMode).getFps()));
         } else {
             mScreenOffTime += timeElapsedMs;
         }
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index cd6075f..9a9523f 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -332,7 +332,7 @@
     const nsecs_t last = mLastResyncTime.exchange(now);
 
     if (now - last > kIgnoreDelay) {
-        resyncToHardwareVsync(false, mRefreshRateConfigs.getCurrentRefreshRate().vsyncPeriod);
+        resyncToHardwareVsync(false, mRefreshRateConfigs.getCurrentRefreshRate().getVsyncPeriod());
     }
 }
 
@@ -389,34 +389,34 @@
     // keep the layer history, since we use it for other features (like Frame Rate API), so layers
     // still need to be registered.
     if (!mUseContentDetection) {
-        mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
-                                     mRefreshRateConfigs.getMaxRefreshRate().fps,
+        mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+                                     mRefreshRateConfigs.getMaxRefreshRate().getFps(),
                                      scheduler::LayerHistory::LayerVoteType::NoVote);
         return;
     }
 
     // In V1 of content detection, all layers are registered as Heuristic (unless it's wallpaper).
     if (!mUseContentDetectionV2) {
-        const auto lowFps = mRefreshRateConfigs.getMinRefreshRate().fps;
+        const auto lowFps = mRefreshRateConfigs.getMinRefreshRate().getFps();
         const auto highFps = layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER
                 ? lowFps
-                : mRefreshRateConfigs.getMaxRefreshRate().fps;
+                : mRefreshRateConfigs.getMaxRefreshRate().getFps();
 
         mLayerHistory->registerLayer(layer, lowFps, highFps,
                                      scheduler::LayerHistory::LayerVoteType::Heuristic);
     } else {
         if (layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER) {
             // Running Wallpaper at Min is considered as part of content detection.
-            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
-                                         mRefreshRateConfigs.getMaxRefreshRate().fps,
+            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+                                         mRefreshRateConfigs.getMaxRefreshRate().getFps(),
                                          scheduler::LayerHistory::LayerVoteType::Min);
         } else if (layer->getWindowType() == InputWindowInfo::TYPE_STATUS_BAR) {
-            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
-                                         mRefreshRateConfigs.getMaxRefreshRate().fps,
+            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+                                         mRefreshRateConfigs.getMaxRefreshRate().getFps(),
                                          scheduler::LayerHistory::LayerVoteType::NoVote);
         } else {
-            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
-                                         mRefreshRateConfigs.getMaxRefreshRate().fps,
+            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+                                         mRefreshRateConfigs.getMaxRefreshRate().getFps(),
                                          scheduler::LayerHistory::LayerVoteType::Heuristic);
         }
     }
@@ -503,12 +503,13 @@
     // magic number
     const auto& refreshRate = mRefreshRateConfigs.getCurrentRefreshRate();
     constexpr float FPS_THRESHOLD_FOR_KERNEL_TIMER = 65.0f;
-    if (state == TimerState::Reset && refreshRate.fps > FPS_THRESHOLD_FOR_KERNEL_TIMER) {
+    if (state == TimerState::Reset && refreshRate.getFps() > FPS_THRESHOLD_FOR_KERNEL_TIMER) {
         // If we're not in performance mode then the kernel timer shouldn't do
         // anything, as the refresh rate during DPU power collapse will be the
         // same.
-        resyncToHardwareVsync(true /* makeAvailable */, refreshRate.vsyncPeriod);
-    } else if (state == TimerState::Expired && refreshRate.fps <= FPS_THRESHOLD_FOR_KERNEL_TIMER) {
+        resyncToHardwareVsync(true /* makeAvailable */, refreshRate.getVsyncPeriod());
+    } else if (state == TimerState::Expired &&
+               refreshRate.getFps() <= FPS_THRESHOLD_FOR_KERNEL_TIMER) {
         // Disable HW VSYNC if the timer expired, as we don't need it enabled if
         // we're not pushing frames, and if we're in PERFORMANCE mode then we'll
         // need to update the DispSync model anyway.
@@ -580,30 +581,31 @@
     if (mDisplayPowerTimer &&
         (!mFeatures.isDisplayPowerStateNormal ||
          mFeatures.displayPowerTimer == TimerState::Reset)) {
-        return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+        return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
     }
 
     if (!mUseContentDetectionV2) {
         // As long as touch is active we want to be in performance mode.
         if (mTouchTimer && mFeatures.touch == TouchState::Active) {
-            return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+            return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
         }
     }
 
     // If timer has expired as it means there is no new content on the screen.
     if (mIdleTimer && mFeatures.idleTimer == TimerState::Expired) {
-        return mRefreshRateConfigs.getMinRefreshRateByPolicy().configId;
+        return mRefreshRateConfigs.getMinRefreshRateByPolicy().getConfigId();
     }
 
     if (!mUseContentDetectionV2) {
         // If content detection is off we choose performance as we don't know the content fps.
         if (mFeatures.contentDetectionV1 == ContentDetectionState::Off) {
             // NOTE: V1 always calls this, but this is not a default behavior for V2.
-            return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+            return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
         }
 
         // Content detection is on, find the appropriate refresh rate with minimal error
-        return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements).configId;
+        return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements)
+                .getConfigId();
     }
 
     bool touchConsidered;
@@ -613,7 +615,7 @@
                                                 mTouchTimer &&
                                                         mFeatures.touch == TouchState::Active,
                                                 &touchConsidered)
-                    .configId;
+                    .getConfigId();
     if (touchConsidered) {
         // Clear layer history if refresh rate was selected based on touch to allow
         // the hueristic to pick up with the new rate.
diff --git a/services/surfaceflinger/Scheduler/TimeKeeper.h b/services/surfaceflinger/Scheduler/TimeKeeper.h
index 38f0708..da2195c 100644
--- a/services/surfaceflinger/Scheduler/TimeKeeper.h
+++ b/services/surfaceflinger/Scheduler/TimeKeeper.h
@@ -53,6 +53,8 @@
      */
     virtual void alarmCancel() = 0;
 
+    virtual void dump(std::string& result) const = 0;
+
 protected:
     TimeKeeper(TimeKeeper const&) = delete;
     TimeKeeper& operator=(TimeKeeper const&) = delete;
diff --git a/services/surfaceflinger/Scheduler/Timer.cpp b/services/surfaceflinger/Scheduler/Timer.cpp
index 8f81c2c..7c5058e 100644
--- a/services/surfaceflinger/Scheduler/Timer.cpp
+++ b/services/surfaceflinger/Scheduler/Timer.cpp
@@ -17,6 +17,7 @@
 #undef LOG_TAG
 #define LOG_TAG "SchedulerTimer"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <android-base/stringprintf.h>
 #include <log/log.h>
 #include <sys/epoll.h>
 #include <sys/timerfd.h>
@@ -29,28 +30,53 @@
 #include "Timer.h"
 
 namespace android::scheduler {
+using base::StringAppendF;
 
 static constexpr size_t kReadPipe = 0;
 static constexpr size_t kWritePipe = 1;
 
-Timer::Timer()
-      : mTimerFd(timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK)),
-        mEpollFd(epoll_create1(EPOLL_CLOEXEC)) {
-    if (pipe2(mPipes.data(), O_CLOEXEC | O_NONBLOCK)) {
-        ALOGE("could not create TimerDispatch mPipes");
-    };
-
-    mDispatchThread = std::thread(std::bind(&Timer::dispatch, this));
+Timer::Timer() {
+    reset();
+    mDispatchThread = std::thread([this]() { threadMain(); });
 }
 
 Timer::~Timer() {
     endDispatch();
     mDispatchThread.join();
+    cleanup();
+}
 
-    close(mPipes[kWritePipe]);
-    close(mPipes[kReadPipe]);
-    close(mEpollFd);
-    close(mTimerFd);
+void Timer::reset() {
+    cleanup();
+    mTimerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
+    mEpollFd = epoll_create1(EPOLL_CLOEXEC);
+    if (pipe2(mPipes.data(), O_CLOEXEC | O_NONBLOCK)) {
+        ALOGE("could not create TimerDispatch mPipes");
+        return;
+    };
+    setDebugState(DebugState::Reset);
+}
+
+void Timer::cleanup() {
+    if (mTimerFd != -1) {
+        close(mTimerFd);
+        mTimerFd = -1;
+    }
+
+    if (mEpollFd != -1) {
+        close(mEpollFd);
+        mEpollFd = -1;
+    }
+
+    if (mPipes[kReadPipe] != -1) {
+        close(mPipes[kReadPipe]);
+        mPipes[kReadPipe] = -1;
+    }
+
+    if (mPipes[kWritePipe] != -1) {
+        close(mPipes[kWritePipe]);
+        mPipes[kWritePipe] = -1;
+    }
 }
 
 void Timer::endDispatch() {
@@ -99,7 +125,14 @@
     }
 }
 
-void Timer::dispatch() {
+void Timer::threadMain() {
+    while (dispatch()) {
+        reset();
+    }
+}
+
+bool Timer::dispatch() {
+    setDebugState(DebugState::Running);
     struct sched_param param = {0};
     param.sched_priority = 2;
     if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &param) != 0) {
@@ -116,7 +149,7 @@
     timerEvent.data.u32 = DispatchType::TIMER;
     if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mTimerFd, &timerEvent) == -1) {
         ALOGE("Error adding timer fd to epoll dispatch loop");
-        return;
+        return true;
     }
 
     epoll_event terminateEvent;
@@ -124,18 +157,20 @@
     terminateEvent.data.u32 = DispatchType::TERMINATE;
     if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mPipes[kReadPipe], &terminateEvent) == -1) {
         ALOGE("Error adding control fd to dispatch loop");
-        return;
+        return true;
     }
 
     uint64_t iteration = 0;
     char const traceNamePrefix[] = "TimerIteration #";
     static constexpr size_t maxlen = arrayLen(traceNamePrefix) + max64print;
     std::array<char, maxlen> str_buffer;
-    auto timing = true;
-    while (timing) {
+
+    while (true) {
+        setDebugState(DebugState::Waiting);
         epoll_event events[DispatchType::MAX_DISPATCH_TYPE];
         int nfds = epoll_wait(mEpollFd, events, DispatchType::MAX_DISPATCH_TYPE, -1);
 
+        setDebugState(DebugState::Running);
         if (ATRACE_ENABLED()) {
             snprintf(str_buffer.data(), str_buffer.size(), "%s%" PRIu64, traceNamePrefix,
                      iteration++);
@@ -144,29 +179,62 @@
 
         if (nfds == -1) {
             if (errno != EINTR) {
-                timing = false;
-                continue;
+                ALOGE("Error waiting on epoll: %s", strerror(errno));
+                return true;
             }
         }
 
         for (auto i = 0; i < nfds; i++) {
             if (events[i].data.u32 == DispatchType::TIMER) {
                 static uint64_t mIgnored = 0;
+                setDebugState(DebugState::Reading);
                 read(mTimerFd, &mIgnored, sizeof(mIgnored));
+                setDebugState(DebugState::Running);
                 std::function<void()> cb;
                 {
                     std::lock_guard<decltype(mMutex)> lk(mMutex);
                     cb = mCallback;
                 }
                 if (cb) {
+                    setDebugState(DebugState::InCallback);
                     cb();
+                    setDebugState(DebugState::Running);
                 }
             }
             if (events[i].data.u32 == DispatchType::TERMINATE) {
-                timing = false;
+                ALOGE("Terminated");
+                setDebugState(DebugState::Running);
+                return false;
             }
         }
     }
 }
 
+void Timer::setDebugState(DebugState state) {
+    std::lock_guard lk(mMutex);
+    mDebugState = state;
+}
+
+const char* Timer::strDebugState(DebugState state) const {
+    switch (state) {
+        case DebugState::Reset:
+            return "Reset";
+        case DebugState::Running:
+            return "Running";
+        case DebugState::Waiting:
+            return "Waiting";
+        case DebugState::Reading:
+            return "Reading";
+        case DebugState::InCallback:
+            return "InCallback";
+        case DebugState::Terminated:
+            return "Terminated";
+    }
+}
+
+void Timer::dump(std::string& result) const {
+    std::lock_guard lk(mMutex);
+    StringAppendF(&result, "\t\tDebugState: %s\n", strDebugState(mDebugState));
+}
+
 } // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/Timer.h b/services/surfaceflinger/Scheduler/Timer.h
index 0ae82c8..a8e2d5a 100644
--- a/services/surfaceflinger/Scheduler/Timer.h
+++ b/services/surfaceflinger/Scheduler/Timer.h
@@ -34,18 +34,27 @@
     //     Most users will want to serialize thes calls so as to be aware of the timer state.
     void alarmIn(std::function<void()> const& cb, nsecs_t fireIn) final;
     void alarmCancel() final;
+    void dump(std::string& result) const final;
 
 private:
-    int const mTimerFd;
-    int const mEpollFd;
-    std::array<int, 2> mPipes;
+    enum class DebugState { Reset, Running, Waiting, Reading, InCallback, Terminated };
+    void reset();
+    void cleanup();
+    void setDebugState(DebugState state) EXCLUDES(mMutex);
+    const char* strDebugState(DebugState state) const;
+
+    int mTimerFd = -1;
+    int mEpollFd = -1;
+    std::array<int, 2> mPipes = {-1, -1};
 
     std::thread mDispatchThread;
-    void dispatch();
+    void threadMain();
+    bool dispatch();
     void endDispatch();
 
-    std::mutex mMutex;
+    mutable std::mutex mMutex;
     std::function<void()> mCallback GUARDED_BY(mMutex);
+    DebugState mDebugState GUARDED_BY(mMutex);
 };
 
 } // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
index 460d4a5..cd15617 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
@@ -168,6 +168,7 @@
     mIntendedWakeupTime = targetTime;
     mTimeKeeper->alarmIn(std::bind(&VSyncDispatchTimerQueue::timerCallback, this),
                          targetTime - now);
+    mLastTimerSchedule = mTimeKeeper->now();
 }
 
 void VSyncDispatchTimerQueue::rearmTimer(nsecs_t now) {
@@ -226,6 +227,7 @@
     std::vector<Invocation> invocations;
     {
         std::lock_guard<decltype(mMutex)> lk(mMutex);
+        mLastTimerCallback = mTimeKeeper->now();
         for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) {
             auto& callback = it->second;
             auto const wakeupTime = callback->wakeupTime();
@@ -322,10 +324,15 @@
 
 void VSyncDispatchTimerQueue::dump(std::string& result) const {
     std::lock_guard<decltype(mMutex)> lk(mMutex);
+    StringAppendF(&result, "\tTimer:\n");
+    mTimeKeeper->dump(result);
     StringAppendF(&result, "\tmTimerSlack: %.2fms mMinVsyncDistance: %.2fms\n", mTimerSlack / 1e6f,
                   mMinVsyncDistance / 1e6f);
     StringAppendF(&result, "\tmIntendedWakeupTime: %.2fms from now\n",
-                  (mIntendedWakeupTime - systemTime()) / 1e6f);
+                  (mIntendedWakeupTime - mTimeKeeper->now()) / 1e6f);
+    StringAppendF(&result, "\tmLastTimerCallback: %.2fms ago mLastTimerSchedule: %.2fms ago\n",
+                  (mTimeKeeper->now() - mLastTimerCallback) / 1e6f,
+                  (mTimeKeeper->now() - mLastTimerSchedule) / 1e6f);
     StringAppendF(&result, "\tCallbacks:\n");
     for (const auto& [token, entry] : mCallbacks) {
         entry->dump(result);
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
index 390e0c4..26a8ec0 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
@@ -152,6 +152,10 @@
         std::array<char, maxlen> str_buffer;
         void note(std::string_view name, nsecs_t in, nsecs_t vs);
     } mTraceBuffer GUARDED_BY(mMutex);
+
+    // For debugging purposes
+    nsecs_t mLastTimerCallback GUARDED_BY(mMutex) = kInvalidTime;
+    nsecs_t mLastTimerSchedule GUARDED_BY(mMutex) = kInvalidTime;
 };
 
 } // namespace android::scheduler
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2da92b3..d721f8d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -169,19 +169,22 @@
 
 #pragma clang diagnostic pop
 
-class ConditionalLock {
-public:
-    ConditionalLock(Mutex& mutex, bool lock) : mMutex(mutex), mLocked(lock) {
-        if (lock) {
-            mMutex.lock();
-        }
+template <typename Mutex>
+struct ConditionalLockGuard {
+    ConditionalLockGuard(Mutex& mutex, bool lock) : mutex(mutex), lock(lock) {
+        if (lock) mutex.lock();
     }
-    ~ConditionalLock() { if (mLocked) mMutex.unlock(); }
-private:
-    Mutex& mMutex;
-    bool mLocked;
+
+    ~ConditionalLockGuard() {
+        if (lock) mutex.unlock();
+    }
+
+    Mutex& mutex;
+    const bool lock;
 };
 
+using ConditionalLock = ConditionalLockGuard<Mutex>;
+
 // TODO(b/141333600): Consolidate with HWC2::Display::Config::Builder::getDefaultDensity.
 constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV / 160.f;
 
@@ -200,6 +203,15 @@
     return dataspace == Dataspace::V0_SRGB || dataspace == Dataspace::DISPLAY_P3;
 }
 
+class FrameRateFlexibilityToken : public BBinder {
+public:
+    FrameRateFlexibilityToken(std::function<void()> callback) : mCallback(callback) {}
+    virtual ~FrameRateFlexibilityToken() { mCallback(); }
+
+private:
+    std::function<void()> mCallback;
+};
+
 }  // namespace anonymous
 
 // ---------------------------------------------------------------------------
@@ -457,17 +469,17 @@
 }
 
 void SurfaceFlinger::destroyDisplay(const sp<IBinder>& displayToken) {
-    Mutex::Autolock _l(mStateLock);
+    Mutex::Autolock lock(mStateLock);
 
-    ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
+    const ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
     if (index < 0) {
-        ALOGE("destroyDisplay: Invalid display token %p", displayToken.get());
+        ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
         return;
     }
 
     const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
-    if (!state.isVirtual()) {
-        ALOGE("destroyDisplay called for non-virtual display");
+    if (state.physical) {
+        ALOGE("%s: Invalid operation on physical display", __FUNCTION__);
         return;
     }
     mInterceptor->saveDisplayDeletion(state.sequenceId);
@@ -899,26 +911,35 @@
 }
 
 int SurfaceFlinger::getActiveConfig(const sp<IBinder>& displayToken) {
-    const auto display = getDisplayDevice(displayToken);
-    if (!display) {
-        ALOGE("getActiveConfig: Invalid display token %p", displayToken.get());
-        return BAD_VALUE;
+    int activeConfig;
+    bool isPrimary;
+
+    {
+        Mutex::Autolock lock(mStateLock);
+
+        if (const auto display = getDisplayDeviceLocked(displayToken)) {
+            activeConfig = display->getActiveConfig().value();
+            isPrimary = display->isPrimary();
+        } else {
+            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+            return NAME_NOT_FOUND;
+        }
     }
 
-    if (display->isPrimary()) {
+    if (isPrimary) {
         std::lock_guard<std::mutex> lock(mActiveConfigLock);
         if (mDesiredActiveConfigChanged) {
             return mDesiredActiveConfig.configId.value();
         }
     }
 
-    return display->getActiveConfig().value();
+    return activeConfig;
 }
 
 void SurfaceFlinger::setDesiredActiveConfig(const ActiveConfigInfo& info) {
     ATRACE_CALL();
     auto& refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(info.configId);
-    ALOGV("setDesiredActiveConfig(%s)", refreshRate.name.c_str());
+    ALOGV("setDesiredActiveConfig(%s)", refreshRate.getName().c_str());
 
     std::lock_guard<std::mutex> lock(mActiveConfigLock);
     if (mDesiredActiveConfigChanged) {
@@ -930,7 +951,7 @@
     } else {
         // Check is we are already at the desired config
         const auto display = getDefaultDisplayDeviceLocked();
-        if (!display || display->getActiveConfig() == refreshRate.configId) {
+        if (!display || display->getActiveConfig() == refreshRate.getConfigId()) {
             return;
         }
 
@@ -942,12 +963,12 @@
         repaintEverythingForHWC();
         // Start receiving vsync samples now, so that we can detect a period
         // switch.
-        mScheduler->resyncToHardwareVsync(true, refreshRate.vsyncPeriod);
+        mScheduler->resyncToHardwareVsync(true, refreshRate.getVsyncPeriod());
         // As we called to set period, we will call to onRefreshRateChangeCompleted once
         // DispSync model is locked.
         mVSyncModulator->onRefreshRateChangeInitiated();
 
-        mPhaseConfiguration->setRefreshRateFps(refreshRate.fps);
+        mPhaseConfiguration->setRefreshRateFps(refreshRate.getFps());
         mVSyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets());
     }
 
@@ -963,22 +984,25 @@
         return BAD_VALUE;
     }
 
-    status_t result = NO_ERROR;
+    status_t result = NAME_NOT_FOUND;
 
     postMessageSync(new LambdaMessage([&]() {
         const auto display = getDisplayDeviceLocked(displayToken);
         if (!display) {
             ALOGE("Attempt to set allowed display configs for invalid display token %p",
                   displayToken.get());
-            result = BAD_VALUE;
         } else if (display->isVirtual()) {
             ALOGW("Attempt to set allowed display configs for virtual display");
-            result = BAD_VALUE;
+            result = INVALID_OPERATION;
         } else {
             HwcConfigIndexType config(mode);
             const auto& refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(config);
-            result = setDesiredDisplayConfigSpecsInternal(display, config, refreshRate.fps,
-                                                          refreshRate.fps);
+            result = setDesiredDisplayConfigSpecsInternal(display,
+                                                          scheduler::RefreshRateConfigs::
+                                                                  Policy{config,
+                                                                         refreshRate.getFps(),
+                                                                         refreshRate.getFps()},
+                                                          /*overridePolicy=*/false);
         }
     }));
 
@@ -993,6 +1017,9 @@
         return;
     }
 
+    auto& oldRefreshRate =
+            mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig());
+
     std::lock_guard<std::mutex> lock(mActiveConfigLock);
     mRefreshRateConfigs->setCurrentConfigId(mUpcomingActiveConfig.configId);
     mRefreshRateStats->setConfigMode(mUpcomingActiveConfig.configId);
@@ -1000,14 +1027,17 @@
 
     auto& refreshRate =
             mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId);
-    mPhaseConfiguration->setRefreshRateFps(refreshRate.fps);
+    if (refreshRate.getVsyncPeriod() != oldRefreshRate.getVsyncPeriod()) {
+        mTimeStats->incrementRefreshRateSwitches();
+    }
+    mPhaseConfiguration->setRefreshRateFps(refreshRate.getFps());
     mVSyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets());
-    ATRACE_INT("ActiveConfigFPS", refreshRate.fps);
+    ATRACE_INT("ActiveConfigFPS", refreshRate.getFps());
 
     if (mUpcomingActiveConfig.event != Scheduler::ConfigEvent::None) {
         const nsecs_t vsyncPeriod =
                 mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId)
-                        .vsyncPeriod;
+                        .getVsyncPeriod();
         mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
                                     mUpcomingActiveConfig.configId, vsyncPeriod);
     }
@@ -1020,62 +1050,53 @@
 
     const auto& refreshRate =
             mRefreshRateConfigs->getRefreshRateFromConfigId(mDesiredActiveConfig.configId);
-    mScheduler->resyncToHardwareVsync(true, refreshRate.vsyncPeriod);
-    mPhaseConfiguration->setRefreshRateFps(refreshRate.fps);
+    mScheduler->resyncToHardwareVsync(true, refreshRate.getVsyncPeriod());
+    mPhaseConfiguration->setRefreshRateFps(refreshRate.getFps());
     mVSyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets());
 }
 
-bool SurfaceFlinger::performSetActiveConfig() {
+void SurfaceFlinger::performSetActiveConfig() {
     ATRACE_CALL();
     ALOGV("performSetActiveConfig");
-    if (mCheckPendingFence) {
-        if (previousFramePending()) {
-            // fence has not signaled yet. wait for the next invalidate
-            mEventQueue->invalidate();
-            return true;
-        }
-
-        // We received the present fence from the HWC, so we assume it successfully updated
-        // the config, hence we update SF.
-        mCheckPendingFence = false;
-        setActiveConfigInternal();
-    }
-
     // Store the local variable to release the lock.
-    ActiveConfigInfo desiredActiveConfig;
-    {
+    const auto desiredActiveConfig = [&]() -> std::optional<ActiveConfigInfo> {
         std::lock_guard<std::mutex> lock(mActiveConfigLock);
-        if (!mDesiredActiveConfigChanged) {
-            return false;
+        if (mDesiredActiveConfigChanged) {
+            return mDesiredActiveConfig;
         }
-        desiredActiveConfig = mDesiredActiveConfig;
+        return std::nullopt;
+    }();
+
+    if (!desiredActiveConfig) {
+        // No desired active config pending to be applied
+        return;
     }
 
     auto& refreshRate =
-            mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig.configId);
-    ALOGV("performSetActiveConfig changing active config to %d(%s)", refreshRate.configId.value(),
-          refreshRate.name.c_str());
+            mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig->configId);
+    ALOGV("performSetActiveConfig changing active config to %d(%s)",
+          refreshRate.getConfigId().value(), refreshRate.getName().c_str());
     const auto display = getDefaultDisplayDeviceLocked();
-    if (!display || display->getActiveConfig() == desiredActiveConfig.configId) {
+    if (!display || display->getActiveConfig() == desiredActiveConfig->configId) {
         // display is not valid or we are already in the requested mode
         // on both cases there is nothing left to do
         desiredActiveConfigChangeDone();
-        return false;
+        return;
     }
 
     // Desired active config was set, it is different than the config currently in use, however
     // allowed configs might have change by the time we process the refresh.
     // Make sure the desired config is still allowed
-    if (!isDisplayConfigAllowed(desiredActiveConfig.configId)) {
+    if (!isDisplayConfigAllowed(desiredActiveConfig->configId)) {
         desiredActiveConfigChangeDone();
-        return false;
+        return;
     }
 
-    mUpcomingActiveConfig = desiredActiveConfig;
+    mUpcomingActiveConfig = *desiredActiveConfig;
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
 
-    ATRACE_INT("ActiveConfigFPS_HWC", refreshRate.fps);
+    ATRACE_INT("ActiveConfigFPS_HWC", refreshRate.getFps());
 
     // TODO(b/142753666) use constrains
     HWC2::VsyncPeriodChangeConstraints constraints;
@@ -1091,13 +1112,12 @@
         // setActiveConfigWithConstraints may fail if a hotplug event is just about
         // to be sent. We just log the error in this case.
         ALOGW("setActiveConfigWithConstraints failed: %d", status);
-        return false;
+        return;
     }
 
     mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline);
     // Scheduler will submit an empty frame to HWC if needed.
-    mCheckPendingFence = true;
-    return false;
+    mSetActiveConfigPending = true;
 }
 
 status_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& displayToken,
@@ -1143,7 +1163,7 @@
 
     // Currently we only support this API for a single internal display.
     if (getInternalDisplayToken() != displayToken) {
-        return BAD_VALUE;
+        return NAME_NOT_FOUND;
     }
 
     memcpy(&primaries, &mInternalDisplayPrimaries, sizeof(ui::DisplayPrimaries));
@@ -1151,7 +1171,9 @@
 }
 
 ColorMode SurfaceFlinger::getActiveColorMode(const sp<IBinder>& displayToken) {
-    if (const auto display = getDisplayDevice(displayToken)) {
+    Mutex::Autolock lock(mStateLock);
+
+    if (const auto display = getDisplayDeviceLocked(displayToken)) {
         return display->getCompositionDisplay()->getState().colorMode;
     }
     return static_cast<ColorMode>(BAD_VALUE);
@@ -1167,7 +1189,7 @@
                   decodeColorMode(mode).c_str(), mode, displayToken.get());
             return;
         }
-        const auto display = getDisplayDevice(displayToken);
+        const auto display = getDisplayDeviceLocked(displayToken);
         if (!display) {
             ALOGE("Attempt to set active color mode %s (%d) for invalid display token %p",
                   decodeColorMode(mode).c_str(), mode, displayToken.get());
@@ -1187,82 +1209,61 @@
 
 status_t SurfaceFlinger::getAutoLowLatencyModeSupport(const sp<IBinder>& displayToken,
                                                       bool* outSupport) const {
-    Mutex::Autolock _l(mStateLock);
-
     if (!displayToken) {
-        ALOGE("getAutoLowLatencyModeSupport() failed. Missing display token.");
         return BAD_VALUE;
     }
+
+    Mutex::Autolock lock(mStateLock);
+
     const auto displayId = getPhysicalDisplayIdLocked(displayToken);
     if (!displayId) {
-        ALOGE("getAutoLowLatencyModeSupport() failed. Display id for display token %p not found.",
-              displayToken.get());
         return NAME_NOT_FOUND;
     }
-    *outSupport = getHwComposer().hasDisplayCapability(displayId,
+    *outSupport = getHwComposer().hasDisplayCapability(*displayId,
                                                        HWC2::DisplayCapability::AutoLowLatencyMode);
     return NO_ERROR;
 }
 
 void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) {
-    postMessageAsync(new LambdaMessage([=] { setAutoLowLatencyModeInternal(displayToken, on); }));
-}
-
-void SurfaceFlinger::setAutoLowLatencyModeInternal(const sp<IBinder>& displayToken, bool on) {
-    if (!displayToken) {
-        ALOGE("setAutoLowLatencyMode() failed. Missing display token.");
-        return;
-    }
-    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
-    if (!displayId) {
-        ALOGE("setAutoLowLatencyMode() failed. Display id for display token %p not found.",
-              displayToken.get());
-        return;
-    }
-
-    getHwComposer().setAutoLowLatencyMode(*displayId, on);
+    postMessageAsync(new LambdaMessage([=] {
+        if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+            getHwComposer().setAutoLowLatencyMode(*displayId, on);
+        } else {
+            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+        }
+    }));
 }
 
 status_t SurfaceFlinger::getGameContentTypeSupport(const sp<IBinder>& displayToken,
                                                    bool* outSupport) const {
-    Mutex::Autolock _l(mStateLock);
-
     if (!displayToken) {
-        ALOGE("getGameContentTypeSupport() failed. Missing display token.");
         return BAD_VALUE;
     }
+
+    Mutex::Autolock lock(mStateLock);
+
     const auto displayId = getPhysicalDisplayIdLocked(displayToken);
     if (!displayId) {
-        ALOGE("getGameContentTypeSupport() failed. Display id for display token %p not found.",
-              displayToken.get());
         return NAME_NOT_FOUND;
     }
 
-    std::vector<HWC2::ContentType> outSupportedContentTypes;
-    getHwComposer().getSupportedContentTypes(*displayId, &outSupportedContentTypes);
-    *outSupport = std::find(outSupportedContentTypes.begin(), outSupportedContentTypes.end(),
-                            HWC2::ContentType::Game) != outSupportedContentTypes.end();
+    std::vector<HWC2::ContentType> types;
+    getHwComposer().getSupportedContentTypes(*displayId, &types);
+
+    *outSupport = std::any_of(types.begin(), types.end(),
+                              [](auto type) { return type == HWC2::ContentType::Game; });
     return NO_ERROR;
 }
 
 void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) {
-    postMessageAsync(new LambdaMessage([=] { setGameContentTypeInternal(displayToken, on); }));
-}
-
-void SurfaceFlinger::setGameContentTypeInternal(const sp<IBinder>& displayToken, bool on) {
-    if (!displayToken) {
-        ALOGE("setGameContentType() failed. Missing display token.");
-        return;
-    }
-    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
-    if (!displayId) {
-        ALOGE("setGameContentType() failed. Display id for display token %p not found.",
-              displayToken.get());
-        return;
-    }
-
-    const HWC2::ContentType type = on ? HWC2::ContentType::Game : HWC2::ContentType::None;
-    getHwComposer().setContentType(*displayId, type);
+    postMessageAsync(new LambdaMessage([=] {
+        if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+            const auto type = on ? HWC2::ContentType::Game : HWC2::ContentType::None;
+            getHwComposer().setContentType(*displayId, type);
+        } else {
+            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+        }
+    }));
 }
 
 status_t SurfaceFlinger::clearAnimationFrameStats() {
@@ -1279,15 +1280,15 @@
 
 status_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& displayToken,
                                             HdrCapabilities* outCapabilities) const {
-    Mutex::Autolock _l(mStateLock);
+    Mutex::Autolock lock(mStateLock);
 
     const auto display = getDisplayDeviceLocked(displayToken);
     if (!display) {
-        ALOGE("getHdrCapabilities: Invalid display token %p", displayToken.get());
-        return BAD_VALUE;
+        ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+        return NAME_NOT_FOUND;
     }
 
-    // At this point the DisplayDeivce should already be set up,
+    // At this point the DisplayDevice should already be set up,
     // meaning the luminance information is already queried from
     // hardware composer and stored properly.
     const HdrCapabilities& capabilities = display->getHdrCapabilities();
@@ -1330,39 +1331,46 @@
     if (!outFormat || !outDataspace || !outComponentMask) {
         return BAD_VALUE;
     }
-    const auto display = getDisplayDevice(displayToken);
-    if (!display || !display->getId()) {
-        ALOGE("getDisplayedContentSamplingAttributes: Bad display token: %p", display.get());
-        return BAD_VALUE;
+
+    Mutex::Autolock lock(mStateLock);
+
+    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
+    if (!displayId) {
+        return NAME_NOT_FOUND;
     }
-    return getHwComposer().getDisplayedContentSamplingAttributes(*display->getId(), outFormat,
+
+    return getHwComposer().getDisplayedContentSamplingAttributes(*displayId, outFormat,
                                                                  outDataspace, outComponentMask);
 }
 
 status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken,
                                                           bool enable, uint8_t componentMask,
-                                                          uint64_t maxFrames) const {
-    const auto display = getDisplayDevice(displayToken);
-    if (!display || !display->getId()) {
-        ALOGE("setDisplayContentSamplingEnabled: Bad display token: %p", display.get());
-        return BAD_VALUE;
-    }
+                                                          uint64_t maxFrames) {
+    status_t result = NAME_NOT_FOUND;
 
-    return getHwComposer().setDisplayContentSamplingEnabled(*display->getId(), enable,
-                                                            componentMask, maxFrames);
+    postMessageSync(new LambdaMessage([&] {
+        if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+            result = getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable,
+                                                                      componentMask, maxFrames);
+        } else {
+            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+        }
+    }));
+
+    return result;
 }
 
 status_t SurfaceFlinger::getDisplayedContentSample(const sp<IBinder>& displayToken,
                                                    uint64_t maxFrames, uint64_t timestamp,
                                                    DisplayedFrameStats* outStats) const {
-    const auto display = getDisplayDevice(displayToken);
-    if (!display || !display->getId()) {
-        ALOGE("getDisplayContentSample: Bad display token: %p", displayToken.get());
-        return BAD_VALUE;
+    Mutex::Autolock lock(mStateLock);
+
+    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
+    if (!displayId) {
+        return NAME_NOT_FOUND;
     }
 
-    return getHwComposer().getDisplayedContentSample(*display->getId(), maxFrames, timestamp,
-                                                     outStats);
+    return getHwComposer().getDisplayedContentSample(*displayId, maxFrames, timestamp, outStats);
 }
 
 status_t SurfaceFlinger::getProtectedContentSupport(bool* outSupported) const {
@@ -1378,19 +1386,15 @@
     if (!displayToken || !outIsWideColorDisplay) {
         return BAD_VALUE;
     }
-    Mutex::Autolock _l(mStateLock);
+
+    Mutex::Autolock lock(mStateLock);
     const auto display = getDisplayDeviceLocked(displayToken);
     if (!display) {
-        return BAD_VALUE;
+        return NAME_NOT_FOUND;
     }
 
-    // Use hasWideColorDisplay to override built-in display.
-    const auto displayId = display->getId();
-    if (displayId && displayId == getInternalDisplayIdLocked()) {
-        *outIsWideColorDisplay = hasWideColorDisplay;
-        return NO_ERROR;
-    }
-    *outIsWideColorDisplay = display->hasWideColorGamut();
+    *outIsWideColorDisplay =
+            display->isPrimary() ? hasWideColorDisplay : display->hasWideColorGamut();
     return NO_ERROR;
 }
 
@@ -1465,25 +1469,34 @@
     if (!displayToken || !outSupport) {
         return BAD_VALUE;
     }
+
+    Mutex::Autolock lock(mStateLock);
+
     const auto displayId = getPhysicalDisplayIdLocked(displayToken);
     if (!displayId) {
         return NAME_NOT_FOUND;
     }
     *outSupport =
-            getHwComposer().hasDisplayCapability(displayId, HWC2::DisplayCapability::Brightness);
+            getHwComposer().hasDisplayCapability(*displayId, HWC2::DisplayCapability::Brightness);
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken,
-                                              float brightness) const {
+status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) {
     if (!displayToken) {
         return BAD_VALUE;
     }
-    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
-    if (!displayId) {
-        return NAME_NOT_FOUND;
-    }
-    return getHwComposer().setDisplayBrightness(*displayId, brightness);
+
+    status_t result = NAME_NOT_FOUND;
+
+    postMessageSync(new LambdaMessage([&] {
+        if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+            result = getHwComposer().setDisplayBrightness(*displayId, brightness);
+        } else {
+            ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+        }
+    }));
+
+    return result;
 }
 
 status_t SurfaceFlinger::notifyPowerHint(int32_t hintId) {
@@ -1603,13 +1616,13 @@
     ATRACE_CALL();
 
     // Don't do any updating if the current fps is the same as the new one.
-    if (!isDisplayConfigAllowed(refreshRate.configId)) {
+    if (!isDisplayConfigAllowed(refreshRate.getConfigId())) {
         ALOGV("Skipping config %d as it is not part of allowed configs",
-              refreshRate.configId.value());
+              refreshRate.getConfigId().value());
         return;
     }
 
-    setDesiredActiveConfig({refreshRate.configId, event});
+    setDesiredActiveConfig({refreshRate.getConfigId(), event});
 }
 
 void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
@@ -1882,6 +1895,20 @@
                 mGpuFrameMissedCount++;
             }
 
+            // If we are in the middle of a config change and the fence hasn't
+            // fired yet just wait for the next invalidate
+            if (mSetActiveConfigPending) {
+                if (framePending) {
+                    mEventQueue->invalidate();
+                    break;
+                }
+
+                // We received the present fence from the HWC, so we assume it successfully updated
+                // the config, hence we update SF.
+                mSetActiveConfigPending = false;
+                setActiveConfigInternal();
+            }
+
             if (framePending && mPropagateBackpressure) {
                 if ((hwcFrameMissed && !gpuFrameMissed) ||
                     mPropagateBackpressureClientComposition) {
@@ -1929,8 +1956,25 @@
             // potentially trigger a display handoff.
             updateVrFlinger();
 
-            bool refreshNeeded = handleMessageTransaction();
-            refreshNeeded |= handleMessageInvalidate();
+            if (mTracingEnabledChanged) {
+                mTracingEnabled = mTracing.isEnabled();
+                mTracingEnabledChanged = false;
+            }
+
+            bool refreshNeeded;
+            {
+                ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
+
+                refreshNeeded = handleMessageTransaction();
+                refreshNeeded |= handleMessageInvalidate();
+                if (mTracingEnabled) {
+                    mAddCompositionStateToTrace =
+                            mTracing.flagIsSetLocked(SurfaceTracing::TRACE_COMPOSITION);
+                    if (mVisibleRegionsDirty && !mAddCompositionStateToTrace) {
+                        mTracing.notifyLocked("visibleRegionsDirty");
+                    }
+                }
+            }
 
             // Layers need to get updated (in the previous line) before we can use them for
             // choosing the refresh rate.
@@ -1941,9 +1985,7 @@
                 mScheduler->chooseRefreshRateForContent();
             }
 
-            if (performSetActiveConfig()) {
-                break;
-            }
+            performSetActiveConfig();
 
             updateCursorAsync();
             updateInputFlinger();
@@ -2074,7 +2116,7 @@
     mLayersWithQueuedFrames.clear();
     if (mVisibleRegionsDirty) {
         mVisibleRegionsDirty = false;
-        if (mTracingEnabled) {
+        if (mTracingEnabled && mAddCompositionStateToTrace) {
             mTracing.notify("visibleRegionsDirty");
         }
     }
@@ -2213,6 +2255,9 @@
         }
     });
 
+    mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]);
+    mTransactionCompletedThread.sendCallbacks();
+
     if (displayDevice && displayDevice->isPrimary() &&
         displayDevice->getPowerMode() == HWC_POWER_MODE_NORMAL && presentFenceTime->isValid()) {
         mScheduler->addPresentFence(presentFenceTime);
@@ -2293,9 +2338,6 @@
         }
     }
 
-    mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]);
-    mTransactionCompletedThread.sendCallbacks();
-
     if (mLumaSampling && mRegionSamplingThread) {
         mRegionSamplingThread->notifyNewContent();
     }
@@ -2385,7 +2427,8 @@
                 }
 
                 DisplayDeviceState state;
-                state.physical = {displayId, getHwComposer().getDisplayConnectionType(displayId)};
+                state.physical = {displayId, getHwComposer().getDisplayConnectionType(displayId),
+                                  event.hwcDisplayId};
                 state.isSecure = true; // All physical displays are currently considered secure.
                 state.displayName = info->name;
 
@@ -2394,6 +2437,12 @@
                 mPhysicalDisplayTokens.emplace(displayId, std::move(token));
 
                 mInterceptor->saveDisplayCreation(state);
+            } else {
+                ALOGV("Recreating display %s", to_string(displayId).c_str());
+
+                const auto token = it->second;
+                auto& state = mCurrentState.displays.editValueFor(token);
+                state.sequenceId = DisplayDeviceState{}.sequenceId;
             }
         } else {
             ALOGV("Removing display %s", to_string(displayId).c_str());
@@ -2571,20 +2620,17 @@
         producer = bqProducer;
     }
 
-    if (displaySurface != nullptr) {
-        mDisplays.emplace(displayToken,
-                          setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state,
-                                                        displaySurface, producer));
-        if (!state.isVirtual()) {
-            LOG_ALWAYS_FATAL_IF(!displayId);
-            dispatchDisplayHotplugEvent(displayId->value, true);
-        }
+    LOG_FATAL_IF(!displaySurface);
+    const auto display = setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state,
+                                                       displaySurface, producer);
+    mDisplays.emplace(displayToken, display);
+    if (!state.isVirtual()) {
+        LOG_FATAL_IF(!displayId);
+        dispatchDisplayHotplugEvent(displayId->value, true);
+    }
 
-        const auto displayDevice = mDisplays[displayToken];
-        if (displayDevice->isPrimary()) {
-            mScheduler->onPrimaryDisplayAreaChanged(displayDevice->getWidth() *
-                                                    displayDevice->getHeight());
-        }
+    if (display->isPrimary()) {
+        mScheduler->onPrimaryDisplayAreaChanged(display->getWidth() * display->getHeight());
     }
 }
 
@@ -2595,7 +2641,7 @@
         display->disconnect();
 
         if (!display->isVirtual()) {
-            LOG_ALWAYS_FATAL_IF(!displayId);
+            LOG_FATAL_IF(!displayId);
             dispatchDisplayHotplugEvent(displayId->value, false);
         }
     }
@@ -2608,13 +2654,19 @@
                                            const DisplayDeviceState& drawingState) {
     const sp<IBinder> currentBinder = IInterface::asBinder(currentState.surface);
     const sp<IBinder> drawingBinder = IInterface::asBinder(drawingState.surface);
-    if (currentBinder != drawingBinder) {
+    if (currentBinder != drawingBinder || currentState.sequenceId != drawingState.sequenceId) {
         // changing the surface is like destroying and recreating the DisplayDevice
         if (const auto display = getDisplayDeviceLocked(displayToken)) {
             display->disconnect();
         }
         mDisplays.erase(displayToken);
+        if (const auto& physical = currentState.physical) {
+            getHwComposer().allocatePhysicalDisplay(physical->hwcDisplayId, physical->id);
+        }
         processDisplayAdded(displayToken, currentState);
+        if (currentState.physical) {
+            initializeDisplays();
+        }
         return;
     }
 
@@ -2939,15 +2991,14 @@
     // classes from EventThread, and there should be no run-time binder cost
     // anyway since there are no connected apps at this point.
     const nsecs_t vsyncPeriod =
-            mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig).vsyncPeriod;
+            mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig).getVsyncPeriod();
     mScheduler->onConfigChanged(mAppConnectionHandle, primaryDisplayId.value, currentConfig,
                                 vsyncPeriod);
 }
 
 void SurfaceFlinger::commitTransaction()
 {
-    withTracingLock([this]() { commitTransactionLocked(); });
-
+    commitTransactionLocked();
     mTransactionPending = false;
     mAnimTransactionPending = false;
     mTransactionCV.broadcast();
@@ -2996,26 +3047,6 @@
     mDrawingState.traverse([&](Layer* layer) { layer->updateMirrorInfo(); });
 }
 
-void SurfaceFlinger::withTracingLock(std::function<void()> lockedOperation) {
-    if (mTracingEnabledChanged) {
-        mTracingEnabled = mTracing.isEnabled();
-        mTracingEnabledChanged = false;
-    }
-
-    // Synchronize with Tracing thread
-    std::unique_lock<std::mutex> lock;
-    if (mTracingEnabled) {
-        lock = std::unique_lock<std::mutex>(mDrawingStateLock);
-    }
-
-    lockedOperation();
-
-    // Synchronize with Tracing thread
-    if (mTracingEnabled) {
-        lock.unlock();
-    }
-}
-
 void SurfaceFlinger::commitOffscreenLayers() {
     for (Layer* offscreenLayer : mOffscreenLayers) {
         offscreenLayer->traverse(LayerVector::StateSet::Drawing, [](Layer* layer) {
@@ -3480,12 +3511,13 @@
     return flags;
 }
 
-bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess() {
+bool SurfaceFlinger::callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache) {
     IPCThreadState* ipc = IPCThreadState::self();
     const int pid = ipc->getCallingPid();
     const int uid = ipc->getCallingUid();
     if ((uid != AID_GRAPHICS && uid != AID_SYSTEM) &&
-        !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) {
+        (usePermissionCache ? !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)
+                            : !checkPermission(sAccessSurfaceFlinger, pid, uid))) {
         return false;
     }
     return true;
@@ -4132,6 +4164,9 @@
     }
 
     if (currentMode == HWC_POWER_MODE_OFF) {
+        if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
+            ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
+        }
         getHwComposer().setPowerMode(*displayId, mode);
         if (display->isPrimary() && mode != HWC_POWER_MODE_DOZE_SUSPEND) {
             setVsyncEnabledInHWC(*displayId, mHWCVsyncPendingState);
@@ -4142,19 +4177,11 @@
         mVisibleRegionsDirty = true;
         mHasPoweredOff = true;
         repaintEverything();
-
-        struct sched_param param = {0};
-        param.sched_priority = 1;
-        if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
-            ALOGW("Couldn't set SCHED_FIFO on display on");
-        }
     } else if (mode == HWC_POWER_MODE_OFF) {
         // Turn off the display
-        struct sched_param param = {0};
-        if (sched_setscheduler(0, SCHED_OTHER, &param) != 0) {
-            ALOGW("Couldn't set SCHED_OTHER on display off");
+        if (SurfaceFlinger::setSchedFifo(false) != NO_ERROR) {
+            ALOGW("Couldn't set SCHED_OTHER on display off: %s\n", strerror(errno));
         }
-
         if (display->isPrimary() && currentMode != HWC_POWER_MODE_DOZE_SUSPEND) {
             mScheduler->disableHardwareVsync(true);
             mScheduler->onScreenReleased(mAppConnectionHandle);
@@ -4197,7 +4224,7 @@
 
 void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
     postMessageSync(new LambdaMessage([&]() NO_THREAD_SAFETY_ANALYSIS {
-        const auto display = getDisplayDevice(displayToken);
+        const auto display = getDisplayDeviceLocked(displayToken);
         if (!display) {
             ALOGE("Attempt to set power mode %d for invalid display token %p", mode,
                   displayToken.get());
@@ -4362,17 +4389,16 @@
                   "      present offset: %9" PRId64 " ns\t     VSYNC period: %9" PRId64 " ns\n\n",
                   dispSyncPresentTimeOffset, getVsyncPeriod());
 
-    HwcConfigIndexType defaultConfig;
-    float minFps, maxFps;
-    mRefreshRateConfigs->getPolicy(&defaultConfig, &minFps, &maxFps);
+    scheduler::RefreshRateConfigs::Policy policy = mRefreshRateConfigs->getDisplayManagerPolicy();
     StringAppendF(&result,
                   "DesiredDisplayConfigSpecs: default config ID: %d"
                   ", min: %.2f Hz, max: %.2f Hz",
-                  defaultConfig.value(), minFps, maxFps);
+                  policy.defaultConfig.value(), policy.minRefreshRate, policy.maxRefreshRate);
     StringAppendF(&result, "(config override by backdoor: %s)\n\n",
                   mDebugDisplayConfigSetByBackdoor ? "yes" : "no");
 
     mScheduler->dump(mAppConnectionHandle, result);
+    mScheduler->getPrimaryDispSync().dump(result);
 }
 
 void SurfaceFlinger::dumpStaticScreenStats(std::string& result) const {
@@ -4527,11 +4553,13 @@
     result.append("\n");
 }
 
-LayersProto SurfaceFlinger::dumpDrawingStateProto(
-        uint32_t traceFlags, const sp<const DisplayDevice>& displayDevice) const {
+LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
+    // If context is SurfaceTracing thread, mTracingLock blocks display transactions on main thread.
+    const auto display = getDefaultDisplayDeviceLocked();
+
     LayersProto layersProto;
     for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) {
-        layer->writeToProto(layersProto, traceFlags, displayDevice);
+        layer->writeToProto(layersProto, traceFlags, display);
     }
 
     return layersProto;
@@ -4563,10 +4591,7 @@
 
 LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) {
     LayersProto layersProto;
-    postMessageSync(new LambdaMessage([&]() {
-        const auto& displayDevice = getDefaultDisplayDeviceLocked();
-        layersProto = dumpDrawingStateProto(traceFlags, displayDevice);
-    }));
+    postMessageSync(new LambdaMessage([&] { layersProto = dumpDrawingStateProto(traceFlags); }));
     return layersProto;
 }
 
@@ -4807,8 +4832,12 @@
         case SET_DISPLAY_CONTENT_SAMPLING_ENABLED:
         case GET_DISPLAYED_CONTENT_SAMPLE:
         case NOTIFY_POWER_HINT:
-        case SET_GLOBAL_SHADOW_SETTINGS: {
-            if (!callingThreadHasUnscopedSurfaceFlingerAccess()) {
+        case SET_GLOBAL_SHADOW_SETTINGS:
+        case ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN: {
+            // ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN is used by CTS tests, which acquire the
+            // necessary permission dynamically. Don't use the permission cache for this check.
+            bool usePermissionCache = code != ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN;
+            if (!callingThreadHasUnscopedSurfaceFlingerAccess(usePermissionCache)) {
                 IPCThreadState* ipc = IPCThreadState::self();
                 ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d",
                         ipc->getCallingPid(), ipc->getCallingUid());
@@ -5089,20 +5118,12 @@
                 n = data.readInt32();
                 if (n) {
                     ALOGD("LayerTracing enabled");
-                    Mutex::Autolock lock(mStateLock);
-                    mTracingEnabledChanged = true;
-                    mTracing.enable();
+                    mTracingEnabledChanged = mTracing.enable();
                     reply->writeInt32(NO_ERROR);
                 } else {
                     ALOGD("LayerTracing disabled");
-                    bool writeFile = false;
-                    {
-                        Mutex::Autolock lock(mStateLock);
-                        mTracingEnabledChanged = true;
-                        writeFile = mTracing.disable();
-                    }
-
-                    if (writeFile) {
+                    mTracingEnabledChanged = mTracing.disable();
+                    if (mTracingEnabledChanged) {
                         reply->writeInt32(mTracing.writeToFile());
                     } else {
                         reply->writeInt32(NO_ERROR);
@@ -5307,10 +5328,10 @@
 
     sp<DisplayDevice> display;
     {
-        Mutex::Autolock _l(mStateLock);
+        Mutex::Autolock lock(mStateLock);
 
         display = getDisplayDeviceLocked(displayToken);
-        if (!display) return BAD_VALUE;
+        if (!display) return NAME_NOT_FOUND;
 
         // set the requested width/height to the logical display viewport size
         // by default
@@ -5322,7 +5343,6 @@
 
     DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, reqDataspace,
                                  renderAreaRotation, captureSecureLayers);
-
     auto traverseLayers = std::bind(&SurfaceFlinger::traverseLayersInDisplay, this, display,
                                     std::placeholders::_1);
     return captureScreenCommon(renderArea, traverseLayers, outBuffer, reqPixelFormat,
@@ -5341,6 +5361,26 @@
     }
 }
 
+status_t SurfaceFlinger::setSchedFifo(bool enabled) {
+    static constexpr int kFifoPriority = 2;
+    static constexpr int kOtherPriority = 0;
+
+    struct sched_param param = {0};
+    int sched_policy;
+    if (enabled) {
+        sched_policy = SCHED_FIFO;
+        param.sched_priority = kFifoPriority;
+    } else {
+        sched_policy = SCHED_OTHER;
+        param.sched_priority = kOtherPriority;
+    }
+
+    if (sched_setscheduler(0, sched_policy, &param) != 0) {
+        return -errno;
+    }
+    return NO_ERROR;
+}
+
 const sp<DisplayDevice> SurfaceFlinger::getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) {
     const sp<IBinder> displayToken = getPhysicalDisplayTokenLocked(DisplayId{displayOrLayerStack});
     if (displayToken) {
@@ -5367,10 +5407,10 @@
     uint32_t height;
     ui::Transform::RotationFlags captureOrientation;
     {
-        Mutex::Autolock _l(mStateLock);
+        Mutex::Autolock lock(mStateLock);
         display = getDisplayByIdOrLayerStack(displayOrLayerStack);
         if (!display) {
-            return BAD_VALUE;
+            return NAME_NOT_FOUND;
         }
 
         width = uint32_t(display->getViewport().width());
@@ -5430,10 +5470,7 @@
                 mFlinger(flinger),
                 mChildrenOnly(childrenOnly) {}
         const ui::Transform& getTransform() const override { return mTransform; }
-        Rect getBounds() const override {
-            const Layer::State& layerState(mLayer->getDrawingState());
-            return mLayer->getBufferSize(layerState);
-        }
+        Rect getBounds() const override { return mLayer->getBufferSize(mLayer->getDrawingState()); }
         int getHeight() const override {
             return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight();
         }
@@ -5476,9 +5513,8 @@
                 mTransform = mLayer->getTransform().inverse();
                 drawLayers();
             } else {
-                Rect bounds = getBounds();
-                uint32_t w = static_cast<uint32_t>(bounds.getWidth());
-                uint32_t h = static_cast<uint32_t>(bounds.getHeight());
+                uint32_t w = static_cast<uint32_t>(getWidth());
+                uint32_t h = static_cast<uint32_t>(getHeight());
                 // In the "childrenOnly" case we reparent the children to a screenshot
                 // layer which has no properties set and which does not draw.
                 sp<ContainerLayer> screenshotParentLayer =
@@ -5509,7 +5545,7 @@
     std::unordered_set<sp<Layer>, ISurfaceComposer::SpHash<Layer>> excludeLayers;
     Rect displayViewport;
     {
-        Mutex::Autolock _l(mStateLock);
+        Mutex::Autolock lock(mStateLock);
 
         parent = fromHandle(layerHandleBinder);
         if (parent == nullptr || parent->isRemovedFromCurrentState()) {
@@ -5553,9 +5589,9 @@
             }
         }
 
-        auto display = getDisplayByLayerStack(parent->getLayerStack());
+        const auto display = getDisplayByLayerStack(parent->getLayerStack());
         if (!display) {
-            return BAD_VALUE;
+            return NAME_NOT_FOUND;
         }
 
         displayViewport = display->getViewport();
@@ -5693,9 +5729,9 @@
 
     const auto reqWidth = renderArea.getReqWidth();
     const auto reqHeight = renderArea.getReqHeight();
-    const auto rotation = renderArea.getRotationFlags();
-    const auto transform = renderArea.getTransform();
     const auto sourceCrop = renderArea.getSourceCrop();
+    const auto transform = renderArea.getTransform();
+    const auto rotation = renderArea.getRotationFlags();
     const auto& displayViewport = renderArea.getDisplayViewport();
 
     renderengine::DisplaySettings clientCompositionDisplay;
@@ -5705,55 +5741,7 @@
     // buffer bounds.
     clientCompositionDisplay.physicalDisplay = Rect(reqWidth, reqHeight);
     clientCompositionDisplay.clip = sourceCrop;
-    clientCompositionDisplay.globalTransform = transform.asMatrix4();
-
-    // Now take into account the rotation flag. We append a transform that
-    // rotates the layer stack about the origin, then translate by buffer
-    // boundaries to be in the right quadrant.
-    mat4 rotMatrix;
-    int displacementX = 0;
-    int displacementY = 0;
-    float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f;
-    switch (rotation) {
-        case ui::Transform::ROT_90:
-            rotMatrix = mat4::rotate(rot90InRadians, vec3(0, 0, 1));
-            displacementX = renderArea.getBounds().getHeight();
-            break;
-        case ui::Transform::ROT_180:
-            rotMatrix = mat4::rotate(rot90InRadians * 2.0f, vec3(0, 0, 1));
-            displacementY = renderArea.getBounds().getWidth();
-            displacementX = renderArea.getBounds().getHeight();
-            break;
-        case ui::Transform::ROT_270:
-            rotMatrix = mat4::rotate(rot90InRadians * 3.0f, vec3(0, 0, 1));
-            displacementY = renderArea.getBounds().getWidth();
-            break;
-        default:
-            break;
-    }
-
-    // We need to transform the clipping window into the right spot.
-    // First, rotate the clipping rectangle by the rotation hint to get the
-    // right orientation
-    const vec4 clipTL = vec4(sourceCrop.left, sourceCrop.top, 0, 1);
-    const vec4 clipBR = vec4(sourceCrop.right, sourceCrop.bottom, 0, 1);
-    const vec4 rotClipTL = rotMatrix * clipTL;
-    const vec4 rotClipBR = rotMatrix * clipBR;
-    const int newClipLeft = std::min(rotClipTL[0], rotClipBR[0]);
-    const int newClipTop = std::min(rotClipTL[1], rotClipBR[1]);
-    const int newClipRight = std::max(rotClipTL[0], rotClipBR[0]);
-    const int newClipBottom = std::max(rotClipTL[1], rotClipBR[1]);
-
-    // Now reposition the clipping rectangle with the displacement vector
-    // computed above.
-    const mat4 displacementMat = mat4::translate(vec4(displacementX, displacementY, 0, 1));
-    clientCompositionDisplay.clip =
-            Rect(newClipLeft + displacementX, newClipTop + displacementY,
-                 newClipRight + displacementX, newClipBottom + displacementY);
-
-    mat4 clipTransform = displacementMat * rotMatrix;
-    clientCompositionDisplay.globalTransform =
-            clipTransform * clientCompositionDisplay.globalTransform;
+    clientCompositionDisplay.orientation = rotation;
 
     clientCompositionDisplay.outputDataspace = renderArea.getReqDataSpace();
     clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance;
@@ -5763,10 +5751,12 @@
     compositionengine::LayerFE::LayerSettings fillLayer;
     fillLayer.source.buffer.buffer = nullptr;
     fillLayer.source.solidColor = half3(0.0, 0.0, 0.0);
-    fillLayer.geometry.boundaries = FloatRect(0.0, 0.0, 1.0, 1.0);
+    fillLayer.geometry.boundaries =
+            FloatRect(sourceCrop.left, sourceCrop.top, sourceCrop.right, sourceCrop.bottom);
     fillLayer.alpha = half(alpha);
     clientCompositionLayers.push_back(fillLayer);
 
+    std::vector<Layer*> renderedLayers;
     Region clearRegion = Region::INVALID_REGION;
     traverseLayers([&](Layer* layer) {
         const bool supportProtectedContent = false;
@@ -5774,7 +5764,8 @@
         compositionengine::LayerFE::ClientCompositionTargetSettings targetSettings{
                 clip,
                 useIdentityTransform,
-                layer->needsFiltering(renderArea.getDisplayDevice()) || renderArea.needsFiltering(),
+                layer->needsFilteringForScreenshots(renderArea.getDisplayDevice(), transform) ||
+                        renderArea.needsFiltering(),
                 renderArea.isSecure(),
                 supportProtectedContent,
                 clearRegion,
@@ -5785,19 +5776,23 @@
         };
         std::vector<compositionengine::LayerFE::LayerSettings> results =
                 layer->prepareClientCompositionList(targetSettings);
-        clientCompositionLayers.insert(clientCompositionLayers.end(),
-                                       std::make_move_iterator(results.begin()),
-                                       std::make_move_iterator(results.end()));
-        results.clear();
-
+        if (results.size() > 0) {
+            for (auto& settings : results) {
+                settings.geometry.positionTransform =
+                        transform.asMatrix4() * settings.geometry.positionTransform;
+            }
+            clientCompositionLayers.insert(clientCompositionLayers.end(),
+                                           std::make_move_iterator(results.begin()),
+                                           std::make_move_iterator(results.end()));
+            renderedLayers.push_back(layer);
+        }
     });
 
-    std::vector<const renderengine::LayerSettings*> clientCompositionLayerPointers;
-    clientCompositionLayers.reserve(clientCompositionLayers.size());
+    std::vector<const renderengine::LayerSettings*> clientCompositionLayerPointers(
+            clientCompositionLayers.size());
     std::transform(clientCompositionLayers.begin(), clientCompositionLayers.end(),
-                   std::back_inserter(clientCompositionLayerPointers),
-                   [](compositionengine::LayerFE::LayerSettings& settings)
-                           -> renderengine::LayerSettings* { return &settings; });
+                   clientCompositionLayerPointers.begin(),
+                   std::pointer_traits<renderengine::LayerSettings*>::pointer_to);
 
     clientCompositionDisplay.clearRegion = clearRegion;
     // Use an empty fence for the buffer fence, since we just created the buffer so
@@ -5809,6 +5804,13 @@
                                  /*useFramebufferCache=*/false, std::move(bufferFence), &drawFence);
 
     *outSyncFd = drawFence.release();
+
+    if (*outSyncFd >= 0) {
+        sp<Fence> releaseFence = new Fence(dup(*outSyncFd));
+        for (auto* layer : renderedLayers) {
+            layer->onLayerDisplayed(releaseFence);
+        }
+    }
 }
 
 status_t SurfaceFlinger::captureScreenImplLocked(const RenderArea& renderArea,
@@ -5877,12 +5879,15 @@
     }
 }
 
-status_t SurfaceFlinger::setDesiredDisplayConfigSpecsInternal(const sp<DisplayDevice>& display,
-                                                              HwcConfigIndexType defaultConfig,
-                                                              float minRefreshRate,
-                                                              float maxRefreshRate) {
+status_t SurfaceFlinger::setDesiredDisplayConfigSpecsInternal(
+        const sp<DisplayDevice>& display,
+        const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy) {
     Mutex::Autolock lock(mStateLock);
 
+    LOG_ALWAYS_FATAL_IF(!display->isPrimary() && overridePolicy,
+                        "Can only set override policy on the primary display");
+    LOG_ALWAYS_FATAL_IF(!policy && !overridePolicy, "Can only clear the override policy");
+
     if (!display->isPrimary()) {
         // TODO(b/144711714): For non-primary displays we should be able to set an active config
         // as well. For now, just call directly to setActiveConfigWithConstraints but ideally
@@ -5896,7 +5901,8 @@
         constraints.seamlessRequired = false;
 
         HWC2::VsyncPeriodChangeTimeline timeline = {0, 0, 0};
-        if (getHwComposer().setActiveConfigWithConstraints(*displayId, defaultConfig.value(),
+        if (getHwComposer().setActiveConfigWithConstraints(*displayId,
+                                                           policy->defaultConfig.value(),
                                                            constraints, &timeline) < 0) {
             return BAD_VALUE;
         }
@@ -5904,11 +5910,12 @@
             repaintEverythingForHWC();
         }
 
-        display->setActiveConfig(defaultConfig);
-        const nsecs_t vsyncPeriod =
-                getHwComposer().getConfigs(*displayId)[defaultConfig.value()]->getVsyncPeriod();
-        mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value, defaultConfig,
-                                    vsyncPeriod);
+        display->setActiveConfig(policy->defaultConfig);
+        const nsecs_t vsyncPeriod = getHwComposer()
+                                            .getConfigs(*displayId)[policy->defaultConfig.value()]
+                                            ->getVsyncPeriod();
+        mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
+                                    policy->defaultConfig, vsyncPeriod);
         return NO_ERROR;
     }
 
@@ -5917,23 +5924,27 @@
         return NO_ERROR;
     }
 
-    bool policyChanged;
-    if (mRefreshRateConfigs->setPolicy(defaultConfig, minRefreshRate, maxRefreshRate,
-                                       &policyChanged) < 0) {
+    status_t setPolicyResult = overridePolicy
+            ? mRefreshRateConfigs->setOverridePolicy(policy)
+            : mRefreshRateConfigs->setDisplayManagerPolicy(*policy);
+    if (setPolicyResult < 0) {
         return BAD_VALUE;
     }
-    if (!policyChanged) {
+    if (setPolicyResult == scheduler::RefreshRateConfigs::CURRENT_POLICY_UNCHANGED) {
         return NO_ERROR;
     }
+    scheduler::RefreshRateConfigs::Policy currentPolicy = mRefreshRateConfigs->getCurrentPolicy();
 
     ALOGV("Setting desired display config specs: defaultConfig: %d min: %.f max: %.f",
-          defaultConfig.value(), minRefreshRate, maxRefreshRate);
+          currentPolicy.defaultConfig.value(), currentPolicy.minRefreshRate,
+          currentPolicy.maxRefreshRate);
 
     // TODO(b/140204874): This hack triggers a notification that something has changed, so
     // that listeners that care about a change in allowed configs can get the notification.
     // Giving current ActiveConfig so that most other listeners would just drop the event
     const nsecs_t vsyncPeriod =
-            mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig()).vsyncPeriod;
+            mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig())
+                    .getVsyncPeriod();
     mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
                                 display->getActiveConfig(), vsyncPeriod);
 
@@ -5941,15 +5952,18 @@
     auto& preferredRefreshRate = configId
             ? mRefreshRateConfigs->getRefreshRateFromConfigId(*configId)
             // NOTE: Choose the default config ID, if Scheduler doesn't have one in mind.
-            : mRefreshRateConfigs->getRefreshRateFromConfigId(defaultConfig);
+            : mRefreshRateConfigs->getRefreshRateFromConfigId(currentPolicy.defaultConfig);
     ALOGV("trying to switch to Scheduler preferred config %d (%s)",
-          preferredRefreshRate.configId.value(), preferredRefreshRate.name.c_str());
+          preferredRefreshRate.getConfigId().value(), preferredRefreshRate.getName().c_str());
 
-    if (isDisplayConfigAllowed(preferredRefreshRate.configId)) {
-        ALOGV("switching to Scheduler preferred config %d", preferredRefreshRate.configId.value());
-        setDesiredActiveConfig({preferredRefreshRate.configId, Scheduler::ConfigEvent::Changed});
+    if (isDisplayConfigAllowed(preferredRefreshRate.getConfigId())) {
+        ALOGV("switching to Scheduler preferred config %d",
+              preferredRefreshRate.getConfigId().value());
+        setDesiredActiveConfig(
+                {preferredRefreshRate.getConfigId(), Scheduler::ConfigEvent::Changed});
     } else {
-        LOG_ALWAYS_FATAL("Desired config not allowed: %d", preferredRefreshRate.configId.value());
+        LOG_ALWAYS_FATAL("Desired config not allowed: %d",
+                         preferredRefreshRate.getConfigId().value());
     }
 
     return NO_ERROR;
@@ -5964,21 +5978,24 @@
         return BAD_VALUE;
     }
 
-    status_t result = NO_ERROR;
+    status_t result = NAME_NOT_FOUND;
 
     postMessageSync(new LambdaMessage([&]() {
         const auto display = getDisplayDeviceLocked(displayToken);
         if (!display) {
-            result = BAD_VALUE;
             ALOGE("Attempt to set desired display configs for invalid display token %p",
                   displayToken.get());
         } else if (display->isVirtual()) {
-            result = BAD_VALUE;
             ALOGW("Attempt to set desired display configs for virtual display");
+            result = INVALID_OPERATION;
         } else {
-            result =
-                    setDesiredDisplayConfigSpecsInternal(display, HwcConfigIndexType(defaultConfig),
-                                                         minRefreshRate, maxRefreshRate);
+            result = setDesiredDisplayConfigSpecsInternal(display,
+                                                          scheduler::RefreshRateConfigs::
+                                                                  Policy{HwcConfigIndexType(
+                                                                                 defaultConfig),
+                                                                         minRefreshRate,
+                                                                         maxRefreshRate},
+                                                          /*overridePolicy=*/false);
         }
     }));
 
@@ -6002,17 +6019,18 @@
     }
 
     if (display->isPrimary()) {
-        HwcConfigIndexType defaultConfig;
-        mRefreshRateConfigs->getPolicy(&defaultConfig, outMinRefreshRate, outMaxRefreshRate);
-        *outDefaultConfig = defaultConfig.value();
+        scheduler::RefreshRateConfigs::Policy policy =
+                mRefreshRateConfigs->getDisplayManagerPolicy();
+        *outDefaultConfig = policy.defaultConfig.value();
+        *outMinRefreshRate = policy.minRefreshRate;
+        *outMaxRefreshRate = policy.maxRefreshRate;
         return NO_ERROR;
     } else if (display->isVirtual()) {
-        return BAD_VALUE;
+        return INVALID_OPERATION;
     } else {
         const auto displayId = display->getId();
-        if (!displayId) {
-            return BAD_VALUE;
-        }
+        LOG_FATAL_IF(!displayId);
+
         *outDefaultConfig = getHwComposer().getActiveConfigIndex(*displayId);
         auto vsyncPeriod = getHwComposer().getActiveConfig(*displayId)->getVsyncPeriod();
         *outMinRefreshRate = 1e9f / vsyncPeriod;
@@ -6124,6 +6142,68 @@
     return NO_ERROR;
 }
 
+status_t SurfaceFlinger::acquireFrameRateFlexibilityToken(sp<IBinder>* outToken) {
+    if (!outToken) {
+        return BAD_VALUE;
+    }
+    status_t result = NO_ERROR;
+    postMessageSync(new LambdaMessage([&]() {
+        if (mFrameRateFlexibilityTokenCount == 0) {
+            // |mStateLock| not needed as we are on the main thread
+            const auto display = getDefaultDisplayDeviceLocked();
+
+            // This is a little racy, but not in a way that hurts anything. As we grab the
+            // defaultConfig from the display manager policy, we could be setting a new display
+            // manager policy, leaving us using a stale defaultConfig. The defaultConfig doesn't
+            // matter for the override policy though, since we set allowGroupSwitching to true, so
+            // it's not a problem.
+            scheduler::RefreshRateConfigs::Policy overridePolicy;
+            overridePolicy.defaultConfig =
+                    mRefreshRateConfigs->getDisplayManagerPolicy().defaultConfig;
+            overridePolicy.allowGroupSwitching = true;
+            result = setDesiredDisplayConfigSpecsInternal(display, overridePolicy,
+                                                          /*overridePolicy=*/true);
+        }
+
+        if (result == NO_ERROR) {
+            mFrameRateFlexibilityTokenCount++;
+            // Handing out a reference to the SurfaceFlinger object, as we're doing in the line
+            // below, is something to consider carefully. The lifetime of the
+            // FrameRateFlexibilityToken isn't tied to SurfaceFlinger object lifetime, so if this
+            // SurfaceFlinger object were to be destroyed while the token still exists, the token
+            // destructor would be accessing a stale SurfaceFlinger reference, and crash. This is ok
+            // in this case, for two reasons:
+            //   1. Once SurfaceFlinger::run() is called by main_surfaceflinger.cpp, the only way
+            //   the program exits is via a crash. So we won't have a situation where the
+            //   SurfaceFlinger object is dead but the process is still up.
+            //   2. The frame rate flexibility token is acquired/released only by CTS tests, so even
+            //   if condition 1 were changed, the problem would only show up when running CTS tests,
+            //   not on end user devices, so we could spot it and fix it without serious impact.
+            *outToken = new FrameRateFlexibilityToken(
+                    [this]() { onFrameRateFlexibilityTokenReleased(); });
+            ALOGD("Frame rate flexibility token acquired. count=%d",
+                  mFrameRateFlexibilityTokenCount);
+        }
+    }));
+    return result;
+}
+
+void SurfaceFlinger::onFrameRateFlexibilityTokenReleased() {
+    postMessageAsync(new LambdaMessage([&]() {
+        LOG_ALWAYS_FATAL_IF(mFrameRateFlexibilityTokenCount == 0,
+                            "Failed tracking frame rate flexibility tokens");
+        mFrameRateFlexibilityTokenCount--;
+        ALOGD("Frame rate flexibility token released. count=%d", mFrameRateFlexibilityTokenCount);
+        if (mFrameRateFlexibilityTokenCount == 0) {
+            // |mStateLock| not needed as we are on the main thread
+            const auto display = getDefaultDisplayDeviceLocked();
+            status_t result =
+                    setDesiredDisplayConfigSpecsInternal(display, {}, /*overridePolicy=*/true);
+            LOG_ALWAYS_FATAL_IF(result < 0, "Failed releasing frame rate flexibility token");
+        }
+    }));
+}
+
 } // namespace android
 
 #if defined(__gl_h_)
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 6ab1fcf..eb0afc8 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -259,6 +259,9 @@
     // overhead that is caused by reading from sysprop.
     static bool useFrameRateApi;
 
+    // set main thread scheduling policy
+    static status_t setSchedFifo(bool enabled) ANDROID_API;
+
     static char const* getServiceName() ANDROID_API {
         return "SurfaceFlinger";
     }
@@ -404,7 +407,8 @@
      */
     status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override;
     status_t dump(int fd, const Vector<String16>& args) override { return priorityDump(fd, args); }
-    bool callingThreadHasUnscopedSurfaceFlingerAccess() EXCLUDES(mStateLock);
+    bool callingThreadHasUnscopedSurfaceFlingerAccess(bool usePermissionCache = true)
+            EXCLUDES(mStateLock);
 
     /* ------------------------------------------------------------------------
      * ISurfaceComposer interface
@@ -471,14 +475,13 @@
     status_t getCompositionPreference(ui::Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
                                       ui::Dataspace* outWideColorGamutDataspace,
                                       ui::PixelFormat* outWideColorGamutPixelFormat) const override;
-    status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& display,
+    status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& displayToken,
                                                    ui::PixelFormat* outFormat,
                                                    ui::Dataspace* outDataspace,
                                                    uint8_t* outComponentMask) const override;
-    status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
-                                              uint8_t componentMask,
-                                              uint64_t maxFrames) const override;
-    status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames,
+    status_t setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken, bool enable,
+                                              uint8_t componentMask, uint64_t maxFrames) override;
+    status_t getDisplayedContentSample(const sp<IBinder>& displayToken, uint64_t maxFrames,
                                        uint64_t timestamp,
                                        DisplayedFrameStats* outStats) const override;
     status_t getProtectedContentSupport(bool* outSupported) const override;
@@ -494,12 +497,13 @@
                                           float* outMaxRefreshRate) override;
     status_t getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
                                          bool* outSupport) const override;
-    status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) const override;
+    status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) override;
     status_t notifyPowerHint(int32_t hintId) override;
     status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
                                      float lightPosY, float lightPosZ, float lightRadius) override;
     status_t setFrameRate(const sp<IGraphicBufferProducer>& surface, float frameRate,
                           int8_t compatibility) override;
+    status_t acquireFrameRateFlexibilityToken(sp<IBinder>* outToken) override;
     /* ------------------------------------------------------------------------
      * DeathRecipient interface
      */
@@ -560,27 +564,20 @@
     // Once HWC has returned the present fence, this sets the active config and a new refresh
     // rate in SF.
     void setActiveConfigInternal() REQUIRES(mStateLock);
-    // Active config is updated on INVALIDATE call in a state machine-like manner. When the
-    // desired config was set, HWC needs to update the panel on the next refresh, and when
-    // we receive the fence back, we know that the process was complete. It returns whether
-    // we need to wait for the next invalidate
-    bool performSetActiveConfig() REQUIRES(mStateLock);
+    // Calls to setActiveConfig on the main thread if there is a pending config
+    // that needs to be applied.
+    void performSetActiveConfig() REQUIRES(mStateLock);
     // Called when active config is no longer is progress
     void desiredActiveConfigChangeDone() REQUIRES(mStateLock);
     // called on the main thread in response to setPowerMode()
     void setPowerModeInternal(const sp<DisplayDevice>& display, int mode) REQUIRES(mStateLock);
 
     // Sets the desired display configs.
-    status_t setDesiredDisplayConfigSpecsInternal(const sp<DisplayDevice>& display,
-                                                  HwcConfigIndexType defaultConfig,
-                                                  float minRefreshRate, float maxRefreshRate)
+    status_t setDesiredDisplayConfigSpecsInternal(
+            const sp<DisplayDevice>& display,
+            const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy)
             EXCLUDES(mStateLock);
 
-    // called on the main thread in response to setAutoLowLatencyMode()
-    void setAutoLowLatencyModeInternal(const sp<IBinder>& displayToken, bool on);
-    // called on the main thread in response to setGameContentType()
-    void setGameContentTypeInternal(const sp<IBinder>& displayToken, bool on);
-
     // Returns whether the transaction actually modified any state
     bool handleMessageTransaction();
 
@@ -735,16 +732,6 @@
     // called when starting, or restarting after system_server death
     void initializeDisplays();
 
-    sp<const DisplayDevice> getDisplayDevice(const wp<IBinder>& displayToken) const {
-        Mutex::Autolock _l(mStateLock);
-        return getDisplayDeviceLocked(displayToken);
-    }
-
-    sp<DisplayDevice> getDisplayDevice(const wp<IBinder>& displayToken) {
-        Mutex::Autolock _l(mStateLock);
-        return getDisplayDeviceLocked(displayToken);
-    }
-
     // NOTE: can only be called from the main thread or with mStateLock held
     sp<const DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) const {
         return const_cast<SurfaceFlinger*>(this)->getDisplayDeviceLocked(displayToken);
@@ -942,8 +929,7 @@
     void dumpDisplayIdentificationData(std::string& result) const;
     void dumpRawDisplayIdentificationData(const DumpArgs&, std::string& result) const;
     void dumpWideColorInfo(std::string& result) const;
-    LayersProto dumpDrawingStateProto(uint32_t traceFlags = SurfaceTracing::TRACE_ALL,
-                                      const sp<const DisplayDevice>& displayDevice = nullptr) const;
+    LayersProto dumpDrawingStateProto(uint32_t traceFlags) const;
     void dumpOffscreenLayersProto(LayersProto& layersProto,
                                   uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
     // Dumps state from HW Composer
@@ -951,7 +937,6 @@
     LayersProto dumpProtoFromMainThread(uint32_t traceFlags = SurfaceTracing::TRACE_ALL)
             EXCLUDES(mStateLock);
     void dumpOffscreenLayers(std::string& result) EXCLUDES(mStateLock);
-    void withTracingLock(std::function<void()> operation) REQUIRES(mStateLock);
 
     bool isLayerTripleBufferingDisabled() const {
         return this->mLayerTripleBufferingDisabled;
@@ -965,6 +950,8 @@
         return doDump(fd, args, asProto);
     }
 
+    void onFrameRateFlexibilityTokenReleased();
+
     /* ------------------------------------------------------------------------
      * VrFlinger
      */
@@ -991,9 +978,6 @@
     SortedVector<sp<Layer>> mLayersPendingRemoval;
     bool mTraversalNeededMainThread = false;
 
-    // guards access to the mDrawing state if tracing is enabled.
-    mutable std::mutex mDrawingStateLock;
-
     // global color transform states
     Daltonizer mDaltonizer;
     float mGlobalSaturationFactor = 1.0f;
@@ -1068,9 +1052,13 @@
     bool mPropagateBackpressure = true;
     bool mPropagateBackpressureClientComposition = false;
     std::unique_ptr<SurfaceInterceptor> mInterceptor;
+
     SurfaceTracing mTracing{*this};
+    std::mutex mTracingLock;
     bool mTracingEnabled = false;
-    bool mTracingEnabledChanged GUARDED_BY(mStateLock) = false;
+    bool mAddCompositionStateToTrace = false;
+    std::atomic<bool> mTracingEnabledChanged = false;
+
     const std::shared_ptr<TimeStats> mTimeStats;
     const std::unique_ptr<FrameTracer> mFrameTracer;
     bool mUseHwcVirtualDisplays = false;
@@ -1217,7 +1205,7 @@
     // below flags are set by main thread only
     TracedOrdinal<bool> mDesiredActiveConfigChanged
             GUARDED_BY(mActiveConfigLock) = {"DesiredActiveConfigChanged", false};
-    bool mCheckPendingFence = false;
+    bool mSetActiveConfigPending = false;
 
     bool mLumaSampling = true;
     sp<RegionSamplingThread> mRegionSamplingThread;
@@ -1272,6 +1260,8 @@
     std::atomic<bool> mInputDirty = true;
     void dirtyInput() { mInputDirty = true; }
     bool inputDirty() { return mInputDirty; }
+
+    int mFrameRateFlexibilityTokenCount = 0;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index a9c3332..d84ce69 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -33,33 +33,32 @@
 namespace android {
 
 SurfaceTracing::SurfaceTracing(SurfaceFlinger& flinger)
-      : mFlinger(flinger), mSfLock(flinger.mDrawingStateLock) {}
+      : mFlinger(flinger), mSfLock(flinger.mTracingLock) {}
 
 void SurfaceTracing::mainLoop() {
-    addFirstEntry();
-    bool enabled = true;
+    bool enabled = addFirstEntry();
     while (enabled) {
         LayersTraceProto entry = traceWhenNotified();
         enabled = addTraceToBuffer(entry);
     }
 }
 
-void SurfaceTracing::addFirstEntry() {
-    const auto displayDevice = mFlinger.getDefaultDisplayDevice();
+bool SurfaceTracing::addFirstEntry() {
     LayersTraceProto entry;
     {
         std::scoped_lock lock(mSfLock);
-        entry = traceLayersLocked("tracing.enable", displayDevice);
+        entry = traceLayersLocked("tracing.enable");
     }
-    addTraceToBuffer(entry);
+    return addTraceToBuffer(entry);
 }
 
 LayersTraceProto SurfaceTracing::traceWhenNotified() {
-    const auto displayDevice = mFlinger.getDefaultDisplayDevice();
     std::unique_lock<std::mutex> lock(mSfLock);
     mCanStartTrace.wait(lock);
     android::base::ScopedLockAssertion assumeLock(mSfLock);
-    LayersTraceProto entry = traceLayersLocked(mWhere, displayDevice);
+    LayersTraceProto entry = traceLayersLocked(mWhere);
+    mTracingInProgress = false;
+    mMissedTraceEntries = 0;
     lock.unlock();
     return entry;
 }
@@ -76,7 +75,15 @@
 
 void SurfaceTracing::notify(const char* where) {
     std::scoped_lock lock(mSfLock);
+    notifyLocked(where);
+}
+
+void SurfaceTracing::notifyLocked(const char* where) {
     mWhere = where;
+    if (mTracingInProgress) {
+        mMissedTraceEntries++;
+    }
+    mTracingInProgress = true;
     mCanStartTrace.notify_one();
 }
 
@@ -117,15 +124,17 @@
     }
 }
 
-void SurfaceTracing::enable() {
+bool SurfaceTracing::enable() {
     std::scoped_lock lock(mTraceLock);
 
     if (mEnabled) {
-        return;
+        return false;
     }
+
     mBuffer.reset(mBufferSize);
     mEnabled = true;
     mThread = std::thread(&SurfaceTracing::mainLoop, this);
+    return true;
 }
 
 status_t SurfaceTracing::writeToFile() {
@@ -167,15 +176,17 @@
     mTraceFlags = flags;
 }
 
-LayersTraceProto SurfaceTracing::traceLayersLocked(const char* where,
-                                                   const sp<const DisplayDevice>& displayDevice) {
+LayersTraceProto SurfaceTracing::traceLayersLocked(const char* where) {
     ATRACE_CALL();
 
     LayersTraceProto entry;
     entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
     entry.set_where(where);
-    LayersProto layers(mFlinger.dumpDrawingStateProto(mTraceFlags, displayDevice));
-    mFlinger.dumpOffscreenLayersProto(layers);
+    LayersProto layers(mFlinger.dumpDrawingStateProto(mTraceFlags));
+
+    if (flagIsSetLocked(SurfaceTracing::TRACE_EXTRA)) {
+        mFlinger.dumpOffscreenLayersProto(layers);
+    }
     entry.mutable_layers()->Swap(&layers);
 
     if (mTraceFlags & SurfaceTracing::TRACE_HWC) {
@@ -183,6 +194,10 @@
         mFlinger.dumpHwc(hwcDump);
         entry.set_hwc_blob(hwcDump);
     }
+    if (!flagIsSetLocked(SurfaceTracing::TRACE_COMPOSITION)) {
+        entry.set_excludes_composition_state(true);
+    }
+    entry.set_missed_entries(mMissedTraceEntries);
 
     return entry;
 }
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 83872ed..f208eb8 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -27,8 +27,6 @@
 #include <queue>
 #include <thread>
 
-#include "DisplayDevice.h"
-
 using namespace android::surfaceflinger;
 
 namespace android {
@@ -44,11 +42,12 @@
 class SurfaceTracing {
 public:
     explicit SurfaceTracing(SurfaceFlinger& flinger);
-    void enable();
+    bool enable();
     bool disable();
     status_t writeToFile();
     bool isEnabled() const;
     void notify(const char* where);
+    void notifyLocked(const char* where) NO_THREAD_SAFETY_ANALYSIS /* REQUIRES(mSfLock) */;
 
     void setBufferSize(size_t bufferSizeInByte);
     void writeToFileAsync();
@@ -57,11 +56,15 @@
     enum : uint32_t {
         TRACE_CRITICAL = 1 << 0,
         TRACE_INPUT = 1 << 1,
-        TRACE_EXTRA = 1 << 2,
-        TRACE_HWC = 1 << 3,
+        TRACE_COMPOSITION = 1 << 2,
+        TRACE_EXTRA = 1 << 3,
+        TRACE_HWC = 1 << 4,
         TRACE_ALL = 0xffffffff
     };
     void setTraceFlags(uint32_t flags);
+    bool flagIsSetLocked(uint32_t flags) NO_THREAD_SAFETY_ANALYSIS /* REQUIRES(mSfLock) */ {
+        return (mTraceFlags & flags) == flags;
+    }
 
 private:
     static constexpr auto kDefaultBufferCapInByte = 5_MB;
@@ -85,11 +88,9 @@
     };
 
     void mainLoop();
-    void addFirstEntry();
+    bool addFirstEntry();
     LayersTraceProto traceWhenNotified();
-    LayersTraceProto traceLayersLocked(const char* where,
-                                       const sp<const DisplayDevice>& displayDevice)
-            REQUIRES(mSfLock);
+    LayersTraceProto traceLayersLocked(const char* where) REQUIRES(mSfLock);
 
     // Returns true if trace is enabled.
     bool addTraceToBuffer(LayersTraceProto& entry);
@@ -103,6 +104,8 @@
     std::mutex& mSfLock;
     uint32_t mTraceFlags GUARDED_BY(mSfLock) = TRACE_CRITICAL | TRACE_INPUT;
     const char* mWhere GUARDED_BY(mSfLock) = "";
+    uint32_t mMissedTraceEntries GUARDED_BY(mSfLock) = 0;
+    bool mTracingInProgress GUARDED_BY(mSfLock) = false;
 
     mutable std::mutex mTraceLock;
     LayersTraceBuffer mBuffer GUARDED_BY(mTraceLock);
diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp
index 4f59bf2..606e137 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.cpp
+++ b/services/surfaceflinger/TimeStats/TimeStats.cpp
@@ -281,6 +281,15 @@
     mTimeStats.clientCompositionReusedFrames++;
 }
 
+void TimeStats::incrementRefreshRateSwitches() {
+    if (!mEnabled.load()) return;
+
+    ATRACE_CALL();
+
+    std::lock_guard<std::mutex> lock(mMutex);
+    mTimeStats.refreshRateSwitches++;
+}
+
 void TimeStats::recordDisplayEventConnectionCount(int32_t count) {
     if (!mEnabled.load()) return;
 
@@ -834,6 +843,7 @@
     mTimeStats.missedFrames = 0;
     mTimeStats.clientCompositionFrames = 0;
     mTimeStats.clientCompositionReusedFrames = 0;
+    mTimeStats.refreshRateSwitches = 0;
     mTimeStats.displayEventConnectionsCount = 0;
     mTimeStats.displayOnTime = 0;
     mTimeStats.presentToPresent.hist.clear();
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index f9bd90b..806b47e 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -52,6 +52,8 @@
     virtual void incrementMissedFrames() = 0;
     virtual void incrementClientCompositionFrames() = 0;
     virtual void incrementClientCompositionReusedFrames() = 0;
+    // Increments the number of times the display refresh rate changed.
+    virtual void incrementRefreshRateSwitches() = 0;
     // Records the most up-to-date count of display event connections.
     // The stored count will be the maximum ever recoded.
     virtual void recordDisplayEventConnectionCount(int32_t count) = 0;
@@ -215,6 +217,7 @@
     void incrementMissedFrames() override;
     void incrementClientCompositionFrames() override;
     void incrementClientCompositionReusedFrames() override;
+    void incrementRefreshRateSwitches() override;
     void recordDisplayEventConnectionCount(int32_t count) override;
 
     void recordFrameDuration(nsecs_t startTime, nsecs_t endTime) override;
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
index e2f85cc..5305de9 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
+++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
@@ -105,6 +105,7 @@
     StringAppendF(&result, "missedFrames = %d\n", missedFrames);
     StringAppendF(&result, "clientCompositionFrames = %d\n", clientCompositionFrames);
     StringAppendF(&result, "clientCompositionReusedFrames = %d\n", clientCompositionReusedFrames);
+    StringAppendF(&result, "refreshRateSwitches = %d\n", refreshRateSwitches);
     StringAppendF(&result, "displayOnTime = %" PRId64 " ms\n", displayOnTime);
     StringAppendF(&result, "displayConfigStats is as below:\n");
     for (const auto& [fps, duration] : refreshRateStats) {
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
index 5e7c449..afb98e0 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
+++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
@@ -62,6 +62,7 @@
         int32_t missedFrames = 0;
         int32_t clientCompositionFrames = 0;
         int32_t clientCompositionReusedFrames = 0;
+        int32_t refreshRateSwitches = 0;
         int32_t displayEventConnectionsCount = 0;
         int64_t displayOnTime = 0;
         Histogram presentToPresent;
diff --git a/services/surfaceflinger/layerproto/layerstrace.proto b/services/surfaceflinger/layerproto/layerstrace.proto
index ac33a0e..acf621e 100644
--- a/services/surfaceflinger/layerproto/layerstrace.proto
+++ b/services/surfaceflinger/layerproto/layerstrace.proto
@@ -51,4 +51,10 @@
 
     // Blob for the current HWC information for all layers, reported by dumpsys.
     optional string hwc_blob = 4;
+
+    /* Includes state sent during composition like visible region and composition type. */
+    optional bool excludes_composition_state = 5;
+
+    /* Number of missed entries since the last entry was recorded. */
+    optional int32 missed_entries = 6;
 }
diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp
index d7ad9de..2b8424c 100644
--- a/services/surfaceflinger/main_surfaceflinger.cpp
+++ b/services/surfaceflinger/main_surfaceflinger.cpp
@@ -31,6 +31,7 @@
 #include <binder/ProcessState.h>
 #include <configstore/Utils.h>
 #include <displayservice/DisplayService.h>
+#include <errno.h>
 #include <hidl/LegacySupport.h>
 #include <processgroup/sched_policy.h>
 #include "SurfaceFlinger.h"
@@ -114,10 +115,8 @@
 
     startDisplayService(); // dependency on SF getting registered above
 
-    struct sched_param param = {0};
-    param.sched_priority = 2;
-    if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
-        ALOGE("Couldn't set SCHED_FIFO");
+    if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
+        ALOGW("Couldn't set to SCHED_FIFO: %s", strerror(errno));
     }
 
     // run surface flinger in this thread
diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h
index 932c7c8..40ec502 100644
--- a/services/surfaceflinger/tests/LayerTransactionTest.h
+++ b/services/surfaceflinger/tests/LayerTransactionTest.h
@@ -52,9 +52,10 @@
     virtual sp<SurfaceControl> createLayer(const sp<SurfaceComposerClient>& client,
                                            const char* name, uint32_t width, uint32_t height,
                                            uint32_t flags = 0, SurfaceControl* parent = nullptr,
-                                           uint32_t* outTransformHint = nullptr) {
-        auto layer = createSurface(client, name, width, height, PIXEL_FORMAT_RGBA_8888, flags,
-                                   parent, outTransformHint);
+                                           uint32_t* outTransformHint = nullptr,
+                                           PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
+        auto layer =
+                createSurface(client, name, width, height, format, flags, parent, outTransformHint);
 
         Transaction t;
         t.setLayerStack(layer, mDisplayLayerStack).setLayer(layer, mLayerZBase);
@@ -81,8 +82,9 @@
 
     virtual sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
                                            uint32_t flags = 0, SurfaceControl* parent = nullptr,
-                                           uint32_t* outTransformHint = nullptr) {
-        return createLayer(mClient, name, width, height, flags, parent, outTransformHint);
+                                           uint32_t* outTransformHint = nullptr,
+                                           PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
+        return createLayer(mClient, name, width, height, flags, parent, outTransformHint, format);
     }
 
     sp<SurfaceControl> createColorLayer(const char* name, const Color& color,
diff --git a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
index 2fd2579..d666d7e 100644
--- a/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTypeAndRenderTypeTransaction_test.cpp
@@ -365,6 +365,67 @@
         getScreenCapture()->expectColor(Rect(0, 0, 32, 32), Color::RED);
     }
 }
+
+TEST_P(LayerTypeAndRenderTypeTransactionTest, SetBufferFormat) {
+    int32_t width = 100;
+    int32_t height = 100;
+    Rect crop = Rect(0, 0, width, height);
+
+    sp<SurfaceControl> behindLayer = createColorLayer("Behind layer", Color::RED);
+    sp<SurfaceControl> layer;
+    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", width, height, 0, nullptr, nullptr,
+                                                PIXEL_FORMAT_RGBX_8888));
+
+    Transaction()
+            .setLayer(layer, INT32_MAX - 1)
+            .show(layer)
+            .setLayerStack(behindLayer, mDisplayLayerStack)
+            .setCrop_legacy(behindLayer, crop)
+            .setLayer(behindLayer, INT32_MAX - 2)
+            .show(behindLayer)
+            .apply();
+
+    sp<Surface> surface = layer->getSurface();
+
+    sp<GraphicBuffer> buffer =
+            new GraphicBuffer(width, height, PIXEL_FORMAT_RGBX_8888, 1,
+                              BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                                      BufferUsage::COMPOSER_OVERLAY,
+                              "test");
+    ASSERT_NO_FATAL_FAILURE(
+            TransactionUtils::fillGraphicBufferColor(buffer, crop, Color::TRANSPARENT));
+
+    if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) {
+        Surface::attachAndQueueBufferWithDataspace(surface.get(), buffer, ui::Dataspace::V0_SRGB);
+    } else {
+        Transaction().setBuffer(layer, buffer).apply();
+    }
+
+    {
+        SCOPED_TRACE("Buffer Opaque Format");
+        auto shot = screenshot();
+        shot->expectColor(crop, Color::BLACK);
+    }
+
+    buffer = new GraphicBuffer(width, height, PIXEL_FORMAT_RGBA_8888, 1,
+                               BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+                                       BufferUsage::COMPOSER_OVERLAY,
+                               "test");
+    ASSERT_NO_FATAL_FAILURE(
+            TransactionUtils::fillGraphicBufferColor(buffer, crop, Color::TRANSPARENT));
+
+    if (mLayerType == ISurfaceComposerClient::eFXSurfaceBufferQueue) {
+        Surface::attachAndQueueBufferWithDataspace(surface.get(), buffer, ui::Dataspace::V0_SRGB);
+    } else {
+        Transaction().setBuffer(layer, buffer).apply();
+    }
+
+    {
+        SCOPED_TRACE("Buffer Transparent Format");
+        auto shot = screenshot();
+        shot->expectColor(crop, Color::RED);
+    }
+}
 } // namespace android
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp b/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp
index f8a5b40..06e8761 100644
--- a/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp
+++ b/services/surfaceflinger/tests/MultiDisplayLayerBounds_test.cpp
@@ -104,7 +104,7 @@
     // Verify color layer renders correctly on virtual display.
     ScreenCapture::captureScreen(&sc, mVirtualDisplay);
     sc->expectColor(Rect(10, 10, 40, 50), mExpectedColor);
-    sc->expectColor(Rect(1, 1, 9, 9), {0, 0, 0, 0});
+    sc->expectColor(Rect(1, 1, 9, 9), {0, 0, 0, 255});
 }
 
 TEST_F(MultiDisplayLayerBoundsTest, RenderLayerInMirroredVirtualDisplay) {
diff --git a/services/surfaceflinger/tests/TransactionTestHarnesses.h b/services/surfaceflinger/tests/TransactionTestHarnesses.h
index 040852f..f0af363 100644
--- a/services/surfaceflinger/tests/TransactionTestHarnesses.h
+++ b/services/surfaceflinger/tests/TransactionTestHarnesses.h
@@ -88,13 +88,14 @@
 
     sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height,
                                    uint32_t flags = 0, SurfaceControl* parent = nullptr,
-                                   uint32_t* outTransformHint = nullptr) {
+                                   uint32_t* outTransformHint = nullptr,
+                                   PixelFormat format = PIXEL_FORMAT_RGBA_8888) {
         // if the flags already have a layer type specified, return an error
         if (flags & ISurfaceComposerClient::eFXSurfaceMask) {
             return nullptr;
         }
         return LayerTransactionTest::createLayer(name, width, height, flags | mLayerType, parent,
-                                                 outTransformHint);
+                                                 outTransformHint, format);
     }
 
     void fillLayerColor(const sp<SurfaceControl>& layer, const Color& color, int32_t bufferWidth,
diff --git a/services/surfaceflinger/tests/hwc2/Android.bp b/services/surfaceflinger/tests/hwc2/Android.bp
deleted file mode 100644
index 1c8e396..0000000
--- a/services/surfaceflinger/tests/hwc2/Android.bp
+++ /dev/null
@@ -1,55 +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.
-
-cc_test {
-    name: "test-hwc2",
-    defaults: ["surfaceflinger_defaults"],
-    cflags: [
-        "-DEGL_EGLEXT_PROTOTYPES",
-        "-DGL_GLEXT_PROTOTYPES",
-        "-fno-builtin",
-        "-fstack-protector-all",
-        "-g",
-        "-Wextra",
-    ],
-    srcs: [
-        "Hwc2Test.cpp",
-        "Hwc2TestProperties.cpp",
-        "Hwc2TestLayer.cpp",
-        "Hwc2TestLayers.cpp",
-        "Hwc2TestBuffer.cpp",
-        "Hwc2TestClientTarget.cpp",
-        "Hwc2TestVirtualDisplay.cpp",
-        "Hwc2TestPixelComparator.cpp",
-    ],
-    static_libs: [
-        "libadf",
-        "libadfhwc",
-        "libbase",
-        "libmath",
-    ],
-    shared_libs: [
-        "android.hardware.graphics.common@1.1",
-        "libcutils",
-        "libEGL",
-        "libGLESv2",
-        "libgui",
-        "libhardware",
-        "libhwui",
-        "liblog",
-        "libsync",
-        "libui",
-        "libutils",
-    ],
-}
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2Test.cpp b/services/surfaceflinger/tests/hwc2/Hwc2Test.cpp
deleted file mode 100644
index f9a1fe9..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2Test.cpp
+++ /dev/null
@@ -1,4779 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-
-#include <array>
-#include <unordered_set>
-#include <unordered_map>
-#include <gtest/gtest.h>
-#include <dlfcn.h>
-#include <android-base/unique_fd.h>
-#include <hardware/hardware.h>
-#include <sync/sync.h>
-#include <ui/GraphicTypes.h>
-
-#define HWC2_INCLUDE_STRINGIFICATION
-#define HWC2_USE_CPP11
-#include <hardware/hwcomposer2.h>
-#undef HWC2_INCLUDE_STRINGIFICATION
-#undef HWC2_USE_CPP11
-
-#include "Hwc2TestLayer.h"
-#include "Hwc2TestLayers.h"
-#include "Hwc2TestClientTarget.h"
-#include "Hwc2TestVirtualDisplay.h"
-
-using android::ui::ColorMode;
-using android::ui::Dataspace;
-
-void hwc2TestHotplugCallback(hwc2_callback_data_t callbackData,
-        hwc2_display_t display, int32_t connected);
-void hwc2TestVsyncCallback(hwc2_callback_data_t callbackData,
-        hwc2_display_t display, int64_t timestamp);
-
-class Hwc2Test : public testing::Test {
-public:
-
-    virtual void SetUp()
-    {
-        hw_module_t const* hwc2Module;
-
-        int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &hwc2Module);
-        ASSERT_GE(err, 0) << "failed to get hwc hardware module: "
-                << strerror(-err);
-
-        /* The following method will fail if you have not run
-         * "adb shell stop" */
-        err = hwc2_open(hwc2Module, &mHwc2Device);
-        ASSERT_GE(err, 0) << "failed to open hwc hardware module: "
-                << strerror(-err);
-
-        populateDisplays();
-    }
-
-    virtual void TearDown()
-    {
-
-        for (auto itr = mLayers.begin(); itr != mLayers.end();) {
-            hwc2_display_t display = itr->first;
-            hwc2_layer_t layer = itr->second;
-            itr++;
-            /* Destroys and removes the layer from mLayers */
-            destroyLayer(display, layer);
-        }
-
-        for (auto itr = mActiveDisplays.begin(); itr != mActiveDisplays.end();) {
-            hwc2_display_t display = *itr;
-            itr++;
-            /* Sets power mode to off and removes the display from
-             * mActiveDisplays */
-            setPowerMode(display, HWC2_POWER_MODE_OFF);
-        }
-
-        for (auto itr = mVirtualDisplays.begin(); itr != mVirtualDisplays.end();) {
-            hwc2_display_t display = *itr;
-            itr++;
-            /* Destroys virtual displays */
-            destroyVirtualDisplay(display);
-        }
-
-        if (mHwc2Device)
-            hwc2_close(mHwc2Device);
-    }
-
-    void registerCallback(hwc2_callback_descriptor_t descriptor,
-            hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_REGISTER_CALLBACK>(
-                getFunction(HWC2_FUNCTION_REGISTER_CALLBACK));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, descriptor,
-                callbackData, pointer));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to register callback";
-        }
-    }
-
-    void getDisplayType(hwc2_display_t display, hwc2_display_type_t* outType,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_DISPLAY_TYPE>(
-                getFunction(HWC2_FUNCTION_GET_DISPLAY_TYPE));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                    reinterpret_cast<int32_t*>(outType)));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get display type";
-        }
-    }
-
-    /* If the populateDisplays function is still receiving displays and the
-     * display is connected, the display handle is stored in mDisplays. */
-    void hotplugCallback(hwc2_display_t display, int32_t connected)
-    {
-        std::lock_guard<std::mutex> lock(mHotplugMutex);
-
-        if (mHotplugStatus != Hwc2TestHotplugStatus::Receiving)
-            return;
-
-        if (connected == HWC2_CONNECTION_CONNECTED)
-            mDisplays.insert(display);
-
-        mHotplugCv.notify_all();
-    }
-
-    void createLayer(hwc2_display_t display, hwc2_layer_t* outLayer,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_CREATE_LAYER>(
-                getFunction(HWC2_FUNCTION_CREATE_LAYER));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                outLayer));
-
-        if (err == HWC2_ERROR_NONE)
-            mLayers.insert(std::make_pair(display, *outLayer));
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to create layer";
-        }
-    }
-
-    void destroyLayer(hwc2_display_t display, hwc2_layer_t layer,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_DESTROY_LAYER>(
-                getFunction(HWC2_FUNCTION_DESTROY_LAYER));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer));
-
-        if (err == HWC2_ERROR_NONE)
-            mLayers.erase(std::make_pair(display, layer));
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to destroy layer "
-                    << layer;
-        }
-    }
-
-    void getDisplayAttribute(hwc2_display_t display, hwc2_config_t config,
-            hwc2_attribute_t attribute, int32_t* outValue,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
-                getFunction(HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, config,
-                attribute, outValue));
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get display attribute "
-                    << getAttributeName(attribute) << " for config " << config;
-        }
-    }
-
-    void getDisplayConfigs(hwc2_display_t display,
-            std::vector<hwc2_config_t>* outConfigs,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_DISPLAY_CONFIGS>(
-                getFunction(HWC2_FUNCTION_GET_DISPLAY_CONFIGS));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        uint32_t numConfigs = 0;
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                &numConfigs, nullptr));
-
-        if (err == HWC2_ERROR_NONE) {
-            outConfigs->resize(numConfigs);
-
-            err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                    &numConfigs, outConfigs->data()));
-        }
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get configs for"
-                    " display " << display;
-        }
-    }
-
-    void getActiveConfig(hwc2_display_t display, hwc2_config_t* outConfig,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_ACTIVE_CONFIG>(
-                getFunction(HWC2_FUNCTION_GET_ACTIVE_CONFIG));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                outConfig));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get active config on"
-                    " display " << display;
-        }
-    }
-
-    void setActiveConfig(hwc2_display_t display, hwc2_config_t config,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_ACTIVE_CONFIG>(
-                getFunction(HWC2_FUNCTION_SET_ACTIVE_CONFIG));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, config));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set active config "
-                    << config;
-        }
-    }
-
-    void getDozeSupport(hwc2_display_t display, int32_t* outSupport,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_DOZE_SUPPORT>(
-                getFunction(HWC2_FUNCTION_GET_DOZE_SUPPORT));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                outSupport));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get doze support on"
-                    " display " << display;
-        }
-    }
-
-    void setPowerMode(hwc2_display_t display, hwc2_power_mode_t mode,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_POWER_MODE>(
-                getFunction(HWC2_FUNCTION_SET_POWER_MODE));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                mode));
-        if (outErr) {
-            *outErr = err;
-            if (err != HWC2_ERROR_NONE)
-                return;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set power mode "
-                    << getPowerModeName(mode) << " on display " << display;
-        }
-
-        if (mode == HWC2_POWER_MODE_OFF) {
-            mActiveDisplays.erase(display);
-        } else {
-            mActiveDisplays.insert(display);
-        }
-    }
-
-    void setVsyncEnabled(hwc2_display_t display, hwc2_vsync_t enabled,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_VSYNC_ENABLED>(
-                getFunction(HWC2_FUNCTION_SET_VSYNC_ENABLED));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                enabled));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set vsync enabled "
-                    << getVsyncName(enabled);
-        }
-    }
-
-    void vsyncCallback(hwc2_display_t display, int64_t timestamp)
-    {
-        std::lock_guard<std::mutex> lock(mVsyncMutex);
-        mVsyncDisplay = display;
-        mVsyncTimestamp = timestamp;
-        mVsyncCv.notify_all();
-    }
-
-    void getDisplayName(hwc2_display_t display, std::string* outName,
-                hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_DISPLAY_NAME>(
-                getFunction(HWC2_FUNCTION_GET_DISPLAY_NAME));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        uint32_t size = 0;
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, &size,
-                nullptr));
-
-        if (err == HWC2_ERROR_NONE) {
-            std::vector<char> name(size);
-
-            err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, &size,
-                    name.data()));
-
-            outName->assign(name.data());
-        }
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get display name for "
-                    << display;
-        }
-    }
-
-    void setLayerCompositionType(hwc2_display_t display, hwc2_layer_t layer,
-            hwc2_composition_t composition, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
-                composition));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer composition"
-                    " type " << getCompositionName(composition);
-        }
-    }
-
-    void setCursorPosition(hwc2_display_t display, hwc2_layer_t layer,
-            int32_t x, int32_t y, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_CURSOR_POSITION>(
-                getFunction(HWC2_FUNCTION_SET_CURSOR_POSITION));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer, x,
-                y));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_TRUE((err == HWC2_ERROR_NONE) ||
-                (err == HWC2_ERROR_BAD_LAYER)) <<
-                "failed to set cursor position";
-        }
-    }
-
-    void setLayerBlendMode(hwc2_display_t display, hwc2_layer_t layer,
-            hwc2_blend_mode_t mode, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_BLEND_MODE>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_BLEND_MODE));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
-                mode));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer blend mode "
-                    << getBlendModeName(mode);
-        }
-    }
-
-    void setLayerBuffer(hwc2_display_t display, hwc2_layer_t layer,
-            buffer_handle_t buffer, int32_t acquireFence,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_BUFFER>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_BUFFER));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
-                buffer, acquireFence));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer buffer";
-        }
-    }
-
-    void setLayerColor(hwc2_display_t display, hwc2_layer_t layer,
-            hwc_color_t color, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_COLOR>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_COLOR));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
-                color));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer color";
-        }
-    }
-
-    void setLayerDataspace(hwc2_display_t display, hwc2_layer_t layer,
-            Dataspace dataspace, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_DATASPACE>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_DATASPACE));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                layer, static_cast<int>(dataspace)));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer dataspace";
-        }
-    }
-
-    void setLayerDisplayFrame(hwc2_display_t display, hwc2_layer_t layer,
-            const hwc_rect_t& displayFrame, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
-                displayFrame));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer display"
-                    " frame";
-        }
-    }
-
-    void setLayerPlaneAlpha(hwc2_display_t display, hwc2_layer_t layer,
-            float alpha, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
-                alpha));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer plane alpha "
-                    << alpha;
-        }
-    }
-
-    void setLayerSourceCrop(hwc2_display_t display, hwc2_layer_t layer,
-            const hwc_frect_t& sourceCrop, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_SOURCE_CROP));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
-                sourceCrop));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer source crop";
-        }
-    }
-
-    void setLayerSurfaceDamage(hwc2_display_t display, hwc2_layer_t layer,
-            const hwc_region_t& surfaceDamage, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
-                surfaceDamage));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer surface"
-                    " damage";
-        }
-    }
-
-    void setLayerTransform(hwc2_display_t display, hwc2_layer_t layer,
-            hwc_transform_t transform, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_TRANSFORM>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_TRANSFORM));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
-                transform));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer transform "
-                    << getTransformName(transform);
-        }
-    }
-
-    void setLayerVisibleRegion(hwc2_display_t display, hwc2_layer_t layer,
-            const hwc_region_t& visibleRegion, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
-                visibleRegion));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer visible"
-                    " region";
-        }
-    }
-
-    void setLayerZOrder(hwc2_display_t display, hwc2_layer_t layer,
-            uint32_t zOrder, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_LAYER_Z_ORDER>(
-                getFunction(HWC2_FUNCTION_SET_LAYER_Z_ORDER));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, layer,
-                zOrder));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set layer z order "
-                    << zOrder;
-        }
-    }
-
-    void validateDisplay(hwc2_display_t display, uint32_t* outNumTypes,
-            uint32_t* outNumRequests, hwc2_error_t* outErr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_VALIDATE_DISPLAY>(
-                getFunction(HWC2_FUNCTION_VALIDATE_DISPLAY));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        *outErr = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                outNumTypes, outNumRequests));
-    }
-
-    void validateDisplay(hwc2_display_t display, uint32_t* outNumTypes,
-            uint32_t* outNumRequests, bool* outHasChanges)
-    {
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        EXPECT_NO_FATAL_FAILURE(validateDisplay(display, outNumTypes,
-                outNumRequests, &err));
-
-        if (err != HWC2_ERROR_HAS_CHANGES) {
-            *outHasChanges = false;
-            EXPECT_EQ(err, HWC2_ERROR_NONE) << "failed to validate display";
-        } else {
-            *outHasChanges = true;
-        }
-    }
-
-    void getDisplayRequests(hwc2_display_t display,
-            hwc2_display_request_t* outDisplayRequests,
-            std::vector<hwc2_layer_t>* outLayers,
-            std::vector<hwc2_layer_request_t>* outLayerRequests,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_DISPLAY_REQUESTS>(
-                getFunction(HWC2_FUNCTION_GET_DISPLAY_REQUESTS));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        uint32_t numElements = 0;
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                reinterpret_cast<int32_t*>(outDisplayRequests), &numElements,
-                nullptr, nullptr));
-
-        if (err == HWC2_ERROR_NONE && numElements > 0) {
-            outLayers->resize(numElements);
-            outLayerRequests->resize(numElements);
-
-            err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                    reinterpret_cast<int32_t*>(outDisplayRequests), &numElements,
-                    reinterpret_cast<uint64_t*>(outLayers->data()),
-                    reinterpret_cast<int32_t*>(outLayerRequests->data())));
-        }
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get display requests";
-        }
-    }
-
-    void handleRequests(hwc2_display_t display,
-            const std::vector<hwc2_layer_t>& layers, uint32_t numRequests,
-            std::set<hwc2_layer_t>* outClearLayers = nullptr,
-            bool* outFlipClientTarget = nullptr)
-    {
-        hwc2_display_request_t displayRequest =
-                static_cast<hwc2_display_request_t>(0);
-        std::vector<hwc2_layer_t> requestedLayers;
-        std::vector<hwc2_layer_request_t> requests;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayRequests(display, &displayRequest,
-                &requestedLayers, &requests));
-
-        EXPECT_EQ(numRequests, requests.size()) << "validate returned "
-                << numRequests << " requests and get display requests returned "
-                << requests.size() << " requests";
-
-        for (size_t i = 0; i < requests.size(); i++) {
-            hwc2_layer_t requestedLayer = requestedLayers.at(i);
-            hwc2_layer_request_t request = requests.at(i);
-
-            EXPECT_EQ(std::count(layers.begin(), layers.end(), requestedLayer),
-                    1) << "get display requests returned an unknown layer";
-            EXPECT_NE(request, 0) << "returned empty request for layer "
-                    << requestedLayer;
-
-            if (outClearLayers && request
-                    == HWC2_LAYER_REQUEST_CLEAR_CLIENT_TARGET)
-                outClearLayers->insert(requestedLayer);
-        }
-
-        if (outFlipClientTarget)
-            *outFlipClientTarget = displayRequest
-                    & HWC2_DISPLAY_REQUEST_FLIP_CLIENT_TARGET;
-    }
-
-    void getChangedCompositionTypes(hwc2_display_t display,
-            std::vector<hwc2_layer_t>* outLayers,
-            std::vector<hwc2_composition_t>* outTypes,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
-                getFunction(HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        uint32_t numElements = 0;
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                &numElements, nullptr, nullptr));
-
-        if (err == HWC2_ERROR_NONE && numElements > 0) {
-            outLayers->resize(numElements);
-            outTypes->resize(numElements);
-
-            err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                    &numElements, reinterpret_cast<uint64_t*>(outLayers->data()),
-                    reinterpret_cast<int32_t*>(outTypes->data())));
-        }
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get changed"
-                    " composition types";
-        }
-    }
-
-    void handleCompositionChanges(hwc2_display_t display,
-            const Hwc2TestLayers& testLayers,
-            const std::vector<hwc2_layer_t>& layers, uint32_t numTypes,
-            std::set<hwc2_layer_t>* outClientLayers = nullptr)
-    {
-        std::vector<hwc2_layer_t> changedLayers;
-        std::vector<hwc2_composition_t> types;
-
-        ASSERT_NO_FATAL_FAILURE(getChangedCompositionTypes(display,
-                &changedLayers, &types));
-
-        EXPECT_EQ(numTypes, types.size()) << "validate returned "
-                << numTypes << " types and get changed composition types"
-                " returned " << types.size() << " types";
-
-        for (size_t i = 0; i < types.size(); i++) {
-
-            auto layer = std::find(layers.begin(), layers.end(),
-                    changedLayers.at(i));
-
-            EXPECT_TRUE(layer != layers.end() || !testLayers.contains(*layer))
-                    << "get changed composition types returned an unknown layer";
-
-            hwc2_composition_t requestedType = testLayers.getComposition(*layer);
-            hwc2_composition_t returnedType = types.at(i);
-
-            EXPECT_NE(returnedType, HWC2_COMPOSITION_INVALID) << "get changed"
-                    " composition types returned invalid composition";
-
-            switch (requestedType) {
-            case HWC2_COMPOSITION_CLIENT:
-                EXPECT_TRUE(false) << getCompositionName(returnedType)
-                        << " cannot be changed";
-                break;
-            case HWC2_COMPOSITION_DEVICE:
-            case HWC2_COMPOSITION_SOLID_COLOR:
-                EXPECT_EQ(returnedType, HWC2_COMPOSITION_CLIENT)
-                        << "composition of type "
-                        << getCompositionName(requestedType)
-                        << " can only be changed to "
-                        << getCompositionName(HWC2_COMPOSITION_CLIENT);
-                break;
-            case HWC2_COMPOSITION_CURSOR:
-            case HWC2_COMPOSITION_SIDEBAND:
-                EXPECT_TRUE(returnedType == HWC2_COMPOSITION_CLIENT
-                        || returnedType == HWC2_COMPOSITION_DEVICE)
-                        << "composition of type "
-                        << getCompositionName(requestedType)
-                        << " can only be changed to "
-                        << getCompositionName(HWC2_COMPOSITION_CLIENT) << " or "
-                        << getCompositionName(HWC2_COMPOSITION_DEVICE);
-                break;
-            default:
-                EXPECT_TRUE(false) << "unknown type "
-                        << getCompositionName(requestedType);
-                break;
-            }
-
-            if (outClientLayers)
-                if (returnedType == HWC2_COMPOSITION_CLIENT)
-                    outClientLayers->insert(*layer);
-        }
-
-        if (outClientLayers) {
-            for (auto layer : layers) {
-                if (testLayers.getComposition(layer) == HWC2_COMPOSITION_CLIENT)
-                    outClientLayers->insert(layer);
-            }
-        }
-    }
-
-    void acceptDisplayChanges(hwc2_display_t display,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
-                getFunction(HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to accept display changes";
-        }
-    }
-
-    void getClientTargetSupport(hwc2_display_t display, int32_t width,
-            int32_t height, android_pixel_format_t format,
-            Dataspace dataspace, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
-                getFunction(HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, width,
-                height, format, static_cast<int>(dataspace)));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get client target"
-                    " support";
-        }
-    }
-
-    void setClientTarget(hwc2_display_t display, buffer_handle_t handle,
-            int32_t acquireFence, Dataspace dataspace,
-            hwc_region_t damage, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_CLIENT_TARGET>(
-                getFunction(HWC2_FUNCTION_SET_CLIENT_TARGET));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, handle,
-                acquireFence, static_cast<int>(dataspace), damage));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set client target";
-        }
-    }
-
-    void presentDisplay(hwc2_display_t display, int32_t* outPresentFence,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_PRESENT_DISPLAY>(
-                getFunction(HWC2_FUNCTION_PRESENT_DISPLAY));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                outPresentFence));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to present display";
-        }
-    }
-
-    void getReleaseFences(hwc2_display_t display,
-            std::vector<hwc2_layer_t>* outLayers,
-            std::vector<int32_t>* outFences, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_RELEASE_FENCES>(
-                getFunction(HWC2_FUNCTION_GET_RELEASE_FENCES));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        uint32_t numElements = 0;
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                &numElements, nullptr, nullptr));
-
-        if (err == HWC2_ERROR_NONE) {
-            outLayers->resize(numElements);
-            outFences->resize(numElements);
-
-            err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                    &numElements, outLayers->data(), outFences->data()));
-        }
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get release fences";
-        }
-    }
-
-    void getColorModes(hwc2_display_t display,
-            std::vector<ColorMode>* outColorModes,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_COLOR_MODES>(
-                getFunction(HWC2_FUNCTION_GET_COLOR_MODES));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        uint32_t numColorModes = 0;
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                &numColorModes, nullptr));
-        if (err == HWC2_ERROR_NONE) {
-            outColorModes->resize(numColorModes);
-
-            err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                    &numColorModes,
-                    reinterpret_cast<int32_t*>(outColorModes->data())));
-        }
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get color modes for"
-                    " display " << display;
-        }
-    }
-
-    void setColorMode(hwc2_display_t display, ColorMode colorMode,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_COLOR_MODE>(
-                getFunction(HWC2_FUNCTION_SET_COLOR_MODE));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                static_cast<int32_t>(colorMode)));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set color mode "
-                    << static_cast<int>(colorMode);
-        }
-    }
-
-    void getHdrCapabilities(hwc2_display_t display,
-            std::vector<android_hdr_t>* outTypes, float* outMaxLuminance,
-            float* outMaxAverageLuminance, float* outMinLuminance,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_HDR_CAPABILITIES>(
-                getFunction(HWC2_FUNCTION_GET_HDR_CAPABILITIES));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        uint32_t numTypes = 0;
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                &numTypes, nullptr, outMaxLuminance, outMaxAverageLuminance,
-                outMinLuminance));
-
-        if (err == HWC2_ERROR_NONE) {
-            outTypes->resize(numTypes);
-
-            err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, &numTypes,
-                    reinterpret_cast<int32_t*>(outTypes->data()), outMaxLuminance,
-                    outMaxAverageLuminance, outMinLuminance));
-        }
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to get hdr capabilities"
-                    " for display " << display;
-        }
-    }
-
-    void setColorTransform(hwc2_display_t display,
-            const std::array<float, 16>& matrix, android_color_transform_t hint,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_COLOR_TRANSFORM>(
-                getFunction(HWC2_FUNCTION_SET_COLOR_TRANSFORM));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display,
-                matrix.data(), hint));
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set color transform "
-                    << hint;
-        }
-    }
-
-    void createVirtualDisplay(uint32_t width, uint32_t height,
-            android_pixel_format_t* outFormat, hwc2_display_t* outDisplay,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
-                getFunction(HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, width, height,
-                reinterpret_cast<int32_t*>(outFormat), outDisplay));
-
-        if (err == HWC2_ERROR_NONE)
-            mVirtualDisplays.insert(*outDisplay);
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to create virtual display";
-        }
-    }
-
-    void destroyVirtualDisplay(hwc2_display_t display,
-            hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
-                getFunction(HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display));
-
-        if (err == HWC2_ERROR_NONE)
-            mVirtualDisplays.erase(display);
-
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to destroy virtual display";
-        }
-    }
-
-    void getMaxVirtualDisplayCount(uint32_t* outMaxCnt)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
-                getFunction(HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        *outMaxCnt = pfn(mHwc2Device);
-    }
-
-    void setOutputBuffer(hwc2_display_t display, buffer_handle_t buffer,
-            int32_t releaseFence, hwc2_error_t* outErr = nullptr)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_SET_OUTPUT_BUFFER>(
-                getFunction(HWC2_FUNCTION_SET_OUTPUT_BUFFER));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        auto err = static_cast<hwc2_error_t>(pfn(mHwc2Device, display, buffer,
-                releaseFence));
-        if (outErr) {
-            *outErr = err;
-        } else {
-            ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to set output buffer";
-        }
-    }
-
-    void dump(std::string* outBuffer)
-    {
-        auto pfn = reinterpret_cast<HWC2_PFN_DUMP>(
-                getFunction(HWC2_FUNCTION_DUMP));
-        ASSERT_TRUE(pfn) << "failed to get function";
-
-        uint32_t size = 0;
-
-        pfn(mHwc2Device, &size, nullptr);
-
-        std::vector<char> buffer(size);
-
-        pfn(mHwc2Device, &size, buffer.data());
-
-        outBuffer->assign(buffer.data());
-    }
-
-    void getBadDisplay(hwc2_display_t* outDisplay)
-    {
-        for (hwc2_display_t display = 0; display < UINT64_MAX; display++) {
-            if (mDisplays.count(display) == 0) {
-                *outDisplay = display;
-                return;
-            }
-        }
-        ASSERT_TRUE(false) << "Unable to find bad display. UINT64_MAX displays"
-                " are registered. This should never happen.";
-    }
-
-    void waitForVsync(hwc2_display_t* outDisplay = nullptr,
-            int64_t* outTimestamp = nullptr)
-    {
-        std::unique_lock<std::mutex> lock(mVsyncMutex);
-        ASSERT_EQ(mVsyncCv.wait_for(lock, std::chrono::seconds(3)),
-                std::cv_status::no_timeout) << "timed out attempting to get"
-                " vsync callback";
-        if (outDisplay)
-            *outDisplay = mVsyncDisplay;
-        if (outTimestamp)
-            *outTimestamp = mVsyncTimestamp;
-    }
-
-    void enableVsync(hwc2_display_t display)
-    {
-        ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_VSYNC, this,
-                reinterpret_cast<hwc2_function_pointer_t>(
-                hwc2TestVsyncCallback)));
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_ENABLE));
-    }
-
-    void disableVsync(hwc2_display_t display)
-    {
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_DISABLE));
-    }
-
-protected:
-    hwc2_function_pointer_t getFunction(hwc2_function_descriptor_t descriptor)
-    {
-        return mHwc2Device->getFunction(mHwc2Device, descriptor);
-    }
-
-    void getCapabilities(std::vector<hwc2_capability_t>* outCapabilities)
-    {
-        uint32_t num = 0;
-
-        mHwc2Device->getCapabilities(mHwc2Device, &num, nullptr);
-
-        outCapabilities->resize(num);
-
-        mHwc2Device->getCapabilities(mHwc2Device, &num,
-                reinterpret_cast<int32_t*>(outCapabilities->data()));
-    }
-
-    /* Registers a hotplug callback and waits for hotplug callbacks. This
-     * function will have no effect if called more than once. */
-    void populateDisplays()
-    {
-        /* Sets the hotplug status to receiving */
-        {
-            std::lock_guard<std::mutex> lock(mHotplugMutex);
-
-            if (mHotplugStatus != Hwc2TestHotplugStatus::Init)
-                return;
-            mHotplugStatus = Hwc2TestHotplugStatus::Receiving;
-        }
-
-        /* Registers the callback. This function call cannot be locked because
-         * a callback could happen on the same thread */
-        ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_HOTPLUG, this,
-                reinterpret_cast<hwc2_function_pointer_t>(
-                hwc2TestHotplugCallback)));
-
-        /* Waits for hotplug events. If a hotplug event has not come within 1
-         * second, stop waiting. */
-        std::unique_lock<std::mutex> lock(mHotplugMutex);
-
-        while (mHotplugCv.wait_for(lock, std::chrono::seconds(1)) !=
-                std::cv_status::timeout) { }
-
-        /* Sets the hotplug status to done. Future calls will have no effect */
-        mHotplugStatus = Hwc2TestHotplugStatus::Done;
-    }
-
-    /* NOTE: will create min(newlayerCnt, max supported layers) layers */
-    void createLayers(hwc2_display_t display,
-            std::vector<hwc2_layer_t>* outLayers, size_t newLayerCnt)
-    {
-        std::vector<hwc2_layer_t> newLayers;
-        hwc2_layer_t layer;
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        for (size_t i = 0; i < newLayerCnt; i++) {
-
-            EXPECT_NO_FATAL_FAILURE(createLayer(display, &layer, &err));
-            if (err == HWC2_ERROR_NO_RESOURCES)
-                break;
-            if (err != HWC2_ERROR_NONE) {
-                newLayers.clear();
-                ASSERT_EQ(err, HWC2_ERROR_NONE) << "failed to create layer";
-            }
-            newLayers.push_back(layer);
-        }
-
-        *outLayers = std::move(newLayers);
-    }
-
-    void destroyLayers(hwc2_display_t display,
-            std::vector<hwc2_layer_t>&& layers)
-    {
-        for (hwc2_layer_t layer : layers) {
-            EXPECT_NO_FATAL_FAILURE(destroyLayer(display, layer));
-        }
-    }
-
-    void getInvalidConfig(hwc2_display_t display, hwc2_config_t* outConfig)
-    {
-        std::vector<hwc2_config_t> configs;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-        hwc2_config_t CONFIG_MAX = UINT32_MAX;
-
-        ASSERT_LE(configs.size() - 1, CONFIG_MAX) << "every config value"
-                " (2^32 values) has been taken which shouldn't happen";
-
-        hwc2_config_t config;
-        for (config = 0; config < CONFIG_MAX; config++) {
-            if (std::count(configs.begin(), configs.end(), config) == 0)
-                break;
-        }
-
-        *outConfig = config;
-    }
-
-    /* Calls a set property function from Hwc2Test to set a property value from
-     * Hwc2TestLayer to hwc2_layer_t on hwc2_display_t */
-    using TestLayerPropertyFunction = void (*)(Hwc2Test* test,
-            hwc2_display_t display, hwc2_layer_t layer,
-            Hwc2TestLayer* testLayer, hwc2_error_t* outErr);
-
-    /* Calls a set property function from Hwc2Test to set property values from
-     * Hwc2TestLayers to hwc2_layer_t on hwc2_display_t */
-    using TestLayerPropertiesFunction = void (*)(Hwc2Test* test,
-            hwc2_display_t display, hwc2_layer_t layer,
-            Hwc2TestLayers* testLayers);
-
-    /* Calls a set property function from Hwc2Test to set a bad property value
-     * on hwc2_layer_t on hwc2_display_t */
-    using TestLayerPropertyBadLayerFunction = void (*)(Hwc2Test* test,
-            hwc2_display_t display, hwc2_layer_t layer,
-            Hwc2TestLayer* testLayer, hwc2_error_t* outErr);
-
-    /* Calls a set property function from Hwc2Test to set a bad property value
-     * on hwc2_layer_t on hwc2_display_t */
-    using TestLayerPropertyBadParameterFunction = void (*)(Hwc2Test* test,
-            hwc2_display_t display, hwc2_layer_t layer, hwc2_error_t* outErr);
-
-    /* Is called after a display is powered on and all layer properties have
-     * been set. It should be used to test functions such as validate, accepting
-     * changes, present, etc. */
-    using TestDisplayLayersFunction = void (*)(Hwc2Test* test,
-            hwc2_display_t display, const std::vector<hwc2_layer_t>& layers,
-            Hwc2TestLayers* testLayers);
-
-    /* It is called on an non validated display */
-    using TestDisplayNonValidatedLayersFunction = void (*)(Hwc2Test* test,
-            hwc2_display_t display, std::vector<hwc2_layer_t>* layers);
-
-    /* Tests client target support on a particular display and config */
-    using TestClientTargetSupportFunction = void (*)(Hwc2Test* test,
-            hwc2_display_t display,
-            const Hwc2TestClientTargetSupport& testClientTargetSupport);
-
-    /* Tests a particular active display config */
-    using TestActiveDisplayConfigFunction = void (*)(Hwc2Test* test,
-            hwc2_display_t display);
-
-    /* Tests a newly created virtual display */
-    using TestCreateVirtualDisplayFunction = void (*)(Hwc2Test* test,
-            hwc2_display_t display, Hwc2TestVirtualDisplay* testVirtualDisplay);
-
-    /* Advances a property of Hwc2TestLayer */
-    using AdvanceProperty = bool (*)(Hwc2TestLayer* testLayer);
-
-    /* Advances properties of Hwc2TestLayers */
-    using AdvanceProperties = bool (*)(Hwc2TestLayers* testLayer);
-
-    /* Advances properties of Hwc2TestClientTargetSupport */
-    using AdvanceClientTargetSupport = bool (*)(
-            Hwc2TestClientTargetSupport* testClientTargetSupport);
-
-    /* For each active display it cycles through each display config and tests
-     * each property value. It creates a layer, sets the property and then
-     * destroys the layer */
-    void setLayerProperty(Hwc2TestCoverage coverage,
-            TestLayerPropertyFunction function, AdvanceProperty advance)
-    {
-        for (auto display : mDisplays) {
-            std::vector<hwc2_config_t> configs;
-
-            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-            for (auto config : configs) {
-                hwc2_layer_t layer;
-                Area displayArea;
-
-                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-                ASSERT_NO_FATAL_FAILURE(getActiveDisplayArea(display,
-                        &displayArea));
-                Hwc2TestLayer testLayer(coverage, displayArea);
-
-                do {
-                    ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
-
-                    ASSERT_NO_FATAL_FAILURE(function(this, display, layer,
-                            &testLayer, nullptr));
-
-                    ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
-                } while (advance(&testLayer));
-            }
-        }
-    }
-
-    /* For each active display it cycles through each display config and tests
-     * each property value. It creates a layer, cycles through each property
-     * value and updates the layer property value and then destroys the layer */
-    void setLayerPropertyUpdate(Hwc2TestCoverage coverage,
-            TestLayerPropertyFunction function, AdvanceProperty advance)
-    {
-        for (auto display : mDisplays) {
-            std::vector<hwc2_config_t> configs;
-
-            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-            for (auto config : configs) {
-                hwc2_layer_t layer;
-                Area displayArea;
-
-                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-                ASSERT_NO_FATAL_FAILURE(getActiveDisplayArea(display,
-                        &displayArea));
-                Hwc2TestLayer testLayer(coverage, displayArea);
-
-                ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
-
-                do {
-                    ASSERT_NO_FATAL_FAILURE(function(this, display, layer,
-                            &testLayer, nullptr));
-                } while (advance(&testLayer));
-
-                ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
-            }
-        }
-    }
-
-    /* For each active display it cycles through each display config and tests
-     * each property value. It creates multiple layers, calls the
-     * TestLayerPropertiesFunction to set property values and then
-     * destroys the layers */
-    void setLayerProperties(Hwc2TestCoverage coverage, size_t layerCnt,
-            TestLayerPropertiesFunction function, AdvanceProperties advance)
-    {
-        for (auto display : mDisplays) {
-            std::vector<hwc2_config_t> configs;
-
-            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-            for (auto config : configs) {
-                std::vector<hwc2_layer_t> layers;
-                Area displayArea;
-
-                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-                ASSERT_NO_FATAL_FAILURE(getActiveDisplayArea(display,
-                        &displayArea));
-
-                ASSERT_NO_FATAL_FAILURE(createLayers(display, &layers, layerCnt));
-                Hwc2TestLayers testLayers(layers, coverage, displayArea);
-
-                do {
-                    for (auto layer : layers) {
-                        EXPECT_NO_FATAL_FAILURE(function(this, display, layer,
-                                &testLayers));
-                    }
-                } while (advance(&testLayers));
-
-                ASSERT_NO_FATAL_FAILURE(destroyLayers(display, std::move(layers)));
-            }
-        }
-    }
-
-    /* For each active display it cycles through each display config.
-     * 1) It attempts to set a valid property value to bad layer handle.
-     * 2) It creates a layer x and attempts to set a valid property value to
-     *    layer x + 1
-     * 3) It destroys the layer x and attempts to set a valid property value to
-     *    the destroyed layer x.
-     */
-    void setLayerPropertyBadLayer(Hwc2TestCoverage coverage,
-            TestLayerPropertyBadLayerFunction function)
-    {
-        for (auto display : mDisplays) {
-            std::vector<hwc2_config_t> configs;
-
-            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-            for (auto config : configs) {
-                hwc2_layer_t layer = 0;
-                Area displayArea;
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-                ASSERT_NO_FATAL_FAILURE(getActiveDisplayArea(display,
-                        &displayArea));
-                Hwc2TestLayer testLayer(coverage, displayArea);
-
-                ASSERT_NO_FATAL_FAILURE(function(this, display, layer,
-                        &testLayer, &err));
-                EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
-
-                ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
-
-                ASSERT_NO_FATAL_FAILURE(function(this, display, layer + 1,
-                        &testLayer, &err));
-                EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
-
-                ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
-
-                ASSERT_NO_FATAL_FAILURE(function(this, display, layer,
-                        &testLayer, &err));
-                EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
-            }
-        }
-    }
-
-    /* For each active display it cycles through each display config and tests
-     * each property value. It creates a layer, sets a bad property value and
-     * then destroys the layer */
-    void setLayerPropertyBadParameter(TestLayerPropertyBadParameterFunction function)
-    {
-        for (auto display : mDisplays) {
-            std::vector<hwc2_config_t> configs;
-
-            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-            for (auto config : configs) {
-                hwc2_layer_t layer;
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-
-                ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
-
-                ASSERT_NO_FATAL_FAILURE(function(this, display, layer, &err));
-                EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER) << "returned wrong"
-                        " error code";
-
-                ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
-            }
-        }
-    }
-
-    /* For each active display it powers on the display, cycles through each
-     * config and creates a set of layers with a certain amount of coverage.
-     * For each active display, for each config and for each set of layers,
-     * it calls the TestDisplayLayersFunction */
-    void displayLayers(Hwc2TestCoverage coverage, size_t layerCnt,
-            TestDisplayLayersFunction function)
-    {
-        for (auto display : mDisplays) {
-            std::vector<hwc2_config_t> configs;
-
-            ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-
-            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-            for (auto config : configs) {
-                Area displayArea;
-                std::vector<hwc2_layer_t> layers;
-
-                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-                ASSERT_NO_FATAL_FAILURE(getActiveDisplayArea(display, &displayArea));
-
-                ASSERT_NO_FATAL_FAILURE(createLayers(display, &layers, layerCnt));
-                Hwc2TestLayers testLayers(layers, coverage, displayArea);
-
-                do {
-                    bool skip;
-
-                    ASSERT_NO_FATAL_FAILURE(setLayerProperties(display, layers,
-                            &testLayers, &skip));
-                    if (!skip)
-                        EXPECT_NO_FATAL_FAILURE(function(this, display, layers,
-                                &testLayers));
-
-                } while (testLayers.advance());
-
-                ASSERT_NO_FATAL_FAILURE(destroyLayers(display,
-                        std::move(layers)));
-            }
-
-            ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-        }
-    }
-
-    /* For each active display, it calls the
-     * TestDisplayNonValidatedLayersFunction on a variety on non-validated
-     * layer combinations */
-    void displayNonValidatedLayers(size_t layerCnt,
-            TestDisplayNonValidatedLayersFunction function)
-    {
-        for (auto display : mDisplays) {
-            uint32_t numTypes, numRequests;
-            std::vector<hwc2_layer_t> layers;
-            bool hasChanges;
-
-            ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-
-            EXPECT_NO_FATAL_FAILURE(function(this, display, &layers));
-
-            ASSERT_NO_FATAL_FAILURE(createLayers(display, &layers, layerCnt));
-
-            EXPECT_NO_FATAL_FAILURE(function(this, display, &layers));
-
-            for (auto layer : layers) {
-                ASSERT_NO_FATAL_FAILURE(setLayerCompositionType(display, layer,
-                        HWC2_COMPOSITION_CLIENT));
-            }
-
-            EXPECT_NO_FATAL_FAILURE(function(this, display, &layers));
-
-            ASSERT_NO_FATAL_FAILURE(validateDisplay(display, &numTypes,
-                    &numRequests, &hasChanges));
-
-            for (auto layer : layers) {
-                ASSERT_NO_FATAL_FAILURE(setLayerCompositionType(display, layer,
-                        HWC2_COMPOSITION_DEVICE));
-            }
-
-            EXPECT_NO_FATAL_FAILURE(function(this, display, &layers));
-
-            ASSERT_NO_FATAL_FAILURE(destroyLayers(display, std::move(layers)));
-
-            EXPECT_NO_FATAL_FAILURE(function(this, display, &layers));
-
-            ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-        }
-    }
-
-    /* Test client target support on each config on each active display */
-    void setClientTargetSupport(Hwc2TestCoverage coverage,
-            TestClientTargetSupportFunction function,
-            AdvanceClientTargetSupport advance)
-    {
-        for (auto display : mDisplays) {
-            std::vector<hwc2_config_t> configs;
-
-            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-            for (auto config : configs) {
-                Area displayArea;
-
-                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-                ASSERT_NO_FATAL_FAILURE(getActiveDisplayArea(display,
-                        &displayArea));
-                Hwc2TestClientTargetSupport testClientTargetSupport(coverage,
-                        displayArea);
-
-                do {
-                    EXPECT_NO_FATAL_FAILURE(function(this, display,
-                            testClientTargetSupport));
-
-                } while (advance(&testClientTargetSupport));
-            }
-        }
-    }
-
-    /* Cycles through each config on each active display and calls
-     * a TestActiveDisplayConfigFunction */
-    void setActiveDisplayConfig(TestActiveDisplayConfigFunction function)
-    {
-        for (auto display : mDisplays) {
-            std::vector<hwc2_config_t> configs;
-
-            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-            for (auto config : configs) {
-                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-
-                EXPECT_NO_FATAL_FAILURE(function(this, display));
-            }
-        }
-    }
-
-    /* Creates a virtual display for testing */
-    void createVirtualDisplay(Hwc2TestCoverage coverage,
-            TestCreateVirtualDisplayFunction function)
-    {
-        Hwc2TestVirtualDisplay testVirtualDisplay(coverage);
-
-        do {
-            hwc2_display_t display;
-            hwc2_error_t err = HWC2_ERROR_NONE;
-
-            const UnsignedArea& dimension =
-                    testVirtualDisplay.getDisplayDimension();
-            android_pixel_format_t desiredFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-
-            ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(dimension.width,
-                    dimension.height, &desiredFormat, &display, &err));
-
-            EXPECT_TRUE(err == HWC2_ERROR_NONE || err == HWC2_ERROR_NO_RESOURCES
-                    || err == HWC2_ERROR_UNSUPPORTED)
-                    << "returned wrong error code";
-            EXPECT_GE(desiredFormat, 0) << "invalid format";
-
-            if (err != HWC2_ERROR_NONE)
-                continue;
-
-            EXPECT_NO_FATAL_FAILURE(function(this, display,
-                    &testVirtualDisplay));
-
-            ASSERT_NO_FATAL_FAILURE(destroyVirtualDisplay(display));
-
-        } while (testVirtualDisplay.advance());
-    }
-
-
-    void getActiveConfigAttribute(hwc2_display_t display,
-            hwc2_attribute_t attribute, int32_t* outValue)
-    {
-        hwc2_config_t config;
-        ASSERT_NO_FATAL_FAILURE(getActiveConfig(display, &config));
-        ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config,
-                attribute, outValue));
-        ASSERT_GE(*outValue, 0) << "failed to get valid "
-                << getAttributeName(attribute);
-    }
-
-    void getActiveDisplayArea(hwc2_display_t display, Area* displayArea)
-    {
-        ASSERT_NO_FATAL_FAILURE(getActiveConfigAttribute(display,
-                HWC2_ATTRIBUTE_WIDTH, &displayArea->width));
-        ASSERT_NO_FATAL_FAILURE(getActiveConfigAttribute(display,
-                HWC2_ATTRIBUTE_HEIGHT, &displayArea->height));
-    }
-
-    void closeFences(hwc2_display_t display, int32_t presentFence)
-    {
-        std::vector<hwc2_layer_t> layers;
-        std::vector<int32_t> fences;
-        const int msWait = 3000;
-
-        if (presentFence >= 0) {
-            ASSERT_GE(sync_wait(presentFence, msWait), 0);
-            close(presentFence);
-        }
-
-        ASSERT_NO_FATAL_FAILURE(getReleaseFences(display, &layers, &fences));
-        EXPECT_EQ(layers.size(), fences.size());
-
-        for (int32_t fence : fences) {
-            if (fence >= 0) {
-                EXPECT_GE(sync_wait(fence, msWait), 0);
-                close(fence);
-            }
-        }
-    }
-
-    void setLayerProperties(hwc2_display_t display, hwc2_layer_t layer,
-            Hwc2TestLayers* testLayers, bool* outSkip)
-    {
-        hwc2_composition_t composition;
-        buffer_handle_t handle = nullptr;
-        int32_t acquireFence;
-        hwc2_error_t err = HWC2_ERROR_NONE;
-        *outSkip = true;
-
-        if (!testLayers->contains(layer))
-            return;
-
-        composition = testLayers->getComposition(layer);
-
-        /* If the device cannot support a buffer format, then do not continue */
-        if ((composition == HWC2_COMPOSITION_DEVICE
-                || composition == HWC2_COMPOSITION_CURSOR)
-                && testLayers->getBuffer(layer, &handle, &acquireFence) < 0)
-            return;
-
-        EXPECT_NO_FATAL_FAILURE(setLayerCompositionType(display, layer,
-                composition, &err));
-        if (err == HWC2_ERROR_UNSUPPORTED)
-            EXPECT_TRUE(composition != HWC2_COMPOSITION_CLIENT
-                    && composition != HWC2_COMPOSITION_DEVICE);
-
-        const hwc_rect_t cursor = testLayers->getCursorPosition(layer);
-
-        EXPECT_NO_FATAL_FAILURE(setLayerBuffer(display, layer, handle,
-                acquireFence));
-        EXPECT_NO_FATAL_FAILURE(setLayerBlendMode(display, layer,
-                testLayers->getBlendMode(layer)));
-        EXPECT_NO_FATAL_FAILURE(setLayerColor(display, layer,
-                testLayers->getColor(layer)));
-        if (composition == HWC2_COMPOSITION_CURSOR)
-            EXPECT_NO_FATAL_FAILURE(setCursorPosition(display, layer,
-            cursor.left, cursor.top));
-        EXPECT_NO_FATAL_FAILURE(setLayerDataspace(display, layer,
-                testLayers->getDataspace(layer)));
-        EXPECT_NO_FATAL_FAILURE(setLayerDisplayFrame(display, layer,
-                testLayers->getDisplayFrame(layer)));
-        EXPECT_NO_FATAL_FAILURE(setLayerPlaneAlpha(display, layer,
-                testLayers->getPlaneAlpha(layer)));
-        EXPECT_NO_FATAL_FAILURE(setLayerSourceCrop(display, layer,
-                testLayers->getSourceCrop(layer)));
-        EXPECT_NO_FATAL_FAILURE(setLayerSurfaceDamage(display, layer,
-                testLayers->getSurfaceDamage(layer)));
-        EXPECT_NO_FATAL_FAILURE(setLayerTransform(display, layer,
-                testLayers->getTransform(layer)));
-        EXPECT_NO_FATAL_FAILURE(setLayerVisibleRegion(display, layer,
-                testLayers->getVisibleRegion(layer)));
-        EXPECT_NO_FATAL_FAILURE(setLayerZOrder(display, layer,
-                testLayers->getZOrder(layer)));
-
-        *outSkip = false;
-    }
-
-    void setLayerProperties(hwc2_display_t display,
-            const std::vector<hwc2_layer_t>& layers,
-            Hwc2TestLayers* testLayers, bool* outSkip)
-    {
-        for (auto layer : layers) {
-            EXPECT_NO_FATAL_FAILURE(setLayerProperties(display, layer,
-                    testLayers, outSkip));
-            if (*outSkip)
-                return;
-        }
-    }
-
-    void setClientTarget(hwc2_display_t display,
-            Hwc2TestClientTarget* testClientTarget,
-            const Hwc2TestLayers& testLayers,
-            const std::set<hwc2_layer_t>& clientLayers,
-            const std::set<hwc2_layer_t>& clearLayers, bool flipClientTarget,
-            const Area& displayArea)
-    {
-        Dataspace dataspace = Dataspace::UNKNOWN;
-        hwc_region_t damage = { };
-        buffer_handle_t handle;
-        int32_t acquireFence;
-
-        ASSERT_EQ(testClientTarget->getBuffer(testLayers, clientLayers,
-                clearLayers, flipClientTarget, displayArea, &handle,
-                &acquireFence), 0);
-        EXPECT_NO_FATAL_FAILURE(setClientTarget(display, handle, acquireFence,
-                dataspace, damage));
-    }
-
-    void presentDisplays(size_t layerCnt, Hwc2TestCoverage coverage,
-            const std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage>&
-            coverageExceptions, bool optimize)
-    {
-        for (auto display : mDisplays) {
-            std::vector<hwc2_config_t> configs;
-
-            ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-            ASSERT_NO_FATAL_FAILURE(enableVsync(display));
-
-            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-            for (auto config : configs) {
-                Area displayArea;
-                std::vector<hwc2_layer_t> layers;
-
-                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-                ASSERT_NO_FATAL_FAILURE(getActiveDisplayArea(display,
-                        &displayArea));
-
-                ASSERT_NO_FATAL_FAILURE(createLayers(display, &layers, layerCnt));
-                Hwc2TestLayers testLayers(layers, coverage, displayArea,
-                        coverageExceptions);
-
-                if (optimize && !testLayers.optimizeLayouts())
-                    continue;
-
-                std::set<hwc2_layer_t> clientLayers;
-                std::set<hwc2_layer_t> clearLayers;
-                Hwc2TestClientTarget testClientTarget;
-
-                do {
-                    uint32_t numTypes, numRequests;
-                    bool hasChanges, skip;
-                    bool flipClientTarget;
-                    int32_t presentFence;
-
-                    ASSERT_NO_FATAL_FAILURE(setLayerProperties(display, layers,
-                            &testLayers, &skip));
-                    if (skip)
-                        continue;
-
-                    ASSERT_NO_FATAL_FAILURE(validateDisplay(display, &numTypes,
-                            &numRequests, &hasChanges));
-                    if (hasChanges)
-                        EXPECT_LE(numTypes, static_cast<uint32_t>(layers.size()))
-                                << "wrong number of requests";
-
-                    ASSERT_NO_FATAL_FAILURE(handleCompositionChanges(display,
-                            testLayers, layers, numTypes, &clientLayers));
-                    ASSERT_NO_FATAL_FAILURE(handleRequests(display, layers,
-                            numRequests, &clearLayers, &flipClientTarget));
-                    ASSERT_NO_FATAL_FAILURE(setClientTarget(display,
-                            &testClientTarget, testLayers, clientLayers,
-                            clearLayers, flipClientTarget, displayArea));
-                    ASSERT_NO_FATAL_FAILURE(acceptDisplayChanges(display));
-
-                    ASSERT_NO_FATAL_FAILURE(waitForVsync());
-
-                    EXPECT_NO_FATAL_FAILURE(presentDisplay(display,
-                            &presentFence));
-
-                    ASSERT_NO_FATAL_FAILURE(closeFences(display, presentFence));
-
-                } while (testLayers.advance());
-
-                ASSERT_NO_FATAL_FAILURE(destroyLayers(display,
-                        std::move(layers)));
-            }
-
-            ASSERT_NO_FATAL_FAILURE(disableVsync(display));
-            ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-        }
-    }
-
-    void createAndPresentVirtualDisplay(size_t layerCnt,
-            Hwc2TestCoverage coverage,
-            const std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage>&
-            coverageExceptions)
-    {
-        Hwc2TestVirtualDisplay testVirtualDisplay(coverage);
-        hwc2_display_t display;
-        android_pixel_format_t desiredFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-
-        do {
-            // Items dependent on the display dimensions
-            hwc2_error_t err = HWC2_ERROR_NONE;
-            const UnsignedArea& dimension =
-                    testVirtualDisplay.getDisplayDimension();
-            ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(dimension.width,
-                    dimension.height, &desiredFormat, &display, &err));
-            ASSERT_TRUE(err == HWC2_ERROR_NONE)
-                    << "Cannot allocate virtual display";
-
-            ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-            ASSERT_NO_FATAL_FAILURE(enableVsync(display));
-
-            std::vector<hwc2_config_t> configs;
-            ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-            for (auto config : configs) {
-                ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-
-                Area displayArea;
-                ASSERT_NO_FATAL_FAILURE(getActiveDisplayArea(display,
-                        &displayArea));
-
-                std::vector<hwc2_layer_t> layers;
-                ASSERT_NO_FATAL_FAILURE(createLayers(display, &layers,
-                        layerCnt));
-                Hwc2TestLayers testLayers(layers, coverage, displayArea,
-                        coverageExceptions);
-
-                /*
-                 * Layouts that do not cover an entire virtual display will
-                 * cause undefined behavior.
-                 * Enable optimizeLayouts to avoid this.
-                 */
-                testLayers.optimizeLayouts();
-                do {
-                    // Items dependent on the testLayers properties
-                    std::set<hwc2_layer_t> clientLayers;
-                    std::set<hwc2_layer_t> clearLayers;
-                    uint32_t numTypes, numRequests;
-                    bool hasChanges, skip;
-                    bool flipClientTarget;
-                    int32_t presentFence;
-                    Hwc2TestClientTarget testClientTarget;
-                    buffer_handle_t outputBufferHandle;
-                    android::base::unique_fd outputBufferReleaseFence;
-
-                    ASSERT_NO_FATAL_FAILURE(setLayerProperties(display, layers,
-                            &testLayers, &skip));
-
-                    if (skip)
-                        continue;
-
-                    ASSERT_NO_FATAL_FAILURE(validateDisplay(display, &numTypes,
-                            &numRequests, &hasChanges));
-
-                    if (hasChanges)
-                        EXPECT_LE(numTypes, static_cast<uint32_t>(layers.size()))
-                                << "wrong number of requests";
-
-                    ASSERT_NO_FATAL_FAILURE(handleCompositionChanges(display,
-                            testLayers, layers, numTypes, &clientLayers));
-
-                    ASSERT_NO_FATAL_FAILURE(handleRequests(display, layers,
-                            numRequests, &clearLayers, &flipClientTarget));
-                    ASSERT_NO_FATAL_FAILURE(setClientTarget(display,
-                            &testClientTarget, testLayers, clientLayers,
-                            clearLayers, flipClientTarget, displayArea));
-                    ASSERT_NO_FATAL_FAILURE(acceptDisplayChanges(display));
-
-                    ASSERT_EQ(testVirtualDisplay.getOutputBuffer(
-                            &outputBufferHandle, &outputBufferReleaseFence), 0);
-                    ASSERT_NO_FATAL_FAILURE(setOutputBuffer(display,
-                            outputBufferHandle, outputBufferReleaseFence));
-
-                    EXPECT_NO_FATAL_FAILURE(presentDisplay(display,
-                            &presentFence));
-                    ASSERT_NO_FATAL_FAILURE(closeFences(display, presentFence));
-
-                    ASSERT_EQ(testVirtualDisplay.verifyOutputBuffer(&testLayers,
-                            &layers, &clearLayers), 0);
-
-                    /*
-                     * Upscaling the image causes minor pixel differences.
-                     * Work around this by using some threshold.
-                     *
-                     * Fail test if we are off by more than 1% of our
-                     * pixels.
-                     */
-                    ComparatorResult& comparatorResult = ComparatorResult::get();
-                    int threshold = (dimension.width * dimension.height) / 100;
-                    double diffPercent = (comparatorResult.getDifferentPixelCount() * 100.0) /
-                            (dimension.width * dimension.height);
-
-                    if (comparatorResult.getDifferentPixelCount() != 0)
-                        EXPECT_TRUE(false)
-                                << comparatorResult.getDifferentPixelCount() << " pixels ("
-                                << diffPercent << "%) are different.";
-
-                    if (comparatorResult.getDifferentPixelCount() > threshold) {
-                        EXPECT_TRUE(false)
-                                << "Mismatched pixel count exceeds threshold. "
-                                << "Writing buffers to file.";
-
-                        const ::testing::TestInfo* const test_info =
-                                ::testing::UnitTest::GetInstance()
-                                ->current_test_info();
-
-                        EXPECT_EQ(testVirtualDisplay.writeBuffersToFile(
-                                test_info->name()), 0)
-                                << "Failed to write buffers.";
-                    }
-
-                    ASSERT_LE(comparatorResult.getDifferentPixelCount(), threshold)
-                            << comparatorResult.getDifferentPixelCount() << " pixels ("
-                            << diffPercent << "%) are different. "
-                            << "Exceeds 1% threshold, terminating test. "
-                            << "Test case: " << testLayers.dump();
-
-                } while (testLayers.advance());
-
-                ASSERT_NO_FATAL_FAILURE(destroyLayers(display,
-                        std::move(layers)));
-            }
-            ASSERT_NO_FATAL_FAILURE(disableVsync(display));
-            ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-            ASSERT_NO_FATAL_FAILURE(destroyVirtualDisplay(display));
-        } while (testVirtualDisplay.advance());
-    }
-
-    hwc2_device_t* mHwc2Device = nullptr;
-
-    enum class Hwc2TestHotplugStatus {
-        Init = 1,
-        Receiving,
-        Done,
-    };
-
-    std::mutex mHotplugMutex;
-    std::condition_variable mHotplugCv;
-    Hwc2TestHotplugStatus mHotplugStatus = Hwc2TestHotplugStatus::Init;
-    std::unordered_set<hwc2_display_t> mDisplays;
-
-    /* Store all created layers that have not been destroyed. If an ASSERT_*
-     * fails, then destroy the layers on exit */
-    std::set<std::pair<hwc2_display_t, hwc2_layer_t>> mLayers;
-
-    /* Store the power mode state. If it is not HWC2_POWER_MODE_OFF when
-     * tearing down the test cases, change it to HWC2_POWER_MODE_OFF */
-    std::set<hwc2_display_t> mActiveDisplays;
-
-    /* Store all created virtual displays that have not been destroyed. If an
-     * ASSERT_* fails, then destroy the virtual displays on exit */
-    std::set<hwc2_display_t> mVirtualDisplays;
-
-    std::mutex mVsyncMutex;
-    std::condition_variable mVsyncCv;
-    hwc2_display_t mVsyncDisplay;
-    int64_t mVsyncTimestamp = -1;
-};
-
-void hwc2TestHotplugCallback(hwc2_callback_data_t callbackData,
-        hwc2_display_t display, int32_t connection)
-{
-    if (callbackData)
-        static_cast<Hwc2Test*>(callbackData)->hotplugCallback(display,
-                connection);
-}
-
-void hwc2TestVsyncCallback(hwc2_callback_data_t callbackData,
-        hwc2_display_t display, int64_t timestamp)
-{
-    if (callbackData)
-        static_cast<Hwc2Test*>(callbackData)->vsyncCallback(display,
-                timestamp);
-}
-
-void setBlendMode(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    EXPECT_NO_FATAL_FAILURE(test->setLayerBlendMode(display, layer,
-            testLayer->getBlendMode(), outErr));
-}
-
-void setBuffer(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    buffer_handle_t handle;
-    android::base::unique_fd acquireFence;
-    hwc2_composition_t composition = testLayer->getComposition();
-
-    if (composition == HWC2_COMPOSITION_CLIENT
-            || composition == HWC2_COMPOSITION_SOLID_COLOR
-            || composition == HWC2_COMPOSITION_SIDEBAND)
-        return;
-
-    if (testLayer->getBuffer(&handle, &acquireFence) < 0)
-        return;
-
-    ASSERT_NO_FATAL_FAILURE(test->setLayerCompositionType(display, layer,
-            composition));
-    EXPECT_NO_FATAL_FAILURE(test->setLayerBuffer(display, layer,
-            handle, acquireFence, outErr));
-}
-
-void setColor(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    ASSERT_NO_FATAL_FAILURE(test->setLayerCompositionType(display,
-            layer, HWC2_COMPOSITION_SOLID_COLOR));
-    ASSERT_NO_FATAL_FAILURE(test->setLayerPlaneAlpha(display,
-            layer, testLayer->getPlaneAlpha()));
-    ASSERT_NO_FATAL_FAILURE(test->setLayerBlendMode(display,
-            layer, testLayer->getBlendMode()));
-    EXPECT_NO_FATAL_FAILURE(test->setLayerColor(display, layer,
-            testLayer->getColor(), outErr));
-}
-
-void setComposition(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    hwc2_composition_t composition = testLayer->getComposition();
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(test->setLayerCompositionType(display, layer,
-            composition, &err));
-    if (outErr) {
-        *outErr = err;
-        return;
-    }
-
-    if (composition != HWC2_COMPOSITION_SIDEBAND) {
-        EXPECT_EQ(err, HWC2_ERROR_NONE) << "returned wrong error code";
-    } else {
-        EXPECT_TRUE(err == HWC2_ERROR_NONE || err == HWC2_ERROR_UNSUPPORTED)
-                 << "returned wrong error code";
-    }
-}
-
-void setCursorPosition(Hwc2Test* test, hwc2_display_t display,
-        hwc2_layer_t layer, Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    ASSERT_NO_FATAL_FAILURE(test->setLayerCompositionType(display,
-            layer, HWC2_COMPOSITION_CURSOR));
-
-    const hwc_rect_t cursorPosition = testLayer->getCursorPosition();
-    EXPECT_NO_FATAL_FAILURE(test->setCursorPosition(display, layer,
-            cursorPosition.left, cursorPosition.top, outErr));
-}
-
-void setDataspace(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    EXPECT_NO_FATAL_FAILURE(test->setLayerDataspace(display, layer,
-            testLayer->getDataspace(), outErr));
-}
-
-void setDisplayFrame(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    EXPECT_NO_FATAL_FAILURE(test->setLayerDisplayFrame(display, layer,
-            testLayer->getDisplayFrame(), outErr));
-}
-
-void setPlaneAlpha(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t *outErr)
-{
-    ASSERT_NO_FATAL_FAILURE(test->setLayerBlendMode(display, layer,
-            testLayer->getBlendMode()));
-    EXPECT_NO_FATAL_FAILURE(test->setLayerPlaneAlpha(display, layer,
-            testLayer->getPlaneAlpha(), outErr));
-}
-
-void setSourceCrop(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    EXPECT_NO_FATAL_FAILURE(test->setLayerSourceCrop(display, layer,
-            testLayer->getSourceCrop(), outErr));
-}
-
-void setSurfaceDamage(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    EXPECT_NO_FATAL_FAILURE(test->setLayerSurfaceDamage(display, layer,
-            testLayer->getSurfaceDamage(), outErr));
-}
-
-void setTransform(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    EXPECT_NO_FATAL_FAILURE(test->setLayerTransform(display, layer,
-            testLayer->getTransform(), outErr));
-}
-
-void setVisibleRegion(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    EXPECT_NO_FATAL_FAILURE(test->setLayerVisibleRegion(display, layer,
-            testLayer->getVisibleRegion(), outErr));
-}
-
-void setZOrder(Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-        Hwc2TestLayer* testLayer, hwc2_error_t* outErr)
-{
-    EXPECT_NO_FATAL_FAILURE(test->setLayerZOrder(display, layer,
-            testLayer->getZOrder(), outErr));
-}
-
-bool advanceBlendMode(Hwc2TestLayer* testLayer)
-{
-    return testLayer->advanceBlendMode();
-}
-
-bool advanceBuffer(Hwc2TestLayer* testLayer)
-{
-    if (testLayer->advanceComposition())
-        return true;
-    return testLayer->advanceBufferArea();
-}
-
-bool advanceColor(Hwc2TestLayer* testLayer)
-{
-    /* Color depends on blend mode so advance blend mode last so color is not
-     * force to update as often */
-    if (testLayer->advancePlaneAlpha())
-        return true;
-    if (testLayer->advanceColor())
-        return true;
-    return testLayer->advanceBlendMode();
-}
-
-bool advanceComposition(Hwc2TestLayer* testLayer)
-{
-    return testLayer->advanceComposition();
-}
-
-bool advanceCursorPosition(Hwc2TestLayer* testLayer)
-{
-    return testLayer->advanceCursorPosition();
-}
-
-bool advanceDataspace(Hwc2TestLayer* testLayer)
-{
-    return testLayer->advanceDataspace();
-}
-
-bool advanceDisplayFrame(Hwc2TestLayer* testLayer)
-{
-    return testLayer->advanceDisplayFrame();
-}
-
-bool advancePlaneAlpha(Hwc2TestLayer* testLayer)
-{
-    return testLayer->advancePlaneAlpha();
-}
-
-bool advanceSourceCrop(Hwc2TestLayer* testLayer)
-{
-    if (testLayer->advanceSourceCrop())
-        return true;
-    return testLayer->advanceBufferArea();
-}
-
-bool advanceSurfaceDamage(Hwc2TestLayer* testLayer)
-{
-    if (testLayer->advanceSurfaceDamage())
-        return true;
-    return testLayer->advanceBufferArea();
-}
-
-bool advanceTransform(Hwc2TestLayer* testLayer)
-{
-    return testLayer->advanceTransform();
-}
-
-bool advanceVisibleRegions(Hwc2TestLayers* testLayers)
-{
-    return testLayers->advanceVisibleRegions();
-}
-
-bool advanceClientTargetSupport(
-        Hwc2TestClientTargetSupport* testClientTargetSupport)
-{
-    return testClientTargetSupport->advance();
-}
-
-static const std::array<hwc2_function_descriptor_t, 42> requiredFunctions = {{
-    HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES,
-    HWC2_FUNCTION_CREATE_LAYER,
-    HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY,
-    HWC2_FUNCTION_DESTROY_LAYER,
-    HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY,
-    HWC2_FUNCTION_DUMP,
-    HWC2_FUNCTION_GET_ACTIVE_CONFIG,
-    HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES,
-    HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT,
-    HWC2_FUNCTION_GET_COLOR_MODES,
-    HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE,
-    HWC2_FUNCTION_GET_DISPLAY_CONFIGS,
-    HWC2_FUNCTION_GET_DISPLAY_NAME,
-    HWC2_FUNCTION_GET_DISPLAY_REQUESTS,
-    HWC2_FUNCTION_GET_DISPLAY_TYPE,
-    HWC2_FUNCTION_GET_DOZE_SUPPORT,
-    HWC2_FUNCTION_GET_HDR_CAPABILITIES,
-    HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT,
-    HWC2_FUNCTION_GET_RELEASE_FENCES,
-    HWC2_FUNCTION_PRESENT_DISPLAY,
-    HWC2_FUNCTION_REGISTER_CALLBACK,
-    HWC2_FUNCTION_SET_ACTIVE_CONFIG,
-    HWC2_FUNCTION_SET_CLIENT_TARGET,
-    HWC2_FUNCTION_SET_COLOR_MODE,
-    HWC2_FUNCTION_SET_COLOR_TRANSFORM,
-    HWC2_FUNCTION_SET_CURSOR_POSITION,
-    HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
-    HWC2_FUNCTION_SET_LAYER_BUFFER,
-    HWC2_FUNCTION_SET_LAYER_COLOR,
-    HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE,
-    HWC2_FUNCTION_SET_LAYER_DATASPACE,
-    HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME,
-    HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA,
-    HWC2_FUNCTION_SET_LAYER_SOURCE_CROP,
-    HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE,
-    HWC2_FUNCTION_SET_LAYER_TRANSFORM,
-    HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION,
-    HWC2_FUNCTION_SET_LAYER_Z_ORDER,
-    HWC2_FUNCTION_SET_OUTPUT_BUFFER,
-    HWC2_FUNCTION_SET_POWER_MODE,
-    HWC2_FUNCTION_SET_VSYNC_ENABLED,
-    HWC2_FUNCTION_VALIDATE_DISPLAY,
-}};
-
-/* TESTCASE: Tests that the HWC2 supports all required functions. */
-TEST_F(Hwc2Test, GET_FUNCTION)
-{
-    for (hwc2_function_descriptor_t descriptor : requiredFunctions) {
-        hwc2_function_pointer_t pfn = getFunction(descriptor);
-        EXPECT_TRUE(pfn) << "failed to get function "
-                << getFunctionDescriptorName(descriptor);
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 fails to retrieve and invalid function. */
-TEST_F(Hwc2Test, GET_FUNCTION_invalid_function)
-{
-    hwc2_function_pointer_t pfn = getFunction(HWC2_FUNCTION_INVALID);
-    EXPECT_FALSE(pfn) << "failed to get invalid function";
-}
-
-/* TESTCASE: Tests that the HWC2 does not return an invalid capability. */
-TEST_F(Hwc2Test, GET_CAPABILITIES)
-{
-    std::vector<hwc2_capability_t> capabilities;
-
-    getCapabilities(&capabilities);
-
-    EXPECT_EQ(std::count(capabilities.begin(), capabilities.end(),
-            HWC2_CAPABILITY_INVALID), 0);
-}
-
-static const std::array<hwc2_callback_descriptor_t, 3> callbackDescriptors = {{
-    HWC2_CALLBACK_HOTPLUG,
-    HWC2_CALLBACK_REFRESH,
-    HWC2_CALLBACK_VSYNC,
-}};
-
-/* TESTCASE: Tests that the HWC2 can successfully register all required
- * callback functions. */
-TEST_F(Hwc2Test, REGISTER_CALLBACK)
-{
-    hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
-            const_cast<char*>("data"));
-
-    for (auto descriptor : callbackDescriptors) {
-        ASSERT_NO_FATAL_FAILURE(registerCallback(descriptor, data,
-                []() { return; }));
-    }
-}
-
-/* TESTCASE: Test that the HWC2 fails to register invalid callbacks. */
-TEST_F(Hwc2Test, REGISTER_CALLBACK_bad_parameter)
-{
-    hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
-            const_cast<char*>("data"));
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_INVALID, data,
-            []() { return; }, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 can register a callback with null data. */
-TEST_F(Hwc2Test, REGISTER_CALLBACK_null_data)
-{
-    hwc2_callback_data_t data = nullptr;
-
-    for (auto descriptor : callbackDescriptors) {
-        ASSERT_NO_FATAL_FAILURE(registerCallback(descriptor, data,
-                []() { return; }));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 returns the correct display type for each
- * physical display. */
-TEST_F(Hwc2Test, GET_DISPLAY_TYPE)
-{
-    for (auto display : mDisplays) {
-        hwc2_display_type_t type;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayType(display, &type));
-        EXPECT_EQ(type, HWC2_DISPLAY_TYPE_PHYSICAL) << "failed to return"
-                " correct display type";
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 returns an error when the display type of a bad
- * display is requested. */
-TEST_F(Hwc2Test, GET_DISPLAY_TYPE_bad_display)
-{
-    hwc2_display_t display;
-    hwc2_display_type_t type;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(getDisplayType(display, &type, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 can create and destroy layers. */
-TEST_F(Hwc2Test, CREATE_DESTROY_LAYER)
-{
-    for (auto display : mDisplays) {
-        hwc2_layer_t layer;
-
-        ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 cannot create a layer for a bad display */
-TEST_F(Hwc2Test, CREATE_LAYER_bad_display)
-{
-    hwc2_display_t display;
-    hwc2_layer_t layer;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 will either support a large number of resources
- * or will return no resources. */
-TEST_F(Hwc2Test, CREATE_LAYER_no_resources)
-{
-    const size_t layerCnt = 1000;
-
-    for (auto display : mDisplays) {
-        std::vector<hwc2_layer_t> layers;
-
-        ASSERT_NO_FATAL_FAILURE(createLayers(display, &layers, layerCnt));
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayers(display, std::move(layers)));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 cannot destroy a layer for a bad display */
-TEST_F(Hwc2Test, DESTROY_LAYER_bad_display)
-{
-    hwc2_display_t badDisplay;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&badDisplay));
-
-    for (auto display : mDisplays) {
-        hwc2_layer_t layer = 0;
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(badDisplay, layer, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-
-        ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(badDisplay, layer, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 cannot destory a bad layer */
-TEST_F(Hwc2Test, DESTROY_LAYER_bad_layer)
-{
-    for (auto display : mDisplays) {
-        hwc2_layer_t layer;
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, UINT64_MAX / 2, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, 0, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, UINT64_MAX - 1, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, 1, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, UINT64_MAX, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
-
-        ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer + 1, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
-
-        ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_LAYER) << "returned wrong error code";
-    }
-}
-
-static const std::array<hwc2_attribute_t, 2> requiredAttributes = {{
-    HWC2_ATTRIBUTE_WIDTH,
-    HWC2_ATTRIBUTE_HEIGHT,
-}};
-
-static const std::array<hwc2_attribute_t, 3> optionalAttributes = {{
-    HWC2_ATTRIBUTE_VSYNC_PERIOD,
-    HWC2_ATTRIBUTE_DPI_X,
-    HWC2_ATTRIBUTE_DPI_Y,
-}};
-
-/* TESTCASE: Tests that the HWC2 can return display attributes for a valid
- * config. */
-TEST_F(Hwc2Test, GET_DISPLAY_ATTRIBUTE)
-{
-    for (auto display : mDisplays) {
-        std::vector<hwc2_config_t> configs;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-        for (auto config : configs) {
-            int32_t value;
-
-            for (auto attribute : requiredAttributes) {
-                ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config,
-                        attribute, &value));
-                EXPECT_GE(value, 0) << "missing required attribute "
-                        << getAttributeName(attribute) << " for config "
-                        << config;
-            }
-            for (auto attribute : optionalAttributes) {
-                ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config,
-                        attribute, &value));
-            }
-        }
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 will return a value of -1 for an invalid
- * attribute */
-TEST_F(Hwc2Test, GET_DISPLAY_ATTRIBUTE_invalid_attribute)
-{
-    const hwc2_attribute_t attribute = HWC2_ATTRIBUTE_INVALID;
-
-    for (auto display : mDisplays) {
-        std::vector<hwc2_config_t> configs;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-        for (auto config : configs) {
-            int32_t value;
-            hwc2_error_t err = HWC2_ERROR_NONE;
-
-            ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config,
-                    attribute, &value, &err));
-            EXPECT_EQ(value, -1) << "failed to return -1 for an invalid"
-                    " attribute for config " << config;
-        }
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 will fail to get attributes for a bad display */
-TEST_F(Hwc2Test, GET_DISPLAY_ATTRIBUTE_bad_display)
-{
-    hwc2_display_t display;
-    const hwc2_config_t config = 0;
-    int32_t value;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    for (auto attribute : requiredAttributes) {
-        ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config, attribute,
-                &value, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-    }
-
-    for (auto attribute : optionalAttributes) {
-        ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config, attribute,
-                &value, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 will fail to get attributes for a bad config */
-TEST_F(Hwc2Test, GET_DISPLAY_ATTRIBUTE_bad_config)
-{
-    for (auto display : mDisplays) {
-        hwc2_config_t config;
-        int32_t value;
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        ASSERT_NO_FATAL_FAILURE(getInvalidConfig(display, &config));
-
-        for (auto attribute : requiredAttributes) {
-            ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config,
-                    attribute, &value, &err));
-            EXPECT_EQ(err, HWC2_ERROR_BAD_CONFIG) << "returned wrong error code";
-        }
-
-        for (auto attribute : optionalAttributes) {
-            ASSERT_NO_FATAL_FAILURE(getDisplayAttribute(display, config,
-                    attribute, &value, &err));
-            EXPECT_EQ(err, HWC2_ERROR_BAD_CONFIG) << "returned wrong error code";
-        }
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 will get display configs for active displays */
-TEST_F(Hwc2Test, GET_DISPLAY_CONFIGS)
-{
-    for (auto display : mDisplays) {
-        std::vector<hwc2_config_t> configs;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 will not get display configs for bad displays */
-TEST_F(Hwc2Test, GET_DISPLAY_CONFIGS_bad_display)
-{
-    hwc2_display_t display;
-    std::vector<hwc2_config_t> configs;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs, &err));
-
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-    EXPECT_TRUE(configs.empty()) << "returned configs for bad display";
-}
-
-/* TESTCASE: Tests that the HWC2 will return the same config list multiple
- * times in a row. */
-TEST_F(Hwc2Test, GET_DISPLAY_CONFIGS_same)
-{
-    for (auto display : mDisplays) {
-        std::vector<hwc2_config_t> configs1, configs2;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs1));
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs2));
-
-        EXPECT_TRUE(std::is_permutation(configs1.begin(), configs1.end(),
-                configs2.begin())) << "returned two different config sets";
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 does not return duplicate display configs */
-TEST_F(Hwc2Test, GET_DISPLAY_CONFIGS_duplicate)
-{
-    for (auto display : mDisplays) {
-        std::vector<hwc2_config_t> configs;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-        std::unordered_set<hwc2_config_t> configsSet(configs.begin(),
-                configs.end());
-        EXPECT_EQ(configs.size(), configsSet.size()) << "returned duplicate"
-                " configs";
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 returns the active config for a display */
-TEST_F(Hwc2Test, GET_ACTIVE_CONFIG)
-{
-    for (auto display : mDisplays) {
-        std::vector<hwc2_config_t> configs;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-        for (auto config : configs) {
-            hwc2_config_t activeConfig;
-
-            ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-            ASSERT_NO_FATAL_FAILURE(getActiveConfig(display, &activeConfig));
-
-            EXPECT_EQ(activeConfig, config) << "failed to get active config";
-        }
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 does not return an active config for a bad
- * display. */
-TEST_F(Hwc2Test, GET_ACTIVE_CONFIG_bad_display)
-{
-    hwc2_display_t display;
-    hwc2_config_t activeConfig;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(getActiveConfig(display, &activeConfig, &err));
-
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 either begins with a valid active config
- * or returns an error when getActiveConfig is called. */
-TEST_F(Hwc2Test, GET_ACTIVE_CONFIG_bad_config)
-{
-    for (auto display : mDisplays) {
-        std::vector<hwc2_config_t> configs;
-        hwc2_config_t activeConfig;
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-        if (configs.empty())
-            return;
-
-        ASSERT_NO_FATAL_FAILURE(getActiveConfig(display, &activeConfig, &err));
-        if (err == HWC2_ERROR_NONE) {
-            EXPECT_NE(std::count(configs.begin(), configs.end(),
-                    activeConfig), 0) << "active config is not found in "
-                    " configs for display";
-        } else {
-            EXPECT_EQ(err, HWC2_ERROR_BAD_CONFIG) << "returned wrong error code";
-        }
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 can set every display config as an active
- * config */
-TEST_F(Hwc2Test, SET_ACTIVE_CONFIG)
-{
-    for (auto display : mDisplays) {
-        std::vector<hwc2_config_t> configs;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-        for (auto config : configs) {
-            EXPECT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-        }
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set an active config for a bad display */
-TEST_F(Hwc2Test, SET_ACTIVE_CONFIG_bad_display)
-{
-    hwc2_display_t display;
-    const hwc2_config_t config = 0;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set an invalid active config */
-TEST_F(Hwc2Test, SET_ACTIVE_CONFIG_bad_config)
-{
-    for (auto display : mDisplays) {
-        hwc2_config_t config;
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        ASSERT_NO_FATAL_FAILURE(getInvalidConfig(display, &config));
-
-        ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_CONFIG) << "returned wrong error code";
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 returns a valid value for getDozeSupport. */
-TEST_F(Hwc2Test, GET_DOZE_SUPPORT)
-{
-    for (auto display : mDisplays) {
-        int32_t support = -1;
-
-        ASSERT_NO_FATAL_FAILURE(getDozeSupport(display, &support));
-
-        EXPECT_TRUE(support == 0 || support == 1) << "invalid doze support value";
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 cannot get doze support for a bad display. */
-TEST_F(Hwc2Test, GET_DOZE_SUPPORT_bad_display)
-{
-    hwc2_display_t display;
-    int32_t support = -1;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(getDozeSupport(display, &support, &err));
-
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 can set all supported power modes */
-TEST_F(Hwc2Test, SET_POWER_MODE)
-{
-    for (auto display : mDisplays) {
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-
-        int32_t support = -1;
-        ASSERT_NO_FATAL_FAILURE(getDozeSupport(display, &support));
-        if (support != 1)
-            return;
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_DOZE));
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display,
-                HWC2_POWER_MODE_DOZE_SUSPEND));
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set a power mode for a bad display. */
-TEST_F(Hwc2Test, SET_POWER_MODE_bad_display)
-{
-    hwc2_display_t display;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-
-    ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-
-    int32_t support = -1;
-    ASSERT_NO_FATAL_FAILURE(getDozeSupport(display, &support, &err));
-    if (support != 1)
-        return;
-
-    ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_DOZE, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-
-    ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_DOZE_SUSPEND,
-            &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set an invalid power mode value. */
-TEST_F(Hwc2Test, SET_POWER_MODE_bad_parameter)
-{
-    for (auto display : mDisplays) {
-        hwc2_power_mode_t mode = static_cast<hwc2_power_mode_t>(
-                HWC2_POWER_MODE_DOZE_SUSPEND + 1);
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, mode, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER) << "returned wrong error code "
-                << mode;
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 will return unsupported if it does not support
- * an optional power mode. */
-TEST_F(Hwc2Test, SET_POWER_MODE_unsupported)
-{
-    for (auto display : mDisplays) {
-        int32_t support = -1;
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        ASSERT_NO_FATAL_FAILURE(getDozeSupport(display, &support, &err));
-        if (support == 1)
-            return;
-
-        ASSERT_EQ(support, 0) << "invalid doze support value";
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_DOZE,
-                &err));
-        EXPECT_EQ(err, HWC2_ERROR_UNSUPPORTED) << "returned wrong error code";
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display,
-                HWC2_POWER_MODE_DOZE_SUSPEND, &err));
-        EXPECT_EQ(err, HWC2_ERROR_UNSUPPORTED) <<  "returned wrong error code";
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 can set the same power mode multiple times. */
-TEST_F(Hwc2Test, SET_POWER_MODE_stress)
-{
-    for (auto display : mDisplays) {
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-
-        int32_t support = -1;
-        ASSERT_NO_FATAL_FAILURE(getDozeSupport(display, &support));
-        if (support != 1)
-            return;
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_DOZE));
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_DOZE));
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display,
-                HWC2_POWER_MODE_DOZE_SUSPEND));
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display,
-                HWC2_POWER_MODE_DOZE_SUSPEND));
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 can enable and disable vsync on active
- * displays */
-TEST_F(Hwc2Test, SET_VSYNC_ENABLED)
-{
-    for (auto display : mDisplays) {
-        hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
-                const_cast<char*>("data"));
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-
-        ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_VSYNC, data,
-                []() { return; }));
-
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_ENABLE));
-
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_DISABLE));
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 issues a valid vsync callback. */
-TEST_F(Hwc2Test, SET_VSYNC_ENABLED_callback)
-{
-    for (auto display : mDisplays) {
-        hwc2_display_t receivedDisplay;
-        int64_t receivedTimestamp;
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-
-        ASSERT_NO_FATAL_FAILURE(enableVsync(display));
-
-        ASSERT_NO_FATAL_FAILURE(waitForVsync(&receivedDisplay,
-                &receivedTimestamp));
-
-        EXPECT_EQ(receivedDisplay, display) << "failed to get correct display";
-        EXPECT_GE(receivedTimestamp, 0) << "failed to get valid timestamp";
-
-        ASSERT_NO_FATAL_FAILURE(disableVsync(display));
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 cannot enable a vsync for a bad display */
-TEST_F(Hwc2Test, SET_VSYNC_ENABLED_bad_display)
-{
-    hwc2_display_t display;
-    hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
-            const_cast<char*>("data"));
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_VSYNC, data,
-            []() { return; }));
-
-    ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_ENABLE, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-
-    ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_DISABLE, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 cannot enable an invalid vsync value */
-TEST_F(Hwc2Test, SET_VSYNC_ENABLED_bad_parameter)
-{
-    for (auto display : mDisplays) {
-        hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
-                const_cast<char*>("data"));
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-
-        ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_VSYNC, data,
-                []() { return; }));
-
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_INVALID,
-                &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER) << "returned wrong error code";
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 can enable and disable a vsync value multiple
- * times. */
-TEST_F(Hwc2Test, SET_VSYNC_ENABLED_stress)
-{
-    for (auto display : mDisplays) {
-        hwc2_callback_data_t data = reinterpret_cast<hwc2_callback_data_t>(
-                const_cast<char*>("data"));
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-
-        ASSERT_NO_FATAL_FAILURE(registerCallback(HWC2_CALLBACK_VSYNC, data,
-                []() { return; }));
-
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_DISABLE));
-
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_ENABLE));
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_ENABLE));
-
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_DISABLE));
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_DISABLE));
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 can set a vsync enable value when the display
- * is off and no callback is registered. */
-TEST_F(Hwc2Test, SET_VSYNC_ENABLED_no_callback_no_power)
-{
-    const uint secs = 1;
-
-    for (auto display : mDisplays) {
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_ENABLE));
-
-        sleep(secs);
-
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_DISABLE));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 can set a vsync enable value when no callback
- * is registered. */
-TEST_F(Hwc2Test, SET_VSYNC_ENABLED_no_callback)
-{
-    const uint secs = 1;
-
-    for (auto display : mDisplays) {
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_ENABLE));
-
-        sleep(secs);
-
-        ASSERT_NO_FATAL_FAILURE(setVsyncEnabled(display, HWC2_VSYNC_DISABLE));
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 returns a display name for each display */
-TEST_F(Hwc2Test, GET_DISPLAY_NAME)
-{
-    for (auto display : mDisplays) {
-        std::string name;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayName(display, &name));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 does not return a display name for a bad
- * display */
-TEST_F(Hwc2Test, GET_DISPLAY_NAME_bad_display)
-{
-    hwc2_display_t display;
-    std::string name;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(getDisplayName(display, &name, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 can set basic composition types. */
-TEST_F(Hwc2Test, SET_LAYER_COMPOSITION_TYPE)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            setComposition, advanceComposition));
-}
-
-/* TESTCASE: Tests that the HWC2 can update a basic composition type on a
- * layer. */
-TEST_F(Hwc2Test, SET_LAYER_COMPOSITION_TYPE_update)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
-            setComposition, advanceComposition));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set a composition type for a bad layer */
-TEST_F(Hwc2Test, SET_LAYER_COMPOSITION_TYPE_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            setComposition));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set a bad composition type */
-TEST_F(Hwc2Test, SET_LAYER_COMPOSITION_TYPE_bad_parameter)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadParameter(
-            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-                    hwc2_error_t* outErr) {
-
-                ASSERT_NO_FATAL_FAILURE(test->setLayerCompositionType(display,
-                        layer, HWC2_COMPOSITION_INVALID, outErr));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the cursor position of a layer. */
-TEST_F(Hwc2Test, SET_CURSOR_POSITION)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            ::setCursorPosition, advanceCursorPosition));
-}
-
-/* TESTCASE: Tests that the HWC2 can update the cursor position of a layer. */
-TEST_F(Hwc2Test, SET_CURSOR_POSITION_update)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
-            ::setCursorPosition, advanceCursorPosition));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the cursor position of a layer when the
- * composition type has not been set to HWC2_COMPOSITION_CURSOR. */
-TEST_F(Hwc2Test, SET_CURSOR_POSITION_composition_type_unset)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-                    Hwc2TestLayer* testLayer, hwc2_error_t* outErr) {
-                const hwc_rect_t cursorPosition = testLayer->getCursorPosition();
-                EXPECT_NO_FATAL_FAILURE(test->setCursorPosition(display, layer,
-                        cursorPosition.left, cursorPosition.top, outErr));
-            },
-
-            advanceCursorPosition));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set the cursor position of a bad
- * display. */
-TEST_F(Hwc2Test, SET_CURSOR_POSITION_bad_display)
-{
-    hwc2_display_t display;
-    hwc2_layer_t layer = 0;
-    int32_t x = 0, y = 0;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(setCursorPosition(display, layer, x, y, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set the cursor position of a bad layer. */
-TEST_F(Hwc2Test, SET_CURSOR_POSITION_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t badLayer,
-                    Hwc2TestLayer* testLayer, hwc2_error_t* outErr) {
-
-                const hwc_rect_t cursorPosition = testLayer->getCursorPosition();
-                EXPECT_NO_FATAL_FAILURE(test->setCursorPosition(display,
-                        badLayer, cursorPosition.left, cursorPosition.top,
-                        outErr));
-            }
-   ));
-}
-
-/* TESTCASE: Tests that the HWC2 can set a blend mode value of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_BLEND_MODE)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            setBlendMode, advanceBlendMode));
-}
-
-/* TESTCASE: Tests that the HWC2 can update a blend mode value of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_BLEND_MODE_update)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
-            setBlendMode, advanceBlendMode));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set a blend mode for a bad layer. */
-TEST_F(Hwc2Test, SET_LAYER_BLEND_MODE_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            setBlendMode));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set an invalid blend mode. */
-TEST_F(Hwc2Test, SET_LAYER_BLEND_MODE_bad_parameter)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadParameter(
-            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-                    hwc2_error_t* outErr) {
-
-                ASSERT_NO_FATAL_FAILURE(test->setLayerBlendMode(display,
-                        layer, HWC2_BLEND_MODE_INVALID, outErr));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the buffer of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_BUFFER)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            setBuffer, advanceBuffer));
-}
-
-/* TESTCASE: Tests that the HWC2 can update the buffer of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_BUFFER_update)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
-            setBuffer, advanceBuffer));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set the buffer of a bad layer. */
-TEST_F(Hwc2Test, SET_LAYER_BUFFER_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t badLayer,
-                    Hwc2TestLayer* testLayer, hwc2_error_t* outErr) {
-
-                buffer_handle_t handle = nullptr;
-                android::base::unique_fd acquireFence;
-
-                /* If there is not available buffer for the given buffer
-                 * properties, it should not fail this test case */
-                if (testLayer->getBuffer(&handle, &acquireFence) == 0) {
-                    *outErr = HWC2_ERROR_BAD_LAYER;
-                    return;
-                }
-
-                ASSERT_NO_FATAL_FAILURE(test->setLayerBuffer(display, badLayer,
-                        handle, acquireFence, outErr));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 can set an invalid buffer for a layer. */
-TEST_F(Hwc2Test, SET_LAYER_BUFFER_bad_parameter)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadParameter(
-            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-                    hwc2_error_t* outErr) {
-
-                buffer_handle_t handle = nullptr;
-                int32_t acquireFence = -1;
-
-                ASSERT_NO_FATAL_FAILURE(test->setLayerBuffer(display, layer,
-                        handle, acquireFence, outErr));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the color of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_COLOR)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            setColor, advanceColor));
-}
-
-/* TESTCASE: Tests that the HWC2 can update the color of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_COLOR_update)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
-            setColor, advanceColor));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the color of a layer when the
- * composition type has not been set to HWC2_COMPOSITION_SOLID_COLOR. */
-TEST_F(Hwc2Test, SET_LAYER_COLOR_composition_type_unset)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Basic,
-            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-                    Hwc2TestLayer* testLayer, hwc2_error_t* outErr) {
-
-                EXPECT_NO_FATAL_FAILURE(test->setLayerColor(display, layer,
-                        testLayer->getColor(), outErr));
-            },
-
-            advanceColor));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set the color of a bad layer. */
-TEST_F(Hwc2Test, SET_LAYER_COLOR_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t badLayer,
-                    Hwc2TestLayer* testLayer, hwc2_error_t* outErr) {
-
-                EXPECT_NO_FATAL_FAILURE(test->setLayerColor(display, badLayer,
-                        testLayer->getColor(), outErr));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the dataspace of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_DATASPACE)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            setDataspace, advanceDataspace));
-}
-
-/* TESTCASE: Tests that the HWC2 can update the dataspace of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_DATASPACE_update)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
-            setDataspace, advanceDataspace));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set a dataspace for a bad layer. */
-TEST_F(Hwc2Test, SET_LAYER_DATASPACE_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            setDataspace));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the display frame of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_DISPLAY_FRAME)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            setDisplayFrame, advanceDisplayFrame));
-}
-
-/* TESTCASE: Tests that the HWC2 can update the display frame of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_DISPLAY_FRAME_update)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
-            setDisplayFrame, advanceDisplayFrame));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set the display frame of a bad layer. */
-TEST_F(Hwc2Test, SET_LAYER_DISPLAY_FRAME_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            setDisplayFrame));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the plane alpha of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_PLANE_ALPHA)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            setPlaneAlpha, advancePlaneAlpha));
-}
-
-/* TESTCASE: Tests that the HWC2 can update the plane alpha of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_PLANE_ALPHA_update)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
-            setPlaneAlpha, advancePlaneAlpha));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set a plane alpha for a bad layer. */
-TEST_F(Hwc2Test, SET_LAYER_PLANE_ALPHA_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t badLayer,
-                    Hwc2TestLayer* testLayer, hwc2_error_t *outErr) {
-
-                    EXPECT_NO_FATAL_FAILURE(test->setLayerPlaneAlpha(display,
-                            badLayer, testLayer->getPlaneAlpha(), outErr));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the source crop of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_SOURCE_CROP)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            setSourceCrop, advanceSourceCrop));
-}
-
-/* TESTCASE: Tests that the HWC2 can update the source crop of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_SOURCE_CROP_update)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
-            setSourceCrop, advanceSourceCrop));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set the source crop of a bad layer. */
-TEST_F(Hwc2Test, SET_LAYER_SOURCE_CROP_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            setSourceCrop));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the surface damage of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_SURFACE_DAMAGE)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            setSurfaceDamage, advanceSurfaceDamage));
-}
-
-/* TESTCASE: Tests that the HWC2 can update the surface damage of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_SURFACE_DAMAGE_update)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
-            setSurfaceDamage, advanceSurfaceDamage));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set the surface damage of a bad layer. */
-TEST_F(Hwc2Test, SET_LAYER_SURFACE_DAMAGE_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            setSurfaceDamage));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the transform value of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_TRANSFORM)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperty(Hwc2TestCoverage::Complete,
-            setTransform, advanceTransform));
-}
-
-/* TESTCASE: Tests that the HWC2 can update the transform value of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_TRANSFORM_update)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyUpdate(Hwc2TestCoverage::Complete,
-            setTransform, advanceTransform));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set the transform for a bad layer. */
-TEST_F(Hwc2Test, SET_LAYER_TRANSFORM_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            setTransform));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the visible region of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_VISIBLE_REGION)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperties(Hwc2TestCoverage::Basic, 5,
-            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-                    Hwc2TestLayers* testLayers) {
-
-                EXPECT_NO_FATAL_FAILURE(test->setLayerVisibleRegion(display,
-                        layer, testLayers->getVisibleRegion(layer)));
-            },
-
-            advanceVisibleRegions));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set the visible region of a bad layer. */
-TEST_F(Hwc2Test, SET_LAYER_VISIBLE_REGION_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            setVisibleRegion));
-}
-
-/* TESTCASE: Tests that the HWC2 can set the z order of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_Z_ORDER)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerProperties(Hwc2TestCoverage::Complete, 10,
-            [] (Hwc2Test* test, hwc2_display_t display, hwc2_layer_t layer,
-                    Hwc2TestLayers* testLayers) {
-
-                EXPECT_NO_FATAL_FAILURE(test->setLayerZOrder(display, layer,
-                        testLayers->getZOrder(layer)));
-            },
-
-            /* TestLayer z orders are set during the construction of TestLayers
-             * and cannot be updated. There is no need (or ability) to cycle
-             * through additional z order configurations. */
-            [] (Hwc2TestLayers* /*testLayers*/) {
-                return false;
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 can update the z order of a layer. */
-TEST_F(Hwc2Test, SET_LAYER_Z_ORDER_update)
-{
-    const std::vector<uint32_t> zOrders = { static_cast<uint32_t>(0),
-            static_cast<uint32_t>(1), static_cast<uint32_t>(UINT32_MAX / 4),
-            static_cast<uint32_t>(UINT32_MAX / 2),
-            static_cast<uint32_t>(UINT32_MAX) };
-
-    for (auto display : mDisplays) {
-        std::vector<hwc2_config_t> configs;
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-        for (auto config : configs) {
-            hwc2_layer_t layer;
-
-            ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-
-            ASSERT_NO_FATAL_FAILURE(createLayer(display, &layer));
-
-            for (uint32_t zOrder : zOrders) {
-                EXPECT_NO_FATAL_FAILURE(setLayerZOrder(display, layer, zOrder));
-            }
-
-            ASSERT_NO_FATAL_FAILURE(destroyLayer(display, layer));
-        }
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set the z order of a bad layer. */
-TEST_F(Hwc2Test, SET_LAYER_Z_ORDER_bad_layer)
-{
-    ASSERT_NO_FATAL_FAILURE(setLayerPropertyBadLayer(Hwc2TestCoverage::Default,
-            setZOrder));
-}
-
-/* TESTCASE: Tests that the HWC2 can display a layer with basic property
- * coverage */
-TEST_F(Hwc2Test, VALIDATE_DISPLAY_basic)
-{
-    ASSERT_NO_FATAL_FAILURE(displayLayers(Hwc2TestCoverage::Basic, 1,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    const std::vector<hwc2_layer_t>& layers,
-                    Hwc2TestLayers* /*testLayers*/) {
-
-                uint32_t numTypes, numRequests;
-                bool hasChanges = false;
-
-                EXPECT_NO_FATAL_FAILURE(test->validateDisplay(display, &numTypes,
-                        &numRequests, &hasChanges));
-                if (hasChanges)
-                    EXPECT_LE(numTypes, static_cast<uint32_t>(layers.size()))
-                            << "wrong number of requests";
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 can display 5 layers with default coverage. */
-TEST_F(Hwc2Test, VALIDATE_DISPLAY_default_5)
-{
-    ASSERT_NO_FATAL_FAILURE(displayLayers(Hwc2TestCoverage::Default, 5,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    const std::vector<hwc2_layer_t>& layers,
-                    Hwc2TestLayers* /*testLayers*/) {
-
-                uint32_t numTypes, numRequests;
-                bool hasChanges = false;
-
-                EXPECT_NO_FATAL_FAILURE(test->validateDisplay(display, &numTypes,
-                        &numRequests, &hasChanges));
-                if (hasChanges)
-                    EXPECT_LE(numTypes, static_cast<uint32_t>(layers.size()))
-                            << "wrong number of requests";
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot validate a bad display */
-TEST_F(Hwc2Test, VALIDATE_DISPLAY_bad_display)
-{
-    hwc2_display_t display;
-    uint32_t numTypes, numRequests;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(validateDisplay(display, &numTypes, &numRequests,
-            &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 can get display requests after validating a
- * basic layer. */
-TEST_F(Hwc2Test, GET_DISPLAY_REQUESTS_basic)
-{
-    ASSERT_NO_FATAL_FAILURE(displayLayers(Hwc2TestCoverage::Basic, 1,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    const std::vector<hwc2_layer_t>& layers,
-                    Hwc2TestLayers* /*testLayers*/) {
-
-                uint32_t numTypes, numRequests;
-                bool hasChanges = false;
-
-                ASSERT_NO_FATAL_FAILURE(test->validateDisplay(display, &numTypes,
-                        &numRequests, &hasChanges));
-                if (hasChanges)
-                    EXPECT_LE(numTypes, layers.size())
-                            << "wrong number of requests";
-
-                EXPECT_NO_FATAL_FAILURE(test->handleRequests(display, layers,
-                        numRequests));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot get display requests from a bad display */
-TEST_F(Hwc2Test, GET_DISPLAY_REQUESTS_bad_display)
-{
-    hwc2_display_t display;
-    hwc2_display_request_t displayRequests;
-    std::vector<hwc2_layer_t> layers;
-    std::vector<hwc2_layer_request_t> layerRequests;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    EXPECT_NO_FATAL_FAILURE(getDisplayRequests(display, &displayRequests,
-            &layers, &layerRequests, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 cannot get display requests from an non
- * validated display. */
-TEST_F(Hwc2Test, GET_DISPLAY_REQUESTS_not_validated)
-{
-    ASSERT_NO_FATAL_FAILURE(displayNonValidatedLayers(5,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    std::vector<hwc2_layer_t>* layers) {
-
-                hwc2_display_request_t displayRequests;
-                std::vector<hwc2_layer_request_t> layerRequests;
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(test->getDisplayRequests(display,
-                        &displayRequests, layers, &layerRequests, &err));
-                EXPECT_EQ(err, HWC2_ERROR_NOT_VALIDATED)
-                        << "returned wrong error code";
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 can get changed composition types after
- * validating a basic layer. */
-TEST_F(Hwc2Test, GET_CHANGED_COMPOSITION_TYPES_basic)
-{
-    ASSERT_NO_FATAL_FAILURE(displayLayers(Hwc2TestCoverage::Basic, 1,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    const std::vector<hwc2_layer_t>& layers,
-                    Hwc2TestLayers* testLayers) {
-
-                uint32_t numTypes, numRequests;
-                bool hasChanges = false;
-
-                ASSERT_NO_FATAL_FAILURE(test->validateDisplay(display, &numTypes,
-                        &numRequests, &hasChanges));
-                if (hasChanges)
-                    EXPECT_LE(numTypes, layers.size())
-                            << "wrong number of requests";
-
-                EXPECT_NO_FATAL_FAILURE(test->handleCompositionChanges(display,
-                        *testLayers, layers, numTypes));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot get changed composition types from a bad
- * display */
-TEST_F(Hwc2Test, GET_CHANGED_COMPOSITION_TYPES_bad_display)
-{
-    hwc2_display_t display;
-    std::vector<hwc2_layer_t> layers;
-    std::vector<hwc2_composition_t> types;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    EXPECT_NO_FATAL_FAILURE(getChangedCompositionTypes(display, &layers,
-            &types, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 cannot get changed composition types from an non
- * validated display. */
-TEST_F(Hwc2Test, GET_CHANGED_COMPOSITION_TYPES_not_validated)
-{
-    ASSERT_NO_FATAL_FAILURE(displayNonValidatedLayers(5,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    std::vector<hwc2_layer_t>* layers) {
-
-                std::vector<hwc2_composition_t> types;
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(test->getChangedCompositionTypes(
-                        display, layers, &types, &err));
-                EXPECT_EQ(err, HWC2_ERROR_NOT_VALIDATED)
-                        << "returned wrong error code";
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 can accept display changes after validating a
- * basic layer. */
-TEST_F(Hwc2Test, ACCEPT_DISPLAY_CHANGES_basic)
-{
-    ASSERT_NO_FATAL_FAILURE(displayLayers(Hwc2TestCoverage::Basic, 1,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    const std::vector<hwc2_layer_t>& layers,
-                    Hwc2TestLayers* testLayers) {
-
-                uint32_t numTypes, numRequests;
-                bool hasChanges = false;
-
-                ASSERT_NO_FATAL_FAILURE(test->validateDisplay(display, &numTypes,
-                        &numRequests, &hasChanges));
-                if (hasChanges)
-                    EXPECT_LE(numTypes, layers.size())
-                            << "wrong number of requests";
-
-                ASSERT_NO_FATAL_FAILURE(test->handleCompositionChanges(display,
-                        *testLayers, layers, numTypes));
-
-                EXPECT_NO_FATAL_FAILURE(test->acceptDisplayChanges(display));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot accept display changes from a bad
- * display */
-TEST_F(Hwc2Test, ACCEPT_DISPLAY_CHANGES_bad_display)
-{
-    hwc2_display_t display;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    EXPECT_NO_FATAL_FAILURE(acceptDisplayChanges(display, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 cannot accept display changes from an non
- * validated display. */
-TEST_F(Hwc2Test, ACCEPT_DISPLAY_CHANGES_not_validated)
-{
-    ASSERT_NO_FATAL_FAILURE(displayNonValidatedLayers(5,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    std::vector<hwc2_layer_t>* /*layers*/) {
-
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(test->acceptDisplayChanges(display, &err));
-                EXPECT_EQ(err, HWC2_ERROR_NOT_VALIDATED)
-                        << "returned wrong error code";
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 supports client target with required values */
-TEST_F(Hwc2Test, GET_CLIENT_TARGET_SUPPORT)
-{
-    ASSERT_NO_FATAL_FAILURE(setClientTargetSupport(Hwc2TestCoverage::Default,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    const Hwc2TestClientTargetSupport& testClientTargetSupport) {
-
-                const Area bufferArea = testClientTargetSupport.getBufferArea();
-                const android_pixel_format_t format = HAL_PIXEL_FORMAT_RGBA_8888;
-
-                ASSERT_NO_FATAL_FAILURE(test->getClientTargetSupport(display,
-                        bufferArea.width, bufferArea.height, format,
-                        testClientTargetSupport.getDataspace()));
-            },
-
-            advanceClientTargetSupport));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot get client target support for a bad
- * display. */
-TEST_F(Hwc2Test, GET_CLIENT_TARGET_SUPPORT_bad_display)
-{
-    ASSERT_NO_FATAL_FAILURE(setClientTargetSupport(Hwc2TestCoverage::Default,
-            [] (Hwc2Test* test, hwc2_display_t /*display*/,
-                    const Hwc2TestClientTargetSupport& testClientTargetSupport) {
-
-                const Area bufferArea = testClientTargetSupport.getBufferArea();
-                const android_pixel_format_t format = HAL_PIXEL_FORMAT_RGBA_8888;
-                hwc2_display_t badDisplay;
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(test->getBadDisplay(&badDisplay));
-
-                ASSERT_NO_FATAL_FAILURE(test->getClientTargetSupport(badDisplay,
-                        bufferArea.width, bufferArea.height, format,
-                        testClientTargetSupport.getDataspace(), &err));
-                EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-            },
-
-            advanceClientTargetSupport));
-}
-
-/* TESTCASE: Tests that the HWC2 either supports or returns error unsupported
- * for a variety of client target values. */
-TEST_F(Hwc2Test, GET_CLIENT_TARGET_SUPPORT_unsupported)
-{
-    ASSERT_NO_FATAL_FAILURE(setClientTargetSupport(Hwc2TestCoverage::Complete,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    const Hwc2TestClientTargetSupport& testClientTargetSupport) {
-
-                const Area bufferArea = testClientTargetSupport.getBufferArea();
-                const android_pixel_format_t format = HAL_PIXEL_FORMAT_RGBA_8888;
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(test->getClientTargetSupport(display,
-                        bufferArea.width, bufferArea.height, format,
-                        testClientTargetSupport.getDataspace(), &err));
-                EXPECT_TRUE(err == HWC2_ERROR_NONE
-                        || err == HWC2_ERROR_UNSUPPORTED)
-                        << "returned wrong error code";
-            },
-
-            advanceClientTargetSupport));
-}
-
-/* TESTCASE: Tests that the HWC2 can set a client target buffer for a basic
- * layer. */
-TEST_F(Hwc2Test, SET_CLIENT_TARGET_basic)
-{
-    const Dataspace dataspace = Dataspace::UNKNOWN;
-    const hwc_region_t damage = { };
-    const size_t layerCnt = 1;
-
-    for (auto display : mDisplays) {
-        std::vector<hwc2_config_t> configs;
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_ON));
-
-        ASSERT_NO_FATAL_FAILURE(getDisplayConfigs(display, &configs));
-
-        for (auto config : configs) {
-            Area displayArea;
-            std::vector<hwc2_layer_t> layers;
-
-            ASSERT_NO_FATAL_FAILURE(setActiveConfig(display, config));
-            ASSERT_NO_FATAL_FAILURE(getActiveDisplayArea(display, &displayArea));
-
-            ASSERT_NO_FATAL_FAILURE(createLayers(display, &layers, layerCnt));
-            Hwc2TestLayers testLayers(layers, Hwc2TestCoverage::Basic,
-                    displayArea);
-
-            if (!testLayers.optimizeLayouts())
-                continue;
-
-            Hwc2TestClientTarget testClientTarget;
-
-            do {
-                std::set<hwc2_layer_t> clientLayers;
-                std::set<hwc2_layer_t> clearLayers;
-                uint32_t numTypes, numRequests;
-                bool hasChanges, skip;
-                bool flipClientTarget;
-                buffer_handle_t handle;
-                int32_t acquireFence;
-
-                ASSERT_NO_FATAL_FAILURE(setLayerProperties(display, layers,
-                        &testLayers, &skip));
-                if (skip)
-                    continue;
-
-                ASSERT_NO_FATAL_FAILURE(validateDisplay(display, &numTypes,
-                        &numRequests, &hasChanges));
-                if (hasChanges)
-                    EXPECT_LE(numTypes, layers.size())
-                            << "wrong number of requests";
-
-                ASSERT_NO_FATAL_FAILURE(handleCompositionChanges(display,
-                        testLayers, layers, numTypes, &clientLayers));
-                ASSERT_NO_FATAL_FAILURE(handleRequests(display, layers,
-                        numRequests, &clearLayers, &flipClientTarget));
-                ASSERT_EQ(testClientTarget.getBuffer(testLayers, clientLayers,
-                        clearLayers, flipClientTarget, displayArea, &handle,
-                        &acquireFence), 0);
-                EXPECT_NO_FATAL_FAILURE(setClientTarget(display, handle,
-                        acquireFence, dataspace, damage));
-
-                if (acquireFence >= 0)
-                    close(acquireFence);
-
-            } while (testLayers.advance());
-
-            ASSERT_NO_FATAL_FAILURE(destroyLayers(display, std::move(layers)));
-        }
-
-        ASSERT_NO_FATAL_FAILURE(setPowerMode(display, HWC2_POWER_MODE_OFF));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set a client target for a bad display. */
-TEST_F(Hwc2Test, SET_CLIENT_TARGET_bad_display)
-{
-    hwc2_display_t display;
-    std::vector<hwc2_layer_t> layers;
-    const Area displayArea = {0, 0};
-    Hwc2TestLayers testLayers(layers, Hwc2TestCoverage::Default, displayArea);
-    std::set<hwc2_layer_t> clientLayers;
-    std::set<hwc2_layer_t> flipClientTargetLayers;
-    bool flipClientTarget = true;
-    const Dataspace dataspace = Dataspace::UNKNOWN;
-    const hwc_region_t damage = { };
-    buffer_handle_t handle;
-    int32_t acquireFence;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    Hwc2TestClientTarget testClientTarget;
-
-    ASSERT_EQ(testClientTarget.getBuffer(testLayers, clientLayers,
-            flipClientTargetLayers, flipClientTarget, displayArea, &handle,
-            &acquireFence), 0);
-
-    EXPECT_NO_FATAL_FAILURE(setClientTarget(display, handle, acquireFence,
-            dataspace, damage, &err));
-
-    if (acquireFence >= 0)
-        close(acquireFence);
-
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 default layer. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_default_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions;
-    bool optimize = false;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 2 default layers. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_default_2)
-{
-    const size_t layerCnt = 2;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions;
-    bool optimize = false;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 3 default layers. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_default_3)
-{
-    const size_t layerCnt = 3;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions;
-    bool optimize = false;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 4 default layers. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_default_4)
-{
-    const size_t layerCnt = 4;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions;
-    bool optimize = false;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 5 default layers. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_default_5)
-{
-    const size_t layerCnt = 5;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions;
-    bool optimize = false;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 6 default layers. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_default_6)
-{
-    const size_t layerCnt = 6;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions;
-    bool optimize = false;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * blend mode. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_blend_mode_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::BlendMode, Hwc2TestCoverage::Complete},
-            {Hwc2TestPropertyName::Transform, Hwc2TestCoverage::Basic},
-            {Hwc2TestPropertyName::PlaneAlpha, Hwc2TestCoverage::Basic}};
-    bool optimize = false;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 2 layers with complete coverage of
- * blend mode. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_blend_mode_2)
-{
-    const size_t layerCnt = 2;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::BlendMode, Hwc2TestCoverage::Complete},
-            {Hwc2TestPropertyName::PlaneAlpha, Hwc2TestCoverage::Basic}};
-    bool optimize = false;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * buffer. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_buffer_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::BufferArea, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * color. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_color_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::Composition, Hwc2TestCoverage::Complete},
-            {Hwc2TestPropertyName::Color, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 2 layers with complete coverage of
- * color. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_color_2)
-{
-    const size_t layerCnt = 2;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::Composition, Hwc2TestCoverage::Complete},
-            {Hwc2TestPropertyName::BlendMode, Hwc2TestCoverage::Basic},
-            {Hwc2TestPropertyName::PlaneAlpha, Hwc2TestCoverage::Basic},
-            {Hwc2TestPropertyName::Color, Hwc2TestCoverage::Basic}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * composition. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_composition_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::Composition, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * cursor. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_cursor_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::Composition, Hwc2TestCoverage::Complete},
-            {Hwc2TestPropertyName::CursorPosition, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 2 layers with complete coverage of
- * cursor. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_cursor_2)
-{
-    const size_t layerCnt = 2;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::Composition, Hwc2TestCoverage::Complete},
-            {Hwc2TestPropertyName::CursorPosition, Hwc2TestCoverage::Complete},
-            {Hwc2TestPropertyName::DisplayFrame, Hwc2TestCoverage::Basic}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * dataspace. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_dataspace_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::Dataspace, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * display frame. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_display_frame_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::DisplayFrame, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 2 layers with complete coverage of
- * display frame. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_display_frame_2)
-{
-    const size_t layerCnt = 2;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::DisplayFrame, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 3 layers with complete coverage of
- * display frame. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_display_frame_3)
-{
-    const size_t layerCnt = 3;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::DisplayFrame, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 4 layers with complete coverage of
- * display frame. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_display_frame_4)
-{
-    const size_t layerCnt = 4;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::DisplayFrame, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * plane alpha. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_plane_alpha_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::BlendMode, Hwc2TestCoverage::Basic},
-            {Hwc2TestPropertyName::PlaneAlpha, Hwc2TestCoverage::Complete}};
-    bool optimize = false;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 2 layers with complete coverage of
- * plane alpha. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_plane_alpha_2)
-{
-    const size_t layerCnt = 2;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::BlendMode, Hwc2TestCoverage::Basic},
-            {Hwc2TestPropertyName::PlaneAlpha, Hwc2TestCoverage::Complete}};
-    bool optimize = false;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * source crop. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_source_crop_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::DisplayFrame, Hwc2TestCoverage::Complete},
-            {Hwc2TestPropertyName::SourceCrop, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 2 layers with complete coverage of
- * source crop. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_source_crop_2)
-{
-    const size_t layerCnt = 2;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::DisplayFrame, Hwc2TestCoverage::Complete},
-            {Hwc2TestPropertyName::SourceCrop, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * surface damage. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_surface_damage_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::SurfaceDamage, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * transform. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_transform_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::Transform, Hwc2TestCoverage::Complete}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 2 layers with complete coverage of
- * transform. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_transform_2)
-{
-    const size_t layerCnt = 2;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions =
-            {{Hwc2TestPropertyName::Transform, Hwc2TestCoverage::Complete},
-            {Hwc2TestPropertyName::DisplayFrame, Hwc2TestCoverage::Basic}};
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with complete coverage of
- * basic. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_basic_1)
-{
-    const size_t layerCnt = 1;
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Basic;
-    std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage> exceptions;
-    bool optimize = true;
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplays(layerCnt, coverage, exceptions,
-            optimize));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot present a bad display.  */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_bad_display)
-{
-    hwc2_display_t display;
-    int32_t presentFence;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(presentDisplay(display, &presentFence, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 cannot present an unvalidated display. */
-TEST_F(Hwc2Test, PRESENT_DISPLAY_not_validated)
-{
-    ASSERT_NO_FATAL_FAILURE(displayLayers(Hwc2TestCoverage::Default, 1,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    const std::vector<hwc2_layer_t>& /*layers*/,
-                    Hwc2TestLayers* /*testLayers*/) {
-
-                int32_t presentFence;
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(test->setPowerMode(display,
-                        HWC2_POWER_MODE_ON));
-                ASSERT_NO_FATAL_FAILURE(test->enableVsync(display));
-
-                ASSERT_NO_FATAL_FAILURE(test->waitForVsync());
-
-                ASSERT_NO_FATAL_FAILURE(test->presentDisplay(display,
-                        &presentFence, &err));
-                EXPECT_EQ(err, HWC2_ERROR_NOT_VALIDATED)
-                        << "returned wrong error code";
-
-                ASSERT_NO_FATAL_FAILURE(test->disableVsync(display));
-                ASSERT_NO_FATAL_FAILURE(test->setPowerMode(display,
-                        HWC2_POWER_MODE_OFF));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot get release fences from a bad display. */
-TEST_F(Hwc2Test, GET_RELEASE_FENCES_bad_display)
-{
-    hwc2_display_t display;
-    std::vector<hwc2_layer_t> layers;
-    std::vector<int32_t> fences;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(getReleaseFences(display, &layers, &fences, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-static const std::array<ColorMode, 9> androidColorModes = {{
-    ColorMode::NATIVE,
-    ColorMode::STANDARD_BT601_625,
-    ColorMode::STANDARD_BT601_625_UNADJUSTED,
-    ColorMode::STANDARD_BT601_525,
-    ColorMode::STANDARD_BT601_525_UNADJUSTED,
-    ColorMode::STANDARD_BT709,
-    ColorMode::DCI_P3,
-    ColorMode::SRGB,
-    ColorMode::ADOBE_RGB,
-}};
-
-/* TESTCASE: Tests that the HWC2 can get the color modes for a display. The
- * display must support ColorMode::NATIVE */
-TEST_F(Hwc2Test, GET_COLOR_MODES)
-{
-    ASSERT_NO_FATAL_FAILURE(setActiveDisplayConfig(
-            [] (Hwc2Test* test, hwc2_display_t display) {
-
-                std::vector<ColorMode> colorModes;
-
-                ASSERT_NO_FATAL_FAILURE(test->getColorModes(display,
-                        &colorModes));
-
-                EXPECT_NE(std::count(colorModes.begin(), colorModes.end(),
-                        ColorMode::NATIVE), 0) << "all displays"
-                        " must support ColorMode::NATIVE";
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot get color modes from a bad display. */
-TEST_F(Hwc2Test, GET_COLOR_MODES_bad_display)
-{
-    hwc2_display_t display;
-    std::vector<ColorMode> colorModes;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(getColorModes(display, &colorModes, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 can set the required color mode on a display. */
-TEST_F(Hwc2Test, SET_COLOR_MODES)
-{
-    ASSERT_NO_FATAL_FAILURE(setActiveDisplayConfig(
-            [] (Hwc2Test* test, hwc2_display_t display) {
-
-                const ColorMode colorMode = ColorMode::NATIVE;
-
-                EXPECT_NO_FATAL_FAILURE(test->setColorMode(display, colorMode));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set a color mode on a bad display. */
-TEST_F(Hwc2Test, SET_COLOR_MODES_bad_display)
-{
-    hwc2_display_t display;
-    const ColorMode colorMode = ColorMode::NATIVE;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(setColorMode(display, colorMode, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set an invalid color mode. */
-TEST_F(Hwc2Test, SET_COLOR_MODES_bad_parameter)
-{
-    ASSERT_NO_FATAL_FAILURE(setActiveDisplayConfig(
-            [] (Hwc2Test* test, hwc2_display_t display) {
-
-                const ColorMode colorMode = static_cast<ColorMode>(-1);
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(test->setColorMode(display, colorMode,
-                        &err));
-                EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER)
-                        << "returned wrong error code";
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 either supports or returns error unsupported
- * for all valid color modes. */
-TEST_F(Hwc2Test, SET_COLOR_MODES_unsupported)
-{
-    ASSERT_NO_FATAL_FAILURE(setActiveDisplayConfig(
-            [] (Hwc2Test* test, hwc2_display_t display) {
-
-                for (auto colorMode : androidColorModes) {
-                    hwc2_error_t err = HWC2_ERROR_NONE;
-
-                    ASSERT_NO_FATAL_FAILURE(test->setColorMode(display,
-                            colorMode, &err));
-
-                    EXPECT_TRUE(err == HWC2_ERROR_NONE
-                            || err == HWC2_ERROR_UNSUPPORTED)
-                            << "returned wrong error code";
-                }
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 gets the HDR capabilities for a display and
- * test if they are valid. */
-TEST_F(Hwc2Test, GET_HDR_CAPABILITIES)
-{
-    ASSERT_NO_FATAL_FAILURE(setActiveDisplayConfig(
-            [] (Hwc2Test* test, hwc2_display_t display) {
-
-                std::vector<android_hdr_t> hdrCapabilities;
-                float maxLuminance, maxAverageLuminance, minLuminance;
-
-                EXPECT_NO_FATAL_FAILURE(test->getHdrCapabilities(display,
-                        &hdrCapabilities, &maxLuminance, &maxAverageLuminance,
-                        &minLuminance));
-
-                if (hdrCapabilities.empty())
-                    return;
-
-                EXPECT_GE(maxLuminance, maxAverageLuminance);
-                EXPECT_GE(maxAverageLuminance, minLuminance);
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot get hdr capabilities from a bad display */
-TEST_F(Hwc2Test, GET_HDR_CAPABILITIES_bad_display)
-{
-    hwc2_display_t display;
-    std::vector<android_hdr_t> hdrCapabilities;
-    float maxLuminance, maxAverageLuminance, minLuminance;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(getHdrCapabilities(display, &hdrCapabilities,
-            &maxLuminance, &maxAverageLuminance, &minLuminance, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-static const std::array<float, 16> identityMatrix = {{
-    1.0,  0.0,  0.0,  0.0,
-    0.0,  1.0,  0.0,  0.0,
-    0.0,  0.0,  1.0,  0.0,
-    0.0,  0.0,  0.0,  1.0,
-}};
-
-/* Values for the color transform matrices were precomputed using the source code
- * in surfaceflinger/Effects/Daltonizer.cpp. */
-
-static const std::array<const std::array<float, 16>, 5> exampleMatrices = {{
-    identityMatrix,
-    /* Converts RGB color to the XYZ space */
-    {{ 0.4124, 0.2126, 0.0193, 0,
-       0.3576, 0.7152, 0.1192, 0,
-       0.1805, 0.0722, 0.9505, 0,
-       0     , 0     , 0     , 1 }},
-    /* Protanomaly */
-    {{ 0.068493,  0.931506,  0,  0,
-       0.068493,  0.931507,  0,  0,
-       0.013626, -0.013626,  1,  0,
-       0,         0,         0,  1 }},
-    /* Deuteranomaly */
-    {{ 0.288299, 0.711701,  0,  0,
-       0.052709, 0.947291,  0,  0,
-      -0.257912, 0.257912,  1,  0,
-       0,        0,         0,  1 }},
-    /* Tritanomaly */
-    {{ 1, -0.805712, 0.805712,  0,
-       0,  0.378838, 0.621162,  0,
-       0,  0.104823, 0.895177,  0,
-       0,  0,        0,         1 }},
-}};
-
-/* TESTCASE: Tests that the HWC2 can set the identity color transform */
-TEST_F(Hwc2Test, SET_COLOR_TRANSFORM)
-{
-    ASSERT_NO_FATAL_FAILURE(setActiveDisplayConfig(
-            [] (Hwc2Test* test, hwc2_display_t display) {
-
-                EXPECT_NO_FATAL_FAILURE(test->setColorTransform(display,
-                        identityMatrix, HAL_COLOR_TRANSFORM_IDENTITY));
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set the color transform for a bad
- * display. */
-TEST_F(Hwc2Test, SET_COLOR_TRANSFORM_bad_display)
-{
-    hwc2_display_t display;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(setColorTransform(display, identityMatrix,
-            HAL_COLOR_TRANSFORM_IDENTITY, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set an invalid color transform. */
-TEST_F(Hwc2Test, SET_COLOR_TRANSFORM_bad_parameter)
-{
-    ASSERT_NO_FATAL_FAILURE(setActiveDisplayConfig(
-            [] (Hwc2Test* test, hwc2_display_t display) {
-
-                const android_color_transform_t hint =
-                        static_cast<android_color_transform_t>(-1);
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(test->setColorTransform(display,
-                        identityMatrix, hint, &err));
-                EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER)
-                        << "returned wrong error code";
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 can set an arbitrary color matrix. */
-TEST_F(Hwc2Test, SET_COLOR_TRANSFORM_arbitrary_matrix)
-{
-    ASSERT_NO_FATAL_FAILURE(setActiveDisplayConfig(
-            [] (Hwc2Test* test, hwc2_display_t display) {
-
-                const android_color_transform_t hint =
-                        HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX;
-
-                for (const std::array<float, 16>& matrix : exampleMatrices) {
-                    EXPECT_NO_FATAL_FAILURE(test->setColorTransform(display,
-                            matrix, hint));
-                }
-            }
-    ));
-}
-
-/* TESTCASE: Tests that the HWC2 create an destory virtual displays. */
-TEST_F(Hwc2Test, CREATE_DESTROY_VIRTUAL_DISPLAY)
-{
-    ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(Hwc2TestCoverage::Complete,
-            [] (Hwc2Test* /*test*/, hwc2_display_t /*display*/,
-                    Hwc2TestVirtualDisplay* /*testVirtualDisplay*/) { }));
-}
-
-/* TESTCASE: Tests that the HWC2 can create and destroy multiple virtual
- * displays. */
-TEST_F(Hwc2Test, CREATE_DESTROY_VIRTUAL_DISPLAY_multiple)
-{
-    Hwc2TestVirtualDisplay testVirtualDisplay(Hwc2TestCoverage::Complete);
-    std::vector<hwc2_display_t> displays;
-
-    do {
-        const UnsignedArea& dimension =
-                testVirtualDisplay.getDisplayDimension();
-        android_pixel_format_t desiredFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-        hwc2_display_t display;
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(dimension.width,
-                dimension.height, &desiredFormat, &display, &err));
-
-        EXPECT_TRUE(err == HWC2_ERROR_NONE || err == HWC2_ERROR_NO_RESOURCES
-                || err == HWC2_ERROR_UNSUPPORTED) << "returned wrong error code";
-        EXPECT_GE(desiredFormat, 0) << "invalid format";
-
-        if (err == HWC2_ERROR_NONE)
-            displays.push_back(display);
-
-    } while (testVirtualDisplay.advance());
-
-    for (hwc2_display_t display : displays) {
-        EXPECT_NO_FATAL_FAILURE(destroyVirtualDisplay(display));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 cannot destroy a bad virtual displays.  */
-TEST_F(Hwc2Test, DESTROY_VIRTUAL_DISPLAY_bad_display)
-{
-    hwc2_display_t display;
-    hwc2_error_t err = HWC2_ERROR_NONE;
-
-    ASSERT_NO_FATAL_FAILURE(getBadDisplay(&display));
-
-    ASSERT_NO_FATAL_FAILURE(destroyVirtualDisplay(display, &err));
-    EXPECT_EQ(err, HWC2_ERROR_BAD_DISPLAY) << "returned wrong error code";
-}
-
-/* TESTCASE: Tests that the HWC2 cannot destroy a physical display. */
-TEST_F(Hwc2Test, DESTROY_VIRTUAL_DISPLAY_bad_parameter)
-{
-    hwc2_error_t err = HWC2_ERROR_NONE;
-    for (auto display : mDisplays) {
-        ASSERT_NO_FATAL_FAILURE(destroyVirtualDisplay(display, &err));
-        EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER) << "returned wrong error code";
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 can get the max virtual display count. */
-TEST_F(Hwc2Test, GET_MAX_VIRTUAL_DISPLAY_COUNT)
-{
-    uint32_t maxCnt;
-
-    ASSERT_NO_FATAL_FAILURE(getMaxVirtualDisplayCount(&maxCnt));
-}
-
-/* TESTCASE: Tests that the HWC2 returns the same max virtual display count for
- * each call. */
-TEST_F(Hwc2Test, GET_MAX_VIRTUAL_DISPLAY_COUNT_duplicate)
-{
-    uint32_t maxCnt1, maxCnt2;
-
-    ASSERT_NO_FATAL_FAILURE(getMaxVirtualDisplayCount(&maxCnt1));
-    ASSERT_NO_FATAL_FAILURE(getMaxVirtualDisplayCount(&maxCnt2));
-
-    EXPECT_EQ(maxCnt1, maxCnt2) << "returned two different max virtual display"
-            " counts";
-}
-
-/* TESTCASE: Tests that the HWC2 can create the max number of virtual displays
- * that it reports. */
-TEST_F(Hwc2Test, GET_MAX_VIRTUAL_DISPLAY_COUNT_create_max)
-{
-    std::vector<hwc2_display_t> displays;
-    uint32_t maxCnt;
-
-    ASSERT_NO_FATAL_FAILURE(getMaxVirtualDisplayCount(&maxCnt));
-
-    while (displays.size() < maxCnt) {
-        uint32_t width = 1920, height = 1080;
-        android_pixel_format_t desiredFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-        hwc2_display_t display;
-        hwc2_error_t err = HWC2_ERROR_NONE;
-
-        ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(width, height,
-                    &desiredFormat, &display, &err));
-
-        EXPECT_TRUE(err == HWC2_ERROR_NONE || err == HWC2_ERROR_UNSUPPORTED)
-                << "returned wrong error code";
-        if (err != HWC2_ERROR_NONE)
-            break;
-
-        displays.push_back(display);
-    }
-
-    for (hwc2_display_t display : displays) {
-        EXPECT_NO_FATAL_FAILURE(destroyVirtualDisplay(display));
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 can set an output buffer for a virtual
- * display. */
-TEST_F(Hwc2Test, SET_OUTPUT_BUFFER)
-{
-    ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(Hwc2TestCoverage::Complete,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    Hwc2TestVirtualDisplay* testVirtualDisplay) {
-
-                buffer_handle_t handle;
-                android::base::unique_fd acquireFence;
-
-                if (testVirtualDisplay->getOutputBuffer(&handle, &acquireFence) >= 0)
-                    EXPECT_NO_FATAL_FAILURE(test->setOutputBuffer(display,
-                            handle, acquireFence));
-            }));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set an output buffer for a bad display */
-TEST_F(Hwc2Test, SET_OUTPUT_BUFFER_bad_display)
-{
-    ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(Hwc2TestCoverage::Default,
-            [] (Hwc2Test* test, hwc2_display_t /*display*/,
-                    Hwc2TestVirtualDisplay* testVirtualDisplay) {
-
-                hwc2_display_t badDisplay;
-                buffer_handle_t handle;
-                android::base::unique_fd acquireFence;
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(test->getBadDisplay(&badDisplay));
-
-                if (testVirtualDisplay->getOutputBuffer(&handle, &acquireFence) < 0)
-                    return;
-
-                ASSERT_NO_FATAL_FAILURE(test->setOutputBuffer(badDisplay,
-                        handle, acquireFence, &err));
-                EXPECT_TRUE(err == HWC2_ERROR_BAD_DISPLAY)
-                        << "returned wrong error code";
-            }));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set an invalid output buffer. */
-TEST_F(Hwc2Test, SET_OUTPUT_BUFFER_bad_parameter)
-{
-    ASSERT_NO_FATAL_FAILURE(createVirtualDisplay(Hwc2TestCoverage::Default,
-            [] (Hwc2Test* test, hwc2_display_t display,
-                    Hwc2TestVirtualDisplay* /*testVirtualDisplay*/) {
-
-                const buffer_handle_t handle = nullptr;
-                uint32_t releaseFence = -1;
-                hwc2_error_t err = HWC2_ERROR_NONE;
-
-                ASSERT_NO_FATAL_FAILURE(test->setOutputBuffer(display, handle,
-                        releaseFence, &err));
-                EXPECT_EQ(err, HWC2_ERROR_BAD_PARAMETER)
-                        << "returned wrong error code";
-            }));
-}
-
-/* TESTCASE: Tests that the HWC2 cannot set an output buffer for non virtual
- * display */
-TEST_F(Hwc2Test, SET_OUTPUT_BUFFER_unsupported)
-{
-    for (auto display : mDisplays) {
-        Hwc2TestVirtualDisplay testVirtualDisplay(Hwc2TestCoverage::Complete);
-
-        do {
-            buffer_handle_t handle;
-            android::base::unique_fd acquireFence;
-            hwc2_error_t err = HWC2_ERROR_NONE;
-
-            if (testVirtualDisplay.getOutputBuffer(&handle, &acquireFence) < 0)
-                continue;
-
-            ASSERT_NO_FATAL_FAILURE(setOutputBuffer(display, handle,
-                    acquireFence, &err));
-            EXPECT_EQ(err, HWC2_ERROR_UNSUPPORTED) << "returned wrong error code";
-
-        } while (testVirtualDisplay.advance());
-    }
-}
-
-/* TESTCASE: Tests that the HWC2 can dump debug information. */
-TEST_F(Hwc2Test, DUMP)
-{
-    std::string buffer;
-
-    ASSERT_NO_FATAL_FAILURE(dump(&buffer));
-}
-
-/*
- * TODO(b/64724708): Hwc2TestPropertyName::BufferArea MUST be default for all
- * virtual display tests as we don't handle this case correctly.
- *
- * Only default dataspace is supported in our drawing code.
- */
-const std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage>
-        virtualDisplayExceptions =
-        {{Hwc2TestPropertyName::BufferArea, Hwc2TestCoverage::Default},
-        {Hwc2TestPropertyName::Dataspace, Hwc2TestCoverage::Default}};
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with default coverage on a
- * virtual display. */
-TEST_F(Hwc2Test, PRESENT_VIRTUAL_DISPLAY_default_1)
-{
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    const size_t layerCnt = 1;
-    ASSERT_NO_FATAL_FAILURE(createAndPresentVirtualDisplay(layerCnt, coverage,
-            virtualDisplayExceptions));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 1 layer with basic coverage on a
- * virtual display. */
-TEST_F(Hwc2Test, PRESENT_VIRTUAL_DISPLAY_basic_1)
-{
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Basic;
-    const size_t layerCnt = 1;
-    ASSERT_NO_FATAL_FAILURE(createAndPresentVirtualDisplay(layerCnt, coverage,
-            virtualDisplayExceptions));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 2 layers with default coverage on a
- * virtual display. */
-TEST_F(Hwc2Test, PRESENT_VIRTUAL_DISPLAY_default_2)
-{
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    const size_t layerCnt = 2;
-    ASSERT_NO_FATAL_FAILURE(createAndPresentVirtualDisplay(layerCnt, coverage,
-            virtualDisplayExceptions));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 3 layers with default coverage on a
- * virtual display. */
-TEST_F(Hwc2Test, PRESENT_VIRTUAL_DISPLAY_default_3)
-{
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    const size_t layerCnt = 3;
-    ASSERT_NO_FATAL_FAILURE(createAndPresentVirtualDisplay(layerCnt, coverage,
-            virtualDisplayExceptions));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 4 layers with default coverage on a
- * virtual display. */
-TEST_F(Hwc2Test, PRESENT_VIRTUAL_DISPLAY_default_4)
-{
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    const size_t layerCnt = 4;
-    ASSERT_NO_FATAL_FAILURE(createAndPresentVirtualDisplay(layerCnt, coverage,
-            virtualDisplayExceptions));
-}
-
-/* TESTCASE: Tests that the HWC2 can present 5 layers with default coverage on a
- * virtual display. */
-TEST_F(Hwc2Test, PRESENT_VIRTUAL_DISPLAY_default_5)
-{
-    Hwc2TestCoverage coverage = Hwc2TestCoverage::Default;
-    const size_t layerCnt = 5;
-    ASSERT_NO_FATAL_FAILURE(createAndPresentVirtualDisplay(layerCnt, coverage,
-            virtualDisplayExceptions));
-}
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestBuffer.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestBuffer.cpp
deleted file mode 100644
index fcd0d31..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestBuffer.cpp
+++ /dev/null
@@ -1,798 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-
-#include <mutex>
-#include <array>
-#include <sstream>
-#include <algorithm>
-
-#include <gui/Surface.h>
-#include <gui/BufferItemConsumer.h>
-
-#include <ui/GraphicBuffer.h>
-#include <android/hardware/graphics/common/1.0/types.h>
-#include <math/vec4.h>
-
-#include <GLES3/gl3.h>
-#include <SkImageEncoder.h>
-#include <SkStream.h>
-#include "Hwc2TestBuffer.h"
-#include "Hwc2TestLayers.h"
-
-using namespace android;
-using android::hardware::graphics::common::V1_0::BufferUsage;
-
-/* Returns a fence from egl */
-typedef void (*FenceCallback)(int32_t fence, void* callbackArgs);
-
-/* Returns fence to fence generator */
-static void setFence(int32_t fence, void* fenceGenerator);
-
-
-/* Used to receive the surfaces and fences from egl. The egl buffers are thrown
- * away. The fences are sent to the requester via a callback */
-class Hwc2TestSurfaceManager {
-public:
-    /* Listens for a new frame, detaches the buffer and returns the fence
-     * through saved callback. */
-    class BufferListener : public ConsumerBase::FrameAvailableListener {
-    public:
-        BufferListener(sp<IGraphicBufferConsumer> consumer,
-                FenceCallback callback, void* callbackArgs)
-            : mConsumer(consumer),
-              mCallback(callback),
-              mCallbackArgs(callbackArgs) { }
-
-        void onFrameAvailable(const BufferItem& /*item*/)
-        {
-            BufferItem item;
-
-            if (mConsumer->acquireBuffer(&item, 0))
-                return;
-            if (mConsumer->detachBuffer(item.mSlot))
-                return;
-
-            mCallback(item.mFence->dup(), mCallbackArgs);
-        }
-
-    private:
-        sp<IGraphicBufferConsumer> mConsumer;
-        FenceCallback mCallback;
-        void* mCallbackArgs;
-    };
-
-    /* Creates a buffer listener that waits on a new frame from the buffer
-     * queue. */
-    void initialize(const Area& bufferArea, android_pixel_format_t format,
-            FenceCallback callback, void* callbackArgs)
-    {
-        sp<IGraphicBufferProducer> producer;
-        sp<IGraphicBufferConsumer> consumer;
-        BufferQueue::createBufferQueue(&producer, &consumer);
-
-        consumer->setDefaultBufferSize(bufferArea.width, bufferArea.height);
-        consumer->setDefaultBufferFormat(format);
-
-        mBufferItemConsumer = new BufferItemConsumer(consumer, 0);
-
-        mListener = new BufferListener(consumer, callback, callbackArgs);
-        mBufferItemConsumer->setFrameAvailableListener(mListener);
-
-        mSurface = new Surface(producer, true);
-    }
-
-    /* Used by Egl manager. The surface is never displayed. */
-    sp<Surface> getSurface() const
-    {
-        return mSurface;
-    }
-
-private:
-    sp<BufferItemConsumer> mBufferItemConsumer;
-    sp<BufferListener> mListener;
-    /* Used by Egl manager. The surface is never displayed */
-    sp<Surface> mSurface;
-};
-
-
-/* Used to generate valid fences. It is not possible to create a dummy sync
- * fence for testing. Egl can generate buffers along with a valid fence.
- * The buffer cannot be guaranteed to be the same format across all devices so
- * a CPU filled buffer is used instead. The Egl fence is used along with the
- * CPU filled buffer. */
-class Hwc2TestEglManager {
-public:
-    Hwc2TestEglManager()
-        : mEglDisplay(EGL_NO_DISPLAY),
-          mEglSurface(EGL_NO_SURFACE),
-          mEglContext(EGL_NO_CONTEXT) { }
-
-    ~Hwc2TestEglManager()
-    {
-        cleanup();
-    }
-
-    int initialize(sp<Surface> surface)
-    {
-        mSurface = surface;
-
-        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-        if (mEglDisplay == EGL_NO_DISPLAY) return false;
-
-        EGLint major;
-        EGLint minor;
-        if (!eglInitialize(mEglDisplay, &major, &minor)) {
-            ALOGW("Could not initialize EGL");
-            return false;
-        }
-
-        /* We're going to use a 1x1 pbuffer surface later on
-         * The configuration distance doesn't really matter for what we're
-         * trying to do */
-        EGLint configAttrs[] = {
-                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
-                EGL_RED_SIZE, 8,
-                EGL_GREEN_SIZE, 8,
-                EGL_BLUE_SIZE, 8,
-                EGL_ALPHA_SIZE, 0,
-                EGL_DEPTH_SIZE, 24,
-                EGL_STENCIL_SIZE, 0,
-                EGL_NONE
-        };
-
-        EGLConfig configs[1];
-        EGLint configCnt;
-        if (!eglChooseConfig(mEglDisplay, configAttrs, configs, 1,
-                &configCnt)) {
-            ALOGW("Could not select EGL configuration");
-            eglReleaseThread();
-            eglTerminate(mEglDisplay);
-            return false;
-        }
-
-        if (configCnt <= 0) {
-            ALOGW("Could not find EGL configuration");
-            eglReleaseThread();
-            eglTerminate(mEglDisplay);
-            return false;
-        }
-
-        /* These objects are initialized below but the default "null" values are
-         * used to cleanup properly at any point in the initialization sequence */
-        EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
-        mEglContext = eglCreateContext(mEglDisplay, configs[0], EGL_NO_CONTEXT,
-                attrs);
-        if (mEglContext == EGL_NO_CONTEXT) {
-            ALOGW("Could not create EGL context");
-            cleanup();
-            return false;
-        }
-
-        EGLint surfaceAttrs[] = { EGL_NONE };
-        mEglSurface = eglCreateWindowSurface(mEglDisplay, configs[0],
-                mSurface.get(), surfaceAttrs);
-        if (mEglSurface == EGL_NO_SURFACE) {
-            ALOGW("Could not create EGL surface");
-            cleanup();
-            return false;
-        }
-
-        if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
-            ALOGW("Could not change current EGL context");
-            cleanup();
-            return false;
-        }
-
-        return true;
-    }
-
-    void makeCurrent() const
-    {
-        eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
-    }
-
-    void present() const
-    {
-        eglSwapBuffers(mEglDisplay, mEglSurface);
-    }
-
-private:
-    void cleanup()
-    {
-        if (mEglDisplay == EGL_NO_DISPLAY)
-            return;
-        if (mEglSurface != EGL_NO_SURFACE)
-            eglDestroySurface(mEglDisplay, mEglSurface);
-        if (mEglContext != EGL_NO_CONTEXT)
-            eglDestroyContext(mEglDisplay, mEglContext);
-
-        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
-                EGL_NO_CONTEXT);
-        eglReleaseThread();
-        eglTerminate(mEglDisplay);
-    }
-
-    sp<Surface> mSurface;
-    EGLDisplay mEglDisplay;
-    EGLSurface mEglSurface;
-    EGLContext mEglContext;
-};
-
-
-static const std::array<vec2, 4> triangles = {{
-    {  1.0f,  1.0f },
-    { -1.0f,  1.0f },
-    {  1.0f, -1.0f },
-    { -1.0f, -1.0f },
-}};
-
-class Hwc2TestFenceGenerator {
-public:
-
-    Hwc2TestFenceGenerator()
-    {
-        mSurfaceManager.initialize({1, 1}, HAL_PIXEL_FORMAT_RGBA_8888,
-                setFence, this);
-
-        if (!mEglManager.initialize(mSurfaceManager.getSurface()))
-            return;
-
-        mEglManager.makeCurrent();
-
-        glClearColor(0.0, 0.0, 0.0, 1.0);
-        glEnableVertexAttribArray(0);
-    }
-
-    ~Hwc2TestFenceGenerator()
-    {
-        if (mFence >= 0)
-            close(mFence);
-        mFence = -1;
-
-        mEglManager.makeCurrent();
-    }
-
-    /* It is not possible to simply generate a fence. The easiest way is to
-     * generate a buffer using egl and use the associated fence. The buffer
-     * cannot be guaranteed to be a certain format across all devices using this
-     * method. Instead the buffer is generated using the CPU */
-    int32_t get()
-    {
-        if (mFence >= 0) {
-            return dup(mFence);
-        }
-
-        std::unique_lock<std::mutex> lock(mMutex);
-
-        /* If the pending is still set to false and times out, we cannot recover.
-         * Set an error and return */
-        while (mPending != false) {
-            if (mCv.wait_for(lock, std::chrono::seconds(2)) == std::cv_status::timeout)
-                return -ETIME;
-        }
-
-        /* Generate a fence. The fence will be returned through the setFence
-         * callback */
-        mEglManager.makeCurrent();
-
-        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, triangles.data());
-        glClear(GL_COLOR_BUFFER_BIT);
-
-        mEglManager.present();
-
-        /* Wait for the setFence callback */
-        while (mPending != true) {
-            if (mCv.wait_for(lock, std::chrono::seconds(2)) == std::cv_status::timeout)
-                return -ETIME;
-        }
-
-        mPending = false;
-
-        return dup(mFence);
-    }
-
-    /* Callback that sets the fence */
-    void set(int32_t fence)
-    {
-        mFence = fence;
-        mPending = true;
-
-        mCv.notify_all();
-    }
-
-private:
-
-    Hwc2TestSurfaceManager mSurfaceManager;
-    Hwc2TestEglManager mEglManager;
-
-    std::mutex mMutex;
-    std::condition_variable mCv;
-
-    int32_t mFence = -1;
-    bool mPending = false;
-};
-
-
-static void setFence(int32_t fence, void* fenceGenerator)
-{
-    static_cast<Hwc2TestFenceGenerator*>(fenceGenerator)->set(fence);
-}
-
-
-/* Sets the pixel of a buffer given the location, format, stride and color.
- * Currently only supports RGBA_8888 */
-static void setColor(int32_t x, int32_t y,
-        android_pixel_format_t format, uint32_t stride, uint8_t* img, uint8_t r,
-        uint8_t g, uint8_t b, uint8_t a)
-{
-       switch (format) {
-       case HAL_PIXEL_FORMAT_RGBA_8888:
-           img[(y * stride + x) * 4 + 0] = r;
-           img[(y * stride + x) * 4 + 1] = g;
-           img[(y * stride + x) * 4 + 2] = b;
-           img[(y * stride + x) * 4 + 3] = a;
-           break;
-       default:
-           break;
-       }
-}
-
-Hwc2TestBuffer::Hwc2TestBuffer()
-    : mFenceGenerator(new Hwc2TestFenceGenerator()) { }
-
-Hwc2TestBuffer::~Hwc2TestBuffer() = default;
-
-/* When the buffer changes sizes, save the new size and invalidate the current
- * buffer */
-void Hwc2TestBuffer::updateBufferArea(const Area& bufferArea)
-{
-    if (mBufferArea.width == bufferArea.width
-            && mBufferArea.height == bufferArea.height)
-        return;
-
-    mBufferArea.width = bufferArea.width;
-    mBufferArea.height = bufferArea.height;
-
-    mValidBuffer = false;
-}
-
-/* Returns a valid buffer handle and fence. The handle is filled using the CPU
- * to ensure the correct format across all devices. The fence is created using
- * egl. */
-int Hwc2TestBuffer::get(buffer_handle_t* outHandle, int32_t* outFence)
-{
-    if (mBufferArea.width == -1 || mBufferArea.height == -1)
-        return -EINVAL;
-
-    /* If the current buffer is valid, the previous buffer can be reused.
-     * Otherwise, create new buffer */
-    if (!mValidBuffer) {
-        int ret = generateBuffer();
-        if (ret)
-            return ret;
-    }
-
-    *outFence = mFenceGenerator->get();
-    *outHandle = mHandle;
-
-    mValidBuffer = true;
-
-    return 0;
-}
-
-/* CPU fills a buffer to guarantee the correct buffer format across all
- * devices */
-int Hwc2TestBuffer::generateBuffer()
-{
-    /* Create new graphic buffer with correct dimensions */
-    mGraphicBuffer = new GraphicBuffer(mBufferArea.width, mBufferArea.height,
-            mFormat, BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
-            BufferUsage::COMPOSER_OVERLAY, "hwc2_test_buffer");
-
-    int ret = mGraphicBuffer->initCheck();
-    if (ret) {
-        return ret;
-    }
-    if (!mGraphicBuffer->handle) {
-        return -EINVAL;
-    }
-
-    /* Locks the buffer for writing */
-    uint8_t* img;
-    mGraphicBuffer->lock(static_cast<uint32_t>(BufferUsage::CPU_WRITE_OFTEN),
-            (void**)(&img));
-
-    uint32_t stride = mGraphicBuffer->getStride();
-
-    /* Iterate from the top row of the buffer to the bottom row */
-    for (int32_t y = 0; y < mBufferArea.height; y++) {
-
-        /* Will be used as R, G and B values for pixel colors */
-        uint8_t max = 255;
-        uint8_t min = 0;
-
-        /* Divide the rows into 3 sections. The first section will contain
-         * the lighest colors. The last section will contain the darkest
-         * colors. */
-        if (y < mBufferArea.height * 1.0 / 3.0) {
-            min = 255 / 2;
-        } else if (y >= mBufferArea.height * 2.0 / 3.0) {
-            max = 255 / 2;
-        }
-
-        /* Divide the columns into 3 sections. The first section is red,
-         * the second is green and the third is blue */
-        int32_t x = 0;
-        for (; x < mBufferArea.width / 3; x++) {
-            setColor(x, y, mFormat, stride, img, max, min, min, 255);
-        }
-
-        for (; x < mBufferArea.width * 2 / 3; x++) {
-            setColor(x, y, mFormat, stride, img, min, max, min, 255);
-        }
-
-        for (; x < mBufferArea.width; x++) {
-            setColor(x, y, mFormat, stride, img, min, min, max, 255);
-        }
-    }
-
-    /* Unlock the buffer for reading */
-    mGraphicBuffer->unlock();
-
-    mHandle = mGraphicBuffer->handle;
-
-    return 0;
-}
-
-
-Hwc2TestClientTargetBuffer::Hwc2TestClientTargetBuffer()
-    : mFenceGenerator(new Hwc2TestFenceGenerator()) { }
-
-Hwc2TestClientTargetBuffer::~Hwc2TestClientTargetBuffer() { }
-
-/* Generates a buffer from layersToDraw.
- * Takes into account the individual layer properties such as
- * transform, blend mode, source crop, etc. */
-static void compositeBufferFromLayers(
-        const android::sp<android::GraphicBuffer>& graphicBuffer,
-        android_pixel_format_t format, const Area& bufferArea,
-        const Hwc2TestLayers* testLayers,
-        const std::set<hwc2_layer_t>* layersToDraw,
-        const std::set<hwc2_layer_t>* clearLayers)
-{
-    /* Locks the buffer for writing */
-    uint8_t* img;
-    graphicBuffer->lock(static_cast<uint32_t>(BufferUsage::CPU_WRITE_OFTEN),
-            (void**)(&img));
-
-    uint32_t stride = graphicBuffer->getStride();
-
-    float bWDiv3 = bufferArea.width / 3;
-    float bW2Div3 = bufferArea.width * 2 / 3;
-    float bHDiv3 = bufferArea.height / 3;
-    float bH2Div3 = bufferArea.height * 2 / 3;
-
-    /* Cycle through every pixel in the buffer and determine what color it
-     * should be. */
-    for (int32_t y = 0; y < bufferArea.height; y++) {
-        for (int32_t x = 0; x < bufferArea.width; x++) {
-
-            uint8_t r = 0, g = 0, b = 0;
-            float a = 0.0f;
-
-            /* Cycle through each layer from back to front and
-             * update the pixel color. */
-            for (auto layer = layersToDraw->rbegin();
-                    layer != layersToDraw->rend(); ++layer) {
-
-                const hwc_rect_t df = testLayers->getDisplayFrame(*layer);
-
-                float dfL = df.left;
-                float dfT = df.top;
-                float dfR = df.right;
-                float dfB = df.bottom;
-
-                /* If the pixel location falls outside of the layer display
-                 * frame, skip the layer. */
-                if (x < dfL || x >= dfR || y < dfT || y >= dfB)
-                    continue;
-
-                /* If the device has requested the layer be clear, clear
-                 * the pixel and continue. */
-                if (clearLayers->count(*layer) != 0) {
-                    r = 0;
-                    g = 0;
-                    b = 0;
-                    a = 0.0f;
-                    continue;
-                }
-
-                float planeAlpha = testLayers->getPlaneAlpha(*layer);
-
-                /* If the layer is a solid color, fill the color and
-                 * continue. */
-                if (testLayers->getComposition(*layer)
-                        == HWC2_COMPOSITION_SOLID_COLOR) {
-                    const auto color = testLayers->getColor(*layer);
-                    r = color.r;
-                    g = color.g;
-                    b = color.b;
-                    a = color.a * planeAlpha;
-                    continue;
-                }
-
-                float xPos = x;
-                float yPos = y;
-
-                hwc_transform_t transform = testLayers->getTransform(*layer);
-
-                float dfW = dfR - dfL;
-                float dfH = dfB - dfT;
-
-                /* If a layer has a transform, find which location on the
-                 * layer will end up in the current pixel location. We
-                 * can calculate the color of the current pixel using that
-                 * location. */
-                if (transform > 0) {
-                    /* Change origin to be the center of the layer. */
-                    xPos = xPos - dfL - dfW / 2.0;
-                    yPos = yPos - dfT - dfH / 2.0;
-
-                    /* Flip Horizontal by reflecting across the y axis. */
-                    if (transform & HWC_TRANSFORM_FLIP_H)
-                        xPos = -xPos;
-
-                    /* Flip vertical by reflecting across the x axis. */
-                    if (transform & HWC_TRANSFORM_FLIP_V)
-                        yPos = -yPos;
-
-                    /* Rotate 90 by using a basic linear algebra rotation
-                     * and scaling the result so the display frame remains
-                     * the same. For example, a buffer of size 100x50 should
-                     * rotate 90 degress but remain the same dimension
-                     * (100x50) at the end of the transformation. */
-                    if (transform & HWC_TRANSFORM_ROT_90) {
-                        float tmp = xPos;
-                        xPos = yPos * dfW / dfH;
-                        yPos = -tmp * dfH / dfW;
-                    }
-
-                    /* Change origin back to the top left corner of the
-                     * layer. */
-                    xPos = xPos + dfL + dfW / 2.0;
-                    yPos = yPos + dfT + dfH / 2.0;
-                }
-
-                hwc_frect_t sc = testLayers->getSourceCrop(*layer);
-                float scL = sc.left, scT = sc.top;
-
-                float dfWDivScW = dfW / (sc.right - scL);
-                float dfHDivScH = dfH / (sc.bottom - scT);
-
-                float max = 255, min = 0;
-
-                /* Choose the pixel color. Similar to generateBuffer,
-                 * each layer will be divided into 3x3 colors. Because
-                 * both the source crop and display frame must be taken into
-                 * account, the formulas are more complicated.
-                 *
-                 * If the source crop and display frame were not taken into
-                 * account, we would simply divide the buffer into three
-                 * sections by height. Each section would get one color.
-                 * For example the formula for the first section would be:
-                 *
-                 * if (yPos < bufferArea.height / 3)
-                 *        //Select first section color
-                 *
-                 * However the pixel color is chosen based on the source
-                 * crop and displayed based on the display frame.
-                 *
-                 * If the display frame top was 0 and the source crop height
-                 * and display frame height were the same. The only factor
-                 * would be the source crop top. To calculate the new
-                 * section boundary, the section boundary would be moved up
-                 * by the height of the source crop top. The formula would
-                 * be:
-                 * if (yPos < (bufferArea.height / 3 - sourceCrop.top)
-                 *        //Select first section color
-                 *
-                 * If the display frame top could also vary but source crop
-                 * and display frame heights were the same, the formula
-                 * would be:
-                 * if (yPos < (bufferArea.height / 3 - sourceCrop.top
-                 *              + displayFrameTop)
-                 *        //Select first section color
-                 *
-                 * If the heights were not the same, the conversion between
-                 * the source crop and display frame dimensions must be
-                 * taken into account. The formula would be:
-                 * if (yPos < ((bufferArea.height / 3) - sourceCrop.top)
-                 *              * displayFrameHeight / sourceCropHeight
-                 *              + displayFrameTop)
-                 *        //Select first section color
-                 */
-                if (yPos < ((bHDiv3) - scT) * dfHDivScH + dfT) {
-                    min = 255 / 2;
-                } else if (yPos >= ((bH2Div3) - scT) * dfHDivScH + dfT) {
-                    max = 255 / 2;
-                }
-
-                uint8_t rCur = min, gCur = min, bCur = min;
-                float aCur = 1.0f;
-
-                /* This further divides the color sections from 3 to 3x3.
-                 * The math behind it follows the same logic as the previous
-                 * comment */
-                if (xPos < ((bWDiv3) - scL) * (dfWDivScW) + dfL) {
-                    rCur = max;
-                } else if (xPos < ((bW2Div3) - scL) * (dfWDivScW) + dfL) {
-                    gCur = max;
-                } else {
-                    bCur = max;
-                }
-
-
-                /* Blend the pixel color with the previous layers' pixel
-                 * colors using the plane alpha and blend mode. The final
-                 * pixel color is chosen using the plane alpha and blend
-                 * mode formulas found in hwcomposer2.h */
-                hwc2_blend_mode_t blendMode = testLayers->getBlendMode(*layer);
-
-                if (blendMode == HWC2_BLEND_MODE_PREMULTIPLIED) {
-                    rCur *= planeAlpha;
-                    gCur *= planeAlpha;
-                    bCur *= planeAlpha;
-                }
-
-                aCur *= planeAlpha;
-
-                if (blendMode == HWC2_BLEND_MODE_PREMULTIPLIED) {
-                    r = rCur + r * (1.0 - aCur);
-                    g = gCur + g * (1.0 - aCur);
-                    b = bCur + b * (1.0 - aCur);
-                    a = aCur + a * (1.0 - aCur);
-                } else if (blendMode == HWC2_BLEND_MODE_COVERAGE) {
-                    r = rCur * aCur + r * (1.0 - aCur);
-                    g = gCur * aCur + g * (1.0 - aCur);
-                    b = bCur * aCur + b * (1.0 - aCur);
-                    a = aCur * aCur + a * (1.0 - aCur);
-                } else {
-                    r = rCur;
-                    g = gCur;
-                    b = bCur;
-                    a = aCur;
-                }
-            }
-
-            /* Set the pixel color */
-            setColor(x, y, format, stride, img, r, g, b, a * 255);
-        }
-    }
-
-    graphicBuffer->unlock();
-}
-
-/* Generates a client target buffer using the layers assigned for client
- * composition. Takes into account the individual layer properties such as
- * transform, blend mode, source crop, etc. */
-int Hwc2TestClientTargetBuffer::get(buffer_handle_t* outHandle,
-        int32_t* outFence, const Area& bufferArea,
-        const Hwc2TestLayers* testLayers,
-        const std::set<hwc2_layer_t>* clientLayers,
-        const std::set<hwc2_layer_t>* clearLayers)
-{
-    /* Create new graphic buffer with correct dimensions */
-    mGraphicBuffer = new GraphicBuffer(bufferArea.width, bufferArea.height,
-            mFormat, BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
-            BufferUsage::COMPOSER_OVERLAY, "hwc2_test_buffer");
-
-    int ret = mGraphicBuffer->initCheck();
-    if (ret)
-        return ret;
-
-    if (!mGraphicBuffer->handle)
-        return -EINVAL;
-
-    compositeBufferFromLayers(mGraphicBuffer, mFormat, bufferArea, testLayers,
-            clientLayers, clearLayers);
-
-    *outFence = mFenceGenerator->get();
-    *outHandle = mGraphicBuffer->handle;
-
-    return 0;
-}
-
-void Hwc2TestVirtualBuffer::updateBufferArea(const Area& bufferArea)
-{
-    mBufferArea.width = bufferArea.width;
-    mBufferArea.height = bufferArea.height;
-}
-
-bool Hwc2TestVirtualBuffer::writeBufferToFile(std::string path)
-{
-    SkFILEWStream file(path.c_str());
-    const SkImageInfo info = SkImageInfo::Make(mBufferArea.width,
-            mBufferArea.height, SkColorType::kRGBA_8888_SkColorType,
-            SkAlphaType::kPremul_SkAlphaType);
-
-    uint8_t* img;
-    mGraphicBuffer->lock(static_cast<uint32_t>(BufferUsage::CPU_WRITE_OFTEN),
-            (void**)(&img));
-
-    SkPixmap pixmap(info, img, mGraphicBuffer->getStride());
-    bool result = file.isValid() && SkEncodeImage(&file, pixmap,
-            SkEncodedImageFormat::kPNG, 100);
-
-    mGraphicBuffer->unlock();
-    return result;
-}
-
-/* Generates a buffer that holds the expected result of compositing all of our
- * layers */
-int Hwc2TestExpectedBuffer::generateExpectedBuffer(
-        const Hwc2TestLayers* testLayers,
-        const std::vector<hwc2_layer_t>* allLayers,
-        const std::set<hwc2_layer_t>* clearLayers)
-{
-    mGraphicBuffer = new GraphicBuffer(mBufferArea.width, mBufferArea.height,
-            mFormat, BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN,
-            "hwc2_test_buffer");
-
-    int ret = mGraphicBuffer->initCheck();
-    if (ret)
-        return ret;
-
-    if (!mGraphicBuffer->handle)
-        return -EINVAL;
-
-    const std::set<hwc2_layer_t> allLayerSet(allLayers->begin(),
-            allLayers->end());
-
-    compositeBufferFromLayers(mGraphicBuffer, mFormat, mBufferArea, testLayers,
-            &allLayerSet, clearLayers);
-
-    return 0;
-}
-
-int Hwc2TestOutputBuffer::getOutputBuffer(buffer_handle_t* outHandle,
-        int32_t* outFence)
-{
-    if (mBufferArea.width == -1 || mBufferArea.height == -1)
-        return -EINVAL;
-
-    mGraphicBuffer = new GraphicBuffer(mBufferArea.width, mBufferArea.height,
-            mFormat, BufferUsage::CPU_READ_OFTEN |
-            BufferUsage::GPU_RENDER_TARGET, "hwc2_test_buffer");
-
-    int ret = mGraphicBuffer->initCheck();
-    if (ret)
-        return ret;
-
-    if (!mGraphicBuffer->handle)
-        return -EINVAL;
-
-    *outFence = -1;
-    *outHandle = mGraphicBuffer->handle;
-
-    return 0;
-}
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestBuffer.h b/services/surfaceflinger/tests/hwc2/Hwc2TestBuffer.h
deleted file mode 100644
index fd54fef..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestBuffer.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _HWC2_TEST_BUFFER_H
-#define _HWC2_TEST_BUFFER_H
-
-#include <android-base/unique_fd.h>
-#include <set>
-
-#include <hardware/hwcomposer2.h>
-
-#include <ui/GraphicBuffer.h>
-
-#include "Hwc2TestProperties.h"
-
-class Hwc2TestFenceGenerator;
-class Hwc2TestLayers;
-
-class Hwc2TestBuffer {
-public:
-    Hwc2TestBuffer();
-    ~Hwc2TestBuffer();
-
-    void updateBufferArea(const Area& bufferArea);
-
-    int  get(buffer_handle_t* outHandle, int32_t* outFence);
-
-protected:
-    int generateBuffer();
-
-    android::sp<android::GraphicBuffer> mGraphicBuffer;
-
-    std::unique_ptr<Hwc2TestFenceGenerator> mFenceGenerator;
-
-    Area mBufferArea = {-1, -1};
-    const android_pixel_format_t mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-
-    bool mValidBuffer = false;
-    buffer_handle_t mHandle = nullptr;
-};
-
-
-class Hwc2TestClientTargetBuffer {
-public:
-    Hwc2TestClientTargetBuffer();
-    ~Hwc2TestClientTargetBuffer();
-
-    int  get(buffer_handle_t* outHandle, int32_t* outFence,
-            const Area& bufferArea, const Hwc2TestLayers* testLayers,
-            const std::set<hwc2_layer_t>* clientLayers,
-            const std::set<hwc2_layer_t>* clearLayers);
-
-protected:
-    android::sp<android::GraphicBuffer> mGraphicBuffer;
-
-    std::unique_ptr<Hwc2TestFenceGenerator> mFenceGenerator;
-
-    const android_pixel_format_t mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-};
-
-
-class Hwc2TestVirtualBuffer {
-public:
-    void updateBufferArea(const Area& bufferArea);
-
-    bool writeBufferToFile(std::string path);
-
-    android::sp<android::GraphicBuffer>& graphicBuffer()
-    {
-        return mGraphicBuffer;
-    }
-
-protected:
-    android::sp<android::GraphicBuffer> mGraphicBuffer;
-
-    Area mBufferArea = {-1, -1};
-
-    const android_pixel_format_t mFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-};
-
-
-class Hwc2TestExpectedBuffer : public Hwc2TestVirtualBuffer {
-public:
-    int generateExpectedBuffer(const Hwc2TestLayers* testLayers,
-            const std::vector<hwc2_layer_t>* allLayers,
-            const std::set<hwc2_layer_t>* clearLayers);
-};
-
-
-class Hwc2TestOutputBuffer : public Hwc2TestVirtualBuffer {
-public:
-    int getOutputBuffer(buffer_handle_t* outHandle, int32_t* outFence);
-};
-
-#endif /* ifndef _HWC2_TEST_BUFFER_H */
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.cpp
deleted file mode 100644
index 14c60a7..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sstream>
-
-#include <ui/Rect.h>
-
-#include "Hwc2TestClientTarget.h"
-
-int Hwc2TestClientTarget::getBuffer(const Hwc2TestLayers& testLayers,
-        const std::set<hwc2_layer_t>& clientLayers,
-        const std::set<hwc2_layer_t>& clearLayers, bool flipClientTarget,
-        const Area& displayArea, buffer_handle_t* outHandle,
-        int32_t* outAcquireFence)
-{
-    if (!flipClientTarget) {
-        bool needsClientTarget = false;
-
-        for (auto clientLayer : clientLayers) {
-            if (testLayers.getVisibleRegion(clientLayer).numRects > 0) {
-                needsClientTarget = true;
-                break;
-            }
-        }
-
-        if (!needsClientTarget) {
-           *outHandle = nullptr;
-           *outAcquireFence = -1;
-           return 0;
-        }
-    }
-
-    return mBuffer.get(outHandle, outAcquireFence, displayArea,
-            &testLayers, &clientLayers, &clearLayers);
-}
-
-
-Hwc2TestClientTargetSupport::Hwc2TestClientTargetSupport(
-        Hwc2TestCoverage coverage, const Area& displayArea)
-    : mBufferArea(coverage, displayArea),
-      mDataspace(coverage),
-      mSurfaceDamage(coverage)
-{
-    mBufferArea.setDependent(&mSurfaceDamage);
-}
-
-std::string Hwc2TestClientTargetSupport::dump() const
-{
-    std::stringstream dmp;
-
-    dmp << "client target: \n";
-
-    for (auto property : properties) {
-        dmp << property->dump();
-    }
-
-    return dmp.str();
-}
-
-void Hwc2TestClientTargetSupport::reset()
-{
-    for (auto property : properties) {
-        property->reset();
-    }
-}
-
-bool Hwc2TestClientTargetSupport::advance()
-{
-    for (auto property : properties) {
-        if (property->advance())
-            return true;
-    }
-    return false;
-}
-
-Area Hwc2TestClientTargetSupport::getBufferArea() const
-{
-    return mBufferArea.get();
-}
-
-android::ui::Dataspace Hwc2TestClientTargetSupport::getDataspace() const
-{
-    return mDataspace.get();
-}
-
-const hwc_region_t Hwc2TestClientTargetSupport::getSurfaceDamage() const
-{
-    return mSurfaceDamage.get();
-}
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.h b/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.h
deleted file mode 100644
index 6f4090f..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestClientTarget.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _HWC2_TEST_CLIENT_TARGET_H
-#define _HWC2_TEST_CLIENT_TARGET_H
-
-#include <set>
-
-#define HWC2_INCLUDE_STRINGIFICATION
-#define HWC2_USE_CPP11
-#include <hardware/hwcomposer2.h>
-#undef HWC2_INCLUDE_STRINGIFICATION
-#undef HWC2_USE_CPP11
-
-#include "Hwc2TestProperties.h"
-#include "Hwc2TestLayers.h"
-
-/* Generates client target buffers from client composition layers */
-class Hwc2TestClientTarget {
-public:
-    int getBuffer(const Hwc2TestLayers& layers,
-            const std::set<hwc2_layer_t>& clientLayers,
-            const std::set<hwc2_layer_t>& clearLayers,
-            bool clearClientTarget, const Area& displayArea,
-            buffer_handle_t* outHandle, int32_t* outAcquireFence);
-
-private:
-    Hwc2TestClientTargetBuffer mBuffer;
-};
-
-/* Generates valid client targets to test which ones the device will support */
-class Hwc2TestClientTargetSupport {
-public:
-    Hwc2TestClientTargetSupport(Hwc2TestCoverage coverage,
-            const Area& displayArea);
-
-    std::string dump() const;
-
-    void reset();
-    bool advance();
-
-    Area getBufferArea() const;
-    android::ui::Dataspace getDataspace() const;
-    const hwc_region_t getSurfaceDamage() const;
-
-private:
-    std::array<Hwc2TestContainer*, 3> properties = {{
-        &mDataspace, &mSurfaceDamage, &mBufferArea
-    }};
-
-    Hwc2TestBufferArea mBufferArea;
-    Hwc2TestDataspace mDataspace;
-    Hwc2TestSurfaceDamage mSurfaceDamage;
-};
-
-#endif /* ifndef _HWC2_TEST_CLIENT_TARGET_H */
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.cpp
deleted file mode 100644
index c1c9cc8..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sstream>
-
-#include "Hwc2TestLayer.h"
-
-Hwc2TestCoverage getCoverage(Hwc2TestPropertyName property,
-        Hwc2TestCoverage coverage, const std::unordered_map<Hwc2TestPropertyName,
-        Hwc2TestCoverage>& coverageExceptions) {
-    auto exception = coverageExceptions.find(property);
-    return (exception != coverageExceptions.end())? exception->second : coverage;
-}
-
-Hwc2TestLayer::Hwc2TestLayer(Hwc2TestCoverage coverage,
-        const Area& displayArea)
-    : Hwc2TestLayer(coverage, displayArea,
-            std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage>()) { }
-
-Hwc2TestLayer::Hwc2TestLayer(Hwc2TestCoverage coverage,
-        const Area& displayArea, const std::unordered_map<Hwc2TestPropertyName,
-        Hwc2TestCoverage>& coverageExceptions)
-    : mBlendMode(getCoverage(Hwc2TestPropertyName::BlendMode, coverage,
-           coverageExceptions)),
-      mBufferArea(getCoverage(Hwc2TestPropertyName::BufferArea, coverage,
-           coverageExceptions), displayArea),
-      mColor(getCoverage(Hwc2TestPropertyName::Color, coverage,
-           coverageExceptions)),
-      mComposition(getCoverage(Hwc2TestPropertyName::Composition, coverage,
-           coverageExceptions)),
-      mDataspace(getCoverage(Hwc2TestPropertyName::Dataspace, coverage,
-           coverageExceptions)),
-      mDisplayFrame(getCoverage(Hwc2TestPropertyName::DisplayFrame, coverage,
-           coverageExceptions), displayArea),
-      mPlaneAlpha(getCoverage(Hwc2TestPropertyName::PlaneAlpha, coverage,
-           coverageExceptions)),
-      mSourceCrop(getCoverage(Hwc2TestPropertyName::SourceCrop, coverage,
-           coverageExceptions)),
-      mSurfaceDamage(getCoverage(Hwc2TestPropertyName::SurfaceDamage, coverage,
-           coverageExceptions)),
-      mTransform(getCoverage(Hwc2TestPropertyName::Transform, coverage,
-           coverageExceptions))
-{
-    mBufferArea.setDependent(&mBuffer);
-    mBufferArea.setDependent(&mSourceCrop);
-    mBufferArea.setDependent(&mSurfaceDamage);
-    mBlendMode.setDependent(&mColor);
-}
-
-std::string Hwc2TestLayer::dump() const
-{
-    std::stringstream dmp;
-
-    dmp << "layer: \n";
-
-    for (auto property : mProperties) {
-        dmp << property->dump();
-    }
-
-    dmp << mVisibleRegion.dump();
-    dmp << "\tz order: " << mZOrder << "\n";
-
-    return dmp.str();
-}
-
-int Hwc2TestLayer::getBuffer(buffer_handle_t* outHandle,
-        android::base::unique_fd* outAcquireFence)
-{
-    int32_t acquireFence;
-    int ret = mBuffer.get(outHandle, &acquireFence);
-    outAcquireFence->reset(acquireFence);
-    return ret;
-}
-
-int Hwc2TestLayer::getBuffer(buffer_handle_t* outHandle,
-        int32_t* outAcquireFence)
-{
-    return mBuffer.get(outHandle, outAcquireFence);
-}
-
-void Hwc2TestLayer::setZOrder(uint32_t zOrder)
-{
-    mZOrder = zOrder;
-}
-
-void Hwc2TestLayer::setVisibleRegion(const android::Region& region)
-{
-    return mVisibleRegion.set(region);
-}
-
-void Hwc2TestLayer::reset()
-{
-    mVisibleRegion.release();
-
-    for (auto property : mProperties) {
-        property->reset();
-    }
-}
-
-bool Hwc2TestLayer::advance()
-{
-    for (auto property : mProperties) {
-        if (property->isSupported(mComposition.get()))
-            if (property->advance())
-                return true;
-    }
-    return false;
-}
-
-hwc2_blend_mode_t Hwc2TestLayer::getBlendMode() const
-{
-    return mBlendMode.get();
-}
-
-Area Hwc2TestLayer::getBufferArea() const
-{
-    return mBufferArea.get();
-}
-
-hwc_color_t Hwc2TestLayer::getColor() const
-{
-    return mColor.get();
-}
-
-hwc2_composition_t Hwc2TestLayer::getComposition() const
-{
-    return mComposition.get();
-}
-
-/* The cursor position corresponds to {displayFrame.left, displayFrame.top} */
-hwc_rect_t Hwc2TestLayer::getCursorPosition() const
-{
-    return mDisplayFrame.get();
-}
-
-android::ui::Dataspace Hwc2TestLayer::getDataspace() const
-{
-    return mDataspace.get();
-}
-
-hwc_rect_t Hwc2TestLayer::getDisplayFrame() const
-{
-    return mDisplayFrame.get();
-}
-
-float Hwc2TestLayer::getPlaneAlpha() const
-{
-    return mPlaneAlpha.get();
-}
-
-hwc_frect_t Hwc2TestLayer::getSourceCrop() const
-{
-    return mSourceCrop.get();
-}
-
-hwc_region_t Hwc2TestLayer::getSurfaceDamage() const
-{
-    return mSurfaceDamage.get();
-}
-
-hwc_transform_t Hwc2TestLayer::getTransform() const
-{
-    return mTransform.get();
-}
-
-hwc_region_t Hwc2TestLayer::getVisibleRegion() const
-{
-    return mVisibleRegion.get();
-}
-
-uint32_t Hwc2TestLayer::getZOrder() const
-{
-    return mZOrder;
-}
-
-bool Hwc2TestLayer::advanceBlendMode()
-{
-    return mBlendMode.advance();
-}
-
-bool Hwc2TestLayer::advanceBufferArea()
-{
-    return mBufferArea.advance();
-}
-
-bool Hwc2TestLayer::advanceColor()
-{
-    return mColor.advance();
-}
-
-bool Hwc2TestLayer::advanceComposition()
-{
-    return mComposition.advance();
-}
-
-bool Hwc2TestLayer::advanceCursorPosition()
-{
-    return mDisplayFrame.advance();
-}
-
-bool Hwc2TestLayer::advanceDataspace()
-{
-    return mDataspace.advance();
-}
-
-bool Hwc2TestLayer::advanceDisplayFrame()
-{
-    return mDisplayFrame.advance();
-}
-
-bool Hwc2TestLayer::advancePlaneAlpha()
-{
-    return mPlaneAlpha.advance();
-}
-
-bool Hwc2TestLayer::advanceSourceCrop()
-{
-    return mSourceCrop.advance();
-}
-
-bool Hwc2TestLayer::advanceSurfaceDamage()
-{
-    return mSurfaceDamage.advance();
-}
-
-bool Hwc2TestLayer::advanceTransform()
-{
-    return mTransform.advance();
-}
-
-bool Hwc2TestLayer::advanceVisibleRegion()
-{
-    if (mPlaneAlpha.advance())
-        return true;
-    return mDisplayFrame.advance();
-}
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.h b/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.h
deleted file mode 100644
index 29ae521..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestLayer.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _HWC2_TEST_LAYER_H
-#define _HWC2_TEST_LAYER_H
-
-#include <android-base/unique_fd.h>
-#include <unordered_map>
-
-#include "Hwc2TestBuffer.h"
-#include "Hwc2TestProperties.h"
-
-#define HWC2_INCLUDE_STRINGIFICATION
-#define HWC2_USE_CPP11
-#include <hardware/hwcomposer2.h>
-#undef HWC2_INCLUDE_STRINGIFICATION
-#undef HWC2_USE_CPP11
-
-class Hwc2TestLayer {
-public:
-    Hwc2TestLayer(Hwc2TestCoverage coverage, const Area& displayArea);
-
-    Hwc2TestLayer(Hwc2TestCoverage coverage, const Area& displayArea,
-            const std::unordered_map<Hwc2TestPropertyName,
-            Hwc2TestCoverage>& coverage_exceptions);
-
-    std::string dump() const;
-
-    int getBuffer(buffer_handle_t* outHandle,
-            android::base::unique_fd* outAcquireFence);
-    int getBuffer(buffer_handle_t* outHandle, int32_t* outAcquireFence);
-
-    void setZOrder(uint32_t zOrder);
-    void setVisibleRegion(const android::Region& region);
-
-    void reset();
-    bool advance();
-
-    hwc2_blend_mode_t      getBlendMode() const;
-    Area                   getBufferArea() const;
-    hwc_color_t            getColor() const;
-    hwc2_composition_t     getComposition() const;
-    hwc_rect_t             getCursorPosition() const;
-    android::ui::Dataspace     getDataspace() const;
-    hwc_rect_t             getDisplayFrame() const;
-    float                  getPlaneAlpha() const;
-    hwc_frect_t            getSourceCrop() const;
-    hwc_region_t           getSurfaceDamage() const;
-    hwc_transform_t        getTransform() const;
-    hwc_region_t           getVisibleRegion() const;
-    uint32_t               getZOrder() const;
-
-    bool advanceBlendMode();
-    bool advanceBufferArea();
-    bool advanceColor();
-    bool advanceComposition();
-    bool advanceCursorPosition();
-    bool advanceDataspace();
-    bool advanceDisplayFrame();
-    bool advancePlaneAlpha();
-    bool advanceSourceCrop();
-    bool advanceSurfaceDamage();
-    bool advanceTransform();
-    bool advanceVisibleRegion();
-
-private:
-    std::array<Hwc2TestContainer*, 10> mProperties = {{
-        &mTransform, &mColor, &mDataspace, &mPlaneAlpha, &mSourceCrop,
-        &mSurfaceDamage, &mBlendMode, &mBufferArea, &mDisplayFrame,
-        &mComposition
-    }};
-
-    Hwc2TestBuffer mBuffer;
-
-    Hwc2TestBlendMode mBlendMode;
-    Hwc2TestBufferArea mBufferArea;
-    Hwc2TestColor mColor;
-    Hwc2TestComposition mComposition;
-    Hwc2TestDataspace mDataspace;
-    Hwc2TestDisplayFrame mDisplayFrame;
-    Hwc2TestPlaneAlpha mPlaneAlpha;
-    Hwc2TestSourceCrop mSourceCrop;
-    Hwc2TestSurfaceDamage mSurfaceDamage;
-    Hwc2TestTransform mTransform;
-    Hwc2TestVisibleRegion mVisibleRegion;
-
-    uint32_t mZOrder = UINT32_MAX;
-};
-
-#endif /* ifndef _HWC2_TEST_LAYER_H */
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp
deleted file mode 100644
index b76ace8..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-/* * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-
-#include <sstream>
-#include <gtest/gtest.h>
-
-#include "Hwc2TestLayers.h"
-
-Hwc2TestLayers::Hwc2TestLayers(const std::vector<hwc2_layer_t>& layers,
-        Hwc2TestCoverage coverage, const Area& displayArea)
-    : Hwc2TestLayers(layers, coverage, displayArea,
-            std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage>()) { }
-
-Hwc2TestLayers::Hwc2TestLayers(const std::vector<hwc2_layer_t>& layers,
-        Hwc2TestCoverage coverage, const Area& displayArea,
-        const std::unordered_map<Hwc2TestPropertyName,
-        Hwc2TestCoverage>& coverageExceptions)
-    : mDisplayArea(displayArea)
-{
-    for (auto layer : layers) {
-        mTestLayers.emplace(std::piecewise_construct,
-                std::forward_as_tuple(layer),
-                std::forward_as_tuple(coverage, displayArea, coverageExceptions));
-    }
-
-    /* Iterate over the layers in order and assign z orders in the same order.
-     * This allows us to iterate over z orders in the same way when computing
-     * visible regions */
-    uint32_t nextZOrder = layers.size();
-
-    for (auto& testLayer : mTestLayers) {
-        testLayer.second.setZOrder(nextZOrder--);
-    }
-
-    setVisibleRegions();
-}
-
-std::string Hwc2TestLayers::dump() const
-{
-    std::stringstream dmp;
-    for (auto& testLayer : mTestLayers) {
-        dmp << testLayer.second.dump();
-    }
-    return dmp.str();
-}
-
-void Hwc2TestLayers::reset()
-{
-    for (auto& testLayer : mTestLayers) {
-        testLayer.second.reset();
-    }
-
-    setVisibleRegions();
-}
-
-bool Hwc2TestLayers::advance()
-{
-    auto itr = mTestLayers.begin();
-    bool optimized;
-
-    while (itr != mTestLayers.end()) {
-        if (itr->second.advance()) {
-            optimized = setVisibleRegions();
-            if (!mOptimize || optimized)
-                return true;
-            itr = mTestLayers.begin();
-        } else {
-            itr->second.reset();
-            ++itr;
-        }
-    }
-    return false;
-}
-
-bool Hwc2TestLayers::advanceVisibleRegions()
-{
-    auto itr = mTestLayers.begin();
-    bool optimized;
-
-    while (itr != mTestLayers.end()) {
-        if (itr->second.advanceVisibleRegion()) {
-            optimized = setVisibleRegions();
-            if (!mOptimize || optimized)
-                return true;
-            itr = mTestLayers.begin();
-        } else {
-            itr->second.reset();
-            ++itr;
-        }
-    }
-    return false;
-}
-
-/* Removes layouts that do not cover the entire display.
- * Also removes layouts where a layer is completely blocked from view.
- */
-bool Hwc2TestLayers::optimizeLayouts()
-{
-    mOptimize = true;
-
-    if (setVisibleRegions())
-        return true;
-    return advance();
-}
-
-bool Hwc2TestLayers::contains(hwc2_layer_t layer) const
-{
-    return mTestLayers.count(layer) != 0;
-}
-
-int Hwc2TestLayers::getBuffer(hwc2_layer_t layer, buffer_handle_t* outHandle,
-        int32_t* outAcquireFence)
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getBuffer(outHandle, outAcquireFence);
-}
-
-hwc2_blend_mode_t Hwc2TestLayers::getBlendMode(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getBlendMode();
-}
-
-Area Hwc2TestLayers::getBufferArea(hwc2_layer_t layer) const
-{
-    auto testLayer = mTestLayers.find(layer);
-    if (testLayer == mTestLayers.end())
-        [] () { GTEST_FAIL(); }();
-    return testLayer->second.getBufferArea();
-}
-
-hwc_color_t Hwc2TestLayers::getColor(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getColor();
-}
-
-hwc2_composition_t Hwc2TestLayers::getComposition(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getComposition();
-}
-
-hwc_rect_t Hwc2TestLayers::getCursorPosition(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getCursorPosition();
-}
-
-android::ui::Dataspace Hwc2TestLayers::getDataspace(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getDataspace();
-}
-
-hwc_rect_t Hwc2TestLayers::getDisplayFrame(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getDisplayFrame();
-}
-
-float Hwc2TestLayers::getPlaneAlpha(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getPlaneAlpha();
-}
-
-hwc_frect_t Hwc2TestLayers::getSourceCrop(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getSourceCrop();
-}
-
-hwc_region_t Hwc2TestLayers::getSurfaceDamage(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getSurfaceDamage();
-}
-
-hwc_transform_t Hwc2TestLayers::getTransform(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getTransform();
-}
-
-hwc_region_t Hwc2TestLayers::getVisibleRegion(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getVisibleRegion();
-}
-
-uint32_t Hwc2TestLayers::getZOrder(hwc2_layer_t layer) const
-{
-    if (mTestLayers.count(layer) == 0) {
-        []() { GTEST_FAIL(); }();
-    }
-    return mTestLayers.at(layer).getZOrder();
-}
-
-/* Sets the visible regions for a display. Returns false if the layers do not
- * cover the entire display or if a layer is not visible */
-bool Hwc2TestLayers::setVisibleRegions()
-{
-    /* The region of the display that is covered by layers above the current
-     * layer */
-    android::Region aboveOpaqueLayers;
-
-    bool optimized = true;
-
-    /* Iterate over test layers from max z order to min z order. */
-    for (auto& testLayer : mTestLayers) {
-        android::Region visibleRegion;
-
-        /* Set the visible region of this layer */
-        const hwc_rect_t displayFrame = testLayer.second.getDisplayFrame();
-
-        visibleRegion.set(android::Rect(displayFrame.left, displayFrame.top,
-                displayFrame.right, displayFrame.bottom));
-
-        /* Remove the area covered by opaque layers above this layer
-         * from this layer's visible region */
-        visibleRegion.subtractSelf(aboveOpaqueLayers);
-
-        testLayer.second.setVisibleRegion(visibleRegion);
-
-        /* If a layer is not visible, return false */
-        if (visibleRegion.isEmpty())
-            optimized = false;
-
-        /* If this layer is opaque, store the region it covers */
-        if (testLayer.second.getPlaneAlpha() == 1.0f)
-            aboveOpaqueLayers.orSelf(visibleRegion);
-    }
-
-    /* If the opaque region does not cover the entire display return false */
-    if (!aboveOpaqueLayers.isRect())
-        return false;
-
-    const auto rect = aboveOpaqueLayers.begin();
-    if (rect->left != 0 || rect->top != 0 || rect->right != mDisplayArea.width
-            || rect->bottom != mDisplayArea.height)
-        return false;
-
-    return optimized;
-}
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.h b/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.h
deleted file mode 100644
index 909dd48..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestLayers.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _HWC2_TEST_LAYERS_H
-#define _HWC2_TEST_LAYERS_H
-
-#include <map>
-
-#define HWC2_INCLUDE_STRINGIFICATION
-#define HWC2_USE_CPP11
-#include <hardware/hwcomposer2.h>
-#undef HWC2_INCLUDE_STRINGIFICATION
-#undef HWC2_USE_CPP11
-
-#include "Hwc2TestProperties.h"
-#include "Hwc2TestLayer.h"
-
-class Hwc2TestLayers {
-public:
-    Hwc2TestLayers(const std::vector<hwc2_layer_t>& layers,
-            Hwc2TestCoverage coverage, const Area& displayArea);
-
-    Hwc2TestLayers(const std::vector<hwc2_layer_t>& layers,
-            Hwc2TestCoverage coverage, const Area& displayArea,
-            const std::unordered_map<Hwc2TestPropertyName,
-            Hwc2TestCoverage>& coverageExceptions);
-
-    std::string dump() const;
-
-    void reset();
-
-    bool advance();
-    bool advanceVisibleRegions();
-
-    /* Test cases with multiple layers and property values can take quite some
-     * time to run. A significant amount of time can be spent on test cases
-     * where one layer is changing property values but is not visible. To
-     * decrease runtime, this function can be called. Removes layouts where a
-     * layer is completely blocked from view. It also removes layouts that do
-     * not cover the entire display.*/
-    bool optimizeLayouts();
-
-    bool contains(hwc2_layer_t layer) const;
-
-    int  getBuffer(hwc2_layer_t layer, buffer_handle_t* outHandle,
-            int32_t* outAcquireFence);
-
-    hwc2_blend_mode_t      getBlendMode(hwc2_layer_t layer) const;
-    Area                   getBufferArea(hwc2_layer_t layer) const;
-    hwc_color_t            getColor(hwc2_layer_t layer) const;
-    hwc2_composition_t     getComposition(hwc2_layer_t layer) const;
-    hwc_rect_t             getCursorPosition(hwc2_layer_t layer) const;
-    android::ui::Dataspace     getDataspace(hwc2_layer_t layer) const;
-    hwc_rect_t             getDisplayFrame(hwc2_layer_t layer) const;
-    android_pixel_format_t getFormat(hwc2_layer_t layer) const;
-    float                  getPlaneAlpha(hwc2_layer_t layer) const;
-    hwc_frect_t            getSourceCrop(hwc2_layer_t layer) const;
-    hwc_region_t           getSurfaceDamage(hwc2_layer_t layer) const;
-    hwc_transform_t        getTransform(hwc2_layer_t layer) const;
-    hwc_region_t           getVisibleRegion(hwc2_layer_t layer) const;
-    uint32_t               getZOrder(hwc2_layer_t layer) const;
-
-private:
-    bool setVisibleRegions();
-
-    std::map<hwc2_layer_t, Hwc2TestLayer> mTestLayers;
-
-    Area mDisplayArea;
-
-    bool mOptimize = false;
-};
-
-#endif /* ifndef _HWC2_TEST_LAYERS_H */
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestPixelComparator.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestPixelComparator.cpp
deleted file mode 100644
index 8ca8815..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestPixelComparator.cpp
+++ /dev/null
@@ -1,120 +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.
- */
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-
-#include <sstream>
-#include <android/hardware/graphics/common/1.0/types.h>
-
-#include "Hwc2TestPixelComparator.h"
-
-using android::hardware::graphics::common::V1_0::BufferUsage;
-
-uint32_t ComparatorResult::getPixel(int32_t x, int32_t y, uint32_t stride,
-        uint8_t* img) const
-{
-    uint32_t r = img[(y * stride + x) * 4 + 0];
-    uint32_t g = img[(y * stride + x) * 4 + 1];
-    uint32_t b = img[(y * stride + x) * 4 + 2];
-    uint32_t a = img[(y * stride + x) * 4 + 3];
-
-    uint32_t pixel = 0;
-    pixel |= r;
-    pixel |= g << 8;
-    pixel |= b << 16;
-    pixel |= a << 24;
-    return pixel;
-}
-
-void ComparatorResult::CompareBuffers(
-        android::sp<android::GraphicBuffer>& resultBuffer,
-        android::sp<android::GraphicBuffer>& expectedBuffer)
-{
-    uint8_t* resultBufferImg;
-    uint8_t* expectedBufferImg;
-    resultBuffer->lock(static_cast<uint32_t>(BufferUsage::CPU_READ_OFTEN),
-            (void**)(&resultBufferImg));
-
-    expectedBuffer->lock(static_cast<uint32_t>(BufferUsage::CPU_READ_OFTEN),
-            (void**)(&expectedBufferImg));
-    mComparisons.clear();
-    int32_t mDifferentPixelCount = 0;
-    int32_t mBlankPixelCount = 0;
-
-    for (uint32_t y = 0; y < resultBuffer->getHeight(); y++) {
-        for (uint32_t x = 0; x < resultBuffer->getWidth(); x++) {
-            uint32_t result = getPixel(x, y, resultBuffer->getStride(),
-                    resultBufferImg);
-            uint32_t expected = getPixel(x, y, expectedBuffer->getStride(),
-                    expectedBufferImg);
-
-            if (result == 0)
-                mBlankPixelCount++;
-
-            if (result != expected)
-                mDifferentPixelCount++;
-
-            mComparisons.emplace_back(std::make_tuple(x, y, result, expected));
-        }
-    }
-    resultBuffer->unlock();
-    expectedBuffer->unlock();
-}
-
-std::string ComparatorResult::pixelDiff(uint32_t x, uint32_t y,
-        uint32_t resultPixel, uint32_t expectedPixel) const
-{
-    uint32_t resultAlpha = (resultPixel >> 24) & 0xFF;
-    uint32_t resultBlue = (resultPixel >> 16) & 0xFF;
-    uint32_t resultGreen = (resultPixel >> 8) & 0xFF;
-    uint32_t resultRed = resultPixel & 0xFF;
-
-    uint32_t expectedAlpha = (expectedPixel >> 24) & 0xFF;
-    uint32_t expectedBlue = (expectedPixel >> 16) & 0xFF;
-    uint32_t expectedGreen = (expectedPixel >> 8) & 0xFF;
-    uint32_t expectedRed = expectedPixel & 0xFF;
-
-    std::ostringstream stream;
-
-    stream << "x: " << x << " y: " << y << std::endl;
-    stream << std::hex;
-    stream << "Result pixel:   " << resultRed << "|" << resultGreen << "|"
-           << resultBlue << "|" << resultAlpha << std::endl;
-
-    stream << "Expected pixel: " << expectedRed << "|" << expectedGreen << "|"
-           << expectedBlue << "|" << expectedAlpha << std::endl;
-
-    return stream.str();
-}
-
-std::string ComparatorResult::dumpComparison() const
-{
-    std::ostringstream stream;
-    stream << "Number of different pixels: " << mDifferentPixelCount;
-
-    for (const auto& comparison : mComparisons) {
-        if (std::get<2>(comparison) != std::get<3>(comparison))
-            stream << pixelDiff(std::get<0>(comparison),
-                    std::get<1>(comparison), std::get<2>(comparison),
-                    std::get<3>(comparison));
-    }
-    return stream.str();
-}
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestPixelComparator.h b/services/surfaceflinger/tests/hwc2/Hwc2TestPixelComparator.h
deleted file mode 100644
index 55fa936..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestPixelComparator.h
+++ /dev/null
@@ -1,59 +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.
- */
-#ifndef _HWC2_TEST_PIXEL_COMPARATOR_H
-#define _HWC2_TEST_PIXEL_COMPARATOR_H
-
-#include <ui/GraphicBuffer.h>
-#include <cstdint>
-#include <string>
-#include <utility>
-#include <vector>
-
-class ComparatorResult {
-public:
-    static ComparatorResult& get()
-    {
-        static ComparatorResult instance;
-        return instance;
-    }
-
-    void CompareBuffers(android::sp<android::GraphicBuffer>& resultBuffer,
-            android::sp<android::GraphicBuffer>& expectedBuffer);
-
-    std::string dumpComparison() const;
-
-    ComparatorResult(const ComparatorResult&) = delete;
-    ComparatorResult(ComparatorResult&&) = delete;
-    ComparatorResult& operator=(ComparatorResult const&) = delete;
-    ComparatorResult& operator=(ComparatorResult&&) = delete;
-
-    int32_t getDifferentPixelCount() const { return mDifferentPixelCount; }
-    int32_t getBlankPixelCount() const { return mBlankPixelCount; }
-
-private:
-    ComparatorResult() = default;
-    uint32_t getPixel(int32_t x, int32_t y, uint32_t stride, uint8_t* img) const;
-    std::string pixelDiff(uint32_t x, uint32_t y, uint32_t resultPixel,
-            uint32_t expectedPixel) const;
-
-    int32_t mDifferentPixelCount;
-    int32_t mBlankPixelCount;
-    /* std::tuple<X coordinate, Y coordinate, resultPixel, expectedPixel> */
-    std::vector<std::tuple<uint32_t, uint32_t, uint32_t, uint32_t>>
-            mComparisons;
-};
-
-#endif /* ifndef _HWC2_TEST_PIXEL_COMPARATOR_H */
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.cpp
deleted file mode 100644
index 1efb21e..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.cpp
+++ /dev/null
@@ -1,789 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-
-#include <sstream>
-#include <cutils/log.h>
-#include <ui/Rect.h>
-
-#define HWC2_INCLUDE_STRINGIFICATION
-#define HWC2_USE_CPP11
-#include <hardware/hwcomposer2.h>
-#undef HWC2_INCLUDE_STRINGIFICATION
-#undef HWC2_USE_CPP11
-
-#include "Hwc2TestBuffer.h"
-#include "Hwc2TestProperties.h"
-
-Hwc2TestBufferArea::Hwc2TestBufferArea(Hwc2TestCoverage coverage,
-        const Area& displayArea)
-    : Hwc2TestProperty(mBufferAreas, mCompositionSupport),
-      mScalars((coverage == Hwc2TestCoverage::Complete)? mCompleteScalars:
-            (coverage == Hwc2TestCoverage::Basic)? mBasicScalars:
-            mDefaultScalars),
-      mDisplayArea(displayArea)
-{
-    update();
-}
-
-std::string Hwc2TestBufferArea::dump() const
-{
-    std::stringstream dmp;
-    const Area& curr = get();
-    dmp << "\tbuffer area: width " << curr.width << ", height " << curr.height
-            << "\n";
-    return dmp.str();
-}
-
-void Hwc2TestBufferArea::setDependent(Hwc2TestBuffer* buffer)
-{
-    mBuffer = buffer;
-    if (buffer) {
-        buffer->updateBufferArea(get());
-    }
-}
-
-void Hwc2TestBufferArea::setDependent(Hwc2TestSourceCrop* sourceCrop)
-{
-    mSourceCrop = sourceCrop;
-    if (mSourceCrop) {
-        mSourceCrop->updateBufferArea(get());
-    }
-}
-
-void Hwc2TestBufferArea::setDependent(Hwc2TestSurfaceDamage* surfaceDamage)
-{
-    mSurfaceDamage = surfaceDamage;
-    if (mSurfaceDamage) {
-        mSurfaceDamage->updateBufferArea(get());
-    }
-}
-
-void Hwc2TestBufferArea::update()
-{
-    mBufferAreas.clear();
-
-    if (mDisplayArea.width == 0 && mDisplayArea.height == 0) {
-        mBufferAreas.push_back({0, 0});
-        return;
-    }
-
-    for (auto scalar : mScalars) {
-        mBufferAreas.push_back({static_cast<int32_t>(scalar * mDisplayArea.width),
-                static_cast<int32_t>(scalar * mDisplayArea.height)});
-    }
-
-    updateDependents();
-}
-
-void Hwc2TestBufferArea::updateDependents()
-{
-    const Area& curr = get();
-
-    if (mBuffer)
-        mBuffer->updateBufferArea(curr);
-    if (mSourceCrop)
-        mSourceCrop->updateBufferArea(curr);
-    if (mSurfaceDamage)
-        mSurfaceDamage->updateBufferArea(curr);
-}
-
-const std::vector<float> Hwc2TestBufferArea::mDefaultScalars = {
-    1.0f,
-};
-
-const std::vector<float> Hwc2TestBufferArea::mBasicScalars = {
-    1.0f, 0.5f,
-};
-
-const std::vector<float> Hwc2TestBufferArea::mCompleteScalars = {
-    1.0f, 0.75f, 0.5f
-};
-
-
-Hwc2TestBlendMode::Hwc2TestBlendMode(Hwc2TestCoverage coverage)
-    : Hwc2TestProperty(coverage, mCompleteBlendModes, mBasicBlendModes,
-            mDefaultBlendModes, mCompositionSupport) { }
-
-std::string Hwc2TestBlendMode::dump() const
-{
-    std::stringstream dmp;
-    dmp << "\tblend mode: " << getBlendModeName(get()) << "\n";
-    return dmp.str();
-}
-
-void Hwc2TestBlendMode::setDependent(Hwc2TestColor* color)
-{
-    mColor = color;
-    updateDependents();
-}
-
-void Hwc2TestBlendMode::updateDependents()
-{
-    if (mColor)
-        mColor->updateBlendMode(get());
-}
-
-const std::vector<hwc2_blend_mode_t> Hwc2TestBlendMode::mDefaultBlendModes = {
-    HWC2_BLEND_MODE_NONE,
-};
-
-const std::vector<hwc2_blend_mode_t> Hwc2TestBlendMode::mBasicBlendModes = {
-    HWC2_BLEND_MODE_NONE,
-    HWC2_BLEND_MODE_PREMULTIPLIED,
-};
-
-const std::vector<hwc2_blend_mode_t> Hwc2TestBlendMode::mCompleteBlendModes = {
-    HWC2_BLEND_MODE_NONE,
-    HWC2_BLEND_MODE_PREMULTIPLIED,
-    HWC2_BLEND_MODE_COVERAGE,
-};
-
-
-Hwc2TestColor::Hwc2TestColor(Hwc2TestCoverage coverage,
-        hwc2_blend_mode_t blendMode)
-    : Hwc2TestProperty(mColors, mCompositionSupport),
-      mBaseColors((coverage == Hwc2TestCoverage::Complete)? mCompleteBaseColors:
-            (coverage == Hwc2TestCoverage::Basic)? mBasicBaseColors:
-            mDefaultBaseColors),
-      mBlendMode(blendMode)
-{
-    update();
-}
-
-std::string Hwc2TestColor::dump() const
-{
-    std::stringstream dmp;
-    const hwc_color_t& color = get();
-    dmp << "\tcolor: r " << std::to_string(color.r) << ", g "
-            << std::to_string(color.g) << ", b " << std::to_string(color.b)
-            << ", a " << std::to_string(color.a) << "\n";
-    return dmp.str();
-}
-
-void Hwc2TestColor::updateBlendMode(hwc2_blend_mode_t blendMode)
-{
-    mBlendMode = blendMode;
-    update();
-}
-
-void Hwc2TestColor::update()
-{
-    if (mBlendMode != HWC2_BLEND_MODE_PREMULTIPLIED) {
-        mColors = mBaseColors;
-        return;
-    }
-
-    mColors.clear();
-
-    for (const hwc_color_t& baseColor : mBaseColors) {
-        if (baseColor.a >= baseColor.r && baseColor.a >= baseColor.g
-                && baseColor.a >= baseColor.b) {
-            mColors.push_back(baseColor);
-        }
-    }
-
-}
-
-const std::vector<hwc_color_t> Hwc2TestColor::mDefaultBaseColors = {
-    {UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX},
-};
-
-const std::vector<hwc_color_t> Hwc2TestColor::mBasicBaseColors = {
-    {UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX},
-    {        0,         0,         0,         0},
-};
-
-const std::vector<hwc_color_t> Hwc2TestColor::mCompleteBaseColors = {
-    {UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX},
-    {UINT8_MAX, UINT8_MAX, UINT8_MAX,         0},
-    {UINT8_MAX, UINT8_MAX,         0, UINT8_MAX},
-    {UINT8_MAX, UINT8_MAX,         0,         0},
-    {UINT8_MAX,         0, UINT8_MAX, UINT8_MAX},
-    {UINT8_MAX,         0, UINT8_MAX,         0},
-    {UINT8_MAX,         0,         0, UINT8_MAX},
-    {UINT8_MAX,         0,         0,         0},
-    {        0, UINT8_MAX, UINT8_MAX, UINT8_MAX},
-    {        0, UINT8_MAX, UINT8_MAX,         0},
-    {        0, UINT8_MAX,         0, UINT8_MAX},
-    {        0, UINT8_MAX,         0,         0},
-    {        0,         0, UINT8_MAX, UINT8_MAX},
-    {        0,         0, UINT8_MAX,         0},
-    {        0,         0,         0, UINT8_MAX},
-    {        0,         0,         0,         0},
-};
-
-
-Hwc2TestComposition::Hwc2TestComposition(Hwc2TestCoverage coverage)
-    : Hwc2TestProperty(coverage, mCompleteCompositions, mBasicCompositions,
-            mDefaultCompositions, mCompositionSupport) { }
-
-std::string Hwc2TestComposition::dump() const
-{
-    std::stringstream dmp;
-    dmp << "\tcomposition: " << getCompositionName(get()) << "\n";
-    return dmp.str();
-}
-
-const std::vector<hwc2_composition_t> Hwc2TestComposition::mDefaultCompositions = {
-    HWC2_COMPOSITION_DEVICE,
-};
-
-const std::vector<hwc2_composition_t> Hwc2TestComposition::mBasicCompositions = {
-    HWC2_COMPOSITION_CLIENT,
-    HWC2_COMPOSITION_DEVICE,
-};
-
-const std::vector<hwc2_composition_t> Hwc2TestComposition::mCompleteCompositions = {
-    HWC2_COMPOSITION_CLIENT,
-    HWC2_COMPOSITION_DEVICE,
-    HWC2_COMPOSITION_SOLID_COLOR,
-    HWC2_COMPOSITION_CURSOR,
-    HWC2_COMPOSITION_SIDEBAND,
-};
-
-
-Hwc2TestDataspace::Hwc2TestDataspace(Hwc2TestCoverage coverage)
-    : Hwc2TestProperty(coverage, completeDataspaces, basicDataspaces,
-            defaultDataspaces, mCompositionSupport) { }
-
-std::string Hwc2TestDataspace::dump() const
-{
-    std::stringstream dmp;
-    dmp << "\tdataspace: " << static_cast<int32_t>(get()) << "\n";
-    return dmp.str();
-}
-
-const std::vector<android::ui::Dataspace> Hwc2TestDataspace::defaultDataspaces = {
-    android::ui::Dataspace::UNKNOWN,
-};
-
-const std::vector<android::ui::Dataspace> Hwc2TestDataspace::basicDataspaces = {
-    android::ui::Dataspace::UNKNOWN,
-    android::ui::Dataspace::V0_SRGB,
-};
-
-const std::vector<android::ui::Dataspace> Hwc2TestDataspace::completeDataspaces = {
-    android::ui::Dataspace::UNKNOWN,
-    android::ui::Dataspace::ARBITRARY,
-    android::ui::Dataspace::STANDARD_SHIFT,
-    android::ui::Dataspace::STANDARD_MASK,
-    android::ui::Dataspace::STANDARD_UNSPECIFIED,
-    android::ui::Dataspace::STANDARD_BT709,
-    android::ui::Dataspace::STANDARD_BT601_625,
-    android::ui::Dataspace::STANDARD_BT601_625_UNADJUSTED,
-    android::ui::Dataspace::STANDARD_BT601_525,
-    android::ui::Dataspace::STANDARD_BT601_525_UNADJUSTED,
-    android::ui::Dataspace::STANDARD_BT2020,
-    android::ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE,
-    android::ui::Dataspace::STANDARD_BT470M,
-    android::ui::Dataspace::STANDARD_FILM,
-    android::ui::Dataspace::TRANSFER_SHIFT,
-    android::ui::Dataspace::TRANSFER_MASK,
-    android::ui::Dataspace::TRANSFER_UNSPECIFIED,
-    android::ui::Dataspace::TRANSFER_LINEAR,
-    android::ui::Dataspace::TRANSFER_SRGB,
-    android::ui::Dataspace::TRANSFER_SMPTE_170M,
-    android::ui::Dataspace::TRANSFER_GAMMA2_2,
-    android::ui::Dataspace::TRANSFER_GAMMA2_8,
-    android::ui::Dataspace::TRANSFER_ST2084,
-    android::ui::Dataspace::TRANSFER_HLG,
-    android::ui::Dataspace::RANGE_SHIFT,
-    android::ui::Dataspace::RANGE_MASK,
-    android::ui::Dataspace::RANGE_UNSPECIFIED,
-    android::ui::Dataspace::RANGE_FULL,
-    android::ui::Dataspace::RANGE_LIMITED,
-    android::ui::Dataspace::SRGB_LINEAR,
-    android::ui::Dataspace::V0_SRGB_LINEAR,
-    android::ui::Dataspace::SRGB,
-    android::ui::Dataspace::V0_SRGB,
-    android::ui::Dataspace::JFIF,
-    android::ui::Dataspace::V0_JFIF,
-    android::ui::Dataspace::BT601_625,
-    android::ui::Dataspace::V0_BT601_625,
-    android::ui::Dataspace::BT601_525,
-    android::ui::Dataspace::V0_BT601_525,
-    android::ui::Dataspace::BT709,
-    android::ui::Dataspace::V0_BT709,
-    android::ui::Dataspace::DEPTH,
-};
-
-
-Hwc2TestDisplayDimension::Hwc2TestDisplayDimension(Hwc2TestCoverage coverage)
-    : Hwc2TestProperty(
-            (coverage == Hwc2TestCoverage::Complete)? mCompleteDisplayDimensions:
-            (coverage == Hwc2TestCoverage::Basic)? mBasicDisplayDimensions:
-            mDefaultDisplayDimensions, mCompositionSupport) { }
-
-std::string Hwc2TestDisplayDimension::dump() const
-{
-    std::stringstream dmp;
-    const UnsignedArea& curr = get();
-    dmp << "\tdisplay dimension: " << curr.width<< " x " << curr.height<< "\n";
-    return dmp.str();
-}
-
-void Hwc2TestDisplayDimension::setDependent(Hwc2TestVirtualBuffer* buffer)
-{
-    mBuffers.insert(buffer);
-    updateDependents();
-}
-
-void Hwc2TestDisplayDimension::updateDependents()
-{
-    const UnsignedArea& curr = get();
-
-    for (Hwc2TestVirtualBuffer* buffer : mBuffers)
-        buffer->updateBufferArea({static_cast<int32_t>(curr.width),
-                static_cast<int32_t>(curr.height)});
-}
-
-const std::vector<UnsignedArea>
-        Hwc2TestDisplayDimension::mDefaultDisplayDimensions = {
-    {1920, 1080},
-};
-
-const std::vector<UnsignedArea>
-        Hwc2TestDisplayDimension::mBasicDisplayDimensions = {
-    {640, 480},
-    {1280, 720},
-    {1920, 1080},
-    {1920, 1200},
-};
-
-const std::vector<UnsignedArea>
-        Hwc2TestDisplayDimension::mCompleteDisplayDimensions = {
-    {320, 240},
-    {480, 320},
-    {640, 480},
-    {1280, 720},
-    {1920, 1080},
-    {1920, 1200},
-    {2560, 1440},
-    {2560, 1600},
-    {3840, 2160},
-    {4096, 2160},
-};
-
-
-Hwc2TestDisplayFrame::Hwc2TestDisplayFrame(Hwc2TestCoverage coverage,
-        const Area& displayArea)
-    : Hwc2TestProperty(mDisplayFrames, mCompositionSupport),
-      mFrectScalars((coverage == Hwc2TestCoverage::Complete)? mCompleteFrectScalars:
-            (coverage == Hwc2TestCoverage::Basic)? mBasicFrectScalars:
-            mDefaultFrectScalars),
-      mDisplayArea(displayArea)
-{
-    update();
-}
-
-std::string Hwc2TestDisplayFrame::dump() const
-{
-    std::stringstream dmp;
-    const hwc_rect_t& displayFrame = get();
-    dmp << "\tdisplay frame: left " << displayFrame.left << ", top "
-            << displayFrame.top << ", right " << displayFrame.right
-            << ", bottom " << displayFrame.bottom << "\n";
-    return dmp.str();
-}
-
-void Hwc2TestDisplayFrame::update()
-{
-    mDisplayFrames.clear();
-
-    if (mDisplayArea.width == 0 && mDisplayArea.height == 0) {
-        mDisplayFrames.push_back({0, 0, 0, 0});
-        return;
-    }
-
-    for (const auto& frectScalar : mFrectScalars) {
-        mDisplayFrames.push_back({
-                static_cast<int>(frectScalar.left * mDisplayArea.width),
-                static_cast<int>(frectScalar.top * mDisplayArea.height),
-                static_cast<int>(frectScalar.right * mDisplayArea.width),
-                static_cast<int>(frectScalar.bottom * mDisplayArea.height)});
-    }
-}
-
-const std::vector<hwc_frect_t> Hwc2TestDisplayFrame::mDefaultFrectScalars = {
-    {0.0, 0.0, 1.0, 1.0},
-};
-
-const std::vector<hwc_frect_t> Hwc2TestDisplayFrame::mBasicFrectScalars = {
-    {0.0, 0.0, 1.0, 1.0},
-    {0.0, 0.0, 1.0, 0.05},
-    {0.0, 0.95, 1.0, 1.0},
-};
-
-const std::vector<hwc_frect_t> Hwc2TestDisplayFrame::mCompleteFrectScalars = {
-    {0.0, 0.0, 1.0, 1.0},
-    {0.0, 0.05, 1.0, 0.95},
-    {0.0, 0.05, 1.0, 1.0},
-    {0.0, 0.0, 1.0, 0.05},
-    {0.0, 0.95, 1.0, 1.0},
-    {0.25, 0.0, 0.75, 0.35},
-    {0.25, 0.25, 0.75, 0.75},
-};
-
-
-Hwc2TestPlaneAlpha::Hwc2TestPlaneAlpha(Hwc2TestCoverage coverage)
-    : Hwc2TestProperty(coverage, mCompletePlaneAlphas, mBasicPlaneAlphas,
-            mDefaultPlaneAlphas, mCompositionSupport) { }
-
-std::string Hwc2TestPlaneAlpha::dump() const
-{
-    std::stringstream dmp;
-    dmp << "\tplane alpha: " << get() << "\n";
-    return dmp.str();
-}
-
-const std::vector<float> Hwc2TestPlaneAlpha::mDefaultPlaneAlphas = {
-    1.0f,
-};
-
-const std::vector<float> Hwc2TestPlaneAlpha::mBasicPlaneAlphas = {
-    1.0f, 0.0f,
-};
-
-const std::vector<float> Hwc2TestPlaneAlpha::mCompletePlaneAlphas = {
-    1.0f, 0.75f, 0.5f, 0.25f, 0.0f,
-};
-
-
-Hwc2TestSourceCrop::Hwc2TestSourceCrop(Hwc2TestCoverage coverage,
-        const Area& bufferArea)
-    : Hwc2TestProperty(mSourceCrops, mCompositionSupport),
-      mFrectScalars((coverage == Hwc2TestCoverage::Complete)? mCompleteFrectScalars:
-            (coverage == Hwc2TestCoverage::Basic)? mBasicFrectScalars:
-            mDefaultFrectScalars),
-      mBufferArea(bufferArea)
-{
-    update();
-}
-
-std::string Hwc2TestSourceCrop::dump() const
-{
-    std::stringstream dmp;
-    const hwc_frect_t& sourceCrop = get();
-    dmp << "\tsource crop: left " << sourceCrop.left << ", top "
-            << sourceCrop.top << ", right " << sourceCrop.right << ", bottom "
-            << sourceCrop.bottom << "\n";
-    return dmp.str();
-}
-
-void Hwc2TestSourceCrop::updateBufferArea(const Area& bufferArea)
-{
-    mBufferArea = bufferArea;
-    update();
-}
-
-void Hwc2TestSourceCrop::update()
-{
-    mSourceCrops.clear();
-
-    if (mBufferArea.width == 0 && mBufferArea.height == 0) {
-        mSourceCrops.push_back({0, 0, 0, 0});
-        return;
-    }
-
-    for (const auto& frectScalar : mFrectScalars) {
-        mSourceCrops.push_back({
-                frectScalar.left * mBufferArea.width,
-                frectScalar.top * mBufferArea.height,
-                frectScalar.right * mBufferArea.width,
-                frectScalar.bottom * mBufferArea.height});
-    }
-}
-
-const std::vector<hwc_frect_t> Hwc2TestSourceCrop::mDefaultFrectScalars = {
-    {0.0, 0.0, 1.0, 1.0},
-};
-
-const std::vector<hwc_frect_t> Hwc2TestSourceCrop::mBasicFrectScalars = {
-    {0.0, 0.0, 1.0, 1.0},
-    {0.0, 0.0, 0.5, 0.5},
-    {0.5, 0.5, 1.0, 1.0},
-};
-
-const std::vector<hwc_frect_t> Hwc2TestSourceCrop::mCompleteFrectScalars = {
-    {0.0, 0.0, 1.0, 1.0},
-    {0.0, 0.0, 0.5, 0.5},
-    {0.5, 0.5, 1.0, 1.0},
-    {0.0, 0.0, 0.25, 0.25},
-    {0.25, 0.25, 0.75, 0.75},
-};
-
-
-Hwc2TestSurfaceDamage::Hwc2TestSurfaceDamage(Hwc2TestCoverage coverage)
-    : Hwc2TestProperty(mSurfaceDamages, mCompositionSupport),
-      mRegionScalars((coverage == Hwc2TestCoverage::Complete)? mCompleteRegionScalars:
-            (coverage == Hwc2TestCoverage::Basic)? mBasicRegionScalars:
-            mDefaultRegionScalars)
-{
-    update();
-}
-
-Hwc2TestSurfaceDamage::~Hwc2TestSurfaceDamage()
-{
-    freeSurfaceDamages();
-}
-
-std::string Hwc2TestSurfaceDamage::dump() const
-{
-    std::stringstream dmp;
-
-    const hwc_region_t& curr = get();
-    dmp << "\tsurface damage: region count " << curr.numRects << "\n";
-    for (size_t i = 0; i < curr.numRects; i++) {
-        const hwc_rect_t& rect = curr.rects[i];
-        dmp << "\t\trect: left " << rect.left << ", top " << rect.top
-                << ", right " << rect.right << ", bottom " << rect.bottom << "\n";
-    }
-
-    return dmp.str();
-}
-
-void Hwc2TestSurfaceDamage::updateBufferArea(const Area& bufferArea)
-{
-    mBufferArea = bufferArea;
-    update();
-}
-
-void Hwc2TestSurfaceDamage::update()
-{
-    freeSurfaceDamages();
-
-    if (mBufferArea.width == 0 && mBufferArea.height == 0) {
-        mSurfaceDamages.push_back({0, nullptr});
-        return;
-    }
-
-    hwc_region_t damage;
-
-    for (const auto& regionScalar : mRegionScalars) {
-        damage.numRects = regionScalar.size();
-
-        if (damage.numRects > 0) {
-            hwc_rect_t* rects = new hwc_rect_t[damage.numRects];
-            if (!rects) {
-                ALOGW("failed to allocate new hwc_rect_t array");
-                continue;
-            }
-
-            for (size_t i = 0; i < damage.numRects; i++) {
-                rects[i].left = regionScalar[i].left * mBufferArea.width;
-                rects[i].top = regionScalar[i].top * mBufferArea.height;
-                rects[i].right = regionScalar[i].right * mBufferArea.width;
-                rects[i].bottom = regionScalar[i].bottom * mBufferArea.height;
-            }
-
-            damage.rects = static_cast<hwc_rect_t const*>(rects);
-        } else {
-            damage.rects = nullptr;
-        }
-
-        mSurfaceDamages.push_back(damage);
-    }
-}
-
-void Hwc2TestSurfaceDamage::freeSurfaceDamages()
-{
-    for (const auto& surfaceDamage : mSurfaceDamages) {
-        if (surfaceDamage.numRects > 0 && surfaceDamage.rects)
-            delete[] surfaceDamage.rects;
-    }
-    mSurfaceDamages.clear();
-}
-
-const std::vector<std::vector<hwc_frect_t>> Hwc2TestSurfaceDamage::mDefaultRegionScalars = {
-    {{}},
-};
-
-const std::vector<std::vector<hwc_frect_t>> Hwc2TestSurfaceDamage::mBasicRegionScalars = {
-    {{}},
-    {{0.0, 0.0, 1.0, 1.0}},
-};
-
-const std::vector<std::vector<hwc_frect_t>> Hwc2TestSurfaceDamage::mCompleteRegionScalars = {
-    {{}},
-    {{0.0, 0.0, 1.0, 1.0}},
-    {{0.0, 0.0, 0.5, 0.5}, {0.5, 0.5, 1.0, 1.0}},
-};
-
-
-Hwc2TestTransform::Hwc2TestTransform(Hwc2TestCoverage coverage)
-    : Hwc2TestProperty(coverage, mCompleteTransforms, mBasicTransforms,
-            mDefaultTransforms, mCompositionSupport) { }
-
-std::string Hwc2TestTransform::dump() const
-{
-    std::stringstream dmp;
-    dmp << "\ttransform: " << getTransformName(get()) << "\n";
-    return dmp.str();
-}
-
-const std::vector<hwc_transform_t> Hwc2TestTransform::mDefaultTransforms = {
-    static_cast<hwc_transform_t>(0),
-};
-
-const std::vector<hwc_transform_t> Hwc2TestTransform::mBasicTransforms = {
-    static_cast<hwc_transform_t>(0),
-    HWC_TRANSFORM_FLIP_H,
-    HWC_TRANSFORM_FLIP_V,
-    HWC_TRANSFORM_ROT_90,
-};
-
-const std::vector<hwc_transform_t> Hwc2TestTransform::mCompleteTransforms = {
-    static_cast<hwc_transform_t>(0),
-    HWC_TRANSFORM_FLIP_H,
-    HWC_TRANSFORM_FLIP_V,
-    HWC_TRANSFORM_ROT_90,
-    HWC_TRANSFORM_ROT_180,
-    HWC_TRANSFORM_ROT_270,
-    HWC_TRANSFORM_FLIP_H_ROT_90,
-    HWC_TRANSFORM_FLIP_V_ROT_90,
-};
-
-
-Hwc2TestVisibleRegion::~Hwc2TestVisibleRegion()
-{
-    release();
-}
-
-std::string Hwc2TestVisibleRegion::dump() const
-{
-    std::stringstream dmp;
-
-    const hwc_region_t& curr = get();
-    dmp << "\tvisible region: region count " << curr.numRects << "\n";
-    for (size_t i = 0; i < curr.numRects; i++) {
-        const hwc_rect_t& rect = curr.rects[i];
-        dmp << "\t\trect: left " << rect.left << ", top " << rect.top
-                << ", right " << rect.right << ", bottom " << rect.bottom << "\n";
-    }
-
-    return dmp.str();
-}
-
-void Hwc2TestVisibleRegion::set(const android::Region& visibleRegion)
-{
-    release();
-
-    size_t size = 0;
-    const android::Rect* rects = visibleRegion.getArray(&size);
-
-    mVisibleRegion.numRects = size;
-    mVisibleRegion.rects = nullptr;
-
-    if (size > 0) {
-        hwc_rect_t* hwcRects = new hwc_rect_t[size];
-        for (size_t i = 0; i < size; i++) {
-            hwcRects[i].left = rects[i].left;
-            hwcRects[i].top = rects[i].top;
-            hwcRects[i].right = rects[i].right;
-            hwcRects[i].bottom = rects[i].bottom;
-        }
-        mVisibleRegion.rects = hwcRects;
-    }
-}
-
-hwc_region_t Hwc2TestVisibleRegion::get() const
-{
-    return mVisibleRegion;
-}
-
-void Hwc2TestVisibleRegion::release()
-{
-    if (mVisibleRegion.numRects > 0 && mVisibleRegion.rects)
-        delete[] mVisibleRegion.rects;
-    mVisibleRegion.rects = nullptr;
-    mVisibleRegion.numRects = 0;
-}
-
-/* Identifies which layer properties are supported by each composition type.
- * hwc2_composition_t values range from:
- *  HWC2_COMPOSITION_INVALID = 0,
- *  HWC2_COMPOSITION_CLIENT = 1,
- *  HWC2_COMPOSITION_DEVICE = 2,
- *  HWC2_COMPOSITION_SOLID_COLOR = 3,
- *  HWC2_COMPOSITION_CURSOR = 4,
- *  HWC2_COMPOSITION_SIDEBAND = 5,
- *
- * Each property array can be indexed by a hwc2_composition_t value.
- * By using an array instead of a more complex data structure, runtimes for
- * some test cases showed a noticeable improvement.
- */
-
-/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
-const std::array<bool, 6> Hwc2TestBufferArea::mCompositionSupport = {{
-    false,   true,    true,    false,   true,    true,
-}};
-
-/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
-const std::array<bool, 6> Hwc2TestBlendMode::mCompositionSupport = {{
-    false,   true,    true,    false,   true,    true,
-}};
-
-/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
-const std::array<bool, 6> Hwc2TestColor::mCompositionSupport = {{
-    false,   false,   false,   true,    false,   false,
-}};
-
-/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
-const std::array<bool, 6> Hwc2TestComposition::mCompositionSupport = {{
-    false,   true,    true,    true,    true,    true,
-}};
-
-/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
-const std::array<bool, 6> Hwc2TestDataspace::mCompositionSupport = {{
-    false,   true,    true,    true,    true,    false,
-}};
-
-/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
-const std::array<bool, 6> Hwc2TestDisplayDimension::mCompositionSupport = {{
-    false,   true,    true,    true,    true,    true,
-}};
-
-/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
-const std::array<bool, 6> Hwc2TestDisplayFrame::mCompositionSupport = {{
-    false,   true,    true,    true,    false,   true,
-}};
-
-/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
-const std::array<bool, 6> Hwc2TestPlaneAlpha::mCompositionSupport = {{
-    false,   true,    true,    true,    true,    true,
-}};
-
-/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
-const std::array<bool, 6> Hwc2TestSourceCrop::mCompositionSupport = {{
-    false,   true,    true,    false,   true,    false,
-}};
-
-/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
-const std::array<bool, 6> Hwc2TestSurfaceDamage::mCompositionSupport = {{
-    false,   false,   true,    false,   true,    false,
-}};
-
-/*  INVALID  CLIENT   DEVICE   COLOR    CURSOR   SIDEBAND */
-const std::array<bool, 6> Hwc2TestTransform::mCompositionSupport = {{
-    false,   true,    true,    false,   true,    true,
-}};
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h b/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h
deleted file mode 100644
index 06ae314..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestProperties.h
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _HWC2_TEST_PROPERTIES_H
-#define _HWC2_TEST_PROPERTIES_H
-
-#include <array>
-#include <vector>
-
-#include <ui/GraphicTypes.h>
-#include <ui/Region.h>
-
-#define HWC2_INCLUDE_STRINGIFICATION
-#define HWC2_USE_CPP11
-#include <hardware/hwcomposer2.h>
-#undef HWC2_INCLUDE_STRINGIFICATION
-#undef HWC2_USE_CPP11
-
-enum class Hwc2TestCoverage {
-    Default = 0,
-    Basic,
-    Complete,
-};
-
-enum class Hwc2TestPropertyName {
-    BlendMode = 1,
-    BufferArea,
-    Color,
-    Composition,
-    CursorPosition,
-    Dataspace,
-    DisplayFrame,
-    PlaneAlpha,
-    SourceCrop,
-    SurfaceDamage,
-    Transform,
-};
-
-typedef struct {
-    int32_t width;
-    int32_t height;
-} Area;
-
-
-typedef struct {
-    uint32_t width;
-    uint32_t height;
-} UnsignedArea;
-
-
-class Hwc2TestContainer {
-public:
-    virtual ~Hwc2TestContainer() = default;
-
-    /* Resets the container */
-    virtual void reset() = 0;
-
-    /* Attempts to advance to the next valid value. Returns true if one can be
-     * found */
-    virtual bool advance() = 0;
-
-    virtual std::string dump() const = 0;
-
-    /* Returns true if the container supports the given composition type */
-    virtual bool isSupported(hwc2_composition_t composition) = 0;
-};
-
-
-template <class T>
-class Hwc2TestProperty : public Hwc2TestContainer {
-public:
-    Hwc2TestProperty(Hwc2TestCoverage coverage,
-            const std::vector<T>& completeList, const std::vector<T>& basicList,
-            const std::vector<T>& defaultList,
-            const std::array<bool, 6>& compositionSupport)
-        : Hwc2TestProperty((coverage == Hwc2TestCoverage::Complete)? completeList:
-                (coverage == Hwc2TestCoverage::Basic)? basicList : defaultList,
-                compositionSupport) { }
-
-    Hwc2TestProperty(const std::vector<T>& list,
-            const std::array<bool, 6>& compositionSupport)
-        : mList(list),
-          mCompositionSupport(compositionSupport) { }
-
-    void reset() override
-    {
-        mListIdx = 0;
-    }
-
-    bool advance() override
-    {
-        if (mListIdx + 1 < mList.size()) {
-            mListIdx++;
-            updateDependents();
-            return true;
-        }
-        reset();
-        updateDependents();
-        return false;
-    }
-
-    T get() const
-    {
-        return mList.at(mListIdx);
-    }
-
-    virtual bool isSupported(hwc2_composition_t composition)
-    {
-        return mCompositionSupport.at(composition);
-    }
-
-protected:
-    /* If a derived class has dependents, override this function */
-    virtual void updateDependents() { }
-
-    const std::vector<T>& mList;
-    size_t mListIdx = 0;
-
-    const std::array<bool, 6>& mCompositionSupport;
-};
-
-class Hwc2TestBuffer;
-class Hwc2TestSourceCrop;
-class Hwc2TestSurfaceDamage;
-
-class Hwc2TestBufferArea : public Hwc2TestProperty<Area> {
-public:
-    Hwc2TestBufferArea(Hwc2TestCoverage coverage, const Area& displayArea);
-
-    std::string dump() const override;
-
-    void setDependent(Hwc2TestBuffer* buffer);
-    void setDependent(Hwc2TestSourceCrop* sourceCrop);
-    void setDependent(Hwc2TestSurfaceDamage* surfaceDamage);
-
-protected:
-    void update();
-    void updateDependents() override;
-
-    const std::vector<float>& mScalars;
-    static const std::vector<float> mDefaultScalars;
-    static const std::vector<float> mBasicScalars;
-    static const std::vector<float> mCompleteScalars;
-
-    Area mDisplayArea;
-
-    Hwc2TestBuffer* mBuffer = nullptr;
-    Hwc2TestSourceCrop* mSourceCrop = nullptr;
-    Hwc2TestSurfaceDamage* mSurfaceDamage = nullptr;
-
-    std::vector<Area> mBufferAreas;
-
-    static const std::array<bool, 6> mCompositionSupport;
-};
-
-
-class Hwc2TestColor;
-
-class Hwc2TestBlendMode : public Hwc2TestProperty<hwc2_blend_mode_t> {
-public:
-    explicit Hwc2TestBlendMode(Hwc2TestCoverage coverage);
-
-    std::string dump() const override;
-
-    void setDependent(Hwc2TestColor* color);
-
-protected:
-    void updateDependents() override;
-
-    Hwc2TestColor* mColor = nullptr;
-
-    static const std::vector<hwc2_blend_mode_t> mDefaultBlendModes;
-    static const std::vector<hwc2_blend_mode_t> mBasicBlendModes;
-    static const std::vector<hwc2_blend_mode_t> mCompleteBlendModes;
-
-    static const std::array<bool, 6> mCompositionSupport;
-};
-
-
-class Hwc2TestColor : public Hwc2TestProperty<hwc_color_t> {
-public:
-    explicit Hwc2TestColor(Hwc2TestCoverage coverage,
-                           hwc2_blend_mode_t blendMode = HWC2_BLEND_MODE_NONE);
-
-    std::string dump() const override;
-
-    void updateBlendMode(hwc2_blend_mode_t blendMode);
-
-protected:
-    void update();
-
-    std::vector<hwc_color_t> mBaseColors;
-    static const std::vector<hwc_color_t> mDefaultBaseColors;
-    static const std::vector<hwc_color_t> mBasicBaseColors;
-    static const std::vector<hwc_color_t> mCompleteBaseColors;
-
-    hwc2_blend_mode_t mBlendMode;
-
-    std::vector<hwc_color_t> mColors;
-
-    static const std::array<bool, 6> mCompositionSupport;
-};
-
-
-class Hwc2TestComposition : public Hwc2TestProperty<hwc2_composition_t> {
-public:
-    explicit Hwc2TestComposition(Hwc2TestCoverage coverage);
-
-    std::string dump() const override;
-
-protected:
-    static const std::vector<hwc2_composition_t> mDefaultCompositions;
-    static const std::vector<hwc2_composition_t> mBasicCompositions;
-    static const std::vector<hwc2_composition_t> mCompleteCompositions;
-
-    static const std::array<bool, 6> mCompositionSupport;
-};
-
-
-class Hwc2TestDataspace : public Hwc2TestProperty<android::ui::Dataspace> {
-public:
-    explicit Hwc2TestDataspace(Hwc2TestCoverage coverage);
-
-    std::string dump() const override;
-
-protected:
-    static const std::vector<android::ui::Dataspace> defaultDataspaces;
-    static const std::vector<android::ui::Dataspace> basicDataspaces;
-    static const std::vector<android::ui::Dataspace> completeDataspaces;
-
-    static const std::array<bool, 6> mCompositionSupport;
-};
-
-class Hwc2TestVirtualBuffer;
-
-class Hwc2TestDisplayDimension : public Hwc2TestProperty<UnsignedArea> {
-public:
-    explicit Hwc2TestDisplayDimension(Hwc2TestCoverage coverage);
-
-    std::string dump() const;
-
-    void setDependent(Hwc2TestVirtualBuffer* buffer);
-
-private:
-    void updateDependents();
-
-    std::set<Hwc2TestVirtualBuffer*> mBuffers;
-
-    static const std::vector<UnsignedArea> mDefaultDisplayDimensions;
-    static const std::vector<UnsignedArea> mBasicDisplayDimensions;
-    static const std::vector<UnsignedArea> mCompleteDisplayDimensions;
-
-    static const std::array<bool, 6> mCompositionSupport;
-};
-
-
-class Hwc2TestDisplayFrame : public Hwc2TestProperty<hwc_rect_t> {
-public:
-    Hwc2TestDisplayFrame(Hwc2TestCoverage coverage, const Area& displayArea);
-
-    std::string dump() const override;
-
-protected:
-    void update();
-
-    const std::vector<hwc_frect_t>& mFrectScalars;
-    const static std::vector<hwc_frect_t> mDefaultFrectScalars;
-    const static std::vector<hwc_frect_t> mBasicFrectScalars;
-    const static std::vector<hwc_frect_t> mCompleteFrectScalars;
-
-    Area mDisplayArea;
-
-    std::vector<hwc_rect_t> mDisplayFrames;
-
-    static const std::array<bool, 6> mCompositionSupport;
-};
-
-
-class Hwc2TestPlaneAlpha : public Hwc2TestProperty<float> {
-public:
-    explicit Hwc2TestPlaneAlpha(Hwc2TestCoverage coverage);
-
-    std::string dump() const override;
-
-protected:
-    static const std::vector<float> mDefaultPlaneAlphas;
-    static const std::vector<float> mBasicPlaneAlphas;
-    static const std::vector<float> mCompletePlaneAlphas;
-
-    static const std::array<bool, 6> mCompositionSupport;
-};
-
-
-class Hwc2TestSourceCrop : public Hwc2TestProperty<hwc_frect_t> {
-public:
-    explicit Hwc2TestSourceCrop(Hwc2TestCoverage coverage, const Area& bufferArea = {0, 0});
-
-    std::string dump() const override;
-
-    void updateBufferArea(const Area& bufferArea);
-
-protected:
-    void update();
-
-    const std::vector<hwc_frect_t>& mFrectScalars;
-    const static std::vector<hwc_frect_t> mDefaultFrectScalars;
-    const static std::vector<hwc_frect_t> mBasicFrectScalars;
-    const static std::vector<hwc_frect_t> mCompleteFrectScalars;
-
-    Area mBufferArea;
-
-    std::vector<hwc_frect_t> mSourceCrops;
-
-    static const std::array<bool, 6> mCompositionSupport;
-};
-
-
-class Hwc2TestSurfaceDamage : public Hwc2TestProperty<hwc_region_t> {
-public:
-    explicit Hwc2TestSurfaceDamage(Hwc2TestCoverage coverage);
-    ~Hwc2TestSurfaceDamage();
-
-    std::string dump() const override;
-
-    void updateBufferArea(const Area& bufferArea);
-
-protected:
-    void update();
-    void freeSurfaceDamages();
-
-    const std::vector<std::vector<hwc_frect_t>> &mRegionScalars;
-    const static std::vector<std::vector<hwc_frect_t>> mDefaultRegionScalars;
-    const static std::vector<std::vector<hwc_frect_t>> mBasicRegionScalars;
-    const static std::vector<std::vector<hwc_frect_t>> mCompleteRegionScalars;
-
-    Area mBufferArea = {0, 0};
-
-    std::vector<hwc_region_t> mSurfaceDamages;
-
-    static const std::array<bool, 6> mCompositionSupport;
-};
-
-
-class Hwc2TestTransform : public Hwc2TestProperty<hwc_transform_t> {
-public:
-    explicit Hwc2TestTransform(Hwc2TestCoverage coverage);
-
-    std::string dump() const override;
-
-protected:
-    static const std::vector<hwc_transform_t> mDefaultTransforms;
-    static const std::vector<hwc_transform_t> mBasicTransforms;
-    static const std::vector<hwc_transform_t> mCompleteTransforms;
-
-    static const std::array<bool, 6> mCompositionSupport;
-};
-
-
-class Hwc2TestVisibleRegion {
-public:
-    ~Hwc2TestVisibleRegion();
-
-    std::string dump() const;
-
-    void set(const android::Region& visibleRegion);
-    hwc_region_t get() const;
-    void release();
-
-protected:
-    hwc_region_t mVisibleRegion = {0, nullptr};
-};
-
-#endif /* ifndef _HWC2_TEST_PROPERTIES_H */
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.cpp
deleted file mode 100644
index e6cceb8..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sstream>
-#include <sys/stat.h>
-
-#include "Hwc2TestVirtualDisplay.h"
-
-#define DIR_NAME "images"
-
-Hwc2TestVirtualDisplay::Hwc2TestVirtualDisplay(
-        Hwc2TestCoverage coverage)
-    : mDisplayDimension(coverage)
-{
-    mDisplayDimension.setDependent(&mOutputBuffer);
-    mDisplayDimension.setDependent(&mExpectedBuffer);
-}
-
-std::string Hwc2TestVirtualDisplay::dump() const
-{
-    std::stringstream dmp;
-
-    dmp << "virtual display: \n";
-
-    mDisplayDimension.dump();
-
-    return dmp.str();
-}
-
-int Hwc2TestVirtualDisplay::getOutputBuffer(buffer_handle_t* outHandle,
-        android::base::unique_fd* outAcquireFence)
-{
-    int32_t acquireFence;
-    int ret = mOutputBuffer.getOutputBuffer(outHandle, &acquireFence);
-    outAcquireFence->reset(acquireFence);
-    return ret;
-}
-
-void Hwc2TestVirtualDisplay::reset()
-{
-    return mDisplayDimension.reset();
-}
-
-bool Hwc2TestVirtualDisplay::advance()
-{
-    return mDisplayDimension.advance();
-}
-
-UnsignedArea Hwc2TestVirtualDisplay::getDisplayDimension() const
-{
-    return mDisplayDimension.get();
-}
-
-int Hwc2TestVirtualDisplay::verifyOutputBuffer(const Hwc2TestLayers* testLayers,
-        const std::vector<hwc2_layer_t>* allLayers,
-        const std::set<hwc2_layer_t>* clearLayers)
-{
-    int ret = mExpectedBuffer.generateExpectedBuffer(testLayers, allLayers,
-            clearLayers);
-    if (ret)
-        return ret;
-
-    ComparatorResult::get().CompareBuffers(mOutputBuffer.graphicBuffer(),
-        mExpectedBuffer.graphicBuffer());
-
-    return 0;
-}
-
-int Hwc2TestVirtualDisplay::writeBuffersToFile(std::string name)
-{
-    std::ostringstream expectedPath;
-    std::ostringstream resultPath;
-    int ret = mkdir(DIR_NAME, DEFFILEMODE);
-    if (ret && errno != EEXIST)
-        return ret;
-
-    expectedPath << DIR_NAME << "/expected-" << name << ".png";
-    resultPath << DIR_NAME << "/result-" << name << ".png";
-
-    if (!mExpectedBuffer.writeBufferToFile(expectedPath.str()) ||
-            !mOutputBuffer.writeBufferToFile(resultPath.str()))
-        return -1;
-
-    return 0;
-}
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.h b/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.h
deleted file mode 100644
index 5a74a6c..0000000
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestVirtualDisplay.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _HWC2_TEST_VIRTUAL_DISPLAY_H
-#define _HWC2_TEST_VIRTUAL_DISPLAY_H
-
-#include "Hwc2TestBuffer.h"
-#include "Hwc2TestPixelComparator.h"
-#include "Hwc2TestProperties.h"
-
-#define HWC2_INCLUDE_STRINGIFICATION
-#define HWC2_USE_CPP11
-#include <hardware/hwcomposer2.h>
-#undef HWC2_INCLUDE_STRINGIFICATION
-#undef HWC2_USE_CPP11
-
-class Hwc2TestVirtualDisplay {
-public:
-    explicit Hwc2TestVirtualDisplay(Hwc2TestCoverage coverage);
-
-    std::string dump() const;
-
-    int getOutputBuffer(buffer_handle_t* outHandle,
-            android::base::unique_fd* outAcquireFence);
-
-    int verifyOutputBuffer(const Hwc2TestLayers* testLayers,
-            const std::vector<hwc2_layer_t>* allLayers,
-            const std::set<hwc2_layer_t>* clearLayers);
-
-    int writeBuffersToFile(std::string name);
-    void reset();
-    bool advance();
-
-    UnsignedArea getDisplayDimension() const;
-
-private:
-    Hwc2TestOutputBuffer mOutputBuffer;
-    Hwc2TestExpectedBuffer mExpectedBuffer;
-    Hwc2TestDisplayDimension mDisplayDimension;
-};
-
-#endif /* ifndef _HWC2_TEST_VIRTUAL_DISPLAY_H */
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 680b0a0..2dcaf63 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -305,14 +305,14 @@
                 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
                                                        ceDisplayArgs);
 
-        test->mDisplay =
-                FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay,
-                                          DisplayConnectionType::Internal, true /* isPrimary */)
-                        .setDisplaySurface(test->mDisplaySurface)
-                        .setNativeWindow(test->mNativeWindow)
-                        .setSecure(Derived::IS_SECURE)
-                        .setPowerMode(Derived::INIT_POWER_MODE)
-                        .inject();
+        test->mDisplay = FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay,
+                                                   DisplayConnectionType::Internal, HWC_DISPLAY,
+                                                   true /* isPrimary */)
+                                 .setDisplaySurface(test->mDisplaySurface)
+                                 .setNativeWindow(test->mNativeWindow)
+                                 .setSecure(Derived::IS_SECURE)
+                                 .setPowerMode(Derived::INIT_POWER_MODE)
+                                 .inject();
         Mock::VerifyAndClear(test->mNativeWindow);
         test->mDisplay->setLayerStack(DEFAULT_LAYER_STACK);
     }
diff --git a/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp b/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp
index c2ddfce..2a0e913 100644
--- a/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp
@@ -96,7 +96,7 @@
         "\x0a\x20\x20\x20\x20\x20\x01\x47\x02\x03\x2d\x71\x50\x90\x05"
         "\x04\x03\x07\x02\x06\x01\x1f\x14\x13\x12\x16\x11\x15\x20\x2c"
         "\x09\x07\x03\x15\x07\x50\x57\x07\x00\x39\x07\xbb\x66\x03\x0c"
-        "\x00\x20\x00\x00\x83\x01\x00\x00\x01\x1d\x00\x72\x51\xd0\x1e"
+        "\x00\x12\x34\x00\x83\x01\x00\x00\x01\x1d\x00\x72\x51\xd0\x1e"
         "\x20\x6e\x28\x55\x00\xc4\x8e\x21\x00\x00\x1e\x01\x1d\x80\x18"
         "\x71\x1c\x16\x20\x58\x2c\x25\x00\xc4\x8e\x21\x00\x00\x9e\x8c"
         "\x0a\xd0\x8a\x20\xe0\x2d\x10\x10\x3e\x96\x00\x13\x8e\x21\x00"
@@ -185,6 +185,7 @@
     EXPECT_EQ(12610, edid->productId);
     EXPECT_EQ(21, edid->manufactureOrModelYear);
     EXPECT_EQ(0, edid->manufactureWeek);
+    EXPECT_FALSE(edid->cea861Block);
 
     edid = parseEdid(getExternalEdid());
     ASSERT_TRUE(edid);
@@ -195,6 +196,7 @@
     EXPECT_EQ(10348, edid->productId);
     EXPECT_EQ(22, edid->manufactureOrModelYear);
     EXPECT_EQ(2, edid->manufactureWeek);
+    EXPECT_FALSE(edid->cea861Block);
 
     edid = parseEdid(getExternalEedid());
     ASSERT_TRUE(edid);
@@ -205,6 +207,13 @@
     EXPECT_EQ(2302, edid->productId);
     EXPECT_EQ(21, edid->manufactureOrModelYear);
     EXPECT_EQ(41, edid->manufactureWeek);
+    ASSERT_TRUE(edid->cea861Block);
+    ASSERT_TRUE(edid->cea861Block->hdmiVendorDataBlock);
+    auto physicalAddress = edid->cea861Block->hdmiVendorDataBlock->physicalAddress;
+    EXPECT_EQ(2, physicalAddress.a);
+    EXPECT_EQ(0, physicalAddress.b);
+    EXPECT_EQ(0, physicalAddress.c);
+    EXPECT_EQ(0, physicalAddress.d);
 
     edid = parseEdid(getPanasonicTvEdid());
     ASSERT_TRUE(edid);
@@ -215,6 +224,13 @@
     EXPECT_EQ(41622, edid->productId);
     EXPECT_EQ(29, edid->manufactureOrModelYear);
     EXPECT_EQ(0, edid->manufactureWeek);
+    ASSERT_TRUE(edid->cea861Block);
+    ASSERT_TRUE(edid->cea861Block->hdmiVendorDataBlock);
+    physicalAddress = edid->cea861Block->hdmiVendorDataBlock->physicalAddress;
+    EXPECT_EQ(2, physicalAddress.a);
+    EXPECT_EQ(0, physicalAddress.b);
+    EXPECT_EQ(0, physicalAddress.c);
+    EXPECT_EQ(0, physicalAddress.d);
 
     edid = parseEdid(getHisenseTvEdid());
     ASSERT_TRUE(edid);
@@ -225,6 +241,13 @@
     EXPECT_EQ(0, edid->productId);
     EXPECT_EQ(29, edid->manufactureOrModelYear);
     EXPECT_EQ(18, edid->manufactureWeek);
+    ASSERT_TRUE(edid->cea861Block);
+    ASSERT_TRUE(edid->cea861Block->hdmiVendorDataBlock);
+    physicalAddress = edid->cea861Block->hdmiVendorDataBlock->physicalAddress;
+    EXPECT_EQ(1, physicalAddress.a);
+    EXPECT_EQ(2, physicalAddress.b);
+    EXPECT_EQ(3, physicalAddress.c);
+    EXPECT_EQ(4, physicalAddress.d);
 
     edid = parseEdid(getCtlDisplayEdid());
     ASSERT_TRUE(edid);
@@ -235,6 +258,8 @@
     EXPECT_EQ(9373, edid->productId);
     EXPECT_EQ(23, edid->manufactureOrModelYear);
     EXPECT_EQ(0xff, edid->manufactureWeek);
+    ASSERT_TRUE(edid->cea861Block);
+    EXPECT_FALSE(edid->cea861Block->hdmiVendorDataBlock);
 }
 
 TEST(DisplayIdentificationTest, parseInvalidEdid) {
@@ -287,6 +312,7 @@
     using ManufactureYear = DeviceProductInfo::ManufactureYear;
     using ManufactureWeekAndYear = DeviceProductInfo::ManufactureWeekAndYear;
     using ModelYear = DeviceProductInfo::ModelYear;
+    using RelativeAddress = DeviceProductInfo::RelativeAddress;
 
     {
         const auto displayIdInfo = parseDisplayIdentificationData(0, getInternalEdid());
@@ -298,6 +324,7 @@
         EXPECT_STREQ("12610", info.productId.data());
         ASSERT_TRUE(std::holds_alternative<ManufactureYear>(info.manufactureOrModelDate));
         EXPECT_EQ(2011, std::get<ManufactureYear>(info.manufactureOrModelDate).year);
+        EXPECT_EQ(DeviceProductInfo::NO_RELATIVE_ADDRESS, info.relativeAddress);
     }
     {
         const auto displayIdInfo = parseDisplayIdentificationData(0, getExternalEdid());
@@ -311,6 +338,7 @@
         const auto& date = std::get<ManufactureWeekAndYear>(info.manufactureOrModelDate);
         EXPECT_EQ(2012, date.year);
         EXPECT_EQ(2, date.week);
+        EXPECT_EQ(DeviceProductInfo::NO_RELATIVE_ADDRESS, info.relativeAddress);
     }
     {
         const auto displayIdInfo = parseDisplayIdentificationData(0, getExternalEedid());
@@ -324,6 +352,7 @@
         const auto& date = std::get<ManufactureWeekAndYear>(info.manufactureOrModelDate);
         EXPECT_EQ(2011, date.year);
         EXPECT_EQ(41, date.week);
+        EXPECT_EQ((RelativeAddress{{2, 0, 0, 0}}), info.relativeAddress);
     }
     {
         const auto displayIdInfo = parseDisplayIdentificationData(0, getPanasonicTvEdid());
@@ -336,6 +365,7 @@
         ASSERT_TRUE(std::holds_alternative<ManufactureYear>(info.manufactureOrModelDate));
         const auto& date = std::get<ManufactureYear>(info.manufactureOrModelDate);
         EXPECT_EQ(2019, date.year);
+        EXPECT_EQ((RelativeAddress{{2, 0, 0, 0}}), info.relativeAddress);
     }
     {
         const auto displayIdInfo = parseDisplayIdentificationData(0, getHisenseTvEdid());
@@ -349,6 +379,7 @@
         const auto& date = std::get<ManufactureWeekAndYear>(info.manufactureOrModelDate);
         EXPECT_EQ(2019, date.year);
         EXPECT_EQ(18, date.week);
+        EXPECT_EQ((RelativeAddress{{1, 2, 3, 4}}), info.relativeAddress);
     }
     {
         const auto displayIdInfo = parseDisplayIdentificationData(0, getCtlDisplayEdid());
@@ -360,6 +391,7 @@
         EXPECT_STREQ("9373", info.productId.data());
         ASSERT_TRUE(std::holds_alternative<ModelYear>(info.manufactureOrModelDate));
         EXPECT_EQ(2013, std::get<ModelYear>(info.manufactureOrModelDate).year);
+        EXPECT_EQ(DeviceProductInfo::NO_RELATIVE_ADDRESS, info.relativeAddress);
     }
 }
 
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 6d00ccc..cd11409 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -246,6 +246,7 @@
     constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{777};
     constexpr int DEFAULT_DISPLAY_WIDTH = 1080;
     constexpr int DEFAULT_DISPLAY_HEIGHT = 1920;
+    constexpr hwc2_display_t DEFAULT_DISPLAY_HWC_DISPLAY_ID = 0;
 
     // The DisplayDevice is required to have a framebuffer (behind the
     // ANativeWindow interface) which uses the actual hardware display
@@ -270,7 +271,7 @@
 
     auto injector =
             FakeDisplayDeviceInjector(mFlinger, compositionDisplay, DisplayConnectionType::Internal,
-                                      true /* isPrimary */);
+                                      DEFAULT_DISPLAY_HWC_DISPLAY_ID, true /* isPrimary */);
 
     injector.setNativeWindow(mNativeWindow);
     if (injectExtra) {
@@ -373,6 +374,23 @@
     static constexpr std::optional<DisplayConnectionType> value = PhysicalDisplay::CONNECTION_TYPE;
 };
 
+template <typename>
+struct HwcDisplayIdGetter {
+    static constexpr std::optional<hwc2_display_t> value;
+};
+
+constexpr hwc2_display_t HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
+
+template <DisplayId::Type displayId>
+struct HwcDisplayIdGetter<VirtualDisplayId<displayId>> {
+    static constexpr std::optional<hwc2_display_t> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
+};
+
+template <typename PhysicalDisplay>
+struct HwcDisplayIdGetter<PhysicalDisplayId<PhysicalDisplay>> {
+    static constexpr std::optional<hwc2_display_t> value = PhysicalDisplay::HWC_DISPLAY_ID;
+};
+
 // DisplayIdType can be:
 //     1) PhysicalDisplayId<...> for generated ID of physical display backed by HWC.
 //     2) VirtualDisplayId<...> for hard-coded ID of virtual display backed by HWC.
@@ -382,6 +400,7 @@
 struct DisplayVariant {
     using DISPLAY_ID = DisplayIdGetter<DisplayIdType>;
     using CONNECTION_TYPE = DisplayConnectionTypeGetter<DisplayIdType>;
+    using HWC_DISPLAY_ID_OPT = HwcDisplayIdGetter<DisplayIdType>;
 
     // The display width and height
     static constexpr int WIDTH = width;
@@ -418,9 +437,9 @@
                 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
                                                        ceDisplayArgs.build());
 
-        auto injector =
-                FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay,
-                                          CONNECTION_TYPE::value, static_cast<bool>(PRIMARY));
+        auto injector = FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay,
+                                                  CONNECTION_TYPE::value, HWC_DISPLAY_ID_OPT::value,
+                                                  static_cast<bool>(PRIMARY));
 
         injector.setSecure(static_cast<bool>(SECURE));
         injector.setNativeWindow(test->mNativeWindow);
@@ -603,12 +622,11 @@
 constexpr uint32_t GRALLOC_USAGE_PHYSICAL_DISPLAY =
         GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_FB;
 
-template <hwc2_display_t hwcDisplayId, typename PhysicalDisplay, int width, int height,
-          Critical critical>
+template <typename PhysicalDisplay, int width, int height, Critical critical>
 struct PhysicalDisplayVariant
       : DisplayVariant<PhysicalDisplayId<PhysicalDisplay>, width, height, critical, Async::FALSE,
                        Secure::TRUE, PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
-        HwcDisplayVariant<hwcDisplayId, HWC2::DisplayType::Physical,
+        HwcDisplayVariant<PhysicalDisplay::HWC_DISPLAY_ID, HWC2::DisplayType::Physical,
                           DisplayVariant<PhysicalDisplayId<PhysicalDisplay>, width, height,
                                          critical, Async::FALSE, Secure::TRUE,
                                          PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
@@ -619,6 +637,7 @@
     static constexpr auto CONNECTION_TYPE = DisplayConnectionType::Internal;
     static constexpr Primary PRIMARY = Primary::TRUE;
     static constexpr uint8_t PORT = 255;
+    static constexpr hwc2_display_t HWC_DISPLAY_ID = 1001;
     static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
     static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
 };
@@ -628,6 +647,7 @@
     static constexpr auto CONNECTION_TYPE = DisplayConnectionType::External;
     static constexpr Primary PRIMARY = Primary::FALSE;
     static constexpr uint8_t PORT = 254;
+    static constexpr hwc2_display_t HWC_DISPLAY_ID = 1002;
     static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
     static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
 };
@@ -635,19 +655,19 @@
 struct TertiaryDisplay {
     static constexpr Primary PRIMARY = Primary::FALSE;
     static constexpr uint8_t PORT = 253;
+    static constexpr hwc2_display_t HWC_DISPLAY_ID = 1003;
     static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
 };
 
 // A primary display is a physical display that is critical
 using PrimaryDisplayVariant =
-        PhysicalDisplayVariant<1001, PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
+        PhysicalDisplayVariant<PrimaryDisplay<false>, 3840, 2160, Critical::TRUE>;
 
 // An external display is physical display that is not critical.
 using ExternalDisplayVariant =
-        PhysicalDisplayVariant<1002, ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
+        PhysicalDisplayVariant<ExternalDisplay<false>, 1920, 1280, Critical::FALSE>;
 
-using TertiaryDisplayVariant =
-        PhysicalDisplayVariant<1003, TertiaryDisplay, 1600, 1200, Critical::FALSE>;
+using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200, Critical::FALSE>;
 
 // A virtual display not supported by the HWC.
 constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
@@ -696,7 +716,7 @@
       : DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE, secure,
                        Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
         HwcDisplayVariant<
-                1010, HWC2::DisplayType::Virtual,
+                HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, HWC2::DisplayType::Virtual,
                 DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE,
                                secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>> {
     using Base = DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE,
@@ -1484,7 +1504,7 @@
                                 mHardwareDisplaySize.height),
                   compositionState.transform);
         EXPECT_EQ(TRANSFORM_FLAGS_ROT_90, compositionState.orientation);
-        EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.sourceClip);
+        EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.sourceClip);
         EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip);
         // For 90, the frame and viewport have the hardware display size width and height swapped
         EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.frame);
@@ -1511,7 +1531,7 @@
                                 mHardwareDisplaySize.height),
                   compositionState.transform);
         EXPECT_EQ(TRANSFORM_FLAGS_ROT_270, compositionState.orientation);
-        EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.sourceClip);
+        EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.sourceClip);
         EXPECT_EQ(Rect(mHardwareDisplaySize), compositionState.destinationClip);
         // For 270, the frame and viewport have the hardware display size width and height swapped
         EXPECT_EQ(Rect(SwapWH(mHardwareDisplaySize)), compositionState.frame);
@@ -1711,7 +1731,8 @@
 
     ui::DisplayPrimaries primaries;
     populateDummyDisplayNativePrimaries(primaries);
-    EXPECT_EQ(BAD_VALUE, mFlinger.getDisplayNativePrimaries(notInternalDisplayToken, primaries));
+    EXPECT_EQ(NAME_NOT_FOUND,
+              mFlinger.getDisplayNativePrimaries(notInternalDisplayToken, primaries));
 
     // Check primaries argument wasn't modified in case of failure
     checkDummyDisplayNativePrimaries(primaries);
@@ -1767,7 +1788,9 @@
     if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
         const auto displayId = Case::Display::DISPLAY_ID::get();
         ASSERT_TRUE(displayId);
-        state.physical = {*displayId, *connectionType};
+        const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
+        ASSERT_TRUE(hwcDisplayId);
+        state.physical = {*displayId, *connectionType, *hwcDisplayId};
     }
 
     state.isSecure = static_cast<bool>(Case::Display::SECURE);
@@ -1941,7 +1964,9 @@
     if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
         const auto displayId = Case::Display::DISPLAY_ID::get();
         ASSERT_TRUE(displayId);
-        expectedPhysical = {*displayId, *connectionType};
+        const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
+        ASSERT_TRUE(hwcDisplayId);
+        expectedPhysical = {*displayId, *connectionType, *hwcDisplayId};
     }
 
     // The display should have been set up in the current display state
@@ -2124,11 +2149,11 @@
     ignoresHotplugConnectCommon<SimpleExternalDisplayCase>();
 }
 
-TEST_F(HandleTransactionLockedTest, processHotplugDisconnectPrimaryDisplay) {
+TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectPrimaryDisplay) {
     processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>();
 }
 
-TEST_F(HandleTransactionLockedTest, processHotplugDisconnectExternalDisplay) {
+TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectExternalDisplay) {
     processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
 }
 
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
index 7557faf..71d17a9 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
@@ -63,14 +63,15 @@
 
     auto createLayer() { return sp<mock::MockLayer>(new mock::MockLayer(mFlinger.flinger())); }
 
-    RefreshRateConfigs mConfigs{{
-                                        RefreshRateConfigs::InputConfig{HwcConfigIndexType(0),
-                                                                        HwcConfigGroupType(0),
-                                                                        LO_FPS_PERIOD},
-                                        RefreshRateConfigs::InputConfig{HwcConfigIndexType(1),
-                                                                        HwcConfigGroupType(0),
-                                                                        HI_FPS_PERIOD},
-                                },
+    Hwc2::mock::Display mDisplay;
+    RefreshRateConfigs mConfigs{{HWC2::Display::Config::Builder(mDisplay, 0)
+                                         .setVsyncPeriod(int32_t(LO_FPS_PERIOD))
+                                         .setConfigGroup(0)
+                                         .build(),
+                                 HWC2::Display::Config::Builder(mDisplay, 1)
+                                         .setVsyncPeriod(int32_t(HI_FPS_PERIOD))
+                                         .setConfigGroup(0)
+                                         .build()},
                                 HwcConfigIndexType(0)};
     TestableScheduler* const mScheduler{new TestableScheduler(mConfigs, false)};
     TestableSurfaceFlinger mFlinger;
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
index 8559a5e..71e37a8 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
@@ -72,14 +72,15 @@
 
     auto createLayer() { return sp<mock::MockLayer>(new mock::MockLayer(mFlinger.flinger())); }
 
-    RefreshRateConfigs mConfigs{{
-                                        RefreshRateConfigs::InputConfig{HwcConfigIndexType(0),
-                                                                        HwcConfigGroupType(0),
-                                                                        LO_FPS_PERIOD},
-                                        RefreshRateConfigs::InputConfig{HwcConfigIndexType(1),
-                                                                        HwcConfigGroupType(0),
-                                                                        HI_FPS_PERIOD},
-                                },
+    Hwc2::mock::Display mDisplay;
+    RefreshRateConfigs mConfigs{{HWC2::Display::Config::Builder(mDisplay, 0)
+                                         .setVsyncPeriod(int32_t(LO_FPS_PERIOD))
+                                         .setConfigGroup(0)
+                                         .build(),
+                                 HWC2::Display::Config::Builder(mDisplay, 1)
+                                         .setVsyncPeriod(int32_t(HI_FPS_PERIOD))
+                                         .setConfigGroup(0)
+                                         .build()},
                                 HwcConfigIndexType(0)};
     TestableScheduler* const mScheduler{new TestableScheduler(mConfigs, true)};
     TestableSurfaceFlinger mFlinger;
diff --git a/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp b/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp
index 8d49201..ce5993a 100644
--- a/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp
@@ -45,8 +45,8 @@
 class PhaseDurationTest : public testing::Test {
 protected:
     PhaseDurationTest()
-          : mPhaseDurations(60.0f, 10'500'000, 20'500'000, 16'000'000, 33'500'000, 13'500'000,
-                            38'000'000) {}
+          : mPhaseDurations(60.0f, 10'500'000, 20'500'000, 16'000'000, 16'500'000, 13'500'000,
+                            21'000'000) {}
 
     ~PhaseDurationTest() = default;
 
@@ -69,11 +69,11 @@
 
     EXPECT_EQ(offsets.early.sf, 666'667);
 
-    EXPECT_EQ(offsets.early.app, 500'001);
+    EXPECT_EQ(offsets.early.app, 833'334);
 
     EXPECT_EQ(offsets.earlyGl.sf, 3'166'667);
 
-    EXPECT_EQ(offsets.earlyGl.app, 15'166'668);
+    EXPECT_EQ(offsets.earlyGl.app, 15'500'001);
 }
 
 TEST_F(PhaseDurationTest, getOffsetsForRefreshRate_90Hz) {
@@ -88,11 +88,11 @@
 
     EXPECT_EQ(offsets.early.sf, -4'888'889);
 
-    EXPECT_EQ(offsets.early.app, 6'055'555);
+    EXPECT_EQ(offsets.early.app, 833'333);
 
     EXPECT_EQ(offsets.earlyGl.sf, -2'388'889);
 
-    EXPECT_EQ(offsets.earlyGl.app, 4'055'555);
+    EXPECT_EQ(offsets.earlyGl.app, 9'944'444);
 }
 
 TEST_F(PhaseDurationTest, getOffsetsForRefreshRate_DefaultOffsets) {
@@ -134,11 +134,11 @@
 
     EXPECT_EQ(offsets.early.sf, 52'027'208);
 
-    EXPECT_EQ(offsets.early.app, 18'527'208);
+    EXPECT_EQ(offsets.early.app, 35'527'208);
 
     EXPECT_EQ(offsets.earlyGl.sf, 54'527'208);
 
-    EXPECT_EQ(offsets.earlyGl.app, 16'527'208);
+    EXPECT_EQ(offsets.earlyGl.app, 33'527'208);
 }
 
 } // namespace
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index dd04076..1b8f11b 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -24,6 +24,7 @@
 #include "../../Scheduler/RefreshRateConfigs.h"
 #include "DisplayHardware/HWC2.h"
 #include "Scheduler/RefreshRateConfigs.h"
+#include "mock/DisplayHardware/MockDisplay.h"
 
 using namespace std::chrono_literals;
 using testing::_;
@@ -37,24 +38,95 @@
 
 class RefreshRateConfigsTest : public testing::Test {
 protected:
-    static inline const HwcConfigIndexType HWC_CONFIG_ID_60 = HwcConfigIndexType(0);
-    static inline const HwcConfigIndexType HWC_CONFIG_ID_72 = HwcConfigIndexType(1);
-    static inline const HwcConfigIndexType HWC_CONFIG_ID_90 = HwcConfigIndexType(2);
-    static inline const HwcConfigIndexType HWC_CONFIG_ID_120 = HwcConfigIndexType(3);
-    static inline const HwcConfigIndexType HWC_CONFIG_ID_30 = HwcConfigIndexType(4);
-    static inline const HwcConfigGroupType HWC_GROUP_ID_0 = HwcConfigGroupType(0);
-    static inline const HwcConfigGroupType HWC_GROUP_ID_1 = HwcConfigGroupType(1);
-    static constexpr auto VSYNC_30 = static_cast<int64_t>(1e9f / 30);
-    static constexpr auto VSYNC_60 = static_cast<int64_t>(1e9f / 60);
-    static constexpr auto VSYNC_72 = static_cast<int64_t>(1e9f / 72);
-    static constexpr auto VSYNC_90 = static_cast<int64_t>(1e9f / 90);
-    static constexpr auto VSYNC_120 = static_cast<int64_t>(1e9f / 120);
-    static constexpr int64_t VSYNC_60_POINT_4 = 16666665;
-
     RefreshRateConfigsTest();
     ~RefreshRateConfigsTest();
+
+    // Test config IDs
+    static inline const HwcConfigIndexType HWC_CONFIG_ID_60 = HwcConfigIndexType(0);
+    static inline const HwcConfigIndexType HWC_CONFIG_ID_90 = HwcConfigIndexType(1);
+    static inline const HwcConfigIndexType HWC_CONFIG_ID_72 = HwcConfigIndexType(2);
+    static inline const HwcConfigIndexType HWC_CONFIG_ID_120 = HwcConfigIndexType(3);
+    static inline const HwcConfigIndexType HWC_CONFIG_ID_30 = HwcConfigIndexType(4);
+
+    // Test configs
+    std::shared_ptr<const HWC2::Display::Config> mConfig60 =
+            createConfig(HWC_CONFIG_ID_60, 0, static_cast<int64_t>(1e9f / 60));
+    std::shared_ptr<const HWC2::Display::Config> mConfig90 =
+            createConfig(HWC_CONFIG_ID_90, 0, static_cast<int64_t>(1e9f / 90));
+    std::shared_ptr<const HWC2::Display::Config> mConfig90DifferentGroup =
+            createConfig(HWC_CONFIG_ID_90, 1, static_cast<int64_t>(1e9f / 90));
+    std::shared_ptr<const HWC2::Display::Config> mConfig90DifferentResolution =
+            createConfig(HWC_CONFIG_ID_90, 0, static_cast<int64_t>(1e9f / 90), 111, 222);
+    std::shared_ptr<const HWC2::Display::Config> mConfig72 =
+            createConfig(HWC_CONFIG_ID_72, 0, static_cast<int64_t>(1e9f / 72));
+    std::shared_ptr<const HWC2::Display::Config> mConfig72DifferentGroup =
+            createConfig(HWC_CONFIG_ID_72, 1, static_cast<int64_t>(1e9f / 72));
+    std::shared_ptr<const HWC2::Display::Config> mConfig120 =
+            createConfig(HWC_CONFIG_ID_120, 0, static_cast<int64_t>(1e9f / 120));
+    std::shared_ptr<const HWC2::Display::Config> mConfig120DifferentGroup =
+            createConfig(HWC_CONFIG_ID_120, 1, static_cast<int64_t>(1e9f / 120));
+    std::shared_ptr<const HWC2::Display::Config> mConfig30 =
+            createConfig(HWC_CONFIG_ID_30, 0, static_cast<int64_t>(1e9f / 30));
+
+    // Test device configurations
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60OnlyConfigDevice = {mConfig60};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90Device = {mConfig60, mConfig90};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90DeviceWithDifferentGroups =
+            {mConfig60, mConfig90DifferentGroup};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90DeviceWithDifferentResolutions =
+            {mConfig60, mConfig90DifferentResolution};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_72_90Device = {mConfig60,
+                                                                                 mConfig90,
+                                                                                 mConfig72};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90_72_120Device = {mConfig60,
+                                                                                     mConfig90,
+                                                                                     mConfig72,
+                                                                                     mConfig120};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60_72_90_120Device = {mConfig60,
+                                                                                        mConfig90,
+                                                                                        mConfig72,
+                                                                                        mConfig120,
+                                                                                        mConfig30};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60Device =
+            {mConfig60, mConfig90DifferentGroup, mConfig72DifferentGroup, mConfig120DifferentGroup,
+             mConfig30};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60_72_90Device =
+            {mConfig60, mConfig90, mConfig72, mConfig120DifferentGroup, mConfig30};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60_90Device =
+            {mConfig60, mConfig90, mConfig72DifferentGroup, mConfig120DifferentGroup, mConfig30};
+
+    // Expected RefreshRate objects
+    RefreshRate mExpected60Config = {HWC_CONFIG_ID_60, mConfig60, "60fps", 60,
+                                     RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpectedAlmost60Config = {HWC_CONFIG_ID_60,
+                                           createConfig(HWC_CONFIG_ID_60, 0, 16666665), "60fps", 60,
+                                           RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected90Config = {HWC_CONFIG_ID_90, mConfig90, "90fps", 90,
+                                     RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected90DifferentGroupConfig = {HWC_CONFIG_ID_90, mConfig90DifferentGroup,
+                                                   "90fps", 90, RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected90DifferentResolutionConfig = {HWC_CONFIG_ID_90,
+                                                        mConfig90DifferentResolution, "90fps", 90,
+                                                        RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected72Config = {HWC_CONFIG_ID_72, mConfig72, "72fps", 72,
+                                     RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected30Config = {HWC_CONFIG_ID_30, mConfig30, "30fps", 30,
+                                     RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected120Config = {HWC_CONFIG_ID_120, mConfig120, "120fps", 120,
+                                      RefreshRate::ConstructorTag(0)};
+
+    Hwc2::mock::Display mDisplay;
+
+private:
+    std::shared_ptr<const HWC2::Display::Config> createConfig(HwcConfigIndexType configId,
+                                                              int32_t configGroup,
+                                                              int64_t vsyncPeriod,
+                                                              int32_t hight = -1,
+                                                              int32_t width = -1);
 };
 
+using Builder = HWC2::Display::Config::Builder;
+
 RefreshRateConfigsTest::RefreshRateConfigsTest() {
     const ::testing::TestInfo* const test_info =
             ::testing::UnitTest::GetInstance()->current_test_info();
@@ -67,41 +139,45 @@
     ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
 }
 
+std::shared_ptr<const HWC2::Display::Config> RefreshRateConfigsTest::createConfig(
+        HwcConfigIndexType configId, int32_t configGroup, int64_t vsyncPeriod, int32_t hight,
+        int32_t width) {
+    return HWC2::Display::Config::Builder(mDisplay, hwc2_config_t(configId.value()))
+            .setVsyncPeriod(int32_t(vsyncPeriod))
+            .setConfigGroup(configGroup)
+            .setHeight(hight)
+            .setWidth(width)
+            .build();
+}
+
 namespace {
 /* ------------------------------------------------------------------------
  * Test cases
  */
 TEST_F(RefreshRateConfigsTest, oneDeviceConfig_SwitchingSupported) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60OnlyConfigDevice,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 }
 
 TEST_F(RefreshRateConfigsTest, invalidPolicy) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-    ASSERT_LT(refreshRateConfigs->setPolicy(HwcConfigIndexType(10), 60, 60, nullptr), 0);
-    ASSERT_LT(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 20, 40, nullptr), 0);
+            std::make_unique<RefreshRateConfigs>(m60OnlyConfigDevice,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
+    ASSERT_LT(refreshRateConfigs->setDisplayManagerPolicy({HwcConfigIndexType(10), 60, 60}), 0);
+    ASSERT_LT(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 20, 40}), 0);
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     const auto& minRate = refreshRateConfigs->getMinRefreshRate();
     const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate();
 
-    RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    ASSERT_EQ(expectedDefaultConfig, minRate);
-    RefreshRate expectedPerformanceConfig = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps",
-                                             90};
-    ASSERT_EQ(expectedPerformanceConfig, performanceRate);
+    ASSERT_EQ(mExpected60Config, minRate);
+    ASSERT_EQ(mExpected90Config, performanceRate);
 
     const auto& minRateByPolicy = refreshRateConfigs->getMinRefreshRateByPolicy();
     const auto& performanceRateByPolicy = refreshRateConfigs->getMaxRefreshRateByPolicy();
@@ -110,411 +186,390 @@
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap_differentGroups) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_1, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     const auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy();
     const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate();
     const auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy();
     const auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
 
-    RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    ASSERT_EQ(expectedDefaultConfig, minRate);
-    ASSERT_EQ(expectedDefaultConfig, minRate60);
-    ASSERT_EQ(expectedDefaultConfig, performanceRate60);
+    ASSERT_EQ(mExpected60Config, minRate);
+    ASSERT_EQ(mExpected60Config, minRate60);
+    ASSERT_EQ(mExpected60Config, performanceRate60);
 
-    ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_90, 60, 90, nullptr), 0);
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, 60, 90}), 0);
     refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
 
     const auto& minRate90 = refreshRateConfigs->getMinRefreshRateByPolicy();
     const auto& performanceRate90 = refreshRateConfigs->getMaxRefreshRateByPolicy();
 
-    RefreshRate expectedPerformanceConfig = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_1, "90fps",
-                                             90};
-    ASSERT_EQ(expectedPerformanceConfig, performanceRate);
-    ASSERT_EQ(expectedPerformanceConfig, minRate90);
-    ASSERT_EQ(expectedPerformanceConfig, performanceRate90);
+    ASSERT_EQ(mExpected90DifferentGroupConfig, performanceRate);
+    ASSERT_EQ(mExpected90DifferentGroupConfig, minRate90);
+    ASSERT_EQ(mExpected90DifferentGroupConfig, performanceRate90);
+}
+
+TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap_differentResolutions) {
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentResolutions,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
+
+    const auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy();
+    const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate();
+    const auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy();
+    const auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
+
+    ASSERT_EQ(mExpected60Config, minRate);
+    ASSERT_EQ(mExpected60Config, minRate60);
+    ASSERT_EQ(mExpected60Config, performanceRate60);
+
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, 60, 90}), 0);
+    refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
+
+    const auto& minRate90 = refreshRateConfigs->getMinRefreshRateByPolicy();
+    const auto& performanceRate90 = refreshRateConfigs->getMaxRefreshRateByPolicy();
+
+    ASSERT_EQ(mExpected90DifferentResolutionConfig, performanceRate);
+    ASSERT_EQ(mExpected90DifferentResolutionConfig, minRate90);
+    ASSERT_EQ(mExpected90DifferentResolutionConfig, performanceRate90);
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_policyChange) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy();
     auto& performanceRate = refreshRateConfigs->getMaxRefreshRateByPolicy();
 
-    RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    ASSERT_EQ(expectedDefaultConfig, minRate);
-    RefreshRate expectedPerformanceConfig = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps",
-                                             90};
-    ASSERT_EQ(expectedPerformanceConfig, performanceRate);
+    ASSERT_EQ(mExpected60Config, minRate);
+    ASSERT_EQ(mExpected90Config, performanceRate);
 
-    ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 60, 60, nullptr), 0);
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 60, 60}), 0);
 
     auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy();
     auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
-    ASSERT_EQ(expectedDefaultConfig, minRate60);
-    ASSERT_EQ(expectedDefaultConfig, performanceRate60);
+    ASSERT_EQ(mExpected60Config, minRate60);
+    ASSERT_EQ(mExpected60Config, performanceRate60);
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getCurrentRefreshRate) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
     {
         auto& current = refreshRateConfigs->getCurrentRefreshRate();
-        EXPECT_EQ(current.configId, HWC_CONFIG_ID_60);
+        EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_60);
     }
 
     refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
     {
         auto& current = refreshRateConfigs->getCurrentRefreshRate();
-        EXPECT_EQ(current.configId, HWC_CONFIG_ID_90);
+        EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_90);
     }
 
-    ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_90, 90, 90, nullptr), 0);
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, 90, 90}), 0);
     {
         auto& current = refreshRateConfigs->getCurrentRefreshRate();
-        EXPECT_EQ(current.configId, HWC_CONFIG_ID_90);
+        EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_90);
     }
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContent) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     const auto makeLayerRequirements = [](float refreshRate) -> std::vector<LayerRequirement> {
         return {{"testLayer", LayerVoteType::Heuristic, refreshRate, 1.0f}};
     };
 
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f)));
 
-    ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 60, 60, nullptr), 0);
-    EXPECT_EQ(expected60Config,
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 60, 60}), 0);
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f)));
 
-    ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_90, 90, 90, nullptr), 0);
-    EXPECT_EQ(expected90Config,
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, 90, 90}), 0);
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f)));
-    ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 0, 120, nullptr), 0);
-    EXPECT_EQ(expected90Config,
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 0, 120}), 0);
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f)));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_noLayers) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
-    auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/
-                                                                   HWC_CONFIG_ID_72);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected72Config = {HWC_CONFIG_ID_72, VSYNC_72, HWC_GROUP_ID_0, "72fps", 72};
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m60_72_90Device, /*currentConfigId=*/
+                                                 HWC_CONFIG_ID_72);
 
     // If there are not layers, there is not content detection, so return the current
     // refresh rate.
     auto layers = std::vector<LayerRequirement>{};
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/
                                                              false, &ignored));
 
     // Current refresh rate can always be changed.
     refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_60);
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/
                                                              false, &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_60_90) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
 
     lr.vote = LayerVoteType::Min;
     lr.name = "Min";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
     lr.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
     lr.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz Heuristic";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
     lr.name = "45Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
     lr.name = "30Hz Heuristic";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
     lr.name = "24Hz Heuristic";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.name = "";
-    ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 60, 60, nullptr), 0);
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 60, 60}), 0);
 
     lr.vote = LayerVoteType::Min;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
-    ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_90, 90, 90, nullptr), 0);
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, 90, 90}), 0);
 
     lr.vote = LayerVoteType::Min;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
-    ASSERT_GE(refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 0, 120, nullptr), 0);
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 0, 120}), 0);
     lr.vote = LayerVoteType::Min;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_60_72_90) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected72Config = {HWC_CONFIG_ID_72, VSYNC_72, HWC_GROUP_ID_0, "72fps", 70};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_72_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
 
     lr.vote = LayerVoteType::Min;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60_72_90_120) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
-             {HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90},
-             {HWC_CONFIG_ID_120, HWC_GROUP_ID_0, VSYNC_120}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected72Config = {HWC_CONFIG_ID_72, VSYNC_72, HWC_GROUP_ID_0, "72fps", 70};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
-    RefreshRate expected120Config = {HWC_CONFIG_ID_120, VSYNC_120, HWC_GROUP_ID_0, "120fps", 120};
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -525,7 +580,7 @@
     lr1.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected120Config,
+    EXPECT_EQ(mExpected120Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -533,7 +588,7 @@
     lr1.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 48.0f;
     lr2.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -541,27 +596,16 @@
     lr1.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 48.0f;
     lr2.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60_90_120_DifferentTypes) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
-             {HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90},
-             {HWC_CONFIG_ID_120, HWC_GROUP_ID_0, VSYNC_120}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected72Config = {HWC_CONFIG_ID_72, VSYNC_72, HWC_GROUP_ID_0, "72fps", 72};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
-    RefreshRate expected120Config = {HWC_CONFIG_ID_120, VSYNC_120, HWC_GROUP_ID_0, "120fps", 120};
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -574,7 +618,7 @@
     lr2.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "60Hz Heuristic";
-    EXPECT_EQ(expected120Config,
+    EXPECT_EQ(mExpected120Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -584,7 +628,7 @@
     lr2.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "60Hz Heuristic";
-    EXPECT_EQ(expected120Config,
+    EXPECT_EQ(mExpected120Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -594,7 +638,7 @@
     lr2.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "60Hz ExplicitDefault";
-    EXPECT_EQ(expected120Config,
+    EXPECT_EQ(mExpected120Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -604,7 +648,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -614,7 +658,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -624,7 +668,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -634,7 +678,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "90Hz ExplicitDefault";
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -644,7 +688,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "90Hz ExplicitDefault";
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -654,158 +698,137 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.name = "90Hz ExplicitExactOrMultiple";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
+            std::make_unique<RefreshRateConfigs>(m30_60Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
 
     lr.vote = LayerVoteType::Min;
-    EXPECT_EQ(expected30Config,
+    EXPECT_EQ(mExpected30Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
-    EXPECT_EQ(expected30Config,
+    EXPECT_EQ(mExpected30Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60_72_90) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
-             {HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected72Config = {HWC_CONFIG_ID_72, VSYNC_72, HWC_GROUP_ID_0, "72fps", 70};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
 
     lr.vote = LayerVoteType::Min;
     lr.name = "Min";
-    EXPECT_EQ(expected30Config,
+    EXPECT_EQ(mExpected30Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
     lr.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
     lr.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz Heuristic";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
     lr.name = "45Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
     lr.name = "30Hz Heuristic";
-    EXPECT_EQ(expected30Config,
+    EXPECT_EQ(mExpected30Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
     lr.name = "24Hz Heuristic";
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
     lr.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr.name = "24Hz ExplicitExactOrMultiple";
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_PriorityTest) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
-             {HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m30_60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -814,35 +837,35 @@
 
     lr1.vote = LayerVoteType::Min;
     lr2.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr1.vote = LayerVoteType::Min;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr1.vote = LayerVoteType::Min;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr1.vote = LayerVoteType::Max;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr1.vote = LayerVoteType::Max;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -850,7 +873,7 @@
     lr1.desiredRefreshRate = 15.0f;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -858,22 +881,16 @@
     lr1.desiredRefreshRate = 30.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_24FpsVideo) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
@@ -884,20 +901,15 @@
         const auto& refreshRate =
                 refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                                &ignored);
-        printf("%.2fHz chooses %s\n", fps, refreshRate.name.c_str());
-        EXPECT_EQ(expected60Config, refreshRate);
+        printf("%.2fHz chooses %s\n", fps, refreshRate.getName().c_str());
+        EXPECT_EQ(mExpected60Config, refreshRate);
     }
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContent_Explicit) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -908,25 +920,20 @@
     lr1.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 90.0f;
-    EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContent(layers));
+    EXPECT_EQ(mExpected90Config, refreshRateConfigs->getRefreshRateForContent(layers));
 
     lr1.vote = LayerVoteType::Heuristic;
     lr1.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(layers));
+    EXPECT_EQ(mExpected60Config, refreshRateConfigs->getRefreshRateForContent(layers));
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_Explicit) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -937,7 +944,7 @@
     lr1.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 90.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -945,7 +952,7 @@
     lr1.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -953,32 +960,24 @@
     lr1.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, testInPolicy) {
-    RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60_POINT_4, HWC_GROUP_ID_0,
-                                         "60fps", 60};
-    ASSERT_TRUE(expectedDefaultConfig.inPolicy(60.000004f, 60.000004f));
-    ASSERT_TRUE(expectedDefaultConfig.inPolicy(59.0f, 60.1f));
-    ASSERT_FALSE(expectedDefaultConfig.inPolicy(75.0f, 90.0f));
-    ASSERT_FALSE(expectedDefaultConfig.inPolicy(60.0011f, 90.0f));
-    ASSERT_FALSE(expectedDefaultConfig.inPolicy(50.0f, 59.998f));
+    ASSERT_TRUE(mExpectedAlmost60Config.inPolicy(60.000004f, 60.000004f));
+    ASSERT_TRUE(mExpectedAlmost60Config.inPolicy(59.0f, 60.1f));
+    ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(75.0f, 90.0f));
+    ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(60.0011f, 90.0f));
+    ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(50.0f, 59.998f));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_75HzContent) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
@@ -989,21 +988,16 @@
         const auto& refreshRate =
                 refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                                &ignored);
-        printf("%.2fHz chooses %s\n", fps, refreshRate.name.c_str());
-        EXPECT_EQ(expected90Config, refreshRate);
+        printf("%.2fHz chooses %s\n", fps, refreshRate.getName().c_str());
+        EXPECT_EQ(mExpected90Config, refreshRate);
     }
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_Multiples) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -1016,7 +1010,7 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -1026,7 +1020,7 @@
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz ExplicitDefault";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -1035,7 +1029,7 @@
     lr1.name = "60Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -1045,7 +1039,7 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -1054,21 +1048,16 @@
     lr1.name = "30Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, scrollWhileWatching60fps_60_90) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -1080,7 +1069,7 @@
     lr1.name = "60Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::NoVote;
     lr2.name = "NoVote";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, false, &ignored));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -1088,7 +1077,7 @@
     lr1.name = "60Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::NoVote;
     lr2.name = "NoVote";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, true, &ignored));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -1096,7 +1085,7 @@
     lr1.name = "60Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, true, &ignored));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -1104,7 +1093,7 @@
     lr1.name = "60Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, false, &ignored));
 
     // The other layer starts to provide buffers
@@ -1114,17 +1103,15 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, false, &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, touchConsidered) {
     bool touchConsidered;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     refreshRateConfigs->getRefreshRateForContentV2({}, false, &touchConsidered);
     EXPECT_EQ(false, touchConsidered);
@@ -1172,14 +1159,9 @@
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_ExplicitDefault) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90},
-             {HWC_CONFIG_ID_120, HWC_GROUP_ID_0, VSYNC_120}}};
-
-    auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/
-                                                                   HWC_CONFIG_ID_60);
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m60_90_72_120Device, /*currentConfigId=*/
+                                                 HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
@@ -1213,11 +1195,36 @@
 
         const auto& refreshRate =
                 refreshRateConfigs->getRefreshRateForContentV2(layers, false, &ignored);
-        EXPECT_FLOAT_EQ(refreshRate.fps, test.second)
+        EXPECT_FLOAT_EQ(refreshRate.getFps(), test.second)
                 << "Expecting " << test.first << "fps => " << test.second << "Hz";
     }
 }
 
+TEST_F(RefreshRateConfigsTest, groupSwitching) {
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
+
+    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
+    auto& layer = layers[0];
+    layer.vote = LayerVoteType::ExplicitDefault;
+    layer.desiredRefreshRate = 90.0f;
+    layer.name = "90Hz ExplicitDefault";
+
+    bool touchConsidered;
+    ASSERT_EQ(HWC_CONFIG_ID_60,
+              refreshRateConfigs->getRefreshRateForContentV2(layers, false, &touchConsidered)
+                      .getConfigId());
+
+    RefreshRateConfigs::Policy policy;
+    policy.defaultConfig = refreshRateConfigs->getCurrentPolicy().defaultConfig;
+    policy.allowGroupSwitching = true;
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
+    ASSERT_EQ(HWC_CONFIG_ID_90,
+              refreshRateConfigs->getRefreshRateForContentV2(layers, false, &touchConsidered)
+                      .getConfigId());
+}
+
 } // namespace
 } // namespace scheduler
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
index 18d6bd2..038e6e6 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
@@ -26,6 +26,7 @@
 #include <thread>
 
 #include "Scheduler/RefreshRateStats.h"
+#include "mock/DisplayHardware/MockDisplay.h"
 #include "mock/MockTimeStats.h"
 
 using namespace std::chrono_literals;
@@ -39,14 +40,14 @@
 protected:
     static inline const auto CONFIG_ID_0 = HwcConfigIndexType(0);
     static inline const auto CONFIG_ID_1 = HwcConfigIndexType(1);
-    static inline const auto CONFIG_GROUP_0 = HwcConfigGroupType(0);
+    static inline const auto CONFIG_GROUP_0 = 0;
     static constexpr int64_t VSYNC_90 = 11111111;
     static constexpr int64_t VSYNC_60 = 16666667;
 
     RefreshRateStatsTest();
     ~RefreshRateStatsTest();
 
-    void init(const std::vector<RefreshRateConfigs::InputConfig>& configs) {
+    void init(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) {
         mRefreshRateConfigs =
                 std::make_unique<RefreshRateConfigs>(configs, /*currentConfig=*/CONFIG_ID_0);
         mRefreshRateStats =
@@ -55,9 +56,14 @@
                                                    /*currentPowerMode=*/HWC_POWER_MODE_OFF);
     }
 
+    Hwc2::mock::Display mDisplay;
     mock::TimeStats mTimeStats;
     std::unique_ptr<RefreshRateConfigs> mRefreshRateConfigs;
     std::unique_ptr<RefreshRateStats> mRefreshRateStats;
+
+    std::shared_ptr<const HWC2::Display::Config> createConfig(HwcConfigIndexType configId,
+                                                              int32_t configGroup,
+                                                              int64_t vsyncPeriod);
 };
 
 RefreshRateStatsTest::RefreshRateStatsTest() {
@@ -72,12 +78,20 @@
     ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
 }
 
+std::shared_ptr<const HWC2::Display::Config> RefreshRateStatsTest::createConfig(
+        HwcConfigIndexType configId, int32_t configGroup, int64_t vsyncPeriod) {
+    return HWC2::Display::Config::Builder(mDisplay, hwc2_config_t(configId.value()))
+            .setVsyncPeriod(int32_t(vsyncPeriod))
+            .setConfigGroup(configGroup)
+            .build();
+}
+
 namespace {
 /* ------------------------------------------------------------------------
  * Test cases
  */
 TEST_F(RefreshRateStatsTest, oneConfigTest) {
-    init({{{CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90}}});
+    init({createConfig(CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90)});
 
     EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
     EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
@@ -123,7 +137,8 @@
 }
 
 TEST_F(RefreshRateStatsTest, twoConfigsTest) {
-    init({{{CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90}, {CONFIG_ID_1, CONFIG_GROUP_0, VSYNC_60}}});
+    init({createConfig(CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90),
+          createConfig(CONFIG_ID_1, CONFIG_GROUP_0, VSYNC_60)});
 
     EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
     EXPECT_CALL(mTimeStats, recordRefreshRate(60, _)).Times(AtLeast(1));
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 5db11ec..1aa7320 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -31,6 +31,7 @@
 #include "Scheduler/EventThread.h"
 #include "Scheduler/RefreshRateConfigs.h"
 #include "TestableScheduler.h"
+#include "mock/DisplayHardware/MockDisplay.h"
 #include "mock/MockEventThread.h"
 
 using testing::_;
@@ -63,6 +64,7 @@
     Scheduler::ConnectionHandle mConnectionHandle;
     mock::EventThread* mEventThread;
     sp<MockEventThreadConnection> mEventThreadConnection;
+    Hwc2::mock::Display mDisplay;
 };
 
 SchedulerTest::SchedulerTest() {
@@ -70,8 +72,11 @@
             ::testing::UnitTest::GetInstance()->current_test_info();
     ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
 
-    std::vector<scheduler::RefreshRateConfigs::InputConfig> configs{
-            {{HwcConfigIndexType(0), HwcConfigGroupType(0), 16666667}}};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> configs{
+            HWC2::Display::Config::Builder(mDisplay, 0)
+                    .setVsyncPeriod(int32_t(16666667))
+                    .setConfigGroup(0)
+                    .build()};
     mRefreshRateConfigs = std::make_unique<
             scheduler::RefreshRateConfigs>(configs, /*currentConfig=*/HwcConfigIndexType(0));
 
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 414085c..6995ee0 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -39,6 +39,7 @@
 #include "SurfaceFlingerDefaultFactory.h"
 #include "SurfaceInterceptor.h"
 #include "TestableScheduler.h"
+#include "mock/DisplayHardware/MockDisplay.h"
 
 namespace android {
 
@@ -198,8 +199,12 @@
                         std::unique_ptr<EventThread> appEventThread,
                         std::unique_ptr<EventThread> sfEventThread,
                         bool useContentDetectionV2 = false) {
-        std::vector<scheduler::RefreshRateConfigs::InputConfig> configs{
-                {{HwcConfigIndexType(0), HwcConfigGroupType(0), 16666667}}};
+        std::vector<std::shared_ptr<const HWC2::Display::Config>> configs{
+                HWC2::Display::Config::Builder(mDisplay, 0)
+                        .setVsyncPeriod(int32_t(16666667))
+                        .setConfigGroup(0)
+                        .build()};
+
         mFlinger->mRefreshRateConfigs = std::make_unique<
                 scheduler::RefreshRateConfigs>(configs, /*currentConfig=*/HwcConfigIndexType(0));
         mFlinger->mRefreshRateStats = std::make_unique<
@@ -549,9 +554,10 @@
         FakeDisplayDeviceInjector(TestableSurfaceFlinger& flinger,
                                   std::shared_ptr<compositionengine::Display> compositionDisplay,
                                   std::optional<DisplayConnectionType> connectionType,
-                                  bool isPrimary)
+                                  std::optional<hwc2_display_t> hwcDisplayId, bool isPrimary)
               : mFlinger(flinger),
-                mCreationArgs(flinger.mFlinger.get(), mDisplayToken, compositionDisplay) {
+                mCreationArgs(flinger.mFlinger.get(), mDisplayToken, compositionDisplay),
+                mHwcDisplayId(hwcDisplayId) {
             mCreationArgs.connectionType = connectionType;
             mCreationArgs.isPrimary = isPrimary;
         }
@@ -619,7 +625,8 @@
             DisplayDeviceState state;
             if (const auto type = mCreationArgs.connectionType) {
                 LOG_ALWAYS_FATAL_IF(!displayId);
-                state.physical = {*displayId, *type};
+                LOG_ALWAYS_FATAL_IF(!mHwcDisplayId);
+                state.physical = {*displayId, *type, *mHwcDisplayId};
             }
 
             state.isSecure = mCreationArgs.isSecure;
@@ -640,11 +647,13 @@
         TestableSurfaceFlinger& mFlinger;
         sp<BBinder> mDisplayToken = new BBinder();
         DisplayDeviceCreationArgs mCreationArgs;
+        const std::optional<hwc2_display_t> mHwcDisplayId;
     };
 
     surfaceflinger::test::Factory mFactory;
     sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(mFactory, SurfaceFlinger::SkipInitialization);
     TestableScheduler* mScheduler = nullptr;
+    Hwc2::mock::Display mDisplay;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
index 4f65aee..1f04673 100644
--- a/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
@@ -362,6 +362,21 @@
     EXPECT_THAT(result, HasSubstr(expectedResult));
 }
 
+TEST_F(TimeStatsTest, canIncreaseRefreshRateSwitches) {
+    // this stat is not in the proto so verify by checking the string dump
+    constexpr size_t REFRESH_RATE_SWITCHES = 2;
+
+    EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
+    for (size_t i = 0; i < REFRESH_RATE_SWITCHES; i++) {
+        ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementRefreshRateSwitches());
+    }
+
+    const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
+    const std::string expectedResult =
+            "refreshRateSwitches = " + std::to_string(REFRESH_RATE_SWITCHES);
+    EXPECT_THAT(result, HasSubstr(expectedResult));
+}
+
 TEST_F(TimeStatsTest, canAverageFrameDuration) {
     EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
     mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
@@ -744,6 +759,7 @@
     // These stats are not in the proto so verify by checking the string dump.
     EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
     ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionReusedFrames());
+    ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementRefreshRateSwitches());
     mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
     mTimeStats
             ->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
@@ -759,6 +775,7 @@
 
     const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
     EXPECT_THAT(result, HasSubstr("clientCompositionReusedFrames = 0"));
+    EXPECT_THAT(result, HasSubstr("refreshRateSwitches = 0"));
     EXPECT_THAT(result, HasSubstr("averageFrameDuration = 0.000 ms"));
     EXPECT_THAT(result, HasSubstr("averageRenderEngineTiming = 0.000 ms"));
 }
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
index 3543361..1899bed 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
@@ -71,6 +71,7 @@
     MOCK_CONST_METHOD0(now, nsecs_t());
     MOCK_METHOD2(alarmIn, void(std::function<void()> const&, nsecs_t time));
     MOCK_METHOD0(alarmCancel, void());
+    MOCK_CONST_METHOD1(dump, void(std::string&));
 
     void alarmInDefaultBehavior(std::function<void()> const& callback, nsecs_t time) {
         mCallback = callback;
@@ -188,6 +189,7 @@
             }
             void alarmCancel() final { mControllableClock.alarmCancel(); }
             nsecs_t now() const final { return mControllableClock.now(); }
+            void dump(std::string&) const final {}
 
         private:
             TimeKeeper& mControllableClock;
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 5cbba81..2a31078 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -45,6 +45,7 @@
 
 class Composer : public Hwc2::Composer {
 public:
+    using Display = android::hardware::graphics::composer::V2_1::Display;
     Composer();
     ~Composer() override;
 
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
index 6dc28bc..3968035 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
@@ -29,6 +29,9 @@
 
 class Display : public HWC2::Display {
 public:
+    using Error = ::Error;
+    using Layer = ::Layer;
+
     Display();
     ~Display();
 
@@ -80,6 +83,16 @@
     MOCK_METHOD4(presentOrValidate,
                  Error(uint32_t*, uint32_t*, android::sp<android::Fence>*, uint32_t*));
     MOCK_CONST_METHOD1(setDisplayBrightness, Error(float));
+    MOCK_CONST_METHOD1(getDisplayVsyncPeriod, Error(nsecs_t*));
+    MOCK_METHOD3(setActiveConfigWithConstraints,
+                 Error(const std::shared_ptr<const HWC2::Display::Config>&,
+                       const HWC2::VsyncPeriodChangeConstraints&,
+                       HWC2::VsyncPeriodChangeTimeline*));
+    MOCK_CONST_METHOD1(setAutoLowLatencyMode, Error(bool on));
+    MOCK_CONST_METHOD1(getSupportedContentTypes, Error(std::vector<HWC2::ContentType>*));
+    MOCK_CONST_METHOD1(setContentType, Error(HWC2::ContentType));
+    MOCK_CONST_METHOD1(getConnectionType, Error(android::DisplayConnectionType*));
+    MOCK_CONST_METHOD0(isVsyncPeriodSwitchSupported, bool());
 };
 
 } // namespace mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
index c45d584..9ea4dd0 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
@@ -36,6 +36,7 @@
     MOCK_METHOD0(incrementMissedFrames, void());
     MOCK_METHOD0(incrementClientCompositionFrames, void());
     MOCK_METHOD0(incrementClientCompositionReusedFrames, void());
+    MOCK_METHOD0(incrementRefreshRateSwitches, void());
     MOCK_METHOD1(recordDisplayEventConnectionCount, void(int32_t));
     MOCK_METHOD2(recordFrameDuration, void(nsecs_t, nsecs_t));
     MOCK_METHOD2(recordRenderEngineDuration, void(nsecs_t, nsecs_t));