Merge "FTL: Pull Flags into namespace" into tm-dev
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 53c7f5a..f7cd5c4 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -134,6 +134,7 @@
     SAFE_PARCEL(output.writeByte, changeFrameRateStrategy);
     SAFE_PARCEL(output.writeUint32, fixedTransformHint);
     SAFE_PARCEL(output.writeBool, autoRefresh);
+    SAFE_PARCEL(output.writeBool, dimmingEnabled);
 
     SAFE_PARCEL(output.writeUint32, blurRegions.size());
     for (auto region : blurRegions) {
@@ -243,6 +244,7 @@
     SAFE_PARCEL(input.readUint32, &tmpUint32);
     fixedTransformHint = static_cast<ui::Transform::RotationFlags>(tmpUint32);
     SAFE_PARCEL(input.readBool, &autoRefresh);
+    SAFE_PARCEL(input.readBool, &dimmingEnabled);
 
     uint32_t numRegions = 0;
     SAFE_PARCEL(input.readUint32, &numRegions);
@@ -598,6 +600,10 @@
         what |= eColorSpaceAgnosticChanged;
         colorSpaceAgnostic = other.colorSpaceAgnostic;
     }
+    if (other.what & eDimmingEnabledChanged) {
+        what |= eDimmingEnabledChanged;
+        dimmingEnabled = other.dimmingEnabled;
+    }
     if ((other.what & what) != other.what) {
         ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
               "other.what=0x%" PRIX64 " what=0x%" PRIX64 " unmerged flags=0x%" PRIX64,
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 20c4146..1fb11e0 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1096,6 +1096,17 @@
     *out = input;
 }
 
+void Surface::applyGrallocMetadataLocked(
+        android_native_buffer_t* buffer,
+        const IGraphicBufferProducer::QueueBufferInput& queueBufferInput) {
+    ATRACE_CALL();
+    auto& mapper = GraphicBufferMapper::get();
+    mapper.setDataspace(buffer->handle, static_cast<ui::Dataspace>(queueBufferInput.dataSpace));
+    mapper.setSmpte2086(buffer->handle, queueBufferInput.getHdrMetadata().getSmpte2086());
+    mapper.setCta861_3(buffer->handle, queueBufferInput.getHdrMetadata().getCta8613());
+    mapper.setSmpte2094_40(buffer->handle, queueBufferInput.getHdrMetadata().getHdr10Plus());
+}
+
 void Surface::onBufferQueuedLocked(int slot, sp<Fence> fence,
         const IGraphicBufferProducer::QueueBufferOutput& output) {
     mDequeuedSlots.erase(slot);
@@ -1166,9 +1177,11 @@
     IGraphicBufferProducer::QueueBufferOutput output;
     IGraphicBufferProducer::QueueBufferInput input;
     getQueueBufferInputLocked(buffer, fenceFd, mTimestamp, &input);
+    applyGrallocMetadataLocked(buffer, input);
     sp<Fence> fence = input.fence;
 
     nsecs_t now = systemTime();
+
     status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
     mLastQueueDuration = systemTime() - now;
     if (err != OK)  {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 52a22a7..6c197c4 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1195,6 +1195,20 @@
     return *this;
 }
 
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDimmingEnabled(
+        const sp<SurfaceControl>& sc, bool dimmingEnabled) {
+    layer_state_t* s = getLayerState(sc);
+    if (!s) {
+        mStatus = BAD_INDEX;
+        return *this;
+    }
+    s->what |= layer_state_t::eDimmingEnabledChanged;
+    s->dimmingEnabled = dimmingEnabled;
+
+    registerSurfaceControlForCallback(sc);
+    return *this;
+}
+
 SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAlpha(
         const sp<SurfaceControl>& sc, float alpha) {
     layer_state_t* s = getLayerState(sc);
diff --git a/libs/gui/include/gui/HdrMetadata.h b/libs/gui/include/gui/HdrMetadata.h
index 0bdffac..98a07a3 100644
--- a/libs/gui/include/gui/HdrMetadata.h
+++ b/libs/gui/include/gui/HdrMetadata.h
@@ -17,6 +17,8 @@
 #pragma once
 
 #include <stdint.h>
+#include <ui/GraphicTypes.h>
+#include <optional>
 #include <vector>
 
 #include <system/graphics.h>
@@ -43,6 +45,27 @@
     status_t flatten(void* buffer, size_t size) const;
     status_t unflatten(void const* buffer, size_t size);
 
+    std::optional<ui::Smpte2086> getSmpte2086() const {
+        if (validTypes & Type::SMPTE2086) {
+            return ui::translate(smpte2086);
+        }
+        return {};
+    }
+
+    std::optional<ui::Cta861_3> getCta8613() const {
+        if (validTypes & Type::CTA861_3) {
+            return ui::translate(cta8613);
+        }
+        return {};
+    }
+
+    std::optional<std::vector<uint8_t>> getHdr10Plus() const {
+        if (validTypes & Type::HDR10PLUS) {
+            return hdr10plus;
+        }
+        return {};
+    }
+
     bool operator==(const HdrMetadata& rhs) const;
     bool operator!=(const HdrMetadata& rhs) const { return !(*this == rhs); }
 };
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index b33d4c0..0a9b75a 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -151,7 +151,7 @@
         eTransparentRegionChanged = 0x00000020,
         eFlagsChanged = 0x00000040,
         eLayerStackChanged = 0x00000080,
-        /* unused 0x00000400, */
+        eDimmingEnabledChanged = 0x00000400,
         eShadowRadiusChanged = 0x00000800,
         /* unused 0x00001000, */
         eBufferCropChanged = 0x00002000,
@@ -188,7 +188,7 @@
         eAutoRefreshChanged = 0x1000'00000000,
         eStretchChanged = 0x2000'00000000,
         eTrustedOverlayChanged = 0x4000'00000000,
-        eDropInputModeChanged = 0x8000'00000000,
+        eDropInputModeChanged = 0x8000'00000000
     };
 
     layer_state_t();
