gralloc: add gralloc4 HDR metadata support

Add the ability to get and set HDR metadata.

Bug: 141632767
Test: VtsHalGraphicsMapperV4_0TargetTest
Change-Id: I2fb06eb0bb43d2a5689228f3bd3b76e904d647b6
diff --git a/libs/gralloc/types/Gralloc4.cpp b/libs/gralloc/types/Gralloc4.cpp
index b762f1e..d02e839 100644
--- a/libs/gralloc/types/Gralloc4.cpp
+++ b/libs/gralloc/types/Gralloc4.cpp
@@ -28,6 +28,7 @@
 using aidl::android::hardware::graphics::common::BlendMode;
 using aidl::android::hardware::graphics::common::ChromaSiting;
 using aidl::android::hardware::graphics::common::Compression;
+using aidl::android::hardware::graphics::common::Cta861_3;
 using aidl::android::hardware::graphics::common::Dataspace;
 using aidl::android::hardware::graphics::common::ExtendableType;
 using aidl::android::hardware::graphics::common::Interlaced;
@@ -35,7 +36,9 @@
 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
 using aidl::android::hardware::graphics::common::Rect;
+using aidl::android::hardware::graphics::common::Smpte2086;
 using aidl::android::hardware::graphics::common::StandardMetadataType;
+using aidl::android::hardware::graphics::common::XyColor;
 
 using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
 
@@ -154,6 +157,13 @@
         return mVec->size() > mOffset;
     }
 
+    size_t getRemainingSize() {
+        if (!mVec) {
+            return 0;
+        }
+        return mVec->size() - mOffset;
+    }
+
 private:
     const hidl_vec<uint8_t>* mVec;
     size_t mOffset = 0;
@@ -218,6 +228,15 @@
     return encodeHelper(input, &outputHidlVec);
 }
 
+template <class T>
+status_t encodeOptional(const MetadataType& metadataType, const std::optional<T>& input,
+                        hidl_vec<uint8_t>* output, EncodeHelper<T> encodeHelper) {
+    if (!input) {
+        return NO_ERROR;
+    }
+    return encode(metadataType, *input, output, encodeHelper);
+}
+
 /**
  * decode is the main decode function. It takes in a hidl_vec and uses the decodeHelper function to
  * turn the hidl_vec byte stream into T. If an error occurs, the errorHandler function cleans up
@@ -249,13 +268,32 @@
     return NO_ERROR;
 }
 
+template <class T>
+status_t decodeOptional(const MetadataType& metadataType, const hidl_vec<uint8_t>& input,
+                        std::optional<T>* output, DecodeHelper<T> decodeHelper) {
+    if (!output) {
+        return BAD_VALUE;
+    }
+    if (input.size() <= 0) {
+        output->reset();
+        return NO_ERROR;
+    }
+    T tmp;
+    status_t err = decode(metadataType, input, &tmp, decodeHelper);
+    if (!err) {
+        *output = tmp;
+    }
+    return err;
+}
+
 /**
  * Private helper functions
  */
 template <class T>
 status_t encodeInteger(const T& input, OutputHidlVec* output) {
     static_assert(std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
-                  std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value);
+                  std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
+                  std::is_same<T, float>::value || std::is_same<T, double>::value);
     if (!output) {
         return BAD_VALUE;
     }
@@ -267,7 +305,8 @@
 template <class T>
 status_t decodeInteger(InputHidlVec* input, T* output) {
     static_assert(std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
-                  std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value);
+                  std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
+                  std::is_same<T, float>::value || std::is_same<T, double>::value);
     if (!output) {
         return BAD_VALUE;
     }
@@ -306,6 +345,38 @@
     return input->decode(output, size);
 }
 
