Make the boot config tests more hermetic

Use a test harness to try to reset boot configs to its original state on
completion. Otherwise we would be polluting the state of other tests.

Ideally these tests hit a fake HWC instead and leave hitting a real HWC
instance for xTS. Alas, we don't have a convenient fake set up, and the
alternative is deleting these tests which is worse.

Bug: 304555116
Test: SurfaceFlinger_test, followed by inputflinger_tests
Change-Id: Id70d11713aca69c9da9f404060f377b2b0d2629e
diff --git a/services/surfaceflinger/tests/BootDisplayMode_test.cpp b/services/surfaceflinger/tests/BootDisplayMode_test.cpp
index f2874ae..4f41a81 100644
--- a/services/surfaceflinger/tests/BootDisplayMode_test.cpp
+++ b/services/surfaceflinger/tests/BootDisplayMode_test.cpp
@@ -28,33 +28,95 @@
 
 using gui::aidl_utils::statusTFromBinderStatus;
 
-TEST(BootDisplayModeTest, setBootDisplayMode) {
-    sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
+struct BootDisplayModeTest : public ::testing::Test {
+protected:
+    void SetUp() override {
+        mSf = ComposerServiceAIDL::getComposerService();
 
-    const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
-    ASSERT_FALSE(ids.empty());
-    auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
-    bool bootModeSupport = false;
-    binder::Status status = sf->getBootDisplayModeSupport(&bootModeSupport);
-    ASSERT_NO_FATAL_FAILURE(statusTFromBinderStatus(status));
-    if (bootModeSupport) {
-        status = sf->setBootDisplayMode(displayToken, 0);
+        const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
+        ASSERT_FALSE(ids.empty());
+        mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
+        bool bootModeSupport = false;
+        binder::Status status = mSf->getBootDisplayModeSupport(&bootModeSupport);
+        ASSERT_NO_FATAL_FAILURE(statusTFromBinderStatus(status));
+
+        if (!bootModeSupport) {
+            GTEST_SKIP() << "Boot mode not supported";
+        }
+
+        gui::DynamicDisplayInfo info;
+        status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
         ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+        mOldMode = info.preferredBootDisplayMode;
+        const auto newMode = [&]() -> std::optional<ui::DisplayModeId> {
+            for (const auto& mode : info.supportedDisplayModes) {
+                if (mode.id != mOldMode) {
+                    return std::optional(mode.id);
+                }
+            }
+            return std::nullopt;
+        }();
+
+        if (!newMode) {
+            GTEST_SKIP() << "Only a single mode is supported";
+        }
+
+        mNewMode = *newMode;
     }
+
+    void TearDown() override {
+        binder::Status status = mSf->setBootDisplayMode(mDisplayToken, mOldMode);
+        EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+        gui::DynamicDisplayInfo info;
+        status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+        EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+        EXPECT_EQ(mOldMode, info.preferredBootDisplayMode);
+    }
+
+    ui::DisplayModeId mOldMode;
+    ui::DisplayModeId mNewMode;
+    sp<gui::ISurfaceComposer> mSf;
+    sp<IBinder> mDisplayToken;
+};
+
+TEST_F(BootDisplayModeTest, setBootDisplayMode) {
+    // Set a new mode and check that it got applied
+    binder::Status status = mSf->setBootDisplayMode(mDisplayToken, mNewMode);
+    EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+    gui::DynamicDisplayInfo info;
+    status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+    EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+    EXPECT_EQ(mNewMode, info.preferredBootDisplayMode);
 }
 
-TEST(BootDisplayModeTest, clearBootDisplayMode) {
-    sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
-    const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
-    ASSERT_FALSE(ids.empty());
-    auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
-    bool bootModeSupport = false;
-    binder::Status status = sf->getBootDisplayModeSupport(&bootModeSupport);
-    ASSERT_NO_FATAL_FAILURE(statusTFromBinderStatus(status));
-    if (bootModeSupport) {
-        status = sf->clearBootDisplayMode(displayToken);
-        ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
-    }
+TEST_F(BootDisplayModeTest, clearBootDisplayMode) {
+    // Clear once to figure out what the system default is
+    binder::Status status = mSf->clearBootDisplayMode(mDisplayToken);
+    EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+    gui::DynamicDisplayInfo info;
+    status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+    EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+    const ui::DisplayModeId systemMode = info.preferredBootDisplayMode;
+    const ui::DisplayModeId newMode = systemMode == mOldMode ? mNewMode : mOldMode;
+
+    // Now set a new mode and clear the boot mode again to figure out if the api worked.
+    status = mSf->setBootDisplayMode(mDisplayToken, newMode);
+    EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+    status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+    EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+    EXPECT_EQ(newMode, info.preferredBootDisplayMode);
+
+    status = mSf->clearBootDisplayMode(mDisplayToken);
+    EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+    status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+    EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+    EXPECT_EQ(systemMode, info.preferredBootDisplayMode);
 }
 
 } // namespace android