@@ -299,6 +299,8 @@
 
     // Force inputflinger to drop all input events for the layer and its children.
     gui::DropInputMode dropInputMode;
+
+    bool dimmingEnabled;
 };
 
 struct ComposerState {
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 40d096e..5fe308c 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -398,6 +398,13 @@
     void getQueueBufferInputLocked(android_native_buffer_t* buffer, int fenceFd, nsecs_t timestamp,
             IGraphicBufferProducer::QueueBufferInput* out);
 
+    // For easing in adoption of gralloc4 metadata by vendor components, as well as for supporting
+    // the public ANativeWindow api, allow setting relevant metadata when queueing a buffer through
+    // a native window
+    void applyGrallocMetadataLocked(
+            android_native_buffer_t* buffer,
+            const IGraphicBufferProducer::QueueBufferInput& queueBufferInput);
+
     void onBufferQueuedLocked(int slot, sp<Fence> fence,
             const IGraphicBufferProducer::QueueBufferOutput& output);
 
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 9d03f58..0cc43d8 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -491,6 +491,7 @@
                 uint32_t flags, uint32_t mask);
         Transaction& setTransparentRegionHint(const sp<SurfaceControl>& sc,
                 const Region& transparentRegion);
+        Transaction& setDimmingEnabled(const sp<SurfaceControl>& sc, bool dimmingEnabled);
         Transaction& setAlpha(const sp<SurfaceControl>& sc,
                 float alpha);
         Transaction& setMatrix(const sp<SurfaceControl>& sc,
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index c72ae1b..1fce31d 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -22,6 +22,7 @@
 #include <aidlcommonsupport/NativeHandle.h>
 #include <android/binder_enums.h>
 #include <android/binder_manager.h>
+#include <gralloctypes/Gralloc4.h>
 #include <hidl/ServiceManagement.h>
 #include <hwbinder/IPCThreadState.h>
 #include <ui/Gralloc4.h>
@@ -524,6 +525,37 @@
     return decodeFunction(vec, outMetadata);
 }
 
