Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e708da89 authored by Hao Chen's avatar Hao Chen
Browse files

Add VTS for EVS Display

They are mostly copied from the HIDL 1.0 display test cases, with some minor changes.

Test: `atest VtsHalEvsTargetTest`
Bug: 275626422
Change-Id: Ica5379e7f021083b65ad8abf320f7751c1432c9e
parent 38ff24c7
Loading
Loading
Loading
Loading
+154 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@
#include <ui/GraphicBufferAllocator.h>
#include <utils/Timers.h>

#include <chrono>
#include <deque>
#include <thread>
#include <unordered_set>
@@ -2197,6 +2198,159 @@ TEST_P(EvsAidlTest, UltrasonicsSetFramesInFlight) {
    }
}

/*
 * DisplayOpen:
 * Test both clean shut down and "aggressive open" device stealing behavior.
 */
TEST_P(EvsAidlTest, DisplayOpen) {
    LOG(INFO) << "Starting DisplayOpen test";

    // Request available display IDs.
    std::vector<uint8_t> displayIds;
    ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
    EXPECT_GT(displayIds.size(), 0);

    for (const auto displayId : displayIds) {
        std::shared_ptr<IEvsDisplay> pDisplay;

        // Request exclusive access to each EVS display, then let it go.
        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
        ASSERT_NE(pDisplay, nullptr);

        {
            // Ask the display what its name is.
            DisplayDesc desc;
            ASSERT_TRUE(pDisplay->getDisplayInfo(&desc).isOk());
            LOG(DEBUG) << "Found display " << desc.id;
        }

        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());

        // Ensure we can reopen the display after it has been closed.
        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
        ASSERT_NE(pDisplay, nullptr);

        // Open the display while its already open -- ownership should be transferred.
        std::shared_ptr<IEvsDisplay> pDisplay2;
        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay2).isOk());
        ASSERT_NE(pDisplay2, nullptr);

        {
            // Ensure the old display properly reports its assassination.
            DisplayState badState;
            EXPECT_TRUE(pDisplay->getDisplayState(&badState).isOk());
            EXPECT_EQ(badState, DisplayState::DEAD);
        }

        // Close only the newest display instance -- the other should already be a zombie.
        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay2).isOk());

        // Finally, validate that we can open the display after the provoked failure above.
        ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
        ASSERT_NE(pDisplay, nullptr);
        ASSERT_TRUE(mEnumerator->closeDisplay(pDisplay).isOk());
    }
}

/*
 * DisplayStates:
 * Validate that display states transition as expected and can be queried from either the display
 * object itself or the owning enumerator.
 */
TEST_P(EvsAidlTest, DisplayStates) {
    using std::literals::chrono_literals::operator""ms;

    LOG(INFO) << "Starting DisplayStates test";

    // Request available display IDs.
    std::vector<uint8_t> displayIds;
    ASSERT_TRUE(mEnumerator->getDisplayIdList(&displayIds).isOk());
    EXPECT_GT(displayIds.size(), 0);

    for (const auto displayId : displayIds) {
        // Ensure the display starts in the expected state.
        {
            DisplayState state;
            EXPECT_FALSE(mEnumerator->getDisplayState(&state).isOk());
        }

        // Scope to limit the lifetime of the pDisplay pointer, and thus the IEvsDisplay object.
        {
            // Request exclusive access to the EVS display.
            std::shared_ptr<IEvsDisplay> pDisplay;
            ASSERT_TRUE(mEnumerator->openDisplay(displayId, &pDisplay).isOk());
            ASSERT_NE(pDisplay, nullptr);
            {
                DisplayState state;
                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
            }

            // Activate the display.
            EXPECT_TRUE(pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME).isOk());
            {
                DisplayState state;
                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
            }
            {
                DisplayState state;
                EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::VISIBLE_ON_NEXT_FRAME);
            }

            // Get the output buffer we'd use to display the imagery.
            BufferDesc tgtBuffer;
            ASSERT_TRUE(pDisplay->getTargetBuffer(&tgtBuffer).isOk());

            // Send the target buffer back for display (we didn't actually fill anything).
            EXPECT_TRUE(pDisplay->returnTargetBufferForDisplay(tgtBuffer).isOk());

            // Sleep for a tenth of a second to ensure the driver has time to get the image
            // displayed.
            std::this_thread::sleep_for(100ms);
            {
                DisplayState state;
                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::VISIBLE);
            }
            {
                DisplayState state;
                EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::VISIBLE);
            }

            // Turn off the display.
            EXPECT_TRUE(pDisplay->setDisplayState(DisplayState::NOT_VISIBLE).isOk());
            std::this_thread::sleep_for(100ms);
            {
                DisplayState state;
                EXPECT_TRUE(mEnumerator->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
            }
            {
                DisplayState state;
                EXPECT_TRUE(pDisplay->getDisplayState(&state).isOk());
                EXPECT_EQ(state, DisplayState::NOT_VISIBLE);
            }

            // Close the display.
            mEnumerator->closeDisplay(pDisplay);
        }

        // Now that the display pointer has gone out of scope, causing the IEvsDisplay interface
        // object to be destroyed, we should be back to the "not open" state.
        // NOTE:  If we want this to pass without the sleep above, we'd have to add the
        //        (now recommended) closeDisplay() call instead of relying on the smarter pointer
        //        going out of scope.  I've not done that because I want to verify that the deletion
        //        of the object does actually clean up (eventually).
        {
            DisplayState state;
            EXPECT_FALSE(mEnumerator->getDisplayState(&state).isOk());
        }
    }
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EvsAidlTest);
INSTANTIATE_TEST_SUITE_P(
        PerInstance, EvsAidlTest,