+status_t encodeByteVector(const std::vector<uint8_t>& input, OutputHidlVec* output) {
+    if (!output) {
+        return BAD_VALUE;
+    }
+
+    status_t err = encodeInteger<int64_t>(input.size(), output);
+    if (err) {
+        return err;
+    }
+
+    return output->encode(input.data(), input.size());
+}
+
+status_t decodeByteVector(InputHidlVec* input, std::vector<uint8_t>* output) {
+    if (!output) {
+        return BAD_VALUE;
+    }
+
+    int64_t size = 0;
+    status_t err = decodeInteger<int64_t>(input, &size);
+    if (err || size < 0) {
+        return err;
+    }
+
+    if (size > input->getRemainingSize()) {
+        return BAD_VALUE;
+    }
+    output->resize(size);
+
+    return input->decode(output->data(), size);
+}
+
 status_t encodeExtendableType(const ExtendableType& input, OutputHidlVec* output) {
     status_t err = encodeString(input.name, output);
     if (err) {
@@ -391,6 +462,30 @@
     return NO_ERROR;
 }
 
+status_t encodeXyColor(const XyColor& input, OutputHidlVec* output) {
+    status_t err = encodeInteger<float>(input.x, output);
+    if (err) {
+        return err;
+    }
+    return encodeInteger<float>(input.y, output);
+}
+
+status_t decodeXyColor(InputHidlVec* input, XyColor* output) {
+    status_t err = decodeInteger<float>(input, &output->x);
+    if (err) {
+        return err;
+    }
+    return decodeInteger<float>(input, &output->y);
+}
+
+void clearXyColor(XyColor* output) {
+    if (!output) {
+        return;
+    }
+    output->x = 0;
+    output->y = 0;
+}
+
 status_t encodeRect(const Rect& input, OutputHidlVec* output) {
     status_t err = encodeInteger<int32_t>(static_cast<int32_t>(input.left), output);
     if (err) {
@@ -635,6 +730,70 @@
     output->clear();
 }
 
+status_t encodeSmpte2086Helper(const Smpte2086& smpte2086, OutputHidlVec* outOutputHidlVec) {
+    status_t err = encodeXyColor(smpte2086.primaryRed, outOutputHidlVec);
+    if (err) {
+        return err;
+    }
+    err = encodeXyColor(smpte2086.primaryGreen, outOutputHidlVec);
+    if (err) {
+        return err;
+    }
+    err = encodeXyColor(smpte2086.primaryBlue, outOutputHidlVec);
+    if (err) {
+        return err;
+    }
+    err = encodeXyColor(smpte2086.whitePoint, outOutputHidlVec);
+    if (err) {
+        return err;
+    }
+    err = encodeInteger<float>(smpte2086.maxLuminance, outOutputHidlVec);
+    if (err) {
+        return err;
+    }
+    return encodeInteger<float>(smpte2086.minLuminance, outOutputHidlVec);
+}
+
+status_t decodeSmpte2086Helper(InputHidlVec* inputHidlVec, Smpte2086* outSmpte2086) {
+    status_t err = decodeXyColor(inputHidlVec, &outSmpte2086->primaryRed);
+    if (err) {
+        return err;
+    }
+    err = decodeXyColor(inputHidlVec, &outSmpte2086->primaryGreen);
+    if (err) {
+        return err;
+    }
+    err = decodeXyColor(inputHidlVec, &outSmpte2086->primaryBlue);
+    if (err) {
+        return err;
+    }
+    err = decodeXyColor(inputHidlVec, &outSmpte2086->whitePoint);
+    if (err) {
+        return err;
+    }
+    err = decodeInteger<float>(inputHidlVec, &outSmpte2086->maxLuminance);
+    if (err) {
+        return err;
+    }
+    return decodeInteger<float>(inputHidlVec, &outSmpte2086->minLuminance);
+}
+
+status_t encodeCta861_3Helper(const Cta861_3& cta861_3, OutputHidlVec* outOutputHidlVec) {
+    status_t err = encodeInteger<float>(cta861_3.maxContentLightLevel, outOutputHidlVec);
+    if (err) {
+        return err;
+    }
+    return encodeInteger<float>(cta861_3.maxFrameAverageLightLevel, outOutputHidlVec);
+}
+
+status_t decodeCta861_3Helper(InputHidlVec* inputHidlVec, Cta861_3* outCta861_3) {
+    status_t err = decodeInteger<float>(inputHidlVec, &outCta861_3->maxContentLightLevel);
+    if (err) {
+        return err;
+    }
+    return decodeInteger<float>(inputHidlVec, &outCta861_3->maxFrameAverageLightLevel);
+}
+
 /**
  * Public API functions
  */
@@ -798,6 +957,36 @@
                   decodeInteger);
 }
 