+template <class T>
+status_t Gralloc4Mapper::set(buffer_handle_t bufferHandle, const MetadataType& metadataType,
+                             const T& metadata, EncodeFunction<T> encodeFunction) const {
+    hidl_vec<uint8_t> encodedMetadata;
+    if (const status_t status = encodeFunction(metadata, &encodedMetadata); status != OK) {
+        ALOGE("Encoding metadata(%s) failed with %d", metadataType.name.c_str(), status);
+        return status;
+    }
+    hidl_vec<uint8_t> vec;
+    auto ret =
+            mMapper->set(const_cast<native_handle_t*>(bufferHandle), metadataType, encodedMetadata);
+
+    const Error error = ret.withDefault(kTransactionError);
+    switch (error) {
+        case Error::BAD_DESCRIPTOR:
+        case Error::BAD_BUFFER:
+        case Error::BAD_VALUE:
+        case Error::NO_RESOURCES:
+            ALOGE("set(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
+                  metadataType.value, error);
+            break;
+        // It is not an error to attempt to set metadata that a particular gralloc implementation
+        // happens to not support.
+        case Error::UNSUPPORTED:
+        case Error::NONE:
+            break;
+    }
+
+    return static_cast<status_t>(error);
+}
+
 status_t Gralloc4Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const {
     return get(bufferHandle, gralloc4::MetadataType_BufferId, gralloc4::decodeBufferId,
                outBufferId);
@@ -673,6 +705,12 @@
     return NO_ERROR;
 }
 
+status_t Gralloc4Mapper::setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) const {
+    return set(bufferHandle, gralloc4::MetadataType_Dataspace,
+               static_cast<aidl::android::hardware::graphics::common::Dataspace>(dataspace),
+               gralloc4::encodeDataspace);
+}
+
 status_t Gralloc4Mapper::getBlendMode(buffer_handle_t bufferHandle,
                                       ui::BlendMode* outBlendMode) const {
     return get(bufferHandle, gralloc4::MetadataType_BlendMode, gralloc4::decodeBlendMode,
@@ -685,24 +723,47 @@
                outSmpte2086);
 }
 
+status_t Gralloc4Mapper::setSmpte2086(buffer_handle_t bufferHandle,
+                                      std::optional<ui::Smpte2086> smpte2086) const {
+    return set(bufferHandle, gralloc4::MetadataType_Smpte2086, smpte2086,
+               gralloc4::encodeSmpte2086);
+}
+
 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::setCta861_3(buffer_handle_t bufferHandle,
+                                     std::optional<ui::Cta861_3> cta861_3) const {
+    return set(bufferHandle, gralloc4::MetadataType_Cta861_3, cta861_3, gralloc4::encodeCta861_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);
 }
 
+status_t Gralloc4Mapper::setSmpte2094_40(buffer_handle_t bufferHandle,
+                                         std::optional<std::vector<uint8_t>> smpte2094_40) const {
+    return set(bufferHandle, gralloc4::MetadataType_Smpte2094_40, smpte2094_40,
+               gralloc4::encodeSmpte2094_40);
+}
+
 status_t Gralloc4Mapper::getSmpte2094_10(
         buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_10) const {
     return get(bufferHandle, gralloc4::MetadataType_Smpte2094_10, gralloc4::decodeSmpte2094_10,
                outSmpte2094_10);
 }
 
+status_t Gralloc4Mapper::setSmpte2094_10(buffer_handle_t bufferHandle,
+                                         std::optional<std::vector<uint8_t>> smpte2094_10) const {
+    return set(bufferHandle, gralloc4::MetadataType_Smpte2094_10, smpte2094_10,
+               gralloc4::encodeSmpte2094_10);
+}
+
 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 82d6cd5..a98e697 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -281,6 +281,10 @@
     return mMapper->getDataspace(bufferHandle, outDataspace);
 }
 
