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