1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "VtsHalEvsTest"
18 
19 
20 // These values are called out in the EVS design doc (as of Mar 8, 2017)
21 static const int kMaxStreamStartMilliseconds = 1000;
22 static const int kMinimumFramesPerSecond = 10;
23 
24 static const int kSecondsToMilliseconds = 1000;
25 static const int kMillisecondsToMicroseconds = 1000;
26 static const float kNanoToMilliseconds = 0.000001f;
27 static const float kNanoToSeconds = 0.000000001f;
28 
29 
30 #include "FrameHandler.h"
31 
32 #include <stdio.h>
33 #include <string.h>
34 
35 #include <hidl/HidlTransportSupport.h>
36 #include <hwbinder/ProcessState.h>
37 #include <log/log.h>
38 #include <utils/Errors.h>
39 #include <utils/StrongPointer.h>
40 
41 #include <android/log.h>
42 #include <android/hardware/automotive/evs/1.0/IEvsCamera.h>
43 #include <android/hardware/automotive/evs/1.0/IEvsEnumerator.h>
44 #include <android/hardware/automotive/evs/1.0/IEvsCameraStream.h>
45 #include <android/hardware/automotive/evs/1.0/IEvsDisplay.h>
46 
47 #include <gtest/gtest.h>
48 #include <hidl/GtestPrinter.h>
49 #include <hidl/ServiceManagement.h>
50 
51 using namespace ::android::hardware::automotive::evs::V1_0;
52 using ::android::hardware::Return;
53 using ::android::hardware::Void;
54 using ::android::hardware::hidl_vec;
55 using ::android::hardware::hidl_handle;
56 using ::android::hardware::hidl_string;
57 using ::android::sp;
58 
59 // The main test class for EVS
60 class EvsHidlTest : public ::testing::TestWithParam<std::string> {
61 public:
SetUp()62     virtual void SetUp() override {
63         // Make sure we can connect to the enumerator
64         std::string service_name = GetParam();
65         pEnumerator = IEvsEnumerator::getService(service_name);
66 
67         ASSERT_NE(pEnumerator.get(), nullptr);
68 
69         // "legacy_sw/0" is reserved for EVS manager v1.0 implementation.
70         constexpr static char kEvsManagerName[] = "legacy_sw/0";
71         mIsHwModule = service_name.compare(kEvsManagerName);
72     }
73 
TearDown()74     virtual void TearDown() override {}
75 
76 protected:
loadCameraList()77     void loadCameraList() {
78         // SetUp() must run first!
79         assert(pEnumerator != nullptr);
80 
81         // Get the camera list
82         pEnumerator->getCameraList([this](hidl_vec <CameraDesc> cameraList) {
83                                        ALOGI("Camera list callback received %zu cameras",
84                                              cameraList.size());
85                                        cameraInfo.reserve(cameraList.size());
86                                        for (auto&& cam: cameraList) {
87                                            ALOGI("Found camera %s", cam.cameraId.c_str());
88                                            cameraInfo.push_back(cam);
89                                        }
90                                    }
91         );
92 
93         // We insist on at least one camera for EVS to pass any camera tests
94         ASSERT_GE(cameraInfo.size(), 1u);
95     }
96 
97     sp<IEvsEnumerator>          pEnumerator;    // Every test needs access to the service
98     std::vector <CameraDesc>    cameraInfo;     // Empty unless/until loadCameraList() is called
99     bool                        mIsHwModule;    // boolean to tell current module under testing
100                                                 // is HW module implementation.
101 };
102 
103 
104 // Test cases, their implementations, and corresponding requirements are
105 // documented at go/aae-evs-public-api-test.
106 
107 /*
108  * CameraOpenClean:
109  * Opens each camera reported by the enumerator and then explicitly closes it via a
110  * call to closeCamera.  Then repeats the test to ensure all cameras can be reopened.
111  */
TEST_P(EvsHidlTest,CameraOpenClean)112 TEST_P(EvsHidlTest, CameraOpenClean) {
113     ALOGI("Starting CameraOpenClean test");
114 
115     // Get the camera list
116     loadCameraList();
117 
118     // Open and close each camera twice
119     for (auto&& cam: cameraInfo) {
120         for (int pass = 0; pass < 2; pass++) {
121             sp<IEvsCamera> pCam = pEnumerator->openCamera(cam.cameraId);
122             ASSERT_NE(pCam, nullptr);
123 
124             // Verify that this camera self-identifies correctly
125             pCam->getCameraInfo([&cam](CameraDesc desc) {
126                                     ALOGD("Found camera %s", desc.cameraId.c_str());
127                                     EXPECT_EQ(cam.cameraId, desc.cameraId);
128                                 }
129             );
130 
131             // Explicitly close the camera so resources are released right away
132             pEnumerator->closeCamera(pCam);
133         }
134     }
135 }
136 
137 
138 /*
139  * CameraOpenAggressive:
140  * Opens each camera reported by the enumerator twice in a row without an intervening closeCamera
141  * call.  This ensures that the intended "aggressive open" behavior works.  This is necessary for
142  * the system to be tolerant of shutdown/restart race conditions.
143  */
TEST_P(EvsHidlTest,CameraOpenAggressive)144 TEST_P(EvsHidlTest, CameraOpenAggressive) {
145     ALOGI("Starting CameraOpenAggressive test");
146 
147     // Get the camera list
148     loadCameraList();
149 
150     // Open and close each camera twice
151     for (auto&& cam: cameraInfo) {
152         sp<IEvsCamera> pCam = pEnumerator->openCamera(cam.cameraId);
153         ASSERT_NE(pCam, nullptr);
154 
155         // Verify that this camera self-identifies correctly
156         pCam->getCameraInfo([&cam](CameraDesc desc) {
157                                 ALOGD("Found camera %s", desc.cameraId.c_str());
158                                 EXPECT_EQ(cam.cameraId, desc.cameraId);
159                             }
160         );
161 
162         sp<IEvsCamera> pCam2 = pEnumerator->openCamera(cam.cameraId);
163         ASSERT_NE(pCam, pCam2);
164         ASSERT_NE(pCam2, nullptr);
165 
166         Return<EvsResult> result = pCam->setMaxFramesInFlight(2);
167         if (mIsHwModule) {
168             // Verify that the old camera rejects calls via HW module.
169             EXPECT_EQ(EvsResult::OWNERSHIP_LOST, EvsResult(result));
170         } else {
171             // default implementation supports multiple clients.
172             EXPECT_EQ(EvsResult::OK, EvsResult(result));
173         }
174 
175         // Close the superceded camera
176         pEnumerator->closeCamera(pCam);
177 
178         // Verify that the second camera instance self-identifies correctly
179         pCam2->getCameraInfo([&cam](CameraDesc desc) {
180                                  ALOGD("Found camera %s", desc.cameraId.c_str());
181                                  EXPECT_EQ(cam.cameraId, desc.cameraId);
182                              }
183         );
184 
185         // Close the second camera instance
186         pEnumerator->closeCamera(pCam2);
187     }
188 
189     // Sleep here to ensure the destructor cleanup has time to run so we don't break follow on tests
190     sleep(1);   // I hate that this is an arbitrary time to wait.  :(  b/36122635
191 }
192 
193 
194 /*
195  * DisplayOpen:
196  * Test both clean shut down and "aggressive open" device stealing behavior.
197  */
TEST_P(EvsHidlTest,DisplayOpen)198 TEST_P(EvsHidlTest, DisplayOpen) {
199     ALOGI("Starting DisplayOpen test");
200 
201     // Request exclusive access to the EVS display, then let it go
202     {
203         sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
204         ASSERT_NE(pDisplay, nullptr);
205 
206         // Ask the display what it's name is
207         pDisplay->getDisplayInfo([](DisplayDesc desc) {
208                                      ALOGD("Found display %s", desc.displayId.c_str());
209                                  }
210         );
211 
212         pEnumerator->closeDisplay(pDisplay);
213     }
214 
215     // Ensure we can reopen the display after it has been closed
216     {
217         // Reopen the display
218         sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
219         ASSERT_NE(pDisplay, nullptr);
220 
221         // Open the display while its already open -- ownership should be transferred
222         sp<IEvsDisplay> pDisplay2 = pEnumerator->openDisplay();
223         ASSERT_NE(pDisplay2, nullptr);
224 
225         // Ensure the old display properly reports its assassination
226         Return<DisplayState> badResult = pDisplay->getDisplayState();
227         EXPECT_EQ(badResult, DisplayState::DEAD);
228 
229         // Close only the newest display instance -- the other should already be a zombie
230         pEnumerator->closeDisplay(pDisplay2);
231     }
232 
233     // Finally, validate that we can open the display after the provoked failure above
234     sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
235     ASSERT_NE(pDisplay, nullptr);
236 
237     pEnumerator->closeDisplay(pDisplay);
238 }
239 
240 
241 /*
242  * DisplayStates:
243  * Validate that display states transition as expected and can be queried from either the display
244  * object itself or the owning enumerator.
245  */
TEST_P(EvsHidlTest,DisplayStates)246 TEST_P(EvsHidlTest, DisplayStates) {
247     ALOGI("Starting DisplayStates test");
248 
249     // Ensure the display starts in the expected state
250     EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::NOT_OPEN);
251 
252     // Scope to limit the lifetime of the pDisplay pointer, and thus the IEvsDisplay object
253     {
254         // Request exclusive access to the EVS display
255         sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
256         ASSERT_NE(pDisplay, nullptr);
257         EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::NOT_VISIBLE);
258 
259         // Activate the display
260         pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME);
261         EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::VISIBLE_ON_NEXT_FRAME);
262         EXPECT_EQ((DisplayState)pDisplay->getDisplayState(), DisplayState::VISIBLE_ON_NEXT_FRAME);
263 
264         // Get the output buffer we'd use to display the imagery
265         BufferDesc tgtBuffer = {};
266         pDisplay->getTargetBuffer([&tgtBuffer](const BufferDesc& buff) {
267                                       tgtBuffer = buff;
268                                   }
269         );
270         EXPECT_NE(tgtBuffer.memHandle, nullptr);
271 
272         // Send the target buffer back for display (we didn't actually fill anything)
273         pDisplay->returnTargetBufferForDisplay(tgtBuffer);
274 
275         // Sleep for a tenth of a second to ensure the driver has time to get the image displayed
276         usleep(100 * kMillisecondsToMicroseconds);
277         EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::VISIBLE);
278         EXPECT_EQ((DisplayState)pDisplay->getDisplayState(), DisplayState::VISIBLE);
279 
280         // Turn off the display
281         pDisplay->setDisplayState(DisplayState::NOT_VISIBLE);
282         usleep(100 * kMillisecondsToMicroseconds);
283         EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::NOT_VISIBLE);
284 
285         // Close the display
286         pEnumerator->closeDisplay(pDisplay);
287     }
288 
289     // TODO:  This hack shouldn't be necessary.  b/36122635
290     sleep(1);
291 
292     // Now that the display pointer has gone out of scope, causing the IEvsDisplay interface
293     // object to be destroyed, we should be back to the "not open" state.
294     // NOTE:  If we want this to pass without the sleep above, we'd have to add the
295     //        (now recommended) closeDisplay() call instead of relying on the smarter pointer
296     //        going out of scope.  I've not done that because I want to verify that the deletion
297     //        of the object does actually clean up (eventually).
298     EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::NOT_OPEN);
299 }
300 
301 
302 /*
303  * CameraStreamPerformance:
304  * Measure and qualify the stream start up time and streaming frame rate of each reported camera
305  */
TEST_P(EvsHidlTest,CameraStreamPerformance)306 TEST_P(EvsHidlTest, CameraStreamPerformance) {
307     ALOGI("Starting CameraStreamPerformance test");
308 
309     // Get the camera list
310     loadCameraList();
311 
312     // Test each reported camera
313     for (auto&& cam: cameraInfo) {
314         sp <IEvsCamera> pCam = pEnumerator->openCamera(cam.cameraId);
315         ASSERT_NE(pCam, nullptr);
316 
317         // Set up a frame receiver object which will fire up its own thread
318         sp<FrameHandler> frameHandler = new FrameHandler(pCam, cam,
319                                                          nullptr,
320                                                          FrameHandler::eAutoReturn);
321 
322         // Start the camera's video stream
323         nsecs_t start = systemTime(SYSTEM_TIME_MONOTONIC);
324         bool startResult = frameHandler->startStream();
325         ASSERT_TRUE(startResult);
326 
327         // Ensure the first frame arrived within the expected time
328         frameHandler->waitForFrameCount(1);
329         nsecs_t firstFrame = systemTime(SYSTEM_TIME_MONOTONIC);
330         nsecs_t timeToFirstFrame = systemTime(SYSTEM_TIME_MONOTONIC) - start;
331         EXPECT_LE(nanoseconds_to_milliseconds(timeToFirstFrame), kMaxStreamStartMilliseconds);
332         printf("Measured time to first frame %0.2f ms\n", timeToFirstFrame * kNanoToMilliseconds);
333         ALOGI("Measured time to first frame %0.2f ms", timeToFirstFrame * kNanoToMilliseconds);
334 
335         // Wait a bit, then ensure we get at least the required minimum number of frames
336         sleep(5);
337         nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC);
338         unsigned framesReceived = 0;
339         frameHandler->getFramesCounters(&framesReceived, nullptr);
340         framesReceived = framesReceived - 1;    // Back out the first frame we already waited for
341         nsecs_t runTime = end - firstFrame;
342         float framesPerSecond = framesReceived / (runTime * kNanoToSeconds);
343         printf("Measured camera rate %3.2f fps\n", framesPerSecond);
344         ALOGI("Measured camera rate %3.2f fps", framesPerSecond);
345         EXPECT_GE(framesPerSecond, kMinimumFramesPerSecond);
346 
347         // Even when the camera pointer goes out of scope, the FrameHandler object will
348         // keep the stream alive unless we tell it to shutdown.
349         // Also note that the FrameHandle and the Camera have a mutual circular reference, so
350         // we have to break that cycle in order for either of them to get cleaned up.
351         frameHandler->shutdown();
352 
353         // Explicitly release the camera
354         pEnumerator->closeCamera(pCam);
355     }
356 }
357 
358 
359 /*
360  * CameraStreamBuffering:
361  * Ensure the camera implementation behaves properly when the client holds onto buffers for more
362  * than one frame time.  The camera must cleanly skip frames until the client is ready again.
363  */
TEST_P(EvsHidlTest,CameraStreamBuffering)364 TEST_P(EvsHidlTest, CameraStreamBuffering) {
365     ALOGI("Starting CameraStreamBuffering test");
366 
367     // Maximum number of frames in flight this test case will attempt. This test
368     // case chooses an arbitrary number that is large enough to run a camera
369     // pipeline for a single client.
370     constexpr unsigned int kMaxBuffersToHold = 20;
371 
372     // Initial value for setMaxFramesInFlight() call. This number should be
373     // greater than 1.
374     unsigned int buffersToHold = 2;
375 
376     // Get the camera list
377     loadCameraList();
378 
379     // Test each reported camera
380     for (auto&& cam: cameraInfo) {
381 
382         sp<IEvsCamera> pCam = pEnumerator->openCamera(cam.cameraId);
383         ASSERT_NE(pCam, nullptr);
384 
385         // Ask for a very large number of buffers in flight to ensure it errors correctly
386         Return<EvsResult> badResult = pCam->setMaxFramesInFlight(0xFFFFFFFF);
387         EXPECT_EQ(EvsResult::BUFFER_NOT_AVAILABLE, badResult);
388 
389         // Now ask for exactly two buffers in flight as we'll test behavior in that case
390         // Find the minimum number of buffers to run a target camera.
391         while (buffersToHold < kMaxBuffersToHold) {
392             Return<EvsResult> goodResult = pCam->setMaxFramesInFlight(buffersToHold);
393             if (goodResult == EvsResult::OK) {
394                 break;
395             }
396 
397             ++buffersToHold;
398         }
399         EXPECT_LE(buffersToHold, kMaxBuffersToHold);
400 
401         // Set up a frame receiver object which will fire up its own thread.
402         sp<FrameHandler> frameHandler = new FrameHandler(pCam, cam,
403                                                          nullptr,
404                                                          FrameHandler::eNoAutoReturn);
405 
406         // Start the camera's video stream
407         bool startResult = frameHandler->startStream();
408         ASSERT_TRUE(startResult);
409 
410         // Check that the video stream stalls once we've gotten exactly the number of buffers
411         // we requested since we told the frameHandler not to return them.
412         sleep(2);   // 1 second should be enough for at least 5 frames to be delivered worst case
413         unsigned framesReceived = 0;
414         frameHandler->getFramesCounters(&framesReceived, nullptr);
415         ASSERT_EQ(buffersToHold, framesReceived) << "Stream didn't stall at expected buffer limit";
416 
417 
418         // Give back one buffer
419         bool didReturnBuffer = frameHandler->returnHeldBuffer();
420         EXPECT_TRUE(didReturnBuffer);
421 
422         // Once we return a buffer, it shouldn't take more than 1/10 second to get a new one
423         // filled since we require 10fps minimum -- but give a 10% allowance just in case.
424         usleep(110 * kMillisecondsToMicroseconds);
425         frameHandler->getFramesCounters(&framesReceived, nullptr);
426         EXPECT_EQ(buffersToHold+1, framesReceived) << "Stream should've resumed";
427 
428         // Even when the camera pointer goes out of scope, the FrameHandler object will
429         // keep the stream alive unless we tell it to shutdown.
430         // Also note that the FrameHandle and the Camera have a mutual circular reference, so
431         // we have to break that cycle in order for either of them to get cleaned up.
432         frameHandler->shutdown();
433 
434         // Explicitly release the camera
435         pEnumerator->closeCamera(pCam);
436     }
437 }
438 
439 
440 /*
441  * CameraToDisplayRoundTrip:
442  * End to end test of data flowing from the camera to the display.  Each delivered frame of camera
443  * imagery is simply copied to the display buffer and presented on screen.  This is the one test
444  * which a human could observe to see the operation of the system on the physical display.
445  */
TEST_P(EvsHidlTest,CameraToDisplayRoundTrip)446 TEST_P(EvsHidlTest, CameraToDisplayRoundTrip) {
447     ALOGI("Starting CameraToDisplayRoundTrip test");
448 
449     // Get the camera list
450     loadCameraList();
451 
452     // Request exclusive access to the EVS display
453     sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
454     ASSERT_NE(pDisplay, nullptr);
455 
456     // Test each reported camera
457     for (auto&& cam: cameraInfo) {
458         sp <IEvsCamera> pCam = pEnumerator->openCamera(cam.cameraId);
459         ASSERT_NE(pCam, nullptr);
460 
461         // Set up a frame receiver object which will fire up its own thread.
462         sp<FrameHandler> frameHandler = new FrameHandler(pCam, cam,
463                                                          pDisplay,
464                                                          FrameHandler::eAutoReturn);
465 
466 
467         // Activate the display
468         pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME);
469 
470         // Start the camera's video stream
471         bool startResult = frameHandler->startStream();
472         ASSERT_TRUE(startResult);
473 
474         // Wait a while to let the data flow
475         static const int kSecondsToWait = 5;
476         const int streamTimeMs = kSecondsToWait * kSecondsToMilliseconds -
477                                  kMaxStreamStartMilliseconds;
478         const unsigned minimumFramesExpected = streamTimeMs * kMinimumFramesPerSecond /
479                                                kSecondsToMilliseconds;
480         sleep(kSecondsToWait);
481         unsigned framesReceived = 0;
482         unsigned framesDisplayed = 0;
483         frameHandler->getFramesCounters(&framesReceived, &framesDisplayed);
484         EXPECT_EQ(framesReceived, framesDisplayed);
485         EXPECT_GE(framesDisplayed, minimumFramesExpected);
486 
487         // Turn off the display (yes, before the stream stops -- it should be handled)
488         pDisplay->setDisplayState(DisplayState::NOT_VISIBLE);
489 
490         // Shut down the streamer
491         frameHandler->shutdown();
492 
493         // Explicitly release the camera
494         pEnumerator->closeCamera(pCam);
495     }
496 
497     // Explicitly release the display
498     pEnumerator->closeDisplay(pDisplay);
499 }
500 
501 
502 /*
503  * MultiCameraStream:
504  * Verify that each client can start and stop video streams on the same
505  * underlying camera.
506  */
TEST_P(EvsHidlTest,MultiCameraStream)507 TEST_P(EvsHidlTest, MultiCameraStream) {
508     ALOGI("Starting MultiCameraStream test");
509 
510     if (mIsHwModule) {
511         // This test is not for HW module implementation.
512         return;
513     }
514 
515     // Get the camera list
516     loadCameraList();
517 
518     // Test each reported camera
519     for (auto&& cam: cameraInfo) {
520         // Create two camera clients.
521         sp <IEvsCamera> pCam0 = pEnumerator->openCamera(cam.cameraId);
522         ASSERT_NE(pCam0, nullptr);
523 
524         sp <IEvsCamera> pCam1 = pEnumerator->openCamera(cam.cameraId);
525         ASSERT_NE(pCam1, nullptr);
526 
527         // Set up per-client frame receiver objects which will fire up its own thread
528         sp<FrameHandler> frameHandler0 = new FrameHandler(pCam0, cam,
529                                                           nullptr,
530                                                           FrameHandler::eAutoReturn);
531         ASSERT_NE(frameHandler0, nullptr);
532 
533         sp<FrameHandler> frameHandler1 = new FrameHandler(pCam1, cam,
534                                                           nullptr,
535                                                           FrameHandler::eAutoReturn);
536         ASSERT_NE(frameHandler1, nullptr);
537 
538         // Start the camera's video stream via client 0
539         bool startResult = false;
540         startResult = frameHandler0->startStream() &&
541                       frameHandler1->startStream();
542         ASSERT_TRUE(startResult);
543 
544         // Ensure the stream starts
545         frameHandler0->waitForFrameCount(1);
546         frameHandler1->waitForFrameCount(1);
547 
548         nsecs_t firstFrame = systemTime(SYSTEM_TIME_MONOTONIC);
549 
550         // Wait a bit, then ensure both clients get at least the required minimum number of frames
551         sleep(5);
552         nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC);
553         unsigned framesReceived0 = 0, framesReceived1 = 0;
554         frameHandler0->getFramesCounters(&framesReceived0, nullptr);
555         frameHandler1->getFramesCounters(&framesReceived1, nullptr);
556         framesReceived0 = framesReceived0 - 1;    // Back out the first frame we already waited for
557         framesReceived1 = framesReceived1 - 1;    // Back out the first frame we already waited for
558         nsecs_t runTime = end - firstFrame;
559         float framesPerSecond0 = framesReceived0 / (runTime * kNanoToSeconds);
560         float framesPerSecond1 = framesReceived1 / (runTime * kNanoToSeconds);
561         printf("Measured camera rate %3.2f fps and %3.2f fps\n", framesPerSecond0, framesPerSecond1);
562         ALOGI("Measured camera rate %3.2f fps and %3.2f fps", framesPerSecond0, framesPerSecond1);
563         EXPECT_GE(framesPerSecond0, kMinimumFramesPerSecond);
564         EXPECT_GE(framesPerSecond1, kMinimumFramesPerSecond);
565 
566         // Shutdown one client
567         frameHandler0->shutdown();
568 
569         // Read frame counters again
570         frameHandler0->getFramesCounters(&framesReceived0, nullptr);
571         frameHandler1->getFramesCounters(&framesReceived1, nullptr);
572 
573         // Wait a bit again
574         sleep(5);
575         unsigned framesReceivedAfterStop0 = 0, framesReceivedAfterStop1 = 0;
576         frameHandler0->getFramesCounters(&framesReceivedAfterStop0, nullptr);
577         frameHandler1->getFramesCounters(&framesReceivedAfterStop1, nullptr);
578         EXPECT_EQ(framesReceived0, framesReceivedAfterStop0);
579         EXPECT_LT(framesReceived1, framesReceivedAfterStop1);
580 
581         // Shutdown another
582         frameHandler1->shutdown();
583 
584         // Explicitly release the camera
585         pEnumerator->closeCamera(pCam0);
586         pEnumerator->closeCamera(pCam1);
587     }
588 }
589 
590 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EvsHidlTest);
591 INSTANTIATE_TEST_SUITE_P(
592     PerInstance,
593     EvsHidlTest,
594     testing::ValuesIn(android::hardware::getAllHalInstanceNames(IEvsEnumerator::descriptor)),
595     android::hardware::PrintInstanceNameToString);
596