+status_t GraphicBufferMapper::setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) {
+    return mMapper->setDataspace(bufferHandle, dataspace);
+}
+
 status_t GraphicBufferMapper::getBlendMode(buffer_handle_t bufferHandle,
                                            ui::BlendMode* outBlendMode) {
     return mMapper->getBlendMode(bufferHandle, outBlendMode);
@@ -291,21 +295,41 @@
     return mMapper->getSmpte2086(bufferHandle, outSmpte2086);
 }
 
+status_t GraphicBufferMapper::setSmpte2086(buffer_handle_t bufferHandle,
+                                           std::optional<ui::Smpte2086> smpte2086) {
+    return mMapper->setSmpte2086(bufferHandle, smpte2086);
+}
+
 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::setCta861_3(buffer_handle_t bufferHandle,
+                                          std::optional<ui::Cta861_3> cta861_3) {
+    return mMapper->setCta861_3(bufferHandle, cta861_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::setSmpte2094_40(buffer_handle_t bufferHandle,
+                                              std::optional<std::vector<uint8_t>> smpte2094_40) {
+    return mMapper->setSmpte2094_40(bufferHandle, smpte2094_40);
+}
+
 status_t GraphicBufferMapper::getSmpte2094_10(
         buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_10) {
     return mMapper->getSmpte2094_10(bufferHandle, outSmpte2094_10);
 }
 
+status_t GraphicBufferMapper::setSmpte2094_10(buffer_handle_t bufferHandle,
+                                              std::optional<std::vector<uint8_t>> smpte2094_10) {
+    return mMapper->setSmpte2094_10(bufferHandle, smpte2094_10);
+}
+
 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 753b0a6..6101d4b 100644
--- a/libs/ui/include/ui/Gralloc.h
+++ b/libs/ui/include/ui/Gralloc.h
@@ -161,6 +161,10 @@
                                   ui::Dataspace* /*outDataspace*/) const {
         return INVALID_OPERATION;
     }
+    virtual status_t setDataspace(buffer_handle_t /*bufferHandle*/,
+                                  ui::Dataspace /*dataspace*/) const {
+        return INVALID_OPERATION;
+    }
     virtual status_t getBlendMode(buffer_handle_t /*bufferHandle*/,
                                   ui::BlendMode* /*outBlendMode*/) const {
         return INVALID_OPERATION;
@@ -169,21 +173,36 @@
                                   std::optional<ui::Smpte2086>* /*outSmpte2086*/) const {
         return INVALID_OPERATION;
     }
+    virtual status_t setSmpte2086(buffer_handle_t /*bufferHandle*/,
+                                  std::optional<ui::Smpte2086> /*smpte2086*/) 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 setCta861_3(buffer_handle_t /*bufferHandle*/,
+                                 std::optional<ui::Cta861_3> /*cta861_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 setSmpte2094_40(buffer_handle_t /*bufferHandle*/,
+                                     std::optional<std::vector<uint8_t>> /*smpte2094_40*/) const {
+        return INVALID_OPERATION;
+    }
     virtual status_t getSmpte2094_10(
             buffer_handle_t /*bufferHandle*/,
             std::optional<std::vector<uint8_t>>* /*outSmpte2094_10*/) const {
         return INVALID_OPERATION;
     }
-
+    virtual status_t setSmpte2094_10(buffer_handle_t /*bufferHandle*/,
+                                     std::optional<std::vector<uint8_t>> /*smpte2094_10*/) const {
+        return INVALID_OPERATION;
+    }
     virtual status_t getDefaultPixelFormatFourCC(uint32_t /*width*/, uint32_t /*height*/,
                                                  PixelFormat /*format*/, uint32_t /*layerCount*/,
                                                  uint64_t /*usage*/,
diff --git a/libs/ui/include/ui/Gralloc4.h b/libs/ui/include/ui/Gralloc4.h
index fe38709..cf023c9 100644
--- a/libs/ui/include/ui/Gralloc4.h
+++ b/libs/ui/include/ui/Gralloc4.h
@@ -102,16 +102,24 @@
     status_t getPlaneLayouts(buffer_handle_t bufferHandle,
                              std::vector<ui::PlaneLayout>* outPlaneLayouts) const override;
     status_t getDataspace(buffer_handle_t bufferHandle, ui::Dataspace* outDataspace) const override;
+    status_t setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace) 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 setSmpte2086(buffer_handle_t bufferHandle,
+                          std::optional<ui::Smpte2086> smpte2086) const override;
     status_t getCta861_3(buffer_handle_t bufferHandle,
                          std::optional<ui::Cta861_3>* outCta861_3) const override;
+    status_t setCta861_3(buffer_handle_t bufferHandle,
+                         std::optional<ui::Cta861_3> cta861_3) const override;
     status_t getSmpte2094_40(buffer_handle_t bufferHandle,
                              std::optional<std::vector<uint8_t>>* outSmpte2094_40) const override;
+    status_t setSmpte2094_40(buffer_handle_t bufferHandle,
+                             std::optional<std::vector<uint8_t>> smpte2094_40) const override;
     status_t getSmpte2094_10(buffer_handle_t bufferHandle,
                              std::optional<std::vector<uint8_t>>* outSmpte2094_10) const override;
-
+    status_t setSmpte2094_10(buffer_handle_t bufferHandle,
+                             std::optional<std::vector<uint8_t>> smpte2094_10) const override;
     status_t getDefaultPixelFormatFourCC(uint32_t width, uint32_t height, PixelFormat format,
                                          uint32_t layerCount, uint64_t usage,
                                          uint32_t* outPixelFormatFourCC) const override;
@@ -157,6 +165,8 @@
 
     template <class T>
     using DecodeFunction = status_t (*)(const hardware::hidl_vec<uint8_t>& input, T* output);
+    template <class T>
+    using EncodeFunction = status_t (*)(const T& input, hardware::hidl_vec<uint8_t>* output);
 
     template <class T>
     status_t get(
@@ -165,6 +175,12 @@
             DecodeFunction<T> decodeFunction, T* outMetadata) const;
 
     template <class T>
+    status_t set(
+            buffer_handle_t bufferHandle,
+            const android::hardware::graphics::mapper::V4_0::IMapper::MetadataType& metadataType,
+            const T& metadata, EncodeFunction<T> encodeFunction) const;
+
+    template <class T>
     status_t getDefault(
             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 257c155..507fa35 100644
--- a/libs/ui/include/ui/GraphicBufferMapper.h
+++ b/libs/ui/include/ui/GraphicBufferMapper.h
@@ -121,13 +121,20 @@
     status_t getPlaneLayouts(buffer_handle_t bufferHandle,
                              std::vector<ui::PlaneLayout>* outPlaneLayouts);
     status_t getDataspace(buffer_handle_t bufferHandle, ui::Dataspace* outDataspace);
+    status_t setDataspace(buffer_handle_t bufferHandle, ui::Dataspace dataspace);
     status_t getBlendMode(buffer_handle_t bufferHandle, ui::BlendMode* outBlendMode);
     status_t getSmpte2086(buffer_handle_t bufferHandle, std::optional<ui::Smpte2086>* outSmpte2086);
+    status_t setSmpte2086(buffer_handle_t bufferHandle, std::optional<ui::Smpte2086> smpte2086);
     status_t getCta861_3(buffer_handle_t bufferHandle, std::optional<ui::Cta861_3>* outCta861_3);
+    status_t setCta861_3(buffer_handle_t bufferHandle, std::optional<ui::Cta861_3> cta861_3);
     status_t getSmpte2094_40(buffer_handle_t bufferHandle,
                              std::optional<std::vector<uint8_t>>* outSmpte2094_40);
+    status_t setSmpte2094_40(buffer_handle_t bufferHandle,
+                             std::optional<std::vector<uint8_t>> smpte2094_40);
     status_t getSmpte2094_10(buffer_handle_t bufferHandle,
                              std::optional<std::vector<uint8_t>>* outSmpte2094_10);
+    status_t setSmpte2094_10(buffer_handle_t bufferHandle,
+                             std::optional<std::vector<uint8_t>> smpte2094_10);
 
     /**
      * 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 4bdacb0..8661c36 100644
--- a/libs/ui/include/ui/GraphicTypes.h
+++ b/libs/ui/include/ui/GraphicTypes.h
@@ -62,5 +62,23 @@
 using Compression = aidl::android::hardware::graphics::common::Compression;
 using Interlaced = aidl::android::hardware::graphics::common::Interlaced;
 
+inline aidl::android::hardware::graphics::common::XyColor translate(const android_xy_color& color) {
+    return aidl::android::hardware::graphics::common::XyColor{.x = color.x, .y = color.y};
+}
+
+inline Smpte2086 translate(const android_smpte2086_metadata& metadata) {
+    return Smpte2086{.primaryRed = translate(metadata.displayPrimaryRed),
+                     .primaryGreen = translate(metadata.displayPrimaryGreen),
+                     .primaryBlue = translate(metadata.displayPrimaryBlue),
+                     .whitePoint = translate(metadata.whitePoint),
+                     .maxLuminance = metadata.maxLuminance,
+                     .minLuminance = metadata.minLuminance};
+}
+
+inline Cta861_3 translate(const android_cta861_3_metadata& metadata) {
+    return Cta861_3{.maxContentLightLevel = metadata.maxContentLightLevel,
+                    .maxFrameAverageLightLevel = metadata.maxFrameAverageLightLevel};
+}
+
 }  // namespace ui
 }  // namespace android
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index 9691ad8..32eec29 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -263,15 +263,15 @@
 static void benchmarkNotifyMotion(benchmark::State& state) {
     // Create dispatcher
     sp<FakeInputDispatcherPolicy> fakePolicy = new FakeInputDispatcherPolicy();
-    std::unique_ptr<InputDispatcher> dispatcher = std::make_unique<InputDispatcher>(fakePolicy);
-    dispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
-    dispatcher->start();
+    InputDispatcher dispatcher(fakePolicy);
+    dispatcher.setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
+    dispatcher.start();
 
     // Create a window that will receive motion events
     std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
-    sp<FakeWindowHandle> window = new FakeWindowHandle(application, *dispatcher, "Fake Window");
+    sp<FakeWindowHandle> window = new FakeWindowHandle(application, dispatcher, "Fake Window");
 
-    dispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    dispatcher.setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     NotifyMotionArgs motionArgs = generateMotionArgs();
 
@@ -280,55 +280,79 @@
         motionArgs.action = AMOTION_EVENT_ACTION_DOWN;
         motionArgs.downTime = now();
         motionArgs.eventTime = motionArgs.downTime;
-        dispatcher->notifyMotion(&motionArgs);
+        dispatcher.notifyMotion(&motionArgs);
 
         // Send ACTION_UP
         motionArgs.action = AMOTION_EVENT_ACTION_UP;
         motionArgs.eventTime = now();
-        dispatcher->notifyMotion(&motionArgs);
+        dispatcher.notifyMotion(&motionArgs);
 
         window->consumeEvent();
         window->consumeEvent();
     }
 
-    dispatcher->stop();
+    dispatcher.stop();
 }
 
 static void benchmarkInjectMotion(benchmark::State& state) {
     // Create dispatcher
     sp<FakeInputDispatcherPolicy> fakePolicy = new FakeInputDispatcherPolicy();
-    std::unique_ptr<InputDispatcher> dispatcher = std::make_unique<InputDispatcher>(fakePolicy);
-    dispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
-    dispatcher->start();
+    InputDispatcher dispatcher(fakePolicy);
+    dispatcher.setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
+    dispatcher.start();
 
     // Create a window that will receive motion events
     std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
-    sp<FakeWindowHandle> window = new FakeWindowHandle(application, *dispatcher, "Fake Window");
+    sp<FakeWindowHandle> window = new FakeWindowHandle(application, dispatcher, "Fake Window");
 
-    dispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    dispatcher.setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
 
     for (auto _ : state) {
         MotionEvent event = generateMotionEvent();
         // Send ACTION_DOWN
-        dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
-                                     InputEventInjectionSync::NONE, INJECT_EVENT_TIMEOUT,
-                                     POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
+        dispatcher.injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
+                                    InputEventInjectionSync::NONE, INJECT_EVENT_TIMEOUT,
+                                    POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
 
         // Send ACTION_UP
         event.setAction(AMOTION_EVENT_ACTION_UP);
-        dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
-                                     InputEventInjectionSync::NONE, INJECT_EVENT_TIMEOUT,
-                                     POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
+        dispatcher.injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
+                                    InputEventInjectionSync::NONE, INJECT_EVENT_TIMEOUT,
+                                    POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
 
         window->consumeEvent();
         window->consumeEvent();
     }
 
-    dispatcher->stop();
+    dispatcher.stop();
+}
+
+static void benchmarkOnWindowInfosChanged(benchmark::State& state) {
+    // Create dispatcher
+    sp<FakeInputDispatcherPolicy> fakePolicy = new FakeInputDispatcherPolicy();
+    InputDispatcher dispatcher(fakePolicy);
+    dispatcher.setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
+    dispatcher.start();
+
+    // Create a window
+    std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+    sp<FakeWindowHandle> window = new FakeWindowHandle(application, dispatcher, "Fake Window");
+
+    std::vector<gui::WindowInfo> windowInfos{*window->getInfo()};
+    gui::DisplayInfo info;
+    info.displayId = window->getInfo()->displayId;
+    std::vector<gui::DisplayInfo> displayInfos{info};
+
+    for (auto _ : state) {
+        dispatcher.onWindowInfosChanged(windowInfos, displayInfos);
+        dispatcher.onWindowInfosChanged({} /*windowInfos*/, {} /*displayInfos*/);
+    }
+    dispatcher.stop();
 }
 
 BENCHMARK(benchmarkNotifyMotion);
 BENCHMARK(benchmarkInjectMotion);
