• 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 #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