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

Commit 96ca6580 authored by Hao Chen's avatar Hao Chen Committed by Android (Google) Code Review
Browse files

Merge "Add VTS for EVS Display" into udc-dev

parents 2843cae1 e708da89
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,