Merge "Fix inconsistencies in VehicleArea HAL documentation" into udc-dev
diff --git a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
index 2706c49..60adf93 100644
--- a/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
+++ b/automotive/evs/aidl/vts/VtsHalEvsTargetTest.cpp
@@ -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 @@
}
}
+/*
+ * 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,