Merge "Added automotiveSvV1.0_fuzzer"

This commit is contained in:
Treehugger Robot
2022-04-18 07:24:20 +00:00
committed by Gerrit Code Review
6 changed files with 671 additions and 3 deletions

View File

@@ -29,9 +29,7 @@ cc_binary {
relative_install_path: "hw",
srcs: [
"service.cpp",
"SurroundViewService.cpp",
"SurroundView2dSession.cpp",
"SurroundView3dSession.cpp",
":automotiveSvV1.0_sources",
],
init_rc: ["android.hardware.automotive.sv@1.0-service.rc"],
vintf_fragments: ["android.hardware.automotive.sv@1.0-service.xml"],
@@ -54,3 +52,17 @@ cc_binary {
"-g",
],
}
filegroup {
name: "automotiveSvV1.0_sources",
srcs: [
"SurroundViewService.cpp",
"SurroundView2dSession.cpp",
"SurroundView3dSession.cpp",
],
}
cc_library_headers {
name: "automotiveSvV1.0_headers",
export_include_dirs: ["."],
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2022 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_fuzz {
name: "automotiveSvV1.0_fuzzer",
srcs: [
"AutomotiveSvV1_0Fuzzer.cpp",
"SurroundViewStream.cpp",
":automotiveSvV1.0_sources",
],
header_libs: [
"automotiveSvV1.0_headers",
],
shared_libs: [
"android.hardware.automotive.sv@1.0",
"android.hidl.allocator@1.0",
"libhidlbase",
"libutils",
"libhidlmemory",
"liblog",
],
fuzz_config: {
cc: [
"android-media-fuzzing-reports@google.com",
],
componentid: 533764,
},
}

View File

@@ -0,0 +1,433 @@
/*
* Copyright (C) 2022 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 "AutomotiveSvV1_0Fuzzer.h"
#include <SurroundViewStream.h>
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <hidlmemory/mapping.h>
namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hidl::allocator::V1_0::IAllocator;
constexpr uint32_t kMinConfigDimension = 0;
constexpr uint32_t kMaxConfigDimension = 4096;
constexpr uint32_t kVertexByteSize = (3 * sizeof(float)) + 4;
constexpr uint32_t kIdByteSize = 2;
constexpr size_t kMaxCharacters = 30;
constexpr size_t kMaxVertices = 10;
constexpr size_t kMaxCameraPoints = 10;
constexpr size_t kMaxViews = 10;
constexpr size_t kMaxOverlays = 10;
constexpr size_t kMinSvBuffers = 0;
constexpr size_t kMaxSvBuffers = 10;
void SurroundViewFuzzer::invoke2dSessionAPI() {
sp<ISurroundView2dSession> surroundView2dSession;
while (mFuzzedDataProvider.remaining_bytes() > 0) {
auto surroundView2dFunc = mFuzzedDataProvider.PickValueInArray<
const std::function<void()>>({
[&]() {
mSurroundViewService->start2dSession(
[&surroundView2dSession](const sp<ISurroundView2dSession>& session,
SvResult result) {
if (result == SvResult::OK) {
surroundView2dSession = session;
}
});
},
[&]() {
if (surroundView2dSession) {
sp<SurroundViewStream> handler =
sp<SurroundViewStream>::make(surroundView2dSession);
surroundView2dSession->startStream(handler);
mIs2dStreamStarted = true;
}
},
[&]() {
if (surroundView2dSession) {
surroundView2dSession->get2dMappingInfo(
[]([[maybe_unused]] Sv2dMappingInfo info) {});
}
},
[&]() {
if (surroundView2dSession) {
Sv2dConfig config;
config.width = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
kMinConfigDimension, kMaxConfigDimension);
if (mFuzzedDataProvider.ConsumeBool()) {
config.blending = static_cast<SvQuality>(
mFuzzedDataProvider.ConsumeIntegral<uint32_t>());
} else {
config.blending = mFuzzedDataProvider.ConsumeBool() ? (SvQuality::HIGH)
: (SvQuality::LOW);
}
surroundView2dSession->set2dConfig(config);
}
},
[&]() {
if (surroundView2dSession) {
surroundView2dSession->get2dConfig([&](Sv2dConfig) {});
}
},
[&]() {
if (surroundView2dSession) {
hidl_vec<Point2dInt> points2dCamera;
const size_t camPoints = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
1, kMaxCameraPoints);
points2dCamera.resize(camPoints);
for (size_t i = 0; i < camPoints; ++i) {
points2dCamera[i].x = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
points2dCamera[i].y = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
}
hidl_vec<hidl_string> cameraIds;
mSurroundViewService->getCameraIds(
[&cameraIds](const hidl_vec<hidl_string>& camIds) {
cameraIds = camIds;
});
hidl_string cameraId;
if (cameraIds.size() > 0 && mFuzzedDataProvider.ConsumeBool()) {
const size_t cameraIndex =
mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
0, cameraIds.size() - 1);
cameraId = cameraIds[cameraIndex];
} else {
cameraId =
mFuzzedDataProvider.ConsumeRandomLengthString(kMaxCharacters);
}
surroundView2dSession->projectCameraPoints(
points2dCamera, cameraId,
[]([[maybe_unused]] const hidl_vec<Point2dFloat>& outPoints) {});
}
},
[&]() {
if (surroundView2dSession) {
SvFramesDesc frames;
frames.timestampNs = mFuzzedDataProvider.ConsumeIntegral<uint64_t>();
frames.sequenceId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
size_t numSvBuffers = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
kMinSvBuffers, kMaxSvBuffers);
frames.svBuffers.resize(numSvBuffers);
for (int i = 0; i < numSvBuffers; ++i) {
frames.svBuffers[i].viewId =
mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
frames.svBuffers[i].hardwareBuffer.nativeHandle = new native_handle_t();
frames.svBuffers[i].hardwareBuffer.description[0] =
mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
frames.svBuffers[i].hardwareBuffer.description[1] =
mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
}
surroundView2dSession->doneWithFrames(frames);
for (int i = 0; i < numSvBuffers; ++i) {
delete frames.svBuffers[i].hardwareBuffer.nativeHandle;
}
}
},
[&]() {
if (surroundView2dSession) {
surroundView2dSession->stopStream();
mIs2dStreamStarted = false;
}
},
[&]() {
mSurroundViewService->stop2dSession(
mFuzzedDataProvider.ConsumeBool() ? surroundView2dSession : nullptr);
},
});
surroundView2dFunc();
}
if (surroundView2dSession && mIs2dStreamStarted) {
surroundView2dSession->stopStream();
}
}
void SurroundViewFuzzer::invoke3dSessionAPI() {
sp<ISurroundView3dSession> surroundView3dSession;
while (mFuzzedDataProvider.remaining_bytes() > 0) {
auto surroundView3dFunc = mFuzzedDataProvider.PickValueInArray<
const std::function<void()>>({
[&]() {
mSurroundViewService->start3dSession(
[&surroundView3dSession](const sp<ISurroundView3dSession>& session,
SvResult result) {
if (result == SvResult::OK) {
surroundView3dSession = session;
}
});
},
[&]() {
if (surroundView3dSession) {
sp<SurroundViewStream> handler =
sp<SurroundViewStream>::make(surroundView3dSession);
surroundView3dSession->startStream(handler);
mIs3dStreamStarted = true;
}
},
[&]() {
if (surroundView3dSession) {
const size_t numViews =
mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(1, kMaxViews);
std::vector<View3d> views(numViews);
for (size_t i = 0; i < numViews; ++i) {
views[i].viewId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
}
surroundView3dSession->setViews(views);
}
},
[&]() {
if (surroundView3dSession) {
Sv3dConfig config;
config.width = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
kMinConfigDimension, kMaxConfigDimension);
config.height = mFuzzedDataProvider.ConsumeIntegralInRange<uint32_t>(
kMinConfigDimension, kMaxConfigDimension);
if (mFuzzedDataProvider.ConsumeBool()) {
config.carDetails = static_cast<SvQuality>(
mFuzzedDataProvider.ConsumeIntegral<uint32_t>());
} else {
config.carDetails = mFuzzedDataProvider.ConsumeBool()
? (SvQuality::HIGH)
: (SvQuality::LOW);
}
surroundView3dSession->set3dConfig(config);
}
},
[&]() {
if (surroundView3dSession) {
surroundView3dSession->get3dConfig([&](Sv3dConfig) {});
}
},
[&]() {
if (surroundView3dSession) {
Point2dInt cameraPoint;
cameraPoint.x = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
cameraPoint.y = mFuzzedDataProvider.ConsumeFloatingPoint<float>();
std::vector<Point2dInt> cameraPoints = {cameraPoint};
hidl_vec<hidl_string> cameraIds;
mSurroundViewService->getCameraIds(
[&cameraIds](const hidl_vec<hidl_string>& camIds) {
cameraIds = camIds;
});
hidl_string cameraId;
if (cameraIds.size() > 0 && mFuzzedDataProvider.ConsumeBool()) {
const size_t cameraIndex =
mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
0, cameraIds.size() - 1);
cameraId = cameraIds[cameraIndex];
} else {
cameraId =
mFuzzedDataProvider.ConsumeRandomLengthString(kMaxCharacters);
}
std::vector<Point3dFloat> points3d;
surroundView3dSession->projectCameraPointsTo3dSurface(
cameraPoints, cameraId,
[&points3d]([[maybe_unused]] const hidl_vec<Point3dFloat>&
points3dproj) { points3d = points3dproj; });
}
},
[&]() {
if (surroundView3dSession) {
// success case
surroundView3dSession->updateOverlays(mOverlaysdata);
}
},
[&]() {
if (surroundView3dSession) {
initSampleOverlaysData();
// Fail with ID mismatch
// Set id of second overlay in shared memory to 2 (expected is 1).
auto& overlaysDescVector = mOverlaysdata.overlaysMemoryDesc;
auto& pIMemory = mMemory;
int32_t indexPosition = mFuzzedDataProvider.ConsumeIntegralInRange<int32_t>(
0, mNumOverlays - 1);
int32_t mismatchedValueIndex =
mFuzzedDataProvider.ConsumeIntegralInRange<int32_t>(
0, mNumOverlays - 1);
setIndexOfOverlaysMemory(overlaysDescVector, pIMemory, indexPosition,
overlaysDescVector[mismatchedValueIndex].id);
surroundView3dSession->updateOverlays(mOverlaysdata);
}
},
[&]() {
if (surroundView3dSession) {
// Fail with NULL memory
// Set shared memory to null.
mOverlaysdata.overlaysMemory = hidl_memory();
surroundView3dSession->updateOverlays(mOverlaysdata);
}
},
[&]() {
if (surroundView3dSession) {
SvFramesDesc frames;
frames.timestampNs = mFuzzedDataProvider.ConsumeIntegral<uint64_t>();
frames.sequenceId = mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
size_t numSvBuffers = mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(
kMinSvBuffers, kMaxSvBuffers);
frames.svBuffers.resize(numSvBuffers);
for (int i = 0; i < numSvBuffers; ++i) {
frames.svBuffers[i].viewId =
mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
frames.svBuffers[i].hardwareBuffer.nativeHandle = new native_handle_t();
frames.svBuffers[i].hardwareBuffer.description[0] =
mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
frames.svBuffers[i].hardwareBuffer.description[1] =
mFuzzedDataProvider.ConsumeIntegral<uint32_t>();
}
surroundView3dSession->doneWithFrames(frames);
for (int i = 0; i < numSvBuffers; ++i) {
delete frames.svBuffers[i].hardwareBuffer.nativeHandle;
}
}
},
[&]() {
if (surroundView3dSession) {
surroundView3dSession->stopStream();
mIs3dStreamStarted = false;
}
},
[&]() {
mSurroundViewService->stop3dSession(
mFuzzedDataProvider.ConsumeBool() ? surroundView3dSession : nullptr);
},
});
surroundView3dFunc();
}
if (surroundView3dSession && mIs3dStreamStarted) {
surroundView3dSession->stopStream();
}
}
void SurroundViewFuzzer::process() {
mFuzzedDataProvider.ConsumeBool() ? invoke2dSessionAPI() : invoke3dSessionAPI();
}
std::pair<hidl_memory, sp<IMemory>> SurroundViewFuzzer::getMappedSharedMemory(int32_t bytesSize) {
const auto nullResult = std::make_pair(hidl_memory(), nullptr);
sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
if (ashmemAllocator.get() == nullptr) {
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) {
return nullResult;
}
// Map shared memory.
sp<IMemory> pIMemory = mapMemory(hidlMemory);
if (pIMemory.get() == nullptr) {
return nullResult;
}
return std::make_pair(hidlMemory, pIMemory);
}
void SurroundViewFuzzer::setIndexOfOverlaysMemory(
const std::vector<OverlayMemoryDesc>& overlaysMemDesc, sp<IMemory> pIMemory,
int32_t indexPosition, uint16_t indexValue) {
// Count the number of vertices until the index.
int32_t totalVerticesCount = 0;
for (int32_t i = 0; i < indexPosition; ++i) {
totalVerticesCount += overlaysMemDesc[i].verticesCount;
}
const int32_t indexBytePosition =
(indexPosition * kIdByteSize) + (kVertexByteSize * totalVerticesCount);
uint8_t* pSharedMemoryData = (uint8_t*)((void*)pIMemory->getPointer());
pSharedMemoryData += indexBytePosition;
uint16_t* pIndex16bit = (uint16_t*)pSharedMemoryData;
// Modify shared memory.
pIMemory->update();
*pIndex16bit = indexValue;
pIMemory->commit();
}
void SurroundViewFuzzer::initSampleOverlaysData() {
const size_t mNumOverlays =
mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(kMinOverlays, kMaxOverlays);
mOverlaysdata.overlaysMemoryDesc.resize(mNumOverlays);
int32_t sharedMemBytesSize = 0;
std::vector<OverlayMemoryDesc> overlaysDescVector = {};
OverlayMemoryDesc overlayMemDesc[mNumOverlays];
for (size_t i = 0; i < mNumOverlays; ++i) {
overlayMemDesc[i].id = i;
overlayMemDesc[i].verticesCount =
mFuzzedDataProvider.ConsumeIntegralInRange<size_t>(1, kMaxVertices);
overlayMemDesc[i].overlayPrimitive = mFuzzedDataProvider.ConsumeBool()
? (OverlayPrimitive::TRIANGLES)
: (OverlayPrimitive::TRIANGLES_STRIP);
mOverlaysdata.overlaysMemoryDesc[i] = overlayMemDesc[i];
sharedMemBytesSize += kIdByteSize + kVertexByteSize * overlayMemDesc[i].verticesCount;
overlaysDescVector.push_back(overlayMemDesc[i]);
}
std::pair<hidl_memory, sp<IMemory>> sharedMem = getMappedSharedMemory(sharedMemBytesSize);
sp<IMemory> pIMemory = std::get<1>(sharedMem);
if (pIMemory.get() == nullptr) {
mOverlaysdata = OverlaysData();
mMemory = nullptr;
return;
}
// 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();
// Set indexes in shared memory.
for (size_t i = 0; i < mNumOverlays; ++i) {
setIndexOfOverlaysMemory(overlaysDescVector, pIMemory, i, overlayMemDesc[i].id);
}
mOverlaysdata.overlaysMemoryDesc = overlaysDescVector;
mOverlaysdata.overlaysMemory = std::get<0>(sharedMem);
mMemory = pIMemory;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size < 1) {
return 0;
}
SurroundViewFuzzer surroundViewFuzzer(data, size);
surroundViewFuzzer.process();
return 0;
}
} // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2022 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.
*
*/
#pragma once
#include <SurroundViewService.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <fuzzer/FuzzedDataProvider.h>
namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
using ::android::sp;
using ::android::hidl::memory::V1_0::IMemory;
constexpr size_t kMinOverlays = 2;
class SurroundViewFuzzer {
public:
SurroundViewFuzzer(const uint8_t* data, size_t size) : mFuzzedDataProvider(data, size) {
mSurroundViewService = sp<SurroundViewService>::make();
}
~SurroundViewFuzzer() = default;
void process();
private:
void invoke2dSessionAPI();
void invoke3dSessionAPI();
std::pair<hidl_memory, sp<IMemory>> getMappedSharedMemory(int32_t bytesSize);
void initSampleOverlaysData();
void setIndexOfOverlaysMemory(const std::vector<OverlayMemoryDesc>& overlaysMemDesc,
sp<IMemory> pIMemory, int32_t indexPosition, uint16_t indexValue);
OverlaysData mOverlaysdata = {};
size_t mNumOverlays = kMinOverlays;
sp<IMemory> mMemory = nullptr;
FuzzedDataProvider mFuzzedDataProvider;
sp<SurroundViewService> mSurroundViewService = nullptr;
bool mIs2dStreamStarted = false;
bool mIs3dStreamStarted = false;
};
} // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer

View File

@@ -0,0 +1,74 @@
/*
* Copyright (C) 2022 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 "SurroundViewStream.h"
namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
using std::lock_guard;
SurroundViewStream::SurroundViewStream(sp<ISurroundViewSession> pSession)
: mSession(pSession), mReceiveFramesCount(0) {}
Return<void> SurroundViewStream::notify(SvEvent 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:
break;
}
return android::hardware::Void();
}
Return<void> SurroundViewStream::receiveFrames(const SvFramesDesc& svFramesDesc) {
lock_guard<mutex> lock(mLock);
if ((mLastReceivedFrames.timestampNs >= svFramesDesc.timestampNs ||
mLastReceivedFrames.sequenceId >= svFramesDesc.sequenceId) &&
mReceiveFramesCount != 0) {
// The incoming frames are with invalid timestamp or sequenceId
mAllFramesValid = false;
}
for (int i = 0; i < svFramesDesc.svBuffers.size(); ++i) {
if (svFramesDesc.svBuffers[i].hardwareBuffer.nativeHandle == nullptr) {
mAllFramesValid = false;
// 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;
}
return android::hardware::Void();
}
} // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2022 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.
*/
#pragma once
#include <android/hardware/automotive/sv/1.0/ISurroundViewSession.h>
#include <android/hardware/automotive/sv/1.0/ISurroundViewStream.h>
#include <android/hardware/automotive/sv/1.0/types.h>
#include <thread>
#include <vector>
namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer {
using android::sp;
using android::hardware::Return;
using std::mutex;
using std::vector;
class SurroundViewStream : public ISurroundViewStream {
public:
SurroundViewStream(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;
int mReceiveFramesCount;
bool mAllFramesValid = true;
};
} // namespace android::hardware::automotive::sv::V1_0::implementation::fuzzer