+status_t encodeSmpte2086(const std::optional<Smpte2086>& smpte2086,
+                         hidl_vec<uint8_t>* outSmpte2086) {
+    return encodeOptional(MetadataType_Smpte2086, smpte2086, outSmpte2086, encodeSmpte2086Helper);
+}
+
+status_t decodeSmpte2086(const hidl_vec<uint8_t>& smpte2086,
+                         std::optional<Smpte2086>* outSmpte2086) {
+    return decodeOptional(MetadataType_Smpte2086, smpte2086, outSmpte2086, decodeSmpte2086Helper);
+}
+
+status_t encodeCta861_3(const std::optional<Cta861_3>& cta861_3, hidl_vec<uint8_t>* outCta861_3) {
+    return encodeOptional(MetadataType_Cta861_3, cta861_3, outCta861_3, encodeCta861_3Helper);
+}
+
+status_t decodeCta861_3(const hidl_vec<uint8_t>& cta861_3, std::optional<Cta861_3>* outCta861_3) {
+    return decodeOptional(MetadataType_Cta861_3, cta861_3, outCta861_3, decodeCta861_3Helper);
+}
+
+status_t encodeSmpte2094_40(const std::optional<std::vector<uint8_t>>& smpte2094_40,
+                            hidl_vec<uint8_t>* outSmpte2094_40) {
+    return encodeOptional(MetadataType_Smpte2094_40, smpte2094_40, outSmpte2094_40,
+                          encodeByteVector);
+}
+
+status_t decodeSmpte2094_40(const hidl_vec<uint8_t>& smpte2094_40,
+                            std::optional<std::vector<uint8_t>>* outSmpte2094_40) {
+    return decodeOptional(MetadataType_Smpte2094_40, smpte2094_40, outSmpte2094_40,
+                          decodeByteVector);
+}
+
 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 23c90b8..da8cf97 100644
--- a/libs/gralloc/types/fuzzer/gralloctypes.cpp
+++ b/libs/gralloc/types/fuzzer/gralloctypes.cpp
@@ -60,5 +60,8 @@
     GRALLOCTYPES_DECODE(std::vector<aidl::android::hardware::graphics::common::PlaneLayout>, ::android::gralloc4::decodePlaneLayouts),
     GRALLOCTYPES_DECODE(aidl::android::hardware::graphics::common::Dataspace, ::android::gralloc4::decodeDataspace),
     GRALLOCTYPES_DECODE(aidl::android::hardware::graphics::common::BlendMode, ::android::gralloc4::decodeBlendMode),
+    GRALLOCTYPES_DECODE(std::optional<aidl::android::hardware::graphics::common::Smpte2086>, ::android::gralloc4::decodeSmpte2086),
+    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),
 };
 // clang-format on
diff --git a/libs/gralloc/types/include/gralloctypes/Gralloc4.h b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
index a5d3bb2..94de8f1 100644
--- a/libs/gralloc/types/include/gralloctypes/Gralloc4.h
+++ b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
@@ -17,16 +17,17 @@
 #pragma once
 
 #include <aidl/android/hardware/graphics/common/BlendMode.h>
+#include <aidl/android/hardware/graphics/common/ChromaSiting.h>
+#include <aidl/android/hardware/graphics/common/Compression.h>
+#include <aidl/android/hardware/graphics/common/Cta861_3.h>
 #include <aidl/android/hardware/graphics/common/Dataspace.h>
 #include <aidl/android/hardware/graphics/common/ExtendableType.h>
 #include <aidl/android/hardware/graphics/common/Interlaced.h>
 #include <aidl/android/hardware/graphics/common/PlaneLayout.h>
-#include <aidl/android/hardware/graphics/common/ChromaSiting.h>
-#include <aidl/android/hardware/graphics/common/Compression.h>
-#include <aidl/android/hardware/graphics/common/Interlaced.h>
-#include <aidl/android/hardware/graphics/common/StandardMetadataType.h>
 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
-
+#include <aidl/android/hardware/graphics/common/Smpte2086.h>
+#include <aidl/android/hardware/graphics/common/StandardMetadataType.h>
+#include <aidl/android/hardware/graphics/common/XyColor.h>
 #include <android/hardware/graphics/mapper/4.0/IMapper.h>
 
 namespace android {
@@ -113,6 +114,22 @@
         GRALLOC4_STANDARD_METADATA_TYPE, static_cast<int64_t>(aidl::android::hardware::graphics::common::StandardMetadataType::BLEND_MODE)
 };
 
