• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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