+BENCHMARK(benchmarkOnWindowInfosChanged);
 
 } // namespace android::inputdispatcher
 
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index bcae8d9..c5d7a60 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -1098,6 +1098,13 @@
         }
     }
 
+    if (s.what & layer_state_t::eDimmingEnabledChanged) {
+        if (mDrawingState.dimmingEnabled != s.dimmingEnabled) {
+            ALOGV("%s: false [eDimmingEnabledChanged changed]", __func__);
+            return false;
+        }
+    }
+
     ALOGV("%s: true", __func__);
     return true;
 }
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
index 283fe86..974f7c6 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
@@ -207,6 +207,9 @@
     // framerate of the layer as measured by LayerHistory
     float fps;
 
+    // The dimming flag
+    bool dimmingEnabled{true};
+
     virtual ~LayerFECompositionState();
 
     // Debugging
diff --git a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
index ff7d430..6631a27 100644
--- a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
@@ -121,6 +121,7 @@
     dumpVal(out, "isColorspaceAgnostic", isColorspaceAgnostic);
     dumpVal(out, "dataspace", toString(dataspace), dataspace);
     dumpVal(out, "hdr metadata types", hdrMetadata.validTypes);
+    dumpVal(out, "dimming enabled", dimmingEnabled);
     dumpVal(out, "colorTransform", colorTransform);
 
     out.append("\n");
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 723593d..3289d55 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -324,9 +324,10 @@
 
     // For hdr content, treat the white point as the display brightness - HDR content should not be
     // boosted or dimmed.