+static const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType
+        MetadataType_Smpte2086 = {GRALLOC4_STANDARD_METADATA_TYPE,
+                                  static_cast<int64_t>(aidl::android::hardware::graphics::common::
+                                                               StandardMetadataType::SMPTE2086)};
+
+static const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType
+        MetadataType_Cta861_3 = {GRALLOC4_STANDARD_METADATA_TYPE,
+                                 static_cast<int64_t>(aidl::android::hardware::graphics::common::
+                                                              StandardMetadataType::CTA861_3)};
+
+static const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType
+        MetadataType_Smpte2094_40 = {GRALLOC4_STANDARD_METADATA_TYPE,
+                                     static_cast<int64_t>(
+                                             aidl::android::hardware::graphics::common::
+                                                     StandardMetadataType::SMPTE2094_40)};
+
 /*---------------------------------------------------------------------------------------------*/
 
 /**
@@ -272,6 +289,25 @@
 status_t encodeBlendMode(const aidl::android::hardware::graphics::common::BlendMode& blendMode, android::hardware::hidl_vec<uint8_t>* outBlendMode);
 status_t decodeBlendMode(const android::hardware::hidl_vec<uint8_t>& blendMode, aidl::android::hardware::graphics::common::BlendMode* outBlendMode);
 
+status_t encodeSmpte2086(
+        const std::optional<aidl::android::hardware::graphics::common::Smpte2086>& smpte2086,
+        android::hardware::hidl_vec<uint8_t>* outSmpte2086);
+status_t decodeSmpte2086(
+        const android::hardware::hidl_vec<uint8_t>& smpte2086,
+        std::optional<aidl::android::hardware::graphics::common::Smpte2086>* outSmpte2086);
+
+status_t encodeCta861_3(
+        const std::optional<aidl::android::hardware::graphics::common::Cta861_3>& cta861_3,
+        android::hardware::hidl_vec<uint8_t>* outCta861_3);
+status_t decodeCta861_3(
+        const android::hardware::hidl_vec<uint8_t>& cta861_3,
+        std::optional<aidl::android::hardware::graphics::common::Cta861_3>* outCta861_3);
+
+status_t encodeSmpte2094_40(const std::optional<std::vector<uint8_t>>& smpte2094_40,
+                            android::hardware::hidl_vec<uint8_t>* outSmpte2094_40);
+status_t decodeSmpte2094_40(const android::hardware::hidl_vec<uint8_t>& smpte2094_40,
+                            std::optional<std::vector<uint8_t>>* outSmpte2094_40);
+
 /**
  * The functions below can be used to parse extendable types.
  */
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index 2c897cf..30c48c8 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -614,6 +614,24 @@
                outBlendMode);
 }
 
+status_t Gralloc4Mapper::getSmpte2086(buffer_handle_t bufferHandle,
+                                      std::optional<ui::Smpte2086>* outSmpte2086) const {
+    return get(bufferHandle, gralloc4::MetadataType_Smpte2086, gralloc4::decodeSmpte2086,
+               outSmpte2086);
+}
+
+status_t Gralloc4Mapper::getCta861_3(buffer_handle_t bufferHandle,
+                                     std::optional<ui::Cta861_3>* outCta861_3) const {
+    return get(bufferHandle, gralloc4::MetadataType_Cta861_3, gralloc4::decodeCta861_3,
+               outCta861_3);
+}
+
+status_t Gralloc4Mapper::getSmpte2094_40(
+        buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_40) const {
+    return get(bufferHandle, gralloc4::MetadataType_Smpte2094_40, gralloc4::decodeSmpte2094_40,
+               outSmpte2094_40);
+}
+
 template <class T>
 status_t Gralloc4Mapper::getDefault(uint32_t width, uint32_t height, PixelFormat format,
                                     uint32_t layerCount, uint64_t usage,
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 8540fd3..d20bd7a 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -286,6 +286,21 @@
     return mMapper->getBlendMode(bufferHandle, outBlendMode);
 }
 
+status_t GraphicBufferMapper::getSmpte2086(buffer_handle_t bufferHandle,
+                                           std::optional<ui::Smpte2086>* outSmpte2086) {
+    return mMapper->getSmpte2086(bufferHandle, outSmpte2086);
+}
+
+status_t GraphicBufferMapper::getCta861_3(buffer_handle_t bufferHandle,
+                                          std::optional<ui::Cta861_3>* outCta861_3) {
+    return mMapper->getCta861_3(bufferHandle, outCta861_3);
+}
+
+status_t GraphicBufferMapper::getSmpte2094_40(
+        buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_40) {
+    return mMapper->getSmpte2094_40(bufferHandle, outSmpte2094_40);
+}
+
 status_t GraphicBufferMapper::getDefaultPixelFormatFourCC(uint32_t width, uint32_t height,
                                                           PixelFormat format, uint32_t layerCount,
                                                           uint64_t usage,
diff --git a/libs/ui/include/ui/Gralloc.h b/libs/ui/include/ui/Gralloc.h
index fcd959c..e199648 100644
--- a/libs/ui/include/ui/Gralloc.h
+++ b/libs/ui/include/ui/Gralloc.h
@@ -165,6 +165,19 @@
                                   ui::BlendMode* /*outBlendMode*/) const {
         return INVALID_OPERATION;
     }
