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 <changyeon@google.com>
diff --git a/automotive/evs/1.0/vts/functional/FrameHandler.cpp b/automotive/evs/1.0/vts/functional/FrameHandler.cpp
index d44ba41..bc3790f 100644
--- a/automotive/evs/1.0/vts/functional/FrameHandler.cpp
+++ b/automotive/evs/1.0/vts/functional/FrameHandler.cpp
@@ -137,6 +137,10 @@
         // 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 @@
 
     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 17a3980..3f6103d 100644
--- a/automotive/evs/1.0/vts/functional/FrameHandler.h
+++ b/automotive/evs/1.0/vts/functional/FrameHandler.h
@@ -61,6 +61,7 @@
 
     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 @@
     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 d904ad0..f7580f0 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 @@
 public:
     virtual void SetUp() override {
         // Make sure we can connect to the enumerator
-        pEnumerator = getService<IEvsEnumerator>(
-            EvsHidlEnvironment::Instance()->getServiceName<IEvsEnumerator>(kEnumeratorName));
+        string service_name =
+            EvsHidlEnvironment::Instance()->getServiceName<IEvsEnumerator>(kEnumeratorName);
+        pEnumerator = getService<IEvsEnumerator>(service_name);
         ASSERT_NE(pEnumerator.get(), nullptr);
+
+        mIsHwModule = !service_name.compare(kEnumeratorName);
     }
 
     virtual void TearDown() override {}
@@ -114,12 +117,13 @@
 
     sp<IEvsEnumerator>          pEnumerator;    // Every test needs access to the service
     std::vector <CameraDesc>    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 @@
         ASSERT_NE(pCam, pCam2);
         ASSERT_NE(pCam2, nullptr);
 
-        // Verify that the old camera rejects calls
-        Return<EvsResult> badResult = pCam->setMaxFramesInFlight(2);
-        EXPECT_EQ(EvsResult::OWNERSHIP_LOST, EvsResult(badResult));
+        Return<EvsResult> 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 @@
                              }
         );
 
-        // 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 @@
         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 @@
     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 <IEvsCamera> pCam0 = pEnumerator->openCamera(cam.cameraId);
+        ASSERT_NE(pCam0, nullptr);
+
+        sp <IEvsCamera> pCam1 = pEnumerator->openCamera(cam.cameraId);
+        ASSERT_NE(pCam1, nullptr);
+
+        // Set up per-client frame receiver objects which will fire up its own thread
+        sp<FrameHandler> frameHandler0 = new FrameHandler(pCam0, cam,
+                                                          nullptr,
+                                                          FrameHandler::eAutoReturn);
+        ASSERT_NE(frameHandler0, nullptr);
+
+        sp<FrameHandler> 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);