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 // Note: We have't got a great way to indicate which target
21 // should be tested, so we'll leave the interface served by the
22 // default (mock) EVS driver here for easy reference. All
23 // actual EVS drivers should serve on the EvsEnumeratorHw name,
24 // however, so the code is checked in that way.
25 //const static char kEnumeratorName[] = "EvsEnumeratorHw-Mock";
26 const static char kEnumeratorName[] = "EvsEnumeratorHw";
27
28
29 // These values are called out in the EVS design doc (as of Mar 8, 2017)
30 static const int kMaxStreamStartMilliseconds = 500;
31 static const int kMinimumFramesPerSecond = 10;
32
33 static const int kSecondsToMilliseconds = 1000;
34 static const int kMillisecondsToMicroseconds = 1000;
35 static const float kNanoToMilliseconds = 0.000001f;
36 static const float kNanoToSeconds = 0.000000001f;
37
38
39 #include "FrameHandler.h"
40
41 #include <stdio.h>
42 #include <string.h>
43
44 #include <hidl/HidlTransportSupport.h>
45 #include <hwbinder/ProcessState.h>
46 #include <log/log.h>
47 #include <utils/Errors.h>
48 #include <utils/StrongPointer.h>
49
50 #include <android/log.h>
51 #include <android/hardware/automotive/evs/1.0/IEvsCamera.h>
52 #include <android/hardware/automotive/evs/1.0/IEvsEnumerator.h>
53 #include <android/hardware/automotive/evs/1.0/IEvsCameraStream.h>
54 #include <android/hardware/automotive/evs/1.0/IEvsDisplay.h>
55
56 #include <VtsHalHidlTargetTestBase.h>
57
58
59 using namespace ::android::hardware::automotive::evs::V1_0;
60 using ::android::hardware::Return;
61 using ::android::hardware::Void;
62 using ::android::hardware::hidl_vec;
63 using ::android::hardware::hidl_handle;
64 using ::android::hardware::hidl_string;
65 using ::android::sp;
66
67
68 // The main test class for EVS
69 class EvsHidlTest : public ::testing::VtsHalHidlTargetTestBase {
70 public:
SetUp()71 virtual void SetUp() override {
72 // Make sure we can connect to the enumerator
73 pEnumerator = IEvsEnumerator::getService(kEnumeratorName);
74 ASSERT_NE(pEnumerator.get(), nullptr);
75 }
76
TearDown()77 virtual void TearDown() override {}
78
79 protected:
loadCameraList()80 void loadCameraList() {
81 // SetUp() must run first!
82 assert(pEnumerator != nullptr);
83
84 // Get the camera list
85 pEnumerator->getCameraList([this](hidl_vec <CameraDesc> cameraList) {
86 ALOGI("Camera list callback received %zu cameras",
87 cameraList.size());
88 cameraInfo.reserve(cameraList.size());
89 for (auto&& cam: cameraList) {
90 ALOGI("Found camera %s", cam.cameraId.c_str());
91 cameraInfo.push_back(cam);
92 }
93 }
94 );
95
96 // We insist on at least one camera for EVS to pass any camera tests
97 ASSERT_GE(cameraInfo.size(), 1u);
98 }
99
100 sp<IEvsEnumerator> pEnumerator; // Every test needs access to the service
101 std::vector <CameraDesc> cameraInfo; // Empty unless/until loadCameraList() is called
102 };
103
104
105 //
106 // Tests start here...
107 //
108
109 /*
110 * CameraOpenClean:
111 * Opens each camera reported by the enumerator and then explicitly closes it via a
112 * call to closeCamera. Then repeats the test to ensure all cameras can be reopened.
113 */
TEST_F(EvsHidlTest,CameraOpenClean)114 TEST_F(EvsHidlTest, CameraOpenClean) {
115 ALOGI("Starting CameraOpenClean test");
116
117 // Get the camera list
118 loadCameraList();
119
120 // Open and close each camera twice
121 for (auto&& cam: cameraInfo) {
122 for (int pass = 0; pass < 2; pass++) {
123 sp<IEvsCamera> pCam = pEnumerator->openCamera(cam.cameraId);
124 ASSERT_NE(pCam, nullptr);
125
126 // Verify that this camera self-identifies correctly
127 pCam->getCameraInfo([&cam](CameraDesc desc) {
128 ALOGD("Found camera %s", desc.cameraId.c_str());
129 EXPECT_EQ(cam.cameraId, desc.cameraId);
130 }
131 );
132
133 // Explicitly close the camera so resources are released right away
134 pEnumerator->closeCamera(pCam);
135 }
136 }
137 }
138
139
140 /*
141 * CameraOpenAggressive:
142 * Opens each camera reported by the enumerator twice in a row without an intervening closeCamera
143 * call. This ensures that the intended "aggressive open" behavior works. This is necessary for
144 * the system to be tolerant of shutdown/restart race conditions.
145 */
TEST_F(EvsHidlTest,CameraOpenAggressive)146 TEST_F(EvsHidlTest, CameraOpenAggressive) {
147 ALOGI("Starting CameraOpenAggressive test");
148
149 // Get the camera list
150 loadCameraList();
151
152 // Open and close each camera twice
153 for (auto&& cam: cameraInfo) {
154 sp<IEvsCamera> pCam = pEnumerator->openCamera(cam.cameraId);
155 ASSERT_NE(pCam, nullptr);
156
157 // Verify that this camera self-identifies correctly
158 pCam->getCameraInfo([&cam](CameraDesc desc) {
159 ALOGD("Found camera %s", desc.cameraId.c_str());
160 EXPECT_EQ(cam.cameraId, desc.cameraId);
161 }
162 );
163
164 sp<IEvsCamera> pCam2 = pEnumerator->openCamera(cam.cameraId);
165 ASSERT_NE(pCam, pCam2);
166 ASSERT_NE(pCam2, nullptr);
167
168 // Verify that the old camera rejects calls
169 Return<EvsResult> badResult = pCam->setMaxFramesInFlight(2);
170 EXPECT_EQ(EvsResult::OWNERSHIP_LOST, EvsResult(badResult));
171
172 // Close the superceded camera
173 pEnumerator->closeCamera(pCam);
174
175 // Verify that the second camera instance self-identifies correctly
176 pCam2->getCameraInfo([&cam](CameraDesc desc) {
177 ALOGD("Found camera %s", desc.cameraId.c_str());
178 EXPECT_EQ(cam.cameraId, desc.cameraId);
179 }
180 );
181
182 // Leave the second camera dangling so it gets cleaned up by the destructor path
183 }
184
185 // Sleep here to ensure the destructor cleanup has time to run so we don't break follow on tests
186 sleep(1); // I hate that this is an arbitrary time to wait. :( b/36122635
187 }
188
189
190 /*
191 * DisplayOpen:
192 * Test both clean shut down and "aggressive open" device stealing behavior.
193 */
TEST_F(EvsHidlTest,DisplayOpen)194 TEST_F(EvsHidlTest, DisplayOpen) {
195 ALOGI("Starting DisplayOpen test");
196
197 // Request exclusive access to the EVS display, then let it go
198 {
199 sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
200 ASSERT_NE(pDisplay, nullptr);
201
202 // Ask the display what it's name is
203 pDisplay->getDisplayInfo([](DisplayDesc desc) {
204 ALOGD("Found display %s", desc.displayId.c_str());
205 }
206 );
207
208 pEnumerator->closeDisplay(pDisplay);
209 }
210
211 // Ensure we can reopen the display after it has been closed
212 {
213 // Reopen the display
214 sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
215 ASSERT_NE(pDisplay, nullptr);
216
217 // Open the display while its already open -- ownership should be transferred
218 sp<IEvsDisplay> pDisplay2 = pEnumerator->openDisplay();
219 ASSERT_NE(pDisplay2, nullptr);
220
221 // Ensure the old display properly reports its assassination
222 Return<DisplayState> badResult = pDisplay->getDisplayState();
223 EXPECT_EQ(badResult, DisplayState::DEAD);
224
225 // Close only the newest display instance -- the other should already be a zombie
226 pEnumerator->closeDisplay(pDisplay2);
227 }
228
229 // Finally, validate that we can open the display after the provoked failure above
230 sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
231 ASSERT_NE(pDisplay, nullptr);
232
233 pEnumerator->closeDisplay(pDisplay);
234 }
235
236
237 /*
238 * DisplayStates:
239 * Validate that display states transition as expected and can be queried from either the display
240 * object itself or the owning enumerator.
241 */
TEST_F(EvsHidlTest,DisplayStates)242 TEST_F(EvsHidlTest, DisplayStates) {
243 ALOGI("Starting DisplayStates test");
244
245 // Ensure the display starts in the expected state
246 EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::NOT_OPEN);
247
248 // Scope to limit the lifetime of the pDisplay pointer, and thus the IEvsDisplay object
249 {
250 // Request exclusive access to the EVS display
251 sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
252 ASSERT_NE(pDisplay, nullptr);
253 EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::NOT_VISIBLE);
254
255 // Activate the display
256 pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME);
257 EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::VISIBLE_ON_NEXT_FRAME);
258 EXPECT_EQ((DisplayState)pDisplay->getDisplayState(), DisplayState::VISIBLE_ON_NEXT_FRAME);
259
260 // Get the output buffer we'd use to display the imagery
261 BufferDesc tgtBuffer = {};
262 pDisplay->getTargetBuffer([&tgtBuffer](const BufferDesc& buff) {
263 tgtBuffer = buff;
264 }
265 );
266 EXPECT_NE(tgtBuffer.memHandle, nullptr);
267
268 // Send the target buffer back for display (we didn't actually fill anything)
269 pDisplay->returnTargetBufferForDisplay(tgtBuffer);
270
271 // Sleep for a tenth of a second to ensure the driver has time to get the image displayed
272 usleep(100 * kMillisecondsToMicroseconds);
273 EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::VISIBLE);
274 EXPECT_EQ((DisplayState)pDisplay->getDisplayState(), DisplayState::VISIBLE);
275
276 // Turn off the display
277 pDisplay->setDisplayState(DisplayState::NOT_VISIBLE);
278 usleep(100 * kMillisecondsToMicroseconds);
279 EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::NOT_VISIBLE);
280
281 // Close the display
282 pEnumerator->closeDisplay(pDisplay);
283 }
284
285 // TODO: This hack shouldn't be necessary. b/36122635
286 sleep(1);
287
288 // Now that the display pointer has gone out of scope, causing the IEvsDisplay interface
289 // object to be destroyed, we should be back to the "not open" state.
290 // NOTE: If we want this to pass without the sleep above, we'd have to add the
291 // (now recommended) closeDisplay() call instead of relying on the smarter pointer
292 // going out of scope. I've not done that because I want to verify that the deletion
293 // of the object does actually clean up (eventually).
294 EXPECT_EQ((DisplayState)pEnumerator->getDisplayState(), DisplayState::NOT_OPEN);
295 }
296
297
298 /*
299 * CameraStreamPerformance:
300 * Measure and qualify the stream start up time and streaming frame rate of each reported camera
301 */
TEST_F(EvsHidlTest,CameraStreamPerformance)302 TEST_F(EvsHidlTest, CameraStreamPerformance) {
303 ALOGI("Starting CameraStreamPerformance test");
304
305 // Get the camera list
306 loadCameraList();
307
308 // Test each reported camera
309 for (auto&& cam: cameraInfo) {
310 sp <IEvsCamera> pCam = pEnumerator->openCamera(cam.cameraId);
311 ASSERT_NE(pCam, nullptr);
312
313 // Set up a frame receiver object which will fire up its own thread
314 sp<FrameHandler> frameHandler = new FrameHandler(pCam, cam,
315 nullptr,
316 FrameHandler::eAutoReturn);
317
318 // Start the camera's video stream
319 nsecs_t start = systemTime(SYSTEM_TIME_MONOTONIC);
320 bool startResult = frameHandler->startStream();
321 ASSERT_TRUE(startResult);
322
323 // Ensure the first frame arrived within the expected time
324 frameHandler->waitForFrameCount(1);
325 nsecs_t firstFrame = systemTime(SYSTEM_TIME_MONOTONIC);
326 nsecs_t timeToFirstFrame = systemTime(SYSTEM_TIME_MONOTONIC) - start;
327 EXPECT_LE(nanoseconds_to_milliseconds(timeToFirstFrame), kMaxStreamStartMilliseconds);
328 printf("Measured time to first frame %0.2f ms\n", timeToFirstFrame * kNanoToMilliseconds);
329 ALOGI("Measured time to first frame %0.2f ms", timeToFirstFrame * kNanoToMilliseconds);
330
331 // Wait a bit, then ensure we get at least the required minimum number of frames
332 sleep(5);
333 nsecs_t end = systemTime(SYSTEM_TIME_MONOTONIC);
334 unsigned framesReceived = 0;
335 frameHandler->getFramesCounters(&framesReceived, nullptr);
336 framesReceived = framesReceived - 1; // Back out the first frame we already waited for
337 nsecs_t runTime = end - firstFrame;
338 float framesPerSecond = framesReceived / (runTime * kNanoToSeconds);
339 printf("Measured camera rate %3.2f fps\n", framesPerSecond);
340 ALOGI("Measured camera rate %3.2f fps", framesPerSecond);
341 EXPECT_GE(framesPerSecond, kMinimumFramesPerSecond);
342
343 // Even when the camera pointer goes out of scope, the FrameHandler object will
344 // keep the stream alive unless we tell it to shutdown.
345 // Also note that the FrameHandle and the Camera have a mutual circular reference, so
346 // we have to break that cycle in order for either of them to get cleaned up.
347 frameHandler->shutdown();
348
349 // Explicitly release the camera
350 pEnumerator->closeCamera(pCam);
351 }
352 }
353
354
355 /*
356 * CameraStreamBuffering:
357 * Ensure the camera implementation behaves properly when the client holds onto buffers for more
358 * than one frame time. The camera must cleanly skip frames until the client is ready again.
359 */
TEST_F(EvsHidlTest,CameraStreamBuffering)360 TEST_F(EvsHidlTest, CameraStreamBuffering) {
361 ALOGI("Starting CameraStreamBuffering test");
362
363 // Arbitrary constant (should be > 1 and less than crazy)
364 static const unsigned int kBuffersToHold = 6;
365
366 // Get the camera list
367 loadCameraList();
368
369 // Test each reported camera
370 for (auto&& cam: cameraInfo) {
371
372 sp<IEvsCamera> pCam = pEnumerator->openCamera(cam.cameraId);
373 ASSERT_NE(pCam, nullptr);
374
375 // Ask for a crazy number of buffers in flight to ensure it errors correctly
376 Return<EvsResult> badResult = pCam->setMaxFramesInFlight(0xFFFFFFFF);
377 EXPECT_EQ(EvsResult::BUFFER_NOT_AVAILABLE, badResult);
378
379 // Now ask for exactly two buffers in flight as we'll test behavior in that case
380 Return<EvsResult> goodResult = pCam->setMaxFramesInFlight(kBuffersToHold);
381 EXPECT_EQ(EvsResult::OK, goodResult);
382
383
384 // Set up a frame receiver object which will fire up its own thread.
385 sp<FrameHandler> frameHandler = new FrameHandler(pCam, cam,
386 nullptr,
387 FrameHandler::eNoAutoReturn);
388
389 // Start the camera's video stream
390 bool startResult = frameHandler->startStream();
391 ASSERT_TRUE(startResult);
392
393 // Check that the video stream stalls once we've gotten exactly the number of buffers
394 // we requested since we told the frameHandler not to return them.
395 sleep(2); // 1 second should be enough for at least 5 frames to be delivered worst case
396 unsigned framesReceived = 0;
397 frameHandler->getFramesCounters(&framesReceived, nullptr);
398 ASSERT_EQ(kBuffersToHold, framesReceived) << "Stream didn't stall at expected buffer limit";
399
400
401 // Give back one buffer
402 bool didReturnBuffer = frameHandler->returnHeldBuffer();
403 EXPECT_TRUE(didReturnBuffer);
404
405 // Once we return a buffer, it shouldn't take more than 1/10 second to get a new one
406 // filled since we require 10fps minimum -- but give a 10% allowance just in case.
407 usleep(110 * kMillisecondsToMicroseconds);
408 frameHandler->getFramesCounters(&framesReceived, nullptr);
409 EXPECT_EQ(kBuffersToHold+1, framesReceived) << "Stream should've resumed";
410
411 // Even when the camera pointer goes out of scope, the FrameHandler object will
412 // keep the stream alive unless we tell it to shutdown.
413 // Also note that the FrameHandle and the Camera have a mutual circular reference, so
414 // we have to break that cycle in order for either of them to get cleaned up.
415 frameHandler->shutdown();
416
417 // Explicitly release the camera
418 pEnumerator->closeCamera(pCam);
419 }
420 }
421
422
423 /*
424 * CameraToDisplayRoundTrip:
425 * End to end test of data flowing from the camera to the display. Each delivered frame of camera
426 * imagery is simply copied to the display buffer and presented on screen. This is the one test
427 * which a human could observe to see the operation of the system on the physical display.
428 */
TEST_F(EvsHidlTest,CameraToDisplayRoundTrip)429 TEST_F(EvsHidlTest, CameraToDisplayRoundTrip) {
430 ALOGI("Starting CameraToDisplayRoundTrip test");
431
432 // Get the camera list
433 loadCameraList();
434
435 // Request exclusive access to the EVS display
436 sp<IEvsDisplay> pDisplay = pEnumerator->openDisplay();
437 ASSERT_NE(pDisplay, nullptr);
438
439 // Test each reported camera
440 for (auto&& cam: cameraInfo) {
441 sp <IEvsCamera> pCam = pEnumerator->openCamera(cam.cameraId);
442 ASSERT_NE(pCam, nullptr);
443
444 // Set up a frame receiver object which will fire up its own thread.
445 sp<FrameHandler> frameHandler = new FrameHandler(pCam, cam,
446 pDisplay,
447 FrameHandler::eAutoReturn);
448
449
450 // Activate the display
451 pDisplay->setDisplayState(DisplayState::VISIBLE_ON_NEXT_FRAME);
452
453 // Start the camera's video stream
454 bool startResult = frameHandler->startStream();
455 ASSERT_TRUE(startResult);
456
457 // Wait a while to let the data flow
458 static const int kSecondsToWait = 5;
459 const int streamTimeMs = kSecondsToWait * kSecondsToMilliseconds -
460 kMaxStreamStartMilliseconds;
461 const unsigned minimumFramesExpected = streamTimeMs * kMinimumFramesPerSecond /
462 kSecondsToMilliseconds;
463 sleep(kSecondsToWait);
464 unsigned framesReceived = 0;
465 unsigned framesDisplayed = 0;
466 frameHandler->getFramesCounters(&framesReceived, &framesDisplayed);
467 EXPECT_EQ(framesReceived, framesDisplayed);
468 EXPECT_GE(framesDisplayed, minimumFramesExpected);
469
470 // Turn off the display (yes, before the stream stops -- it should be handled)
471 pDisplay->setDisplayState(DisplayState::NOT_VISIBLE);
472
473 // Shut down the streamer
474 frameHandler->shutdown();
475
476 // Explicitly release the camera
477 pEnumerator->closeCamera(pCam);
478 }
479
480 // Explicitly release the display
481 pEnumerator->closeDisplay(pDisplay);
482 }
483