+    // If the layer explicitly requests to disable dimming, then don't dim either.
     if (isHdrDataspace(state.dataspace) ||
         getOutput().getState().displayBrightnessNits == getOutput().getState().sdrWhitePointNits ||
-        getOutput().getState().displayBrightnessNits == 0.f) {
+        getOutput().getState().displayBrightnessNits == 0.f || !layerFEState->dimmingEnabled) {
         state.dimmingRatio = 1.f;
         state.whitePointNits = getOutput().getState().displayBrightnessNits;
     } else {
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 8eb1946..ceee48c 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -668,6 +668,13 @@
     EXPECT_EQ(mOutputState.sdrWhitePointNits / mOutputState.displayBrightnessNits,
               mOutputLayer.getState().dimmingRatio);
 
+    mLayerFEState.dimmingEnabled = false;
+    mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
+    EXPECT_EQ(mOutputState.displayBrightnessNits, mOutputLayer.getState().whitePointNits);
+    EXPECT_EQ(1.f, mOutputLayer.getState().dimmingRatio);
+
+    // change dimmingEnabled back to true.
+    mLayerFEState.dimmingEnabled = true;
     mLayerFEState.dataspace = ui::Dataspace::BT2020_ITU_PQ;
     mLayerFEState.isColorspaceAgnostic = false;
     mOutputLayer.updateCompositionState(false, false, ui::Transform::RotationFlags::ROT_0);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 41e0487..997b1a1 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -142,6 +142,7 @@
     mDrawingState.destinationFrame.makeInvalid();
     mDrawingState.isTrustedOverlay = false;
     mDrawingState.dropInputMode = gui::DropInputMode::NONE;
+    mDrawingState.dimmingEnabled = true;
 
     if (args.flags & ISurfaceComposerClient::eNoColorFill) {
         // Set an invalid color so there is no color fill.
@@ -480,6 +481,7 @@
     compositionState->colorTransformIsIdentity = !hasColorTransform();
     compositionState->surfaceDamage = surfaceDamageRegion;
     compositionState->hasProtectedContent = isProtected();
+    compositionState->dimmingEnabled = isDimmingEnabled();
 
     const bool usesRoundedCorners = getRoundedCornerState().radius != 0.f;
 
@@ -1041,6 +1043,16 @@
     return true;
 }
 
+bool Layer::setDimmingEnabled(const bool dimmingEnabled) {
+    if (mDrawingState.dimmingEnabled == dimmingEnabled) return false;
+
+    mDrawingState.sequence++;
+    mDrawingState.dimmingEnabled = dimmingEnabled;
+    mDrawingState.modified = true;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+
 bool Layer::setFrameRateSelectionPriority(int32_t priority) {
     if (mDrawingState.frameRateSelectionPriority == priority) return false;
     mDrawingState.frameRateSelectionPriority = priority;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 846460d..565a6ff 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -281,6 +281,8 @@
         gui::DropInputMode dropInputMode;
 
         bool autoRefresh = false;
+
+        bool dimmingEnabled = true;
     };
 
     /*
@@ -411,6 +413,7 @@
     virtual mat4 getColorTransform() const;
     virtual bool hasColorTransform() const;
     virtual bool isColorSpaceAgnostic() const { return mDrawingState.colorSpaceAgnostic; }
+    virtual bool isDimmingEnabled() const { return getDrawingState().dimmingEnabled; };
 
     // Used only to set BufferStateLayer state
     virtual bool setTransform(uint32_t /*transform*/) { return false; };
@@ -437,6 +440,7 @@
     }
     virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace);
     virtual bool setColorSpaceAgnostic(const bool agnostic);
+    virtual bool setDimmingEnabled(const bool dimmingEnabled);
     virtual bool setFrameRateSelectionPriority(int32_t priority);
     virtual bool setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHint);
     virtual void setAutoRefresh(bool /* autoRefresh */) {}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 768ae65..5adc177 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4485,6 +4485,9 @@
     if (what & layer_state_t::eAutoRefreshChanged) {
         layer->setAutoRefresh(s.autoRefresh);
     }
+    if (what & layer_state_t::eDimmingEnabledChanged) {
+        if (layer->setDimmingEnabled(s.dimmingEnabled)) flags |= eTraversalNeeded;
+    }
     if (what & layer_state_t::eTrustedOverlayChanged) {
         if (layer->setTrustedOverlay(s.isTrustedOverlay)) {
             flags |= eTraversalNeeded;