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