[SV HIDL] VTS Test for Surround View
Bug: 148618804
Test: atest -c VtsHalSurroundViewV1_0TargetTest
Change-Id: I1c6bfa77adb699ab80337497aac4582861315bcd
diff --git a/automotive/sv/1.0/vts/functional/Android.bp b/automotive/sv/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..0e5d3df
--- /dev/null
+++ b/automotive/sv/1.0/vts/functional/Android.bp
@@ -0,0 +1,41 @@
+//
+// 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.
+//
+
+cc_test {
+ name: "VtsHalSurroundViewV1_0TargetTest",
+ srcs: [
+ "VtsHalSurroundViewV1_0TargetTest.cpp",
+ "SurroundViewStreamHandler.cpp",
+ ],
+ defaults: ["VtsHalTargetTestDefaults"],
+ static_libs: [
+ "libnativewindow",
+ "android.hardware.automotive.sv@1.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
+ ],
+ shared_libs: [
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "libhidlmemory",
+ ],
+ test_suites: ["general-tests", "vts-core"],
+ cflags: [
+ "-O0",
+ "-g",
+ ],
+}
diff --git a/automotive/sv/1.0/vts/functional/SurroundViewStreamHandler.cpp b/automotive/sv/1.0/vts/functional/SurroundViewStreamHandler.cpp
new file mode 100644
index 0000000..cb45caa
--- /dev/null
+++ b/automotive/sv/1.0/vts/functional/SurroundViewStreamHandler.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+#include "SurroundViewStreamHandler.h"
+
+#include <utils/Log.h>
+
+using std::lock_guard;
+
+SurroundViewServiceHandler::SurroundViewServiceHandler(sp<ISurroundViewSession> pSession) :
+ mSession(pSession),
+ mReceiveFramesCount(0),
+ mDoNotReturnFrames(false) {
+ // Nothing but member initialization
+}
+
+Return<void> SurroundViewServiceHandler::notify(SvEvent svEvent) {
+ ALOGD("SurroundViewServiceHandler::notify %d", svEvent);
+
+ lock_guard<mutex> lock(mLock);
+ switch (svEvent) {
+ case SvEvent::STREAM_STARTED:
+ case SvEvent::CONFIG_UPDATED:
+ case SvEvent::STREAM_STOPPED:
+ case SvEvent::FRAME_DROPPED:
+ case SvEvent::TIMEOUT:
+ mReceivedEvents.emplace_back(svEvent);
+ break;
+ default:
+ ALOGI("[SurroundViewLog] Received other event");
+ }
+
+ return android::hardware::Void();
+}
+
+Return<void> SurroundViewServiceHandler::receiveFrames(const SvFramesDesc& svFramesDesc) {
+ ALOGD("SurroundViewServiceHandler::receiveFrames");
+
+ lock_guard<mutex> lock(mLock);
+ unsigned long timestampNs = svFramesDesc.timestampNs;
+ unsigned sequenceId = svFramesDesc.sequenceId;
+ ALOGD("receiveFrames count: %d", mReceiveFramesCount);
+ ALOGD("timestampNs: %lu, sequenceId: %u", timestampNs, sequenceId);
+ if (mReceiveFramesCount != 0
+ && (mLastReceivedFrames.timestampNs >= svFramesDesc.timestampNs
+ || mLastReceivedFrames.sequenceId >= svFramesDesc.sequenceId)) {
+ mAllFramesValid = false;
+ ALOGD("The incoming frames are with invalid timestamp or sequenceId!");
+ }
+
+ for (int i=0; i<svFramesDesc.svBuffers.size(); i++) {
+ if (svFramesDesc.svBuffers[i].hardwareBuffer.nativeHandle == nullptr) {
+ mAllFramesValid = false;
+ ALOGD("The incoming frames are with invalid nativeHandle!");
+ break;
+ }
+ }
+
+ mReceiveFramesCount++;
+
+ // Store all the information except for the handle
+ mLastReceivedFrames.timestampNs = svFramesDesc.timestampNs;
+ mLastReceivedFrames.sequenceId = svFramesDesc.sequenceId;
+ mLastReceivedFrames.svBuffers.resize(svFramesDesc.svBuffers.size());
+ for (int i=0; i<svFramesDesc.svBuffers.size(); i++) {
+ mLastReceivedFrames.svBuffers[i].viewId = svFramesDesc.svBuffers[i].viewId;
+ mLastReceivedFrames.svBuffers[i].hardwareBuffer.description =
+ svFramesDesc.svBuffers[i].hardwareBuffer.description;
+ }
+
+ if (!mDoNotReturnFrames) {
+ mSession->doneWithFrames(svFramesDesc);
+ }
+
+ return android::hardware::Void();
+}
+
+bool SurroundViewServiceHandler::checkEventReceived(SvEvent svEvent) {
+ ALOGD("SurroundViewServiceHandler::checkEventReceived");
+ int size = mReceivedEvents.size(); // work around
+ ALOGD("Received event number: %d", size);
+ auto iter = find(mReceivedEvents.begin(), mReceivedEvents.end(), svEvent);
+ return iter != mReceivedEvents.end();
+}
+
+SvFramesDesc SurroundViewServiceHandler::getLastReceivedFrames() {
+ return mLastReceivedFrames;
+}
+
+int SurroundViewServiceHandler::getReceiveFramesCount() {
+ return mReceiveFramesCount;
+}
+
+bool SurroundViewServiceHandler::areAllFramesValid() {
+ return mAllFramesValid;
+}
+
+void SurroundViewServiceHandler::setDoNotReturnFrames(bool flag) {
+ mDoNotReturnFrames = flag;
+}
diff --git a/automotive/sv/1.0/vts/functional/SurroundViewStreamHandler.h b/automotive/sv/1.0/vts/functional/SurroundViewStreamHandler.h
new file mode 100644
index 0000000..7d3f61d
--- /dev/null
+++ b/automotive/sv/1.0/vts/functional/SurroundViewStreamHandler.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef SURROUND_VIEW_STREAM_HANDLER_H
+#define SURROUND_VIEW_STREAM_HANDLER_H
+
+#include <android/hardware/automotive/sv/1.0/types.h>
+#include <android/hardware/automotive/sv/1.0/ISurroundViewStream.h>
+#include <android/hardware/automotive/sv/1.0/ISurroundViewSession.h>
+
+#include <thread>
+#include <vector>
+
+using std::vector;
+using std::mutex;
+using android::hardware::Return;
+using android::sp;
+using namespace ::android::hardware::automotive::sv::V1_0;
+
+class SurroundViewServiceHandler : public ISurroundViewStream {
+public:
+ SurroundViewServiceHandler(sp<ISurroundViewSession> session);
+
+ Return<void> notify(SvEvent svEvent) override;
+ Return<void> receiveFrames(const SvFramesDesc& svFramesDesc) override;
+
+ bool checkEventReceived(SvEvent svEvent);
+ SvFramesDesc getLastReceivedFrames();
+ int getReceiveFramesCount();
+ bool areAllFramesValid();
+ void setDoNotReturnFrames(bool flag);
+
+private:
+ mutex mLock;
+
+ vector<SvEvent> mReceivedEvents;
+ sp<ISurroundViewSession> mSession;
+ SvFramesDesc mLastReceivedFrames; // only use timestampNs and sequenceId
+ int mReceiveFramesCount; // TODO(haoxiangl): figure out a better name
+ bool mAllFramesValid = true;
+ bool mDoNotReturnFrames;
+};
+
+#endif //SURROUND_VIEW_STREAM_HANDLER_H
diff --git a/automotive/sv/1.0/vts/functional/VtsHalSurroundViewV1_0TargetTest.cpp b/automotive/sv/1.0/vts/functional/VtsHalSurroundViewV1_0TargetTest.cpp
new file mode 100644
index 0000000..b1b9d16
--- /dev/null
+++ b/automotive/sv/1.0/vts/functional/VtsHalSurroundViewV1_0TargetTest.cpp
@@ -0,0 +1,1137 @@
+//
+// 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 <android/hardware/automotive/sv/1.0/types.h>
+#include <android/hardware/automotive/sv/1.0/ISurroundViewService.h>
+#include <android/hardware/automotive/sv/1.0/ISurroundViewStream.h>
+#include <android/hardware/automotive/sv/1.0/ISurroundView2dSession.h>
+#include <android/hardware/automotive/sv/1.0/ISurroundView3dSession.h>
+#include <android/hardware_buffer.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
+#include <hidlmemory/mapping.h>
+#include <math.h>
+#include <utils/Log.h>
+
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+#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<std::string> {
+public:
+ virtual void SetUp() override {
+ mSurroundViewService = ISurroundViewService::getService(GetParam());
+ ASSERT_NE(mSurroundViewService.get(), nullptr);
+ }
+
+ virtual void TearDown() override {}
+
+ sp<ISurroundViewService> mSurroundViewService; // Every test needs access to the service
+};
+
+TEST_P(SurroundViewHidlTest, startAndStop2dSession) {
+ ALOGD("SurroundViewHidlTest::startAndStop2dSession");
+ sp<ISurroundView2dSession> surroundView2dSession;
+ mSurroundViewService->start2dSession(
+ [&surroundView2dSession](
+ const sp<ISurroundView2dSession>& 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<ISurroundView2dSession> surroundView2dSession;
+ SvResult result = mSurroundViewService->stop2dSession(surroundView2dSession);
+ ASSERT_NE(result, SvResult::OK);
+}
+
+TEST_P(SurroundViewHidlTest, startAndStop2dStream) {
+ ALOGD("SurroundViewHidlTest::startAndStop2dStream");
+ sp<ISurroundView2dSession> surroundView2dSession;
+ mSurroundViewService->start2dSession(
+ [&surroundView2dSession](
+ const sp<ISurroundView2dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView2dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> 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<ISurroundView2dSession> surroundView2dSession;
+ mSurroundViewService->start2dSession(
+ [&surroundView2dSession](
+ const sp<ISurroundView2dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView2dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> 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<ISurroundView2dSession> surroundView2dSession;
+ mSurroundViewService->start2dSession(
+ [&surroundView2dSession](
+ const sp<ISurroundView2dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView2dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> 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<ISurroundView2dSession> surroundView2dSession;
+ mSurroundViewService->start2dSession(
+ [&surroundView2dSession](
+ const sp<ISurroundView2dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView2dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> handler =
+ new SurroundViewServiceHandler(surroundView2dSession);
+
+ surroundView2dSession->stopStream();
+ mSurroundViewService->stop2dSession(surroundView2dSession);
+}
+
+TEST_P(SurroundViewHidlTest, validate2dSvFramesDesc) {
+ ALOGD("SurroundViewHidlTest, validate2dSvFramesDesc");
+ sp<ISurroundView2dSession> surroundView2dSession;
+ mSurroundViewService->start2dSession(
+ [&surroundView2dSession](
+ const sp<ISurroundView2dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView2dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> 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<const AHardwareBuffer_Desc *>(&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<ISurroundView2dSession> surroundView2dSession;
+ mSurroundViewService->start2dSession(
+ [&surroundView2dSession](
+ const sp<ISurroundView2dSession>& 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<ISurroundView2dSession> surroundView2dSession;
+ mSurroundViewService->start2dSession(
+ [&surroundView2dSession](
+ const sp<ISurroundView2dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView2dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> 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<const AHardwareBuffer_Desc *>(&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<ISurroundView2dSession> surroundView2dSession;
+ mSurroundViewService->start2dSession(
+ [&surroundView2dSession](
+ const sp<ISurroundView2dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView2dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> 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<const AHardwareBuffer_Desc *>(&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<ISurroundView2dSession> surroundView2dSession;
+ mSurroundViewService->start2dSession(
+ [&surroundView2dSession](
+ const sp<ISurroundView2dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView2dSession = session;
+ });
+
+ hidl_vec<hidl_string> cameraIds;
+ mSurroundViewService->getCameraIds([&cameraIds](
+ const hidl_vec<hidl_string>& camIds) {
+ cameraIds = camIds;
+ });
+
+ sp<SurroundViewServiceHandler> 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<const AHardwareBuffer_Desc *>(&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<Point2dInt> 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<Point2dFloat>& 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<ISurroundView2dSession> surroundView2dSession;
+ mSurroundViewService->start2dSession(
+ [&surroundView2dSession](
+ const sp<ISurroundView2dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView2dSession = session;
+ });
+
+ hidl_vec<hidl_string> cameraIds;
+ mSurroundViewService->getCameraIds([&cameraIds](
+ const hidl_vec<hidl_string>& 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<Point2dInt> points2dCamera;
+ points2dCamera.resize(1);
+ points2dCamera[0].x = 0;
+ points2dCamera[0].y = 0;
+
+ surroundView2dSession->projectCameraPoints(
+ points2dCamera,
+ invalidCameraId,
+ [] (const hidl_vec<Point2dFloat>& 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& 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<ISurroundView3dSession> surroundView3dSession;
+ SvResult result = mSurroundViewService->stop3dSession(surroundView3dSession);
+ EXPECT_NE(result, SvResult::OK);
+}
+
+TEST_P(SurroundViewHidlTest, startAndStop3dStream) {
+ ALOGD("SurroundViewHidlTest::startAndStop3dStream");
+ sp<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ std::vector<View3d> views(1);
+ SvResult setViewResult = surroundView3dSession->setViews(views);
+ EXPECT_EQ(setViewResult, SvResult::OK);
+
+ sp<SurroundViewServiceHandler> 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ std::vector<View3d> views(1);
+ SvResult setViewResult = surroundView3dSession->setViews(views);
+ EXPECT_EQ(setViewResult, SvResult::OK);
+
+ sp<SurroundViewServiceHandler> 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ std::vector<View3d> views(1);
+ SvResult setViewResult = surroundView3dSession->setViews(views);
+ EXPECT_EQ(setViewResult, SvResult::OK);
+
+ sp<SurroundViewServiceHandler> 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> handler =
+ new SurroundViewServiceHandler(surroundView3dSession);
+
+ std::vector<View3d> 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> handler =
+ new SurroundViewServiceHandler(surroundView3dSession);
+
+ std::vector<View3d> 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<const AHardwareBuffer_Desc *>(&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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> handler =
+ new SurroundViewServiceHandler(surroundView3dSession);
+
+ std::vector<View3d> 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<const AHardwareBuffer_Desc *>(&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<hidl_memory, sp<IMemory>> GetMappedSharedMemory(int bytesSize) {
+
+ const auto nullResult = std::make_pair(hidl_memory(), nullptr);
+
+ sp<IAllocator> 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<void> 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<IMemory> 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<OverlayMemoryDesc>& overlaysMemDesc,
+ sp<IMemory> 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<OverlaysData, sp<IMemory>> 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<hidl_memory, sp<IMemory>> sharedMem =
+ GetMappedSharedMemory(sharedMemBytesSize);
+ sp<IMemory> 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<OverlayMemoryDesc> 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ std::pair<OverlaysData, sp<IMemory>> 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ std::pair<OverlaysData, sp<IMemory>> 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ std::pair<OverlaysData, sp<IMemory>> 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ std::pair<OverlaysData, sp<IMemory>> 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& 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<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ std::pair<OverlaysData, sp<IMemory>> 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<hidl_string> cameraIds;
+ mSurroundViewService->getCameraIds([&cameraIds](
+ const hidl_vec<hidl_string>& camIds) {
+ cameraIds = camIds;
+ });
+ EXPECT_GT(cameraIds.size(), 0);
+
+ sp<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ Point2dInt cameraPoint;
+ cameraPoint.x = 0;
+ cameraPoint.y = 0;
+ std::vector<Point2dInt> cameraPoints = {cameraPoint};
+
+ hidl_string invalidCameraId = "INVALID_CAMERA_ID";
+
+ std::vector<Point3dFloat> points3d;
+ surroundView3dSession->projectCameraPointsTo3dSurface(
+ cameraPoints, invalidCameraId,
+ [&points3d](const hidl_vec<Point3dFloat>& points3dproj) {
+ points3d = points3dproj;
+ });
+
+ EXPECT_TRUE(points3d.empty());
+
+ mSurroundViewService->stop3dSession(surroundView3dSession);
+}
+
+TEST_P(SurroundViewHidlTest, projectPointsInvalidPointsFail) {
+ ALOGD("SurroundViewHidlTest, projectPointsInvalidPointsFail");
+
+ hidl_vec<hidl_string> cameraIds;
+ mSurroundViewService->getCameraIds([&cameraIds](
+ const hidl_vec<hidl_string>& camIds) {
+ cameraIds = camIds;
+ });
+
+ EXPECT_GT(cameraIds.size(), 0);
+
+ sp<ISurroundView3dSession> surroundView3dSession;
+ mSurroundViewService->start3dSession(
+ [&surroundView3dSession](
+ const sp<ISurroundView3dSession>& session, SvResult result) {
+ ASSERT_EQ(result, SvResult::OK);
+ surroundView3dSession = session;
+ });
+
+ sp<SurroundViewServiceHandler> handler =
+ new SurroundViewServiceHandler(surroundView3dSession);
+
+ std::vector<View3d> 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<const AHardwareBuffer_Desc *>(&svBuffer2d.hardwareBuffer.description);
+ width = pDesc->width;
+ height = pDesc->height;
+
+ Point2dInt cameraPoint;
+ cameraPoint.x = width * 2;
+ cameraPoint.y = height * 2;
+ std::vector<Point2dInt> cameraPoints = {cameraPoint};
+
+ std::vector<Point3dFloat> points3d;
+ surroundView3dSession->projectCameraPointsTo3dSurface(
+ cameraPoints, cameraIds[0],
+ [&points3d](const hidl_vec<Point3dFloat>& points3dproj) {
+ points3d = points3dproj;
+ });
+
+ EXPECT_FALSE(points3d[0].isValid);
+
+ surroundView3dSession->stopStream();
+ mSurroundViewService->stop3dSession(surroundView3dSession);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance,
+ SurroundViewHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(ISurroundViewService::descriptor)
+ ),
+ android::hardware::PrintInstanceNameToString
+);