Merge "DO NOT MERGE: Add VirtualCameraFuzzer" into rvc-qpr-dev
diff --git a/evs/manager/1.1/test/fuzzer/Android.bp b/evs/manager/1.1/test/fuzzer/Android.bp
index 0861d67..dfe0203 100644
--- a/evs/manager/1.1/test/fuzzer/Android.bp
+++ b/evs/manager/1.1/test/fuzzer/Android.bp
@@ -12,12 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-cc_fuzz {
- name: "evs_halcamera_fuzzer",
- srcs: [
- "HalCameraFuzzer.cpp",
- ],
-
+cc_defaults {
+ name: "evs_fuzz_default",
static_libs: [
"libgmock",
"libgtest",
@@ -47,3 +43,19 @@
"system/core/libsync",
],
}
+
+cc_fuzz {
+ name: "evs_halcamera_fuzzer",
+ srcs: [
+ "HalCameraFuzzer.cpp",
+ ],
+ defaults: ["evs_fuzz_default"],
+}
+
+cc_fuzz {
+ name: "evs_virtual_camera_fuzzer",
+ srcs: [
+ "VirtualCameraFuzzer.cpp",
+ ],
+ defaults: ["evs_fuzz_default"],
+}
\ No newline at end of file
diff --git a/evs/manager/1.1/test/fuzzer/Common.h b/evs/manager/1.1/test/fuzzer/Common.h
new file mode 100644
index 0000000..b3b53a6
--- /dev/null
+++ b/evs/manager/1.1/test/fuzzer/Common.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 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 EVS_MANAGER_1_1_TEST_FUZZER_COMMON_H_
+#define EVS_MANAGER_1_1_TEST_FUZZER_COMMON_H_
+
+namespace android {
+namespace automotive {
+namespace evs {
+namespace V1_1 {
+namespace implementation {
+
+#define EVS_FUZZ_BASE_ENUM \
+ EVS_FUZZ_NOTIFY, /*verify notify*/ \
+ EVS_FUZZ_GET_HW_CAMERA, /*verify getHalCameras*/ \
+ EVS_FUZZ_DELIVER_FRAME, /* verify deliverFrame */ \
+ EVS_FUZZ_DONE_WITH_FRAME_1_0, /* verify doneWithFrame */ \
+ EVS_FUZZ_DONE_WITH_FRAME_1_1, /* verify doneWithFrame_1_1 */ \
+ EVS_FUZZ_SET_PRIMARY, /* verify setPrimary */ \
+ EVS_FUZZ_FORCE_PRIMARY, /* verify forcePrimary */ \
+ EVS_FUZZ_UNSET_PRIMARY, /* verify unsetPrimary */ \
+ EVS_FUZZ_SET_PARAMETER, /* verify setIntParameter */ \
+ EVS_FUZZ_GET_PARAMETER, /* verify getIntParameter */ \
+ EVS_FUZZ_API_SUM
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace evs
+} // namespace automotive
+} // namespace android
+
+#endif // EVS_MANAGER_1_1_TEST_FUZZER_COMMON_H_
diff --git a/evs/manager/1.1/test/fuzzer/HalCameraFuzzer.cpp b/evs/manager/1.1/test/fuzzer/HalCameraFuzzer.cpp
index edbbc2a..4660182 100644
--- a/evs/manager/1.1/test/fuzzer/HalCameraFuzzer.cpp
+++ b/evs/manager/1.1/test/fuzzer/HalCameraFuzzer.cpp
@@ -16,6 +16,7 @@
#include <fuzzer/FuzzedDataProvider.h>
#include <iostream>
+#include "Common.h"
#include "Enumerator.h"
#include "HalCamera.h"
#include "MockHWCamera.h"
@@ -29,15 +30,21 @@
namespace {
enum EvsFuzzFuncs {
- EVS_FUZZ_MAKE_VIRTUAL_CAMERA = 0, // verify makeVirtualCamera
- EVS_FUZZ_OWN_VIRTUAL_CAMERA, // verify ownVirtualCamera
- EVS_FUZZ_DISOWN_VIRTUAL_CAMERA, // verify disownVirtualCamera
- EVS_FUZZ_GET_HW_CAMERA, // verify getHwCamera
- EVS_FUZZ_GET_CLIENT_COUNT, // verify getClientCount
- EVS_FUZZ_GET_ID, // verify getId
- EVS_FUZZ_GET_STREAM_CONFIG, // verify getStreamConfig
- EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT, // verify changeFramesInFlight
- EVS_FUZZ_API_SUM
+ EVS_FUZZ_MAKE_VIRTUAL_CAMERA = 0, // verify makeVirtualCamera
+ EVS_FUZZ_OWN_VIRTUAL_CAMERA, // verify ownVirtualCamera
+ EVS_FUZZ_DISOWN_VIRTUAL_CAMERA, // verify disownVirtualCamera
+ EVS_FUZZ_GET_CLIENT_COUNT, // verify getClientCount
+ EVS_FUZZ_GET_ID, // verify getId
+ EVS_FUZZ_GET_STREAM_CONFIG, // verify getStreamConfig
+ EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT, // verify changeFramesInFlight
+ EVS_FUZZ_CHANGE_FRAMES_IN_FLIGHT_1, // verify overloaded changeFramesInFlight
+ EVS_FUZZ_REQUEST_NEW_FRAME, // verify requestNewFrame
+ EVS_FUZZ_CLIENT_STREAM_STARTING, // verify clientStreamStarting
+ EVS_FUZZ_CLIENT_STREAM_ENDING, // verify clientStreamEnding
+ EVS_FUZZ_GET_STATS, // verify getStats
+ EVS_FUZZ_GET_STREAM_CONFIGURATION, // verify getStreamConfiguration
+ EVS_FUZZ_DELIVER_FRAME_1_1, // verify deliverFrame_1_1
+ EVS_FUZZ_BASE_ENUM // verify common functions
};
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
diff --git a/evs/manager/1.1/test/fuzzer/MockHWCamera.h b/evs/manager/1.1/test/fuzzer/MockHWCamera.h
index 19f1cb9..a4e0638 100644
--- a/evs/manager/1.1/test/fuzzer/MockHWCamera.h
+++ b/evs/manager/1.1/test/fuzzer/MockHWCamera.h
@@ -29,23 +29,31 @@
MockHWCamera() = default;
// v1.0 methods
- MOCK_METHOD(Return<void>, getCameraInfo, (getCameraInfo_cb _hidl_cb), (override));
+ Return<void> getCameraInfo(getCameraInfo_cb _hidl_cb) override { return {}; }
Return<EvsResult> setMaxFramesInFlight(uint32_t bufferCount) override {
if (bufferCount > 1024) {
return EvsResult::INVALID_ARG;
}
return EvsResult::OK;
}
- MOCK_METHOD(Return<EvsResult>, startVideoStream,
- (const ::android::sp<IEvsCameraStream_1_0>& stream), (override));
- MOCK_METHOD(Return<void>, doneWithFrame, (const BufferDesc_1_0& buffer), (override));
- MOCK_METHOD(Return<void>, stopVideoStream, (), (override));
- MOCK_METHOD(Return<int32_t>, getExtendedInfo, (uint32_t opaqueIdentifier), (override));
- MOCK_METHOD(Return<EvsResult>, setExtendedInfo,
- (uint32_t opaqueIdentifier, int32_t opaqueValue), (override));
+ Return<EvsResult> startVideoStream(const ::android::sp<IEvsCameraStream_1_0>& stream) override {
+ return EvsResult::OK;
+ }
+ Return<void> doneWithFrame(const BufferDesc_1_0& buffer) override { return {}; }
+ Return<void> stopVideoStream() override { return {}; }
+ Return<int32_t> getExtendedInfo(uint32_t opaqueIdentifier) override {
+ if (mExtendedInfo.find(opaqueIdentifier) != mExtendedInfo.end()) {
+ return mExtendedInfo[opaqueIdentifier];
+ }
+ return 0;
+ }
+ Return<EvsResult> setExtendedInfo(uint32_t opaqueIdentifier, int32_t opaqueValue) override {
+ mExtendedInfo[opaqueIdentifier] = opaqueValue;
+ return EvsResult::OK;
+ }
// v1.1 methods
- MOCK_METHOD(Return<void>, getCameraInfo_1_1, (getCameraInfo_1_1_cb _hidl_cb), (override));
+ Return<void> getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb) override { return {}; }
MOCK_METHOD(Return<void>, getPhysicalCameraInfo,
(const hidl_string& deviceId, getPhysicalCameraInfo_cb _hidl_cb), (override));
MOCK_METHOD(Return<EvsResult>, pauseVideoStream, (), (override));
@@ -55,20 +63,41 @@
MOCK_METHOD(Return<EvsResult>, setMaster, (), (override));
MOCK_METHOD(Return<EvsResult>, forceMaster, (const sp<IEvsDisplay_1_0>& display), (override));
MOCK_METHOD(Return<EvsResult>, unsetMaster, (), (override));
- MOCK_METHOD(Return<void>, getParameterList, (getParameterList_cb _hidl_cb), (override));
- MOCK_METHOD(Return<void>, getIntParameterRange,
- (CameraParam id, getIntParameterRange_cb _hidl_cb), (override));
- MOCK_METHOD(Return<void>, setIntParameter,
- (CameraParam id, int32_t value, setIntParameter_cb _hidl_cb), (override));
- MOCK_METHOD(Return<void>, getIntParameter, (CameraParam id, getIntParameter_cb _hidl_cb),
- (override));
- MOCK_METHOD(Return<void>, getExtendedInfo_1_1,
- (uint32_t opaqueIdentifier, getExtendedInfo_1_1_cb _hidl_cb), (override));
- MOCK_METHOD(Return<EvsResult>, setExtendedInfo_1_1,
- (uint32_t opaqueIdentifier, const hidl_vec<uint8_t>& opaqueValue), (override));
- MOCK_METHOD(Return<void>, importExternalBuffers,
- (const hidl_vec<BufferDesc_1_1>& buffers, importExternalBuffers_cb _hidl_cb),
- (override));
+ Return<void> getParameterList(getParameterList_cb _hidl_cb) override { return {}; }
+ Return<void> getIntParameterRange(CameraParam id, getIntParameterRange_cb _hidl_cb) override {
+ return {};
+ }
+ Return<void> setIntParameter(CameraParam id, int32_t value,
+ setIntParameter_cb _hidl_cb) override {
+ // FIXME in default implementation, it's _hidl_cb(EvsResult::INVALID_ARG, 0); which will
+ // always cause a segfault what's the predefined behavior of _hidl_cb?
+ std::vector<int32_t> vec;
+ vec.push_back(0);
+ _hidl_cb(EvsResult::INVALID_ARG, vec);
+ return {};
+ }
+
+ Return<void> getIntParameter(CameraParam id, getIntParameter_cb _hidl_cb) {
+ _hidl_cb(EvsResult::INVALID_ARG, 0);
+ return {};
+ }
+
+ Return<void> getExtendedInfo_1_1(uint32_t opaqueIdentifier,
+ getExtendedInfo_1_1_cb _hidl_cb) override {
+ return {};
+ }
+ Return<EvsResult> setExtendedInfo_1_1(uint32_t opaqueIdentifier,
+ const hidl_vec<uint8_t>& opaqueValue) override {
+ return EvsResult::OK;
+ }
+ Return<void> importExternalBuffers(const hidl_vec<BufferDesc_1_1>& buffers,
+ importExternalBuffers_cb _hidl_cb) override {
+ return {};
+ }
+
+private:
+ std::map<uint32_t, int32_t> mExtendedInfo;
+ std::map<uint32_t, int32_t> mExtendedInfo_1_1;
};
} // namespace implementation
diff --git a/evs/manager/1.1/test/fuzzer/VirtualCameraFuzzer.cpp b/evs/manager/1.1/test/fuzzer/VirtualCameraFuzzer.cpp
new file mode 100644
index 0000000..3776f4b
--- /dev/null
+++ b/evs/manager/1.1/test/fuzzer/VirtualCameraFuzzer.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright 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 <fuzzer/FuzzedDataProvider.h>
+#include <iostream>
+#include "Common.h"
+#include "Enumerator.h"
+#include "MockHWCamera.h"
+#include "VirtualCamera.h"
+
+namespace android {
+namespace automotive {
+namespace evs {
+namespace V1_1 {
+namespace implementation {
+
+namespace {
+
+using CameraDesc_1_0 = ::android::hardware::automotive::evs::V1_0::CameraDesc;
+
+enum EvsFuzzFuncs {
+ EVS_FUZZ_GET_ALLOWED_BUFFERS, // verify getAllowedBuffers
+ EVS_FUZZ_IS_STREAMING, // verify isStreaming
+ EVS_FUZZ_GET_VERSION, // verify getVersion
+ EVS_FUZZ_SET_DESCRIPTOR, // verify setDescriptor
+ EVS_FUZZ_GET_CAMERA_INFO, // verify getCameraInfo
+ EVS_FUZZ_SETMAX_FRAMES_IN_FLIGHT, // verify setMaxFramesInFlight
+ EVS_FUZZ_START_VIDEO_STREAM, // verify startVideoStream
+ EVS_FUZZ_STOP_VIDEO_STREAM, // verify stopVideoStream
+ EVS_FUZZ_GET_EXTENDED_INFO, // verify getExtendedInfo
+ EVS_FUZZ_SET_EXTENDED_INFO, // verify setExtendedInfo
+ EVS_FUZZ_GET_CAMERA_INFO_1_1, // verify getCameraInfo_1_1
+ EVS_FUZZ_GET_PHYSICAL_CAMERA_INFO, // verify getPhysicalCameraInfo
+ EVS_FUZZ_PAUSE_VIDEO_STREAM, // verify pauseVideoStream
+ EVS_FUZZ_RESUME_VIDEO_STREAM, // verify resumeVideoStream
+ EVS_FUZZ_GET_PARAMETER_LIST, // verify getParameterList
+ EVS_FUZZ_GET_INT_PARAMETER_RANGE, // verify getIntParameterRange
+ EVS_FUZZ_SET_EXTENDED_INFO_1_1, // verify setExtendedInfo_1_1
+ EVS_FUZZ_GET_EXTENDED_INFO_1_1, // verify getExtendedInfo_1_1
+ EVS_FUZZ_IMPORT_EXTERNAL_BUFFERS, // verify importExternalBuffers
+ EVS_FUZZ_BASE_ENUM // verify common functions
+};
+
+const int kMaxFuzzerConsumedBytes = 12;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+ sp<IEvsCamera_1_1> mockHWCamera = new MockHWCamera();
+ sp<HalCamera> halCamera = new HalCamera(mockHWCamera);
+ sp<VirtualCamera> virtualCamera = halCamera->makeVirtualCamera();
+
+ std::vector<BufferDesc_1_0> vBufferDesc_1_0;
+ std::vector<BufferDesc_1_1> vBufferDesc_1_1;
+
+ bool videoStarted = false;
+
+ while (fdp.remaining_bytes() > kMaxFuzzerConsumedBytes) {
+ switch (fdp.ConsumeIntegralInRange<uint32_t>(0, EVS_FUZZ_API_SUM)) {
+ case EVS_FUZZ_GET_ALLOWED_BUFFERS: {
+ virtualCamera->getAllowedBuffers();
+ break;
+ }
+ case EVS_FUZZ_IS_STREAMING: {
+ virtualCamera->isStreaming();
+ break;
+ }
+ case EVS_FUZZ_GET_VERSION: {
+ virtualCamera->getVersion();
+ break;
+ }
+ case EVS_FUZZ_GET_HW_CAMERA: {
+ virtualCamera->getHalCameras();
+ break;
+ }
+ case EVS_FUZZ_SET_DESCRIPTOR: {
+ CameraDesc* desc = new CameraDesc();
+ virtualCamera->setDescriptor(desc);
+ break;
+ }
+ case EVS_FUZZ_NOTIFY: {
+ if (videoStarted) {
+ EvsEventDesc event;
+ uint32_t type = fdp.ConsumeIntegralInRange<
+ uint32_t>(0, static_cast<uint32_t>(EvsEventType::STREAM_ERROR));
+ event.aType = static_cast<EvsEventType>(type);
+ virtualCamera->notify(event);
+ }
+ break;
+ }
+ case EVS_FUZZ_DELIVER_FRAME: {
+ BufferDesc buffer;
+ buffer.bufferId = fdp.ConsumeIntegral<int32_t>();
+ virtualCamera->deliverFrame(buffer);
+ vBufferDesc_1_1.emplace_back(buffer);
+ break;
+ }
+ case EVS_FUZZ_GET_CAMERA_INFO: {
+ virtualCamera->getCameraInfo([](CameraDesc_1_0 desc) {});
+ break;
+ }
+ case EVS_FUZZ_SETMAX_FRAMES_IN_FLIGHT: {
+ uint32_t delta = fdp.ConsumeIntegral<uint32_t>();
+ virtualCamera->setMaxFramesInFlight(delta);
+ break;
+ }
+ case EVS_FUZZ_START_VIDEO_STREAM: {
+ if (!videoStarted) {
+ sp<IEvsCamera_1_1> mockHWCamera1 = new MockHWCamera();
+ sp<HalCamera> halCamera1 = new HalCamera(mockHWCamera1);
+ virtualCamera->startVideoStream(halCamera1);
+ videoStarted = true;
+ }
+ break;
+ }
+ case EVS_FUZZ_DONE_WITH_FRAME_1_0: {
+ if (!vBufferDesc_1_0.empty()) {
+ uint32_t whichBuffer =
+ fdp.ConsumeIntegralInRange<uint32_t>(0, vBufferDesc_1_0.size() - 1);
+ virtualCamera->doneWithFrame(vBufferDesc_1_0[whichBuffer]);
+ }
+ break;
+ }
+ case EVS_FUZZ_STOP_VIDEO_STREAM: {
+ virtualCamera->stopVideoStream();
+ videoStarted = false;
+ break;
+ }
+ case EVS_FUZZ_GET_EXTENDED_INFO: {
+ uint32_t opaqueIdentifier = fdp.ConsumeIntegral<uint32_t>();
+ virtualCamera->getExtendedInfo(opaqueIdentifier);
+ break;
+ }
+ case EVS_FUZZ_SET_EXTENDED_INFO: {
+ uint32_t opaqueIdentifier = fdp.ConsumeIntegral<uint32_t>();
+ int32_t opaqueValue = fdp.ConsumeIntegral<int32_t>();
+ virtualCamera->setExtendedInfo(opaqueIdentifier, opaqueValue);
+ break;
+ }
+ case EVS_FUZZ_GET_CAMERA_INFO_1_1: {
+ virtualCamera->getCameraInfo_1_1([](CameraDesc desc) {});
+ break;
+ }
+ case EVS_FUZZ_GET_PHYSICAL_CAMERA_INFO: {
+ hidl_string deviceId("");
+ virtualCamera->getPhysicalCameraInfo(deviceId, [](const CameraDesc& info) {});
+ break;
+ }
+ case EVS_FUZZ_DONE_WITH_FRAME_1_1: {
+ if (!vBufferDesc_1_1.empty()) {
+ hidl_vec<BufferDesc_1_1> buffers(vBufferDesc_1_1);
+ virtualCamera->doneWithFrame_1_1(buffers);
+ }
+ break;
+ }
+ case EVS_FUZZ_PAUSE_VIDEO_STREAM: {
+ virtualCamera->pauseVideoStream();
+ break;
+ }
+ case EVS_FUZZ_RESUME_VIDEO_STREAM: {
+ virtualCamera->resumeVideoStream();
+ break;
+ }
+ case EVS_FUZZ_SET_PRIMARY: {
+ virtualCamera->setMaster();
+ break;
+ }
+ case EVS_FUZZ_FORCE_PRIMARY: {
+ // TODO(161388489) skip this until we finished fuzzing evs display
+ break;
+ }
+ case EVS_FUZZ_UNSET_PRIMARY: {
+ virtualCamera->unsetMaster();
+ break;
+ }
+ case EVS_FUZZ_GET_PARAMETER_LIST: {
+ virtualCamera->getParameterList([](hidl_vec<CameraParam> cmdList) {});
+ break;
+ }
+ case EVS_FUZZ_GET_INT_PARAMETER_RANGE: {
+ uint32_t whichParam =
+ fdp.ConsumeIntegralInRange<uint32_t>(0,
+ static_cast<uint32_t>(
+ CameraParam::ABSOLUTE_ZOOM));
+ virtualCamera->getIntParameterRange(static_cast<CameraParam>(whichParam),
+ [](int32_t val0, int32_t val1, int32_t val2) {
+ });
+ break;
+ }
+ case EVS_FUZZ_SET_PARAMETER: {
+ uint32_t whichParam =
+ fdp.ConsumeIntegralInRange<uint32_t>(0,
+ static_cast<uint32_t>(
+ CameraParam::ABSOLUTE_ZOOM));
+ int32_t val = fdp.ConsumeIntegral<int32_t>();
+ virtualCamera->setIntParameter(static_cast<CameraParam>(whichParam), val,
+ [](auto status, auto effectiveValues) {});
+ break;
+ }
+ case EVS_FUZZ_GET_PARAMETER: {
+ uint32_t whichParam =
+ fdp.ConsumeIntegralInRange<uint32_t>(0,
+ static_cast<uint32_t>(
+ CameraParam::ABSOLUTE_ZOOM));
+ virtualCamera->getIntParameter(static_cast<CameraParam>(whichParam),
+ [](auto status, auto effectiveValues) {});
+ break;
+ }
+ case EVS_FUZZ_SET_EXTENDED_INFO_1_1: {
+ uint32_t opaqueIdentifier = fdp.ConsumeIntegral<uint32_t>();
+ uint8_t opaqueValue = fdp.ConsumeIntegral<uint8_t>();
+ vector<uint8_t> v;
+ v.push_back(opaqueValue);
+ hidl_vec<uint8_t> vec(v);
+ virtualCamera->setExtendedInfo_1_1(opaqueIdentifier, vec);
+ break;
+ }
+ case EVS_FUZZ_GET_EXTENDED_INFO_1_1: {
+ uint32_t opaqueIdentifier = fdp.ConsumeIntegral<uint32_t>();
+ virtualCamera->getExtendedInfo_1_1(opaqueIdentifier,
+ [](const auto& result, const auto& data) {});
+ break;
+ }
+ case EVS_FUZZ_IMPORT_EXTERNAL_BUFFERS: {
+ if (!vBufferDesc_1_1.empty()) {
+ hidl_vec<BufferDesc_1_1> buffers(vBufferDesc_1_1);
+ virtualCamera->importExternalBuffers(buffers, [](auto _result, auto _delta) {});
+ }
+ break;
+ }
+ default:
+ LOG(ERROR) << "Unexpected option, aborting...";
+ break;
+ }
+ }
+
+ if (videoStarted) {
+ // TODO(b/161762538) if we do not stop video stream manually here,
+ // there will be crash at VirtualCamera.cpp::pHwCamera->unsetMaster(this);
+ virtualCamera->stopVideoStream();
+ }
+ return 0;
+}
+
+} // namespace
+} // namespace implementation
+} // namespace V1_1
+} // namespace evs
+} // namespace automotive
+} // namespace android