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