// // Copyright (C) 2020 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #define LOG_TAG "VtsHalSurroundViewTest" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "SurroundViewStreamHandler.h" using namespace ::android::hardware::automotive::sv::V1_0; using ::android::sp; using ::android::hardware::hidl_vec; using ::android::hardware::hidl_string; using ::android::hidl::allocator::V1_0::IAllocator; using ::android::hidl::memory::V1_0::IMemory; using ::android::hardware::hidl_memory; const int kVertexByteSize = (3 * sizeof(float)) + 4; const int kIdByteSize = 2; // The main test class for Surround View Service class SurroundViewHidlTest : public ::testing::TestWithParam { public: virtual void SetUp() override { mSurroundViewService = ISurroundViewService::getService(GetParam()); ASSERT_NE(mSurroundViewService.get(), nullptr); } virtual void TearDown() override {} sp mSurroundViewService; // Every test needs access to the service }; TEST_P(SurroundViewHidlTest, startAndStop2dSession) { ALOGD("SurroundViewHidlTest::startAndStop2dSession"); sp surroundView2dSession; mSurroundViewService->start2dSession( [&surroundView2dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView2dSession = session; }); SvResult result = mSurroundViewService->stop2dSession(surroundView2dSession); ASSERT_EQ(result, SvResult::OK); } TEST_P(SurroundViewHidlTest, stopInvalid2dSession) { ALOGD("SurroundViewHidlTest::stopInvalid2dSession"); sp surroundView2dSession; SvResult result = mSurroundViewService->stop2dSession(surroundView2dSession); ASSERT_NE(result, SvResult::OK); } TEST_P(SurroundViewHidlTest, startAndStop2dStream) { ALOGD("SurroundViewHidlTest::startAndStop2dStream"); sp surroundView2dSession; mSurroundViewService->start2dSession( [&surroundView2dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView2dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView2dSession); SvResult result = surroundView2dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(5); EXPECT_TRUE(handler->checkEventReceived(SvEvent::STREAM_STARTED)); EXPECT_GT(handler->getReceiveFramesCount(), 0); surroundView2dSession->stopStream(); sleep(1); EXPECT_TRUE(handler->checkEventReceived(SvEvent::STREAM_STOPPED)); result = mSurroundViewService->stop2dSession(surroundView2dSession); EXPECT_EQ(result, SvResult::OK); } TEST_P(SurroundViewHidlTest, start2dStreamWithoutReturningFrames) { ALOGD("SurroundViewHidlTest::start2dStreamWithoutReturningFrames"); sp surroundView2dSession; mSurroundViewService->start2dSession( [&surroundView2dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView2dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView2dSession); handler->setDoNotReturnFrames(true); SvResult result = surroundView2dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(5); EXPECT_TRUE(handler->checkEventReceived(SvEvent::STREAM_STARTED)); EXPECT_TRUE(handler->checkEventReceived(SvEvent::FRAME_DROPPED)); EXPECT_GT(handler->getReceiveFramesCount(), 0); surroundView2dSession->stopStream(); sleep(1); EXPECT_TRUE(handler->checkEventReceived(SvEvent::STREAM_STOPPED)); result = mSurroundViewService->stop2dSession(surroundView2dSession); EXPECT_EQ(result, SvResult::OK); } TEST_P(SurroundViewHidlTest, duplicateStart2dStream) { ALOGD("SurroundViewHidlTest, duplicateStart2dStream"); sp surroundView2dSession; mSurroundViewService->start2dSession( [&surroundView2dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView2dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView2dSession); SvResult result = surroundView2dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); result = surroundView2dSession->startStream(handler); EXPECT_NE(result, SvResult::OK); surroundView2dSession->stopStream(); mSurroundViewService->stop2dSession(surroundView2dSession); } TEST_P(SurroundViewHidlTest, stopInvalid2dStream) { ALOGD("SurroundViewHidlTest, stopInvalid2dStream"); sp surroundView2dSession; mSurroundViewService->start2dSession( [&surroundView2dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView2dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView2dSession); surroundView2dSession->stopStream(); mSurroundViewService->stop2dSession(surroundView2dSession); } TEST_P(SurroundViewHidlTest, validate2dSvFramesDesc) { ALOGD("SurroundViewHidlTest, validate2dSvFramesDesc"); sp surroundView2dSession; mSurroundViewService->start2dSession( [&surroundView2dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView2dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView2dSession); SvResult result = surroundView2dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(5); // Validate timestampNs and sequenceId EXPECT_GT(handler->getReceiveFramesCount(), 0); EXPECT_TRUE(handler->areAllFramesValid()); // Validate 2d SvFramesDesc. Do not compare nativeHandle since it is not // stored and already verified on the fly. SvFramesDesc frames = handler->getLastReceivedFrames(); EXPECT_EQ(frames.svBuffers.size(), 1); SvBuffer svBuffer2d = frames.svBuffers[0]; EXPECT_EQ(svBuffer2d.viewId, 0); const AHardwareBuffer_Desc* pDesc = reinterpret_cast(&svBuffer2d.hardwareBuffer.description); float mapWidth, mapHeight; surroundView2dSession->get2dMappingInfo([&mapWidth, &mapHeight] (Sv2dMappingInfo info) { mapWidth = info.width; mapHeight = info.height; }); EXPECT_EQ(pDesc->height, floor(pDesc->width * (mapHeight / mapWidth))); // Clean up surroundView2dSession->stopStream(); result = mSurroundViewService->stop2dSession(surroundView2dSession); } TEST_P(SurroundViewHidlTest, get2dMappingInfo) { ALOGD("SurroundViewHidlTest, get2dMappingInfo"); sp surroundView2dSession; mSurroundViewService->start2dSession( [&surroundView2dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView2dSession = session; }); surroundView2dSession->get2dMappingInfo([] (Sv2dMappingInfo info) { EXPECT_GT(info.width, 0); EXPECT_GT(info.height, 0); }); mSurroundViewService->stop2dSession(surroundView2dSession); } TEST_P(SurroundViewHidlTest, set2dConfigResolution) { ALOGD("SurroundViewHidlTest, set2dConfigResolution"); sp surroundView2dSession; mSurroundViewService->start2dSession( [&surroundView2dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView2dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView2dSession); SvResult result = surroundView2dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(1); // Change config Sv2dConfig config; config.width = 1920; config.blending = SvQuality::HIGH; surroundView2dSession->set2dConfig(config); sleep(1); EXPECT_TRUE(handler->checkEventReceived(SvEvent::CONFIG_UPDATED)); // Check width has been changed but not the ratio SvFramesDesc frames = handler->getLastReceivedFrames(); EXPECT_EQ(frames.svBuffers.size(), 1); SvBuffer svBuffer2d = frames.svBuffers[0]; EXPECT_EQ(svBuffer2d.viewId, 0); const AHardwareBuffer_Desc* pDesc = reinterpret_cast(&svBuffer2d.hardwareBuffer.description); EXPECT_EQ(pDesc->width, config.width); float mapWidth, mapHeight; surroundView2dSession->get2dMappingInfo([&mapWidth, &mapHeight] (Sv2dMappingInfo info) { mapWidth = info.width; mapHeight = info.height; }); EXPECT_EQ(pDesc->height, floor (pDesc->width * (mapHeight / mapWidth))); // Clean up surroundView2dSession->stopStream(); mSurroundViewService->stop2dSession(surroundView2dSession); } TEST_P(SurroundViewHidlTest, set2dConfigBlending) { ALOGD("SurroundViewHidlTest, set2dConfigBlending"); sp surroundView2dSession; mSurroundViewService->start2dSession( [&surroundView2dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView2dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView2dSession); SvResult result = surroundView2dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(1); // Get the width before config changed int oldWidth; SvFramesDesc frames = handler->getLastReceivedFrames(); EXPECT_EQ(frames.svBuffers.size(), 1); SvBuffer svBuffer2d = frames.svBuffers[0]; const AHardwareBuffer_Desc* pDesc = reinterpret_cast(&svBuffer2d.hardwareBuffer.description); oldWidth = pDesc->width; // Change config Sv2dConfig config; config.width = oldWidth; config.blending = SvQuality::LOW; surroundView2dSession->set2dConfig(config); sleep(1); EXPECT_TRUE(handler->checkEventReceived(SvEvent::CONFIG_UPDATED)); Sv2dConfig retConfig; surroundView2dSession->get2dConfig([&retConfig] (Sv2dConfig config) { retConfig.width = config.width; retConfig.blending = config.blending; }); // Check config blending has been changed but not the width EXPECT_EQ(retConfig.blending, config.blending); EXPECT_EQ(retConfig.width, oldWidth); // Clean up surroundView2dSession->stopStream(); mSurroundViewService->stop2dSession(surroundView2dSession); } TEST_P(SurroundViewHidlTest, projectCameraPointsWithValidCameraId) { ALOGD("SurroundViewHidlTest, projectCameraPointsWithValidCameraId"); sp surroundView2dSession; mSurroundViewService->start2dSession( [&surroundView2dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView2dSession = session; }); hidl_vec cameraIds; mSurroundViewService->getCameraIds([&cameraIds]( const hidl_vec& camIds) { cameraIds = camIds; }); sp handler = new SurroundViewServiceHandler(surroundView2dSession); SvResult result = surroundView2dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(1); // Get the width and height of the frame int width, height; SvFramesDesc frames = handler->getLastReceivedFrames(); EXPECT_EQ(frames.svBuffers.size(), 1); SvBuffer svBuffer2d = frames.svBuffers[0]; const AHardwareBuffer_Desc* pDesc = reinterpret_cast(&svBuffer2d.hardwareBuffer.description); width = pDesc->width; height = pDesc->height; float mapWidth, mapHeight, mapCenter[2]; surroundView2dSession->get2dMappingInfo( [&mapWidth, &mapHeight, &mapCenter] (Sv2dMappingInfo info) { mapWidth = info.width; mapHeight = info.height; mapCenter[0] = info.center.x; mapCenter[1] = info.center.y; }); // Set one valid point and one invalid point hidl_vec points2dCamera; points2dCamera.resize(2); points2dCamera[0].x = 0; points2dCamera[0].y = 0; points2dCamera[1].x = width * 2; points2dCamera[1].y = height * 2; surroundView2dSession->projectCameraPoints( points2dCamera, cameraIds[0], [&mapWidth, &mapHeight, &mapCenter] ( const hidl_vec& outPoints) { // Make sure point[0] is valid. EXPECT_TRUE(outPoints[0].isValid); EXPECT_GE(outPoints[0].x, mapCenter[0] - mapWidth); EXPECT_LE(outPoints[0].x, mapCenter[0] + mapWidth); EXPECT_GE(outPoints[0].y, mapCenter[1] - mapHeight); EXPECT_LE(outPoints[0].y, mapCenter[1] + mapHeight); // Make sure point[1] is invalid. EXPECT_FALSE(outPoints[1].isValid); }); // Clean up surroundView2dSession->stopStream(); mSurroundViewService->stop2dSession(surroundView2dSession); } TEST_P(SurroundViewHidlTest, projectCameraPointsWithInvalidCameraId) { ALOGD("SurroundViewHidlTest, projectCameraPointsWithInvalidCameraId"); sp surroundView2dSession; mSurroundViewService->start2dSession( [&surroundView2dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView2dSession = session; }); hidl_vec cameraIds; mSurroundViewService->getCameraIds([&cameraIds]( const hidl_vec& camIds) { cameraIds = camIds; }); hidl_string invalidCameraId = "INVALID_CAMERA_ID"; // In case one of the camera id happens to be identical to // the invalid camera id. for (auto cameraId : cameraIds) { ASSERT_NE(cameraId, invalidCameraId); } // Set one valid point hidl_vec points2dCamera; points2dCamera.resize(1); points2dCamera[0].x = 0; points2dCamera[0].y = 0; surroundView2dSession->projectCameraPoints( points2dCamera, invalidCameraId, [] (const hidl_vec& outPoints) { // No points are return due to invalid camera id EXPECT_EQ(outPoints.size(), 0); }); // Clean up surroundView2dSession->stopStream(); mSurroundViewService->stop2dSession(surroundView2dSession); } TEST_P(SurroundViewHidlTest, startAndStop3dSession) { ALOGD("SurroundViewHidlTest, startAndStop3dSession"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); SvResult result = mSurroundViewService->stop3dSession(surroundView3dSession); EXPECT_EQ(result, SvResult::OK); } TEST_P(SurroundViewHidlTest, stopInvalid3dSession) { ALOGD("SurroundViewHidlTest, stopInvalid3dSession"); sp surroundView3dSession; SvResult result = mSurroundViewService->stop3dSession(surroundView3dSession); EXPECT_NE(result, SvResult::OK); } TEST_P(SurroundViewHidlTest, startAndStop3dStream) { ALOGD("SurroundViewHidlTest::startAndStop3dStream"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); std::vector views(1); SvResult setViewResult = surroundView3dSession->setViews(views); EXPECT_EQ(setViewResult, SvResult::OK); sp handler = new SurroundViewServiceHandler(surroundView3dSession); SvResult result = surroundView3dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(5); EXPECT_TRUE(handler->checkEventReceived(SvEvent::STREAM_STARTED)); EXPECT_GT(handler->getReceiveFramesCount(), 0); surroundView3dSession->stopStream(); sleep(1); EXPECT_TRUE(handler->checkEventReceived(SvEvent::STREAM_STOPPED)); result = mSurroundViewService->stop3dSession(surroundView3dSession); EXPECT_EQ(result, SvResult::OK); } TEST_P(SurroundViewHidlTest, start3dStreamWithoutReturningFrames) { ALOGD("SurroundViewHidlTest::start3dStreamWithoutReturningFrames"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); std::vector views(1); SvResult setViewResult = surroundView3dSession->setViews(views); EXPECT_EQ(setViewResult, SvResult::OK); sp handler = new SurroundViewServiceHandler(surroundView3dSession); handler->setDoNotReturnFrames(true); SvResult result = surroundView3dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(5); EXPECT_TRUE(handler->checkEventReceived(SvEvent::STREAM_STARTED)); EXPECT_TRUE(handler->checkEventReceived(SvEvent::FRAME_DROPPED)); EXPECT_GT(handler->getReceiveFramesCount(), 0); surroundView3dSession->stopStream(); sleep(1); EXPECT_TRUE(handler->checkEventReceived(SvEvent::STREAM_STOPPED)); result = mSurroundViewService->stop3dSession(surroundView3dSession); EXPECT_EQ(result, SvResult::OK); } TEST_P(SurroundViewHidlTest, duplicateStart3dStream) { ALOGD("SurroundViewHidlTest, duplicateStart3dStream"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); std::vector views(1); SvResult setViewResult = surroundView3dSession->setViews(views); EXPECT_EQ(setViewResult, SvResult::OK); sp handler = new SurroundViewServiceHandler(surroundView3dSession); SvResult result = surroundView3dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); result = surroundView3dSession->startStream(handler); EXPECT_NE(result, SvResult::OK); surroundView3dSession->stopStream(); mSurroundViewService->stop3dSession(surroundView3dSession); } TEST_P(SurroundViewHidlTest, start3dStreamNoViewSetFail) { ALOGD("SurroundViewHidlTest, start3dStreamNoViewSetFail"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView3dSession); SvResult result = surroundView3dSession->startStream(handler); EXPECT_EQ(result, SvResult::VIEW_NOT_SET); mSurroundViewService->stop3dSession(surroundView3dSession); } TEST_P(SurroundViewHidlTest, validate3dSvFramesDesc) { ALOGD("SurroundViewHidlTest, validate3dSvFramesDesc"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView3dSession); std::vector views(1); views[0].viewId = 0; SvResult setViewResult = surroundView3dSession->setViews(views); EXPECT_EQ(setViewResult, SvResult::OK); SvResult result = surroundView3dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(5); EXPECT_GT(handler->getReceiveFramesCount(), 0); EXPECT_TRUE(handler->areAllFramesValid()); // Validate 3d SvFramesDesc when only one view is set. SvFramesDesc frames = handler->getLastReceivedFrames(); EXPECT_EQ(frames.svBuffers.size(), 1); EXPECT_EQ(frames.svBuffers[0].viewId, 0); views.resize(3); views[0].viewId = 0; views[1].viewId = 1; views[2].viewId = 2; setViewResult = surroundView3dSession->setViews(views); EXPECT_EQ(setViewResult, SvResult::OK); sleep(1); // Validate 3d SvFramesDesc when multiple views are set. EXPECT_TRUE(handler->areAllFramesValid()); frames = handler->getLastReceivedFrames(); EXPECT_EQ(frames.svBuffers.size(), 3); EXPECT_EQ(frames.svBuffers[0].viewId, 0); EXPECT_EQ(frames.svBuffers[1].viewId, 1); EXPECT_EQ(frames.svBuffers[2].viewId, 2); EXPECT_EQ(frames.svBuffers[0].hardwareBuffer.description[0], frames.svBuffers[1].hardwareBuffer.description[0]); EXPECT_EQ(frames.svBuffers[0].hardwareBuffer.description[1], frames.svBuffers[1].hardwareBuffer.description[1]); EXPECT_EQ(frames.svBuffers[1].hardwareBuffer.description[0], frames.svBuffers[2].hardwareBuffer.description[0]); EXPECT_EQ(frames.svBuffers[1].hardwareBuffer.description[1], frames.svBuffers[2].hardwareBuffer.description[1]); // Clean up surroundView3dSession->stopStream(); result = mSurroundViewService->stop3dSession(surroundView3dSession); } TEST_P(SurroundViewHidlTest, set3dConfigResolution) { ALOGD("SurroundViewHidlTest, set3dConfigResolution"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView3dSession); std::vector views(1); views[0].viewId = 0; SvResult setViewResult = surroundView3dSession->setViews(views); EXPECT_EQ(setViewResult, SvResult::OK); SvResult result = surroundView3dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(1); // Change config Sv3dConfig config; config.width = 1920; config.height = 1080; config.carDetails = SvQuality::HIGH; surroundView3dSession->set3dConfig(config); sleep(1); EXPECT_TRUE(handler->checkEventReceived(SvEvent::CONFIG_UPDATED)); // Check width has been changed but not the ratio SvFramesDesc frames = handler->getLastReceivedFrames(); EXPECT_EQ(frames.svBuffers.size(), 1); SvBuffer svBuffer3d = frames.svBuffers[0]; EXPECT_EQ(svBuffer3d.viewId, 0); const AHardwareBuffer_Desc* pDesc = reinterpret_cast(&svBuffer3d.hardwareBuffer.description); EXPECT_EQ(pDesc->width, config.width); EXPECT_EQ(pDesc->height, config.height); // Clean up surroundView3dSession->stopStream(); mSurroundViewService->stop3dSession(surroundView3dSession); } TEST_P(SurroundViewHidlTest, set3dConfigCarDetails) { ALOGD("SurroundViewHidlTest, set3dConfigCarDetails"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView3dSession); std::vector views(1); views[0].viewId = 0; SvResult setViewResult = surroundView3dSession->setViews(views); EXPECT_EQ(setViewResult, SvResult::OK); SvResult result = surroundView3dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(1); // Get the width before config changed int oldWidth, oldHeight; SvFramesDesc frames = handler->getLastReceivedFrames(); EXPECT_EQ(frames.svBuffers.size(), 1); SvBuffer svBuffer3d = frames.svBuffers[0]; const AHardwareBuffer_Desc* pDesc = reinterpret_cast(&svBuffer3d.hardwareBuffer.description); oldWidth = pDesc->width; oldHeight = pDesc->height; // Change config Sv3dConfig config; config.width = oldWidth; config.height = oldHeight; config.carDetails = SvQuality::LOW; surroundView3dSession->set3dConfig(config); sleep(1); EXPECT_TRUE(handler->checkEventReceived(SvEvent::CONFIG_UPDATED)); Sv3dConfig retConfig; surroundView3dSession->get3dConfig([&retConfig] (Sv3dConfig config) { retConfig.width = config.width; retConfig.height = config.height; retConfig.carDetails = config.carDetails; }); // Check config blending has been changed but not the width EXPECT_EQ(retConfig.carDetails, config.carDetails); EXPECT_EQ(retConfig.width, oldWidth); EXPECT_EQ(retConfig.height, oldHeight); // Clean up surroundView3dSession->stopStream(); mSurroundViewService->stop3dSession(surroundView3dSession); } std::pair> GetMappedSharedMemory(int bytesSize) { const auto nullResult = std::make_pair(hidl_memory(), nullptr); sp ashmemAllocator = IAllocator::getService("ashmem"); if (ashmemAllocator.get() == nullptr) { ALOGE("SurroundViewHidlTest getService ashmem failed"); return nullResult; } // Allocate shared memory. hidl_memory hidlMemory; bool allocateSuccess = false; Return result = ashmemAllocator->allocate(bytesSize, [&](bool success, const hidl_memory& hidlMem) { if (!success) { return; } allocateSuccess = success; hidlMemory = hidlMem; }); // Check result of allocated memory. if (!result.isOk() || !allocateSuccess) { ALOGE("SurroundViewHidlTest allocate shared memory failed"); return nullResult; } // Map shared memory. sp pIMemory = mapMemory(hidlMemory); if (pIMemory.get() == nullptr) { ALOGE("SurroundViewHidlTest map shared memory failed"); return nullResult; } return std::make_pair(hidlMemory, pIMemory); } void SetIndexOfOverlaysMemory( const std::vector& overlaysMemDesc, sp pIMemory, int indexPosition, uint16_t indexValue) { // Count the number of vertices until the index. int totalVerticesCount = 0; for (int i = 0; i < indexPosition; i++) { totalVerticesCount += overlaysMemDesc[i].verticesCount; } const int indexBytePosition = (indexPosition * kIdByteSize) + (kVertexByteSize * totalVerticesCount); uint8_t* pSharedMemoryData = (uint8_t*)((void*)pIMemory->getPointer()); pSharedMemoryData += indexBytePosition; uint16_t* pIndex16bit = (uint16_t*)pSharedMemoryData; ALOGD("Setting index at pos %d", indexBytePosition); // Modify shared memory. pIMemory->update(); *pIndex16bit = indexValue; pIMemory->commit(); } std::pair> GetSampleOverlaysData() { OverlaysData overlaysData; overlaysData.overlaysMemoryDesc.resize(2); int sharedMemBytesSize = 0; OverlayMemoryDesc overlayMemDesc1, overlayMemDesc2; overlayMemDesc1.id = 0; overlayMemDesc1.verticesCount = 6; overlayMemDesc1.overlayPrimitive = OverlayPrimitive::TRIANGLES; overlaysData.overlaysMemoryDesc[0] = overlayMemDesc1; sharedMemBytesSize += kIdByteSize + kVertexByteSize * overlayMemDesc1.verticesCount; overlayMemDesc2.id = 1; overlayMemDesc2.verticesCount = 4; overlayMemDesc2.overlayPrimitive = OverlayPrimitive::TRIANGLES_STRIP; overlaysData.overlaysMemoryDesc[1] = overlayMemDesc2; sharedMemBytesSize += kIdByteSize + kVertexByteSize * overlayMemDesc2.verticesCount; std::pair> sharedMem = GetMappedSharedMemory(sharedMemBytesSize); sp pIMemory = sharedMem.second; if (pIMemory.get() == nullptr) { return std::make_pair(OverlaysData(), nullptr); } // Get pointer to shared memory data and set all bytes to 0. uint8_t* pSharedMemoryData = (uint8_t*)((void*)pIMemory->getPointer()); pIMemory->update(); memset(pSharedMemoryData, 0, sharedMemBytesSize); pIMemory->commit(); std::vector overlaysDesc = {overlayMemDesc1, overlayMemDesc2}; // Set indexes in shared memory. SetIndexOfOverlaysMemory(overlaysDesc, pIMemory, 0, overlayMemDesc1.id); SetIndexOfOverlaysMemory(overlaysDesc, pIMemory, 1, overlayMemDesc2.id); overlaysData.overlaysMemoryDesc = overlaysDesc; overlaysData.overlaysMemory = sharedMem.first; return std::make_pair(overlaysData, pIMemory); } TEST_P(SurroundViewHidlTest, updateOverlaysSuccess) { ALOGD("SurroundViewHidlTest, updateOverlaysSuccess"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); std::pair> overlaysData = GetSampleOverlaysData(); ASSERT_NE(overlaysData.second, nullptr); SvResult result = surroundView3dSession->updateOverlays(overlaysData.first); EXPECT_EQ(result, SvResult::OK); mSurroundViewService->stop3dSession(surroundView3dSession); } TEST_P(SurroundViewHidlTest, overlaysDataMismatchIdFail) { ALOGD("SurroundViewHidlTest, overlaysDataMismatchIdFail"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); std::pair> overlaysDataMismatchId = GetSampleOverlaysData(); ASSERT_NE(overlaysDataMismatchId.second, nullptr); // Set id of second overlay in shared memory to 2 (expected is 1). auto& overlaysDesc = overlaysDataMismatchId.first.overlaysMemoryDesc; auto& pIMemory = overlaysDataMismatchId.second; SetIndexOfOverlaysMemory(overlaysDesc, pIMemory, 1, 2); SvResult result = surroundView3dSession->updateOverlays( overlaysDataMismatchId.first); EXPECT_EQ(result, SvResult::INVALID_ARG); mSurroundViewService->stop3dSession(surroundView3dSession); } TEST_P(SurroundViewHidlTest, overlaysDataNullMemoryFail) { ALOGD("SurroundViewHidlTest, overlaysDataNullMemoryFail"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); std::pair> overlaysDataNullMemory = GetSampleOverlaysData(); // Set shared memory to null. overlaysDataNullMemory.first.overlaysMemory = hidl_memory(); SvResult result = surroundView3dSession->updateOverlays( overlaysDataNullMemory.first); EXPECT_EQ(result, SvResult::INVALID_ARG); mSurroundViewService->stop3dSession(surroundView3dSession); } TEST_P(SurroundViewHidlTest, overlaysDataLessThan3VerticesFail) { ALOGD("SurroundViewHidlTest, overlaysDataLessThan3VerticesFail"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); std::pair> overlaysData2Vertices = GetSampleOverlaysData(); // Set vertices count of second overlay to 2. overlaysData2Vertices.first.overlaysMemoryDesc[1].verticesCount = 2; SvResult result = surroundView3dSession->updateOverlays( overlaysData2Vertices.first); EXPECT_EQ(result, SvResult::INVALID_ARG); mSurroundViewService->stop3dSession(surroundView3dSession); } TEST_P(SurroundViewHidlTest, overlaysDataVerticesCountFail) { ALOGD("SurroundViewHidlTest, overlaysDataVerticesNotMultipleOf3Fail"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); OverlaysData overlaysData; overlaysData.overlaysMemoryDesc.resize(1); OverlayMemoryDesc overlayMemDesc1; overlayMemDesc1.id = 0; overlayMemDesc1.verticesCount = 4; // Invalid count for TRIANGLES primitive. overlayMemDesc1.overlayPrimitive = OverlayPrimitive::TRIANGLES; overlaysData.overlaysMemoryDesc[0] = overlayMemDesc1; const int sharedMemBytesSize = 2 + sizeof(float) * overlayMemDesc1.verticesCount; auto sharedMem = GetMappedSharedMemory(sharedMemBytesSize); // Set index in shared memory. auto& overlaysDesc = overlaysData.overlaysMemoryDesc; auto& pIMemory = sharedMem.second; SetIndexOfOverlaysMemory(overlaysDesc, pIMemory, 0, overlayMemDesc1.id); SvResult result = surroundView3dSession->updateOverlays(overlaysData); EXPECT_EQ(result, SvResult::INVALID_ARG); mSurroundViewService->stop3dSession(surroundView3dSession); } TEST_P(SurroundViewHidlTest, overlaysDataSameIdFail) { ALOGD("SurroundViewHidlTest, overlaysDataSameIdFail"); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); std::pair> overlaysDataSameId = GetSampleOverlaysData(); ASSERT_NE(overlaysDataSameId.second, nullptr); // Set id of second overlay as id of first. auto& overlaysDesc = overlaysDataSameId.first.overlaysMemoryDesc; auto& pIMemory = overlaysDataSameId.second; SetIndexOfOverlaysMemory(overlaysDesc, pIMemory, 1, overlaysDesc[0].id); SvResult result = surroundView3dSession->updateOverlays( overlaysDataSameId.first); EXPECT_EQ(result, SvResult::INVALID_ARG); mSurroundViewService->stop3dSession(surroundView3dSession); } TEST_P(SurroundViewHidlTest, projectPointsIncorrectCameraIdFail) { ALOGD("SurroundViewHidlTest, projectPointsIncorrectCameraIdFail"); hidl_vec cameraIds; mSurroundViewService->getCameraIds([&cameraIds]( const hidl_vec& camIds) { cameraIds = camIds; }); EXPECT_GT(cameraIds.size(), 0); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); Point2dInt cameraPoint; cameraPoint.x = 0; cameraPoint.y = 0; std::vector cameraPoints = {cameraPoint}; hidl_string invalidCameraId = "INVALID_CAMERA_ID"; std::vector points3d; surroundView3dSession->projectCameraPointsTo3dSurface( cameraPoints, invalidCameraId, [&points3d](const hidl_vec& points3dproj) { points3d = points3dproj; }); EXPECT_TRUE(points3d.empty()); mSurroundViewService->stop3dSession(surroundView3dSession); } TEST_P(SurroundViewHidlTest, projectPointsInvalidPointsFail) { ALOGD("SurroundViewHidlTest, projectPointsInvalidPointsFail"); hidl_vec cameraIds; mSurroundViewService->getCameraIds([&cameraIds]( const hidl_vec& camIds) { cameraIds = camIds; }); EXPECT_GT(cameraIds.size(), 0); sp surroundView3dSession; mSurroundViewService->start3dSession( [&surroundView3dSession]( const sp& session, SvResult result) { ASSERT_EQ(result, SvResult::OK); surroundView3dSession = session; }); sp handler = new SurroundViewServiceHandler(surroundView3dSession); std::vector views(1); views[0].viewId = 0; SvResult setViewResult = surroundView3dSession->setViews(views); EXPECT_EQ(setViewResult, SvResult::OK); SvResult result = surroundView3dSession->startStream(handler); EXPECT_EQ(result, SvResult::OK); sleep(1); // Get the width and height of the frame int width, height; SvFramesDesc frames = handler->getLastReceivedFrames(); EXPECT_EQ(frames.svBuffers.size(), 1); SvBuffer svBuffer2d = frames.svBuffers[0]; const AHardwareBuffer_Desc* pDesc = reinterpret_cast(&svBuffer2d.hardwareBuffer.description); width = pDesc->width; height = pDesc->height; Point2dInt cameraPoint; cameraPoint.x = width * 2; cameraPoint.y = height * 2; std::vector cameraPoints = {cameraPoint}; std::vector points3d; surroundView3dSession->projectCameraPointsTo3dSurface( cameraPoints, cameraIds[0], [&points3d](const hidl_vec& points3dproj) { points3d = points3dproj; }); EXPECT_FALSE(points3d[0].isValid); surroundView3dSession->stopStream(); mSurroundViewService->stop3dSession(surroundView3dSession); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SurroundViewHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, SurroundViewHidlTest, testing::ValuesIn( android::hardware::getAllHalInstanceNames(ISurroundViewService::descriptor) ), android::hardware::PrintInstanceNameToString );