+    virtual status_t getSmpte2086(buffer_handle_t /*bufferHandle*/,
+                                  std::optional<ui::Smpte2086>* /*outSmpte2086*/) const {
+        return INVALID_OPERATION;
+    }
+    virtual status_t getCta861_3(buffer_handle_t /*bufferHandle*/,
+                                 std::optional<ui::Cta861_3>* /*outCta861_3*/) const {
+        return INVALID_OPERATION;
+    }
+    virtual status_t getSmpte2094_40(
+            buffer_handle_t /*bufferHandle*/,
+            std::optional<std::vector<uint8_t>>* /*outSmpte2094_40*/) const {
+        return INVALID_OPERATION;
+    }
 
     virtual status_t getDefaultPixelFormatFourCC(uint32_t /*width*/, uint32_t /*height*/,
                                                  PixelFormat /*format*/, uint32_t /*layerCount*/,
diff --git a/libs/ui/include/ui/Gralloc4.h b/libs/ui/include/ui/Gralloc4.h
index af7c076..4729cba 100644
--- a/libs/ui/include/ui/Gralloc4.h
+++ b/libs/ui/include/ui/Gralloc4.h
@@ -102,6 +102,12 @@
                              std::vector<ui::PlaneLayout>* outPlaneLayouts) const override;
     status_t getDataspace(buffer_handle_t bufferHandle, ui::Dataspace* outDataspace) const override;
     status_t getBlendMode(buffer_handle_t bufferHandle, ui::BlendMode* outBlendMode) const override;
+    status_t getSmpte2086(buffer_handle_t bufferHandle,
+                          std::optional<ui::Smpte2086>* outSmpte2086) const override;
+    status_t getCta861_3(buffer_handle_t bufferHandle,
+                         std::optional<ui::Cta861_3>* outCta861_3) const override;
+    status_t getSmpte2094_40(buffer_handle_t bufferHandle,
+                             std::optional<std::vector<uint8_t>>* outSmpte2094_40) const override;
 
     status_t getDefaultPixelFormatFourCC(uint32_t width, uint32_t height, PixelFormat format,
                                          uint32_t layerCount, uint64_t usage,
diff --git a/libs/ui/include/ui/GraphicBufferMapper.h b/libs/ui/include/ui/GraphicBufferMapper.h
index 77c00ae..837e3d8 100644
--- a/libs/ui/include/ui/GraphicBufferMapper.h
+++ b/libs/ui/include/ui/GraphicBufferMapper.h
@@ -122,6 +122,10 @@
                              std::vector<ui::PlaneLayout>* outPlaneLayouts);
     status_t getDataspace(buffer_handle_t bufferHandle, ui::Dataspace* outDataspace);
     status_t getBlendMode(buffer_handle_t bufferHandle, ui::BlendMode* outBlendMode);
+    status_t getSmpte2086(buffer_handle_t bufferHandle, std::optional<ui::Smpte2086>* outSmpte2086);
+    status_t getCta861_3(buffer_handle_t bufferHandle, std::optional<ui::Cta861_3>* outCta861_3);
+    status_t getSmpte2094_40(buffer_handle_t bufferHandle,
+                             std::optional<std::vector<uint8_t>>* outSmpte2094_40);
 
     /**
      * Gets the default metadata for a gralloc buffer allocated with the given parameters.
diff --git a/libs/ui/include/ui/GraphicTypes.h b/libs/ui/include/ui/GraphicTypes.h
index ad5ee80..4bdacb0 100644
--- a/libs/ui/include/ui/GraphicTypes.h
+++ b/libs/ui/include/ui/GraphicTypes.h
@@ -19,8 +19,10 @@
 #include <aidl/android/hardware/graphics/common/BlendMode.h>
 #include <aidl/android/hardware/graphics/common/ChromaSiting.h>
 #include <aidl/android/hardware/graphics/common/Compression.h>
+#include <aidl/android/hardware/graphics/common/Cta861_3.h>
 #include <aidl/android/hardware/graphics/common/Interlaced.h>
 #include <aidl/android/hardware/graphics/common/PlaneLayout.h>
+#include <aidl/android/hardware/graphics/common/Smpte2086.h>
 #include <android/hardware/graphics/common/1.1/types.h>
 #include <android/hardware/graphics/common/1.2/types.h>
 #include <system/graphics.h>
@@ -47,7 +49,9 @@
  * Stable AIDL types
  */
 using aidl::android::hardware::graphics::common::BlendMode;
+using aidl::android::hardware::graphics::common::Cta861_3;
 using aidl::android::hardware::graphics::common::PlaneLayout;
+using aidl::android::hardware::graphics::common::Smpte2086;
 
 /**
  * The following stable AIDL types below have standard platform definitions