Merge "gralloc: add vendor encode/decode helpers"
diff --git a/libs/gralloc/types/Gralloc4.cpp b/libs/gralloc/types/Gralloc4.cpp
index 20050dc..4851b44 100644
--- a/libs/gralloc/types/Gralloc4.cpp
+++ b/libs/gralloc/types/Gralloc4.cpp
@@ -985,6 +985,76 @@
decodeByteVector);
}
+status_t encodeUint32(const MetadataType& metadataType, uint32_t input,
+ hidl_vec<uint8_t>* output) {
+ return encode(metadataType, input, output, encodeInteger);
+}
+
+status_t decodeUint32(const MetadataType& metadataType, const hidl_vec<uint8_t>& input,
+ uint32_t* output) {
+ return decode(metadataType, input, output, decodeInteger);
+}
+
+status_t encodeInt32(const MetadataType& metadataType, int32_t input,
+ hidl_vec<uint8_t>* output) {
+ return encode(metadataType, input, output, encodeInteger);
+}
+
+status_t decodeInt32(const MetadataType& metadataType, const hidl_vec<uint8_t>& input,
+ int32_t* output) {
+ return decode(metadataType, input, output, decodeInteger);
+}
+
+status_t encodeUint64(const MetadataType& metadataType, uint64_t input,
+ hidl_vec<uint8_t>* output) {
+ return encode(metadataType, input, output, encodeInteger);
+}
+
+status_t decodeUint64(const MetadataType& metadataType, const hidl_vec<uint8_t>& input,
+ uint64_t* output) {
+ return decode(metadataType, input, output, decodeInteger);
+}
+
+status_t encodeInt64(const MetadataType& metadataType, int64_t input,
+ hidl_vec<uint8_t>* output) {
+ return encode(metadataType, input, output, encodeInteger);
+}
+
+status_t decodeInt64(const MetadataType& metadataType, const hidl_vec<uint8_t>& input,
+ int64_t* output) {
+ return decode(metadataType, input, output, decodeInteger);
+}
+
+status_t encodeFloat(const MetadataType& metadataType, float input,
+ hidl_vec<uint8_t>* output) {
+ return encode(metadataType, input, output, encodeInteger);
+}
+
+status_t decodeFloat(const MetadataType& metadataType, const hidl_vec<uint8_t>& input,
+ float* output) {
+ return decode(metadataType, input, output, decodeInteger);
+}
+
+status_t encodeDouble(const MetadataType& metadataType, double input,
+ hidl_vec<uint8_t>* output) {
+ return encode(metadataType, input, output, encodeInteger);
+}
+
+status_t decodeDouble(const MetadataType& metadataType, const hidl_vec<uint8_t>& input,
+ double* output) {
+ return decode(metadataType, input, output, decodeInteger);
+}
+
+status_t encodeString(const MetadataType& metadataType, const std::string& input,
+ hidl_vec<uint8_t>* output) {
+ return encode(metadataType, input, output, encodeString);
+}
+
+status_t decodeString(const MetadataType& metadataType, const hidl_vec<uint8_t>& input,
+ std::string* output) {
+ return decode(metadataType, input, output, decodeString);
+}
+
bool isStandardMetadataType(const MetadataType& metadataType) {
return !std::strncmp(metadataType.name.c_str(), GRALLOC4_STANDARD_METADATA_TYPE,
metadataType.name.size());
diff --git a/libs/gralloc/types/fuzzer/gralloctypes.cpp b/libs/gralloc/types/fuzzer/gralloctypes.cpp
index da8cf97..b18f407 100644
--- a/libs/gralloc/types/fuzzer/gralloctypes.cpp
+++ b/libs/gralloc/types/fuzzer/gralloctypes.cpp
@@ -30,9 +30,10 @@
#include "util.h"
using ::android::status_t;
+using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
#define GRALLOCTYPES_DECODE(T, FUNC) \
- [] (const ::android::hardware::hidl_vec<uint8_t>& vec, uint8_t /*data*/) {\
+ [] (const ::android::hardware::hidl_vec<uint8_t>& vec) {\
FUZZ_LOG() << "about to read " #T " using " #FUNC;\
T t;\
status_t err = FUNC(vec, &t);\
@@ -40,6 +41,15 @@
FUZZ_LOG() << #T " done " /* << "err: " << err*/;\
}
+#define GRALLOCTYPES_DECODE_VENDOR_HELPER(T, FUNC) \
+ [] (const MetadataType& metadataType, const ::android::hardware::hidl_vec<uint8_t>& vec) {\
+ FUZZ_LOG() << "about to read " #T " using " #FUNC;\
+ T t;\
+ status_t err = FUNC(metadataType, vec, &t);\
+ (void) err;\
+ FUZZ_LOG() << #T " done " /* << "err: " << err*/;\
+ }
+
// clang-format off
std::vector<GrallocTypesDecode> GRALLOCTYPES_DECODE_FUNCTIONS {
@@ -64,4 +74,14 @@
GRALLOCTYPES_DECODE(std::optional<aidl::android::hardware::graphics::common::Cta861_3>, ::android::gralloc4::decodeCta861_3),
GRALLOCTYPES_DECODE(std::optional<std::vector<uint8_t>>, ::android::gralloc4::decodeSmpte2094_40),
};
+
+std::vector<GrallocTypesVendorHelperDecode> GRALLOCTYPES_DECODE_VENDOR_HELPER_FUNCTIONS {
+ GRALLOCTYPES_DECODE_VENDOR_HELPER(uint32_t, ::android::gralloc4::decodeUint32),
+ GRALLOCTYPES_DECODE_VENDOR_HELPER(int32_t, ::android::gralloc4::decodeInt32),
+ GRALLOCTYPES_DECODE_VENDOR_HELPER(uint64_t, ::android::gralloc4::decodeUint64),
+ GRALLOCTYPES_DECODE_VENDOR_HELPER(int64_t, ::android::gralloc4::decodeInt64),
+ GRALLOCTYPES_DECODE_VENDOR_HELPER(float, ::android::gralloc4::decodeFloat),
+ GRALLOCTYPES_DECODE_VENDOR_HELPER(double, ::android::gralloc4::decodeDouble),
+ GRALLOCTYPES_DECODE_VENDOR_HELPER(std::string, ::android::gralloc4::decodeString),
+};
// clang-format on
diff --git a/libs/gralloc/types/fuzzer/gralloctypes.h b/libs/gralloc/types/fuzzer/gralloctypes.h
index b995fce..a3fe2d9 100644
--- a/libs/gralloc/types/fuzzer/gralloctypes.h
+++ b/libs/gralloc/types/fuzzer/gralloctypes.h
@@ -20,6 +20,8 @@
#include <vector>
-using GrallocTypesDecode = std::function<void(const ::android::hardware::hidl_vec<uint8_t>& vec, uint8_t data)>;
+using GrallocTypesDecode = std::function<void(const ::android::hardware::hidl_vec<uint8_t>& vec)>;
+using GrallocTypesVendorHelperDecode = std::function<void(const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType&, const ::android::hardware::hidl_vec<uint8_t>& vec)>;
extern std::vector<GrallocTypesDecode> GRALLOCTYPES_DECODE_FUNCTIONS;
+extern std::vector<GrallocTypesVendorHelperDecode> GRALLOCTYPES_DECODE_VENDOR_HELPER_FUNCTIONS;
diff --git a/libs/gralloc/types/fuzzer/main.cpp b/libs/gralloc/types/fuzzer/main.cpp
index 2807878..8779fa2 100644
--- a/libs/gralloc/types/fuzzer/main.cpp
+++ b/libs/gralloc/types/fuzzer/main.cpp
@@ -24,52 +24,99 @@
#include <cstdlib>
#include <ctime>
+using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
+
void doFuzz(
- const std::vector<GrallocTypesDecode>& decodes,
- const std::vector<uint8_t>& input,
- const std::vector<uint8_t>& instructions) {
+ const std::vector<GrallocTypesDecode>& decodes, uint8_t instruction,
+ const std::vector<uint8_t>& input) {
::android::hardware::hidl_vec<uint8_t> vec;
vec.setToExternal(const_cast<uint8_t*>(input.data()), input.size(), false /*shouldOwn*/);
// since we are only using a byte to index
CHECK(decodes.size() <= 255) << decodes.size();
+ uint8_t decodeIdx = instruction % decodes.size();
- for (size_t i = 0; i < instructions.size() - 1; i += 2) {
- uint8_t a = instructions[i];
- uint8_t decodeIdx = a % decodes.size();
+ FUZZ_LOG() << "Instruction: " << instruction << " idx: " << static_cast<size_t>(decodeIdx)
+ << " size: " << vec.size();
- uint8_t b = instructions[i + 1];
+ decodes[decodeIdx](vec);
+}
- FUZZ_LOG() << "Instruction: " << (i / 2) + 1 << "/" << instructions.size() / 2
- << " cmd: " << static_cast<size_t>(a) << " (" << static_cast<size_t>(decodeIdx)
- << ") arg: " << static_cast<size_t>(b) << " size: " << vec.size();
+size_t fillInMetadataType(const std::vector<uint8_t>& input, MetadataType* outMetadataType) {
+ if (input.size() < sizeof(outMetadataType->value) + 1) {
+ return 0;
+ }
+ size_t size = 0;
- decodes[decodeIdx](vec, b);
+ outMetadataType->value = *(reinterpret_cast<const int64_t*>(input.data()));
+ size += sizeof(outMetadataType->value);
+
+ uint8_t nameLen = *(input.data() + size);
+ size += 1;
+
+ if (input.size() < size + nameLen) {
+ return 0;
+ }
+ std::string name(reinterpret_cast<const char*>(input.data()) + size, nameLen);
+ outMetadataType->name = name;
+ return size + nameLen;
+}
+
+void doFuzzVendorHelper(
+ const std::vector<GrallocTypesVendorHelperDecode>& decodes, uint8_t instruction,
+ const std::vector<uint8_t>& input) {
+
+ MetadataType metadataType;
+ size_t sizeUsed = fillInMetadataType(input, &metadataType);
+ if (sizeUsed <= 0) {
+ return;
+ }
+
+ ::android::hardware::hidl_vec<uint8_t> vec;
+ vec.setToExternal(const_cast<uint8_t*>(input.data() + sizeUsed), input.size() - sizeUsed,
+ false /*shouldOwn*/);
+
+ // since we are only using a byte to index
+ CHECK(decodes.size() <= 255) << decodes.size();
+ uint8_t decodeIdx = instruction % decodes.size();
+
+ FUZZ_LOG() << "Vendor Helper instruction: " << instruction << " idx: "
+ << static_cast<size_t>(decodeIdx) << " size: " << vec.size();
+
+ decodes[decodeIdx](metadataType, vec);
+}
+
+void fuzz(uint8_t options, uint8_t instruction, const std::vector<uint8_t>& input) {
+ uint8_t option = options & 0x1;
+
+ switch (option) {
+ case 0x0:
+ doFuzz(GRALLOCTYPES_DECODE_FUNCTIONS, instruction, input);
+ break;
+ case 0x1:
+ doFuzzVendorHelper(GRALLOCTYPES_DECODE_VENDOR_HELPER_FUNCTIONS, instruction, input);
+ break;
+ default:
+ LOG_ALWAYS_FATAL("unknown gralloc types %d", static_cast<int>(option));
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size <= 1) return 0; // no use
- // data to fill out parcel
- size_t inputLen = size / 2;
- std::vector<uint8_t> input(data, data + inputLen);
- data += inputLen;
- size -= inputLen;
+ uint8_t options = *data;
+ data++;
+ size--;
- // data to use to determine what to do
- size_t instructionLen = size;
- std::vector<uint8_t> instructions(data, data + instructionLen);
- data += instructionLen;
- size -= instructionLen;
+ uint8_t instruction = *data;
+ data++;
+ size--;
- CHECK(size == 0) << "size: " << size;
+ std::vector<uint8_t> input(data, data + size);
- FUZZ_LOG() << "inputLen: " << inputLen << " instructionLen: " << instructionLen;
FUZZ_LOG() << "input: " << hexString(input);
- FUZZ_LOG() << "instructions: " << hexString(instructions);
- doFuzz(GRALLOCTYPES_DECODE_FUNCTIONS, input, instructions);
+ fuzz(options, instruction, input);
return 0;
}
diff --git a/libs/gralloc/types/include/gralloctypes/Gralloc4.h b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
index 61c9f1c..ca0d4b5 100644
--- a/libs/gralloc/types/include/gralloctypes/Gralloc4.h
+++ b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
@@ -489,6 +489,58 @@
std::optional<std::vector<uint8_t>>* outSmpte2094_40);
/**
+ * The functions below can be used to encode and decode vendor metadata types.
+ */
+status_t encodeUint32(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ uint32_t input, android::hardware::hidl_vec<uint8_t>* output);
+status_t decodeUint32(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ const android::hardware::hidl_vec<uint8_t>& input, uint32_t* output);
+
+status_t encodeInt32(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ int32_t input, android::hardware::hidl_vec<uint8_t>* output);
+status_t decodeInt32(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ const android::hardware::hidl_vec<uint8_t>& input, int32_t* output);
+
+status_t encodeUint64(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ uint64_t input, android::hardware::hidl_vec<uint8_t>* output);
+status_t decodeUint64(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ const android::hardware::hidl_vec<uint8_t>& input, uint64_t* output);
+
+status_t encodeInt64(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ int64_t input, android::hardware::hidl_vec<uint8_t>* output);
+status_t decodeInt64(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ const android::hardware::hidl_vec<uint8_t>& input, int64_t* output);
+
+status_t encodeFloat(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ float input, android::hardware::hidl_vec<uint8_t>* output);
+status_t decodeFloat(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ const android::hardware::hidl_vec<uint8_t>& input, float* output);
+
+status_t encodeDouble(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ double input, android::hardware::hidl_vec<uint8_t>* output);
+status_t decodeDouble(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ const android::hardware::hidl_vec<uint8_t>& input, double* output);
+
+status_t encodeString(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ const std::string& input, android::hardware::hidl_vec<uint8_t>* output);
+status_t decodeString(
+ const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+ const android::hardware::hidl_vec<uint8_t>& input, std::string* output);
+
+/**
* The functions below can be used to parse extendable types.
*/
bool isStandardMetadataType(
diff --git a/libs/gralloc/types/tests/Gralloc4_test.cpp b/libs/gralloc/types/tests/Gralloc4_test.cpp
index d036da1..3542ed9 100644
--- a/libs/gralloc/types/tests/Gralloc4_test.cpp
+++ b/libs/gralloc/types/tests/Gralloc4_test.cpp
@@ -41,6 +41,8 @@
using aidl::android::hardware::graphics::common::StandardMetadataType;
using aidl::android::hardware::graphics::common::XyColor;
+using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
+
namespace android {
template<class T>
@@ -50,12 +52,21 @@
using EncodeConstFunction = status_t(*)(const T&, hidl_vec<uint8_t>*);
template<class T>
+using EncodeMetadataTypeFunction = status_t(*)(const MetadataType&, T, hidl_vec<uint8_t>*);
+
+template<class T>
+using EncodeMetadataTypeConstFunction = status_t(*)(const MetadataType&, const T&, hidl_vec<uint8_t>*);
+
+template<class T>
using EncodeOptionalFunction = status_t(*)(const std::optional<T>&, hidl_vec<uint8_t>*);
template<class T>
using DecodeFunction = status_t(*)(const hidl_vec<uint8_t>&, T*);
template<class T>
+using DecodeMetadataTypeFunction = status_t(*)(const MetadataType&, const hidl_vec<uint8_t>&, T*);
+
+template<class T>
using DecodeOptionalFunction = status_t(*)(const hidl_vec<uint8_t>&, std::optional<T>*);
template<class T>
@@ -77,6 +88,26 @@
}
template<class T>
+void testHelperMetadataType(const T& input, EncodeMetadataTypeFunction<T> encode, DecodeMetadataTypeFunction<T> decode) {
+ hidl_vec<uint8_t> vec;
+ MetadataType metadataType{"vendor.mycompanyname.graphics.common.MetadataType", 0};
+ T output;
+ ASSERT_EQ(NO_ERROR, encode(metadataType, input, &vec));
+ ASSERT_EQ(NO_ERROR, decode(metadataType, vec, &output));
+ ASSERT_EQ(input, output);
+}
+
+template<class T>
+void testHelperMetadataTypeConst(const T& input, EncodeMetadataTypeConstFunction<T> encode, DecodeMetadataTypeFunction<T> decode) {
+ hidl_vec<uint8_t> vec;
+ MetadataType metadataType{"vendor.mycompanyname.graphics.common.MetadataType", 0};
+ T output;
+ ASSERT_EQ(NO_ERROR, encode(metadataType, input, &vec));
+ ASSERT_EQ(NO_ERROR, decode(metadataType, vec, &output));
+ ASSERT_EQ(input, output);
+}
+
+template<class T>
void testHelperStableAidlType(const T& input, EncodeConstFunction<T> encode, DecodeFunction<T> decode) {
hidl_vec<uint8_t> vec;
T output;
@@ -100,6 +131,32 @@
ASSERT_TRUE(*tmp == *output);
}
+class Gralloc4TestUint32 : public testing::TestWithParam<uint32_t> { };
+
+INSTANTIATE_TEST_CASE_P(
+ Gralloc4TestUint32Params, Gralloc4TestUint32,
+ ::testing::Values(0, -1, 1, 5, 100, 0xFF, std::numeric_limits<uint32_t>::min(),
+ std::numeric_limits<uint32_t>::max()));
+
+TEST_P(Gralloc4TestUint32, Uint32) {
+ ASSERT_NO_FATAL_FAILURE(testHelperMetadataType(GetParam(), gralloc4::encodeUint32, gralloc4::decodeUint32));
+}
+
+TEST_P(Gralloc4TestUint32, PixelFormatFourCC) {
+ ASSERT_NO_FATAL_FAILURE(testHelper(GetParam(), gralloc4::encodePixelFormatFourCC, gralloc4::decodePixelFormatFourCC));
+}
+
+class Gralloc4TestInt32 : public testing::TestWithParam<int32_t> { };
+
+INSTANTIATE_TEST_CASE_P(
+ Gralloc4TestInt32Params, Gralloc4TestInt32,
+ ::testing::Values(0, 1, 5, 100, 0xFF, std::numeric_limits<int32_t>::min(),
+ std::numeric_limits<int32_t>::max()));
+
+TEST_P(Gralloc4TestInt32, Int32) {
+ ASSERT_NO_FATAL_FAILURE(testHelperMetadataType(GetParam(), gralloc4::encodeInt32, gralloc4::decodeInt32));
+}
+
class Gralloc4TestUint64 : public testing::TestWithParam<uint64_t> { };
INSTANTIATE_TEST_CASE_P(
@@ -107,6 +164,10 @@
::testing::Values(0, -1, 1, 5, 100, 0xFF, std::numeric_limits<uint64_t>::min(),
std::numeric_limits<uint64_t>::max()));
+TEST_P(Gralloc4TestUint64, Uint64) {
+ ASSERT_NO_FATAL_FAILURE(testHelperMetadataType(GetParam(), gralloc4::encodeUint64, gralloc4::decodeUint64));
+}
+
TEST_P(Gralloc4TestUint64, BufferId) {
ASSERT_NO_FATAL_FAILURE(testHelper(GetParam(), gralloc4::encodeBufferId, gralloc4::decodeBufferId));
}
@@ -139,25 +200,51 @@
ASSERT_NO_FATAL_FAILURE(testHelper(GetParam(), gralloc4::encodeProtectedContent, gralloc4::decodeProtectedContent));
}
+class Gralloc4TestInt64 : public testing::TestWithParam<int64_t> { };
+
+INSTANTIATE_TEST_CASE_P(
+ Gralloc4TestInt64Params, Gralloc4TestInt64,
+ ::testing::Values(0, 1, 5, 100, 0xFF, std::numeric_limits<int64_t>::min(),
+ std::numeric_limits<int64_t>::max()));
+
+TEST_P(Gralloc4TestInt64, Int64) {
+ ASSERT_NO_FATAL_FAILURE(testHelperMetadataType(GetParam(), gralloc4::encodeInt64, gralloc4::decodeInt64));
+}
+
+class Gralloc4TestFloat : public testing::TestWithParam<float> { };
+
+INSTANTIATE_TEST_CASE_P(
+ Gralloc4TestFloatParams, Gralloc4TestFloat,
+ ::testing::Values(0.0, 1.999999, 5.5, 100.1, 1234.5678, std::numeric_limits<float>::min(),
+ std::numeric_limits<float>::max()));
+
+TEST_P(Gralloc4TestFloat, Float) {
+ ASSERT_NO_FATAL_FAILURE(testHelperMetadataType(GetParam(), gralloc4::encodeFloat, gralloc4::decodeFloat));
+}
+
+class Gralloc4TestDouble : public testing::TestWithParam<double> { };
+
+INSTANTIATE_TEST_CASE_P(
+ Gralloc4TestDoubleParams, Gralloc4TestDouble,
+ ::testing::Values(0.0, 1.999999, 5.5, 100.1, 1234.5678, std::numeric_limits<double>::min(),
+ std::numeric_limits<double>::max()));
+
+TEST_P(Gralloc4TestDouble, Double) {
+ ASSERT_NO_FATAL_FAILURE(testHelperMetadataType(GetParam(), gralloc4::encodeDouble, gralloc4::decodeDouble));
+}
+
class Gralloc4TestString : public testing::TestWithParam<std::string> { };
INSTANTIATE_TEST_CASE_P(
Gralloc4TestStringParams, Gralloc4TestString,
::testing::Values("name", "aaaaa", "", "abcdefghijklmnopqrstuvwxyz", "0xFF"));
-TEST_P(Gralloc4TestString, Name) {
- ASSERT_NO_FATAL_FAILURE(testHelperConst(GetParam(), gralloc4::encodeName, gralloc4::decodeName));
+TEST_P(Gralloc4TestString, String) {
+ ASSERT_NO_FATAL_FAILURE(testHelperMetadataTypeConst(GetParam(), gralloc4::encodeString, gralloc4::decodeString));
}
-class Gralloc4TestUint32 : public testing::TestWithParam<uint32_t> { };
-
-INSTANTIATE_TEST_CASE_P(
- Gralloc4TestUint32Params, Gralloc4TestUint32,
- ::testing::Values(0, 1, 5, 100, 0xFF, std::numeric_limits<uint32_t>::min(),
- std::numeric_limits<uint32_t>::max()));
-
-TEST_P(Gralloc4TestUint32, PixelFormatFourCC) {
- ASSERT_NO_FATAL_FAILURE(testHelper(GetParam(), gralloc4::encodePixelFormatFourCC, gralloc4::decodePixelFormatFourCC));
+TEST_P(Gralloc4TestString, Name) {
+ ASSERT_NO_FATAL_FAILURE(testHelperConst(GetParam(), gralloc4::encodeName, gralloc4::decodeName));
}
class Gralloc4TestPixelFormat : public testing::TestWithParam<PixelFormat> { };