From 17aa6d351271222bb8abc8dbb61e00757e358f31 Mon Sep 17 00:00:00 2001 From: Changyeon Jo Date: Sat, 25 May 2019 12:02:43 -0700 Subject: [PATCH] Update EVS VTS test cases This change modifies existing test cases and adds one new test case for EVS manager implementation. Bug: 122468953 Change-Id: I5cee01dfe0b0617c3f5c46beb94dcda0387f4ba0 Signed-off-by: Changyeon Jo --- .../evs/1.0/vts/functional/FrameHandler.cpp | 14 ++ .../evs/1.0/vts/functional/FrameHandler.h | 3 + .../functional/VtsHalEvsV1_0TargetTest.cpp | 123 ++++++++++++++++-- 3 files changed, 131 insertions(+), 9 deletions(-) diff --git a/automotive/evs/1.0/vts/functional/FrameHandler.cpp b/automotive/evs/1.0/vts/functional/FrameHandler.cpp index d44ba41c5d..bc3790f385 100644 --- a/automotive/evs/1.0/vts/functional/FrameHandler.cpp +++ b/automotive/evs/1.0/vts/functional/FrameHandler.cpp @@ -137,6 +137,10 @@ Return FrameHandler::deliverFrame(const BufferDesc& bufferArg) { // Signal that the last frame has been received and the stream is stopped timeToStop = true; } else { + // Store a dimension of a received frame. + mFrameWidth = bufferArg.width; + mFrameHeight = bufferArg.height; + // If we were given an opened display at construction time, then send the received // image back down the camera. if (mDisplay.get()) { @@ -299,3 +303,13 @@ bool FrameHandler::copyBufferContents(const BufferDesc& tgtBuffer, return success; } + +void FrameHandler::getFrameDimension(unsigned* width, unsigned* height) { + if (width) { + *width = mFrameWidth; + } + + if (height) { + *height = mFrameHeight; + } +} diff --git a/automotive/evs/1.0/vts/functional/FrameHandler.h b/automotive/evs/1.0/vts/functional/FrameHandler.h index 17a39803fa..3f6103d8ac 100644 --- a/automotive/evs/1.0/vts/functional/FrameHandler.h +++ b/automotive/evs/1.0/vts/functional/FrameHandler.h @@ -61,6 +61,7 @@ public: void waitForFrameCount(unsigned frameCount); void getFramesCounters(unsigned* received, unsigned* displayed); + void getFrameDimension(unsigned* width, unsigned* height); private: // Implementation for ::android::hardware::automotive::evs::V1_0::ICarCameraStream @@ -85,6 +86,8 @@ private: bool mRunning = false; unsigned mFramesReceived = 0; // Simple counter -- rolls over eventually! unsigned mFramesDisplayed = 0; // Simple counter -- rolls over eventually! + unsigned mFrameWidth = 0; + unsigned mFrameHeight = 0; }; diff --git a/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp b/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp index d904ad06bf..f7580f02a8 100644 --- a/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp +++ b/automotive/evs/1.0/vts/functional/VtsHalEvsV1_0TargetTest.cpp @@ -84,9 +84,12 @@ class EvsHidlTest : public ::testing::VtsHalHidlTargetTestBase { public: virtual void SetUp() override { // Make sure we can connect to the enumerator - pEnumerator = getService( - EvsHidlEnvironment::Instance()->getServiceName(kEnumeratorName)); + string service_name = + EvsHidlEnvironment::Instance()->getServiceName(kEnumeratorName); + pEnumerator = getService(service_name); ASSERT_NE(pEnumerator.get(), nullptr); + + mIsHwModule = !service_name.compare(kEnumeratorName); } virtual void TearDown() override {} @@ -114,12 +117,13 @@ protected: sp pEnumerator; // Every test needs access to the service std::vector cameraInfo; // Empty unless/until loadCameraList() is called + bool mIsHwModule; // boolean to tell current module under testing + // is HW module implementation. }; -// -// Tests start here... -// +// Test cases, their implementations, and corresponding requirements are +// documented at go/aae-evs-public-api-test. /* * CameraOpenClean: @@ -180,9 +184,14 @@ TEST_F(EvsHidlTest, CameraOpenAggressive) { ASSERT_NE(pCam, pCam2); ASSERT_NE(pCam2, nullptr); - // Verify that the old camera rejects calls - Return badResult = pCam->setMaxFramesInFlight(2); - EXPECT_EQ(EvsResult::OWNERSHIP_LOST, EvsResult(badResult)); + Return result = pCam->setMaxFramesInFlight(2); + if (mIsHwModule) { + // Verify that the old camera rejects calls via HW module. + EXPECT_EQ(EvsResult::OWNERSHIP_LOST, EvsResult(result)); + } else { + // default implementation supports multiple clients. + EXPECT_EQ(EvsResult::OK, EvsResult(result)); + } // Close the superceded camera pEnumerator->closeCamera(pCam); @@ -194,7 +203,8 @@ TEST_F(EvsHidlTest, CameraOpenAggressive) { } ); - // Leave the second camera dangling so it gets cleaned up by the destructor path + // Close the second camera instance + pEnumerator->closeCamera(pCam2); } // Sleep here to ensure the destructor cleanup has time to run so we don't break follow on tests @@ -343,6 +353,11 @@ TEST_F(EvsHidlTest, CameraStreamPerformance) { printf("Measured time to first frame %0.2f ms\n", timeToFirstFrame * kNanoToMilliseconds); ALOGI("Measured time to first frame %0.2f ms", timeToFirstFrame * kNanoToMilliseconds); + // Check aspect ratio + unsigned width = 0, height = 0; + frameHandler->getFrameDimension(&width, &height); + EXPECT_GE(width, height); + // Wait a bit, then ensure we get at least the required minimum number of frames sleep(5); nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC); @@ -496,6 +511,96 @@ TEST_F(EvsHidlTest, CameraToDisplayRoundTrip) { pEnumerator->closeDisplay(pDisplay); } + +/* + * MultiCameraStream: + * Verify that each client can start and stop video streams on the same + * underlying camera. + */ +TEST_F(EvsHidlTest, MultiCameraStream) { + ALOGI("Starting MultiCameraStream test"); + + if (mIsHwModule) { + // This test is not for HW module implementation. + return; + } + + // Get the camera list + loadCameraList(); + + // Test each reported camera + for (auto&& cam: cameraInfo) { + // Create two camera clients. + sp pCam0 = pEnumerator->openCamera(cam.cameraId); + ASSERT_NE(pCam0, nullptr); + + sp pCam1 = pEnumerator->openCamera(cam.cameraId); + ASSERT_NE(pCam1, nullptr); + + // Set up per-client frame receiver objects which will fire up its own thread + sp frameHandler0 = new FrameHandler(pCam0, cam, + nullptr, + FrameHandler::eAutoReturn); + ASSERT_NE(frameHandler0, nullptr); + + sp frameHandler1 = new FrameHandler(pCam1, cam, + nullptr, + FrameHandler::eAutoReturn); + ASSERT_NE(frameHandler1, nullptr); + + // Start the camera's video stream via client 0 + bool startResult = false; + startResult = frameHandler0->startStream() && + frameHandler1->startStream(); + ASSERT_TRUE(startResult); + + // Ensure the stream starts + frameHandler0->waitForFrameCount(1); + frameHandler1->waitForFrameCount(1); + + nsecs_t firstFrame = systemTime(SYSTEM_TIME_MONOTONIC); + + // Wait a bit, then ensure both clients get at least the required minimum number of frames + sleep(5); + nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC); + unsigned framesReceived0 = 0, framesReceived1 = 0; + frameHandler0->getFramesCounters(&framesReceived0, nullptr); + frameHandler1->getFramesCounters(&framesReceived1, nullptr); + framesReceived0 = framesReceived0 - 1; // Back out the first frame we already waited for + framesReceived1 = framesReceived1 - 1; // Back out the first frame we already waited for + nsecs_t runTime = end - firstFrame; + float framesPerSecond0 = framesReceived0 / (runTime * kNanoToSeconds); + float framesPerSecond1 = framesReceived1 / (runTime * kNanoToSeconds); + printf("Measured camera rate %3.2f fps and %3.2f fps\n", framesPerSecond0, framesPerSecond1); + ALOGI("Measured camera rate %3.2f fps and %3.2f fps", framesPerSecond0, framesPerSecond1); + EXPECT_GE(framesPerSecond0, kMinimumFramesPerSecond); + EXPECT_GE(framesPerSecond1, kMinimumFramesPerSecond); + + // Shutdown one client + frameHandler0->shutdown(); + + // Read frame counters again + frameHandler0->getFramesCounters(&framesReceived0, nullptr); + frameHandler1->getFramesCounters(&framesReceived1, nullptr); + + // Wait a bit again + sleep(5); + unsigned framesReceivedAfterStop0 = 0, framesReceivedAfterStop1 = 0; + frameHandler0->getFramesCounters(&framesReceivedAfterStop0, nullptr); + frameHandler1->getFramesCounters(&framesReceivedAfterStop1, nullptr); + EXPECT_EQ(framesReceived0, framesReceivedAfterStop0); + EXPECT_LT(framesReceived1, framesReceivedAfterStop1); + + // Shutdown another + frameHandler1->shutdown(); + + // Explicitly release the camera + pEnumerator->closeCamera(pCam0); + pEnumerator->closeCamera(pCam1); + } +} + + int main(int argc, char** argv) { ::testing::AddGlobalTestEnvironment(EvsHidlEnvironment::Instance()); ::testing::InitGoogleTest(&argc, argv);