Merge "SurfaceFlinger: Only update client parent if set." into pi-dev
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 5ce597a..3f7f6e9 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1237,7 +1237,6 @@
 }
 
 static void DumpHals() {
-    using android::sp;
     using android::hidl::manager::V1_0::IServiceManager;
     using android::hardware::defaultServiceManager;
 
@@ -1582,69 +1581,80 @@
             paths[i])));
     }
 
+    sp<IDumpstateDevice> dumpstate_device(IDumpstateDevice::getService());
+    if (dumpstate_device == nullptr) {
+        MYLOGE("No IDumpstateDevice implementation\n");
+        return;
+    }
+
+    using ScopedNativeHandle =
+            std::unique_ptr<native_handle_t, std::function<void(native_handle_t*)>>;
+    ScopedNativeHandle handle(native_handle_create(static_cast<int>(paths.size()), 0),
+                              [](native_handle_t* handle) {
+                                  native_handle_close(handle);
+                                  native_handle_delete(handle);
+                              });
+    if (handle == nullptr) {
+        MYLOGE("Could not create native_handle\n");
+        return;
+    }
+
+    for (size_t i = 0; i < paths.size(); i++) {
+        MYLOGI("Calling IDumpstateDevice implementation using path %s\n", paths[i].c_str());
+
+        android::base::unique_fd fd(TEMP_FAILURE_RETRY(
+            open(paths[i].c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
+                 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
+        if (fd < 0) {
+            MYLOGE("Could not open file %s: %s\n", paths[i].c_str(), strerror(errno));
+            return;
+        }
+        handle.get()->data[i] = fd.release();
+    }
+
     // Given that bugreport is required to diagnose failures, it's better to
-    // drop the result of IDumpstateDevice than to block the rest of bugreport
-    // for an arbitrary amount of time.
-    std::packaged_task<std::unique_ptr<ssize_t[]>()>
-        dumpstate_task([paths]() -> std::unique_ptr<ssize_t[]> {
-            ::android::sp<IDumpstateDevice> dumpstate_device(IDumpstateDevice::getService());
-            if (dumpstate_device == nullptr) {
-                MYLOGE("No IDumpstateDevice implementation\n");
-                return nullptr;
-            }
-
-            using ScopedNativeHandle =
-                std::unique_ptr<native_handle_t, std::function<void(native_handle_t*)>>;
-            ScopedNativeHandle handle(native_handle_create(static_cast<int>(paths.size()), 0),
-                                      [](native_handle_t* handle) {
-                                          native_handle_close(handle);
-                                          native_handle_delete(handle);
-                                      });
-            if (handle == nullptr) {
-                MYLOGE("Could not create native_handle\n");
-                return nullptr;
-            }
-
-            for (size_t i = 0; i < paths.size(); i++) {
-                MYLOGI("Calling IDumpstateDevice implementation using path %s\n", paths[i].c_str());
-
-                android::base::unique_fd fd(TEMP_FAILURE_RETRY(
-                    open(paths[i].c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
-                         S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
-                if (fd < 0) {
-                    MYLOGE("Could not open file %s: %s\n", paths[i].c_str(), strerror(errno));
-                    return nullptr;
-                }
-                handle.get()->data[i] = fd.release();
-            }
-
+    // set an arbitrary amount of timeout for IDumpstateDevice than to block the
+    // rest of bugreport. In the timeout case, we will kill dumpstate board HAL
+    // and grab whatever dumped
+    std::packaged_task<bool()>
+            dumpstate_task([paths, dumpstate_device, &handle]() -> bool {
             android::hardware::Return<void> status = dumpstate_device->dumpstateBoard(handle.get());
             if (!status.isOk()) {
                 MYLOGE("dumpstateBoard failed: %s\n", status.description().c_str());
-                return nullptr;
+                return false;
             }
-            auto file_sizes = std::make_unique<ssize_t[]>(paths.size());
-            for (size_t i = 0; i < paths.size(); i++) {
-                struct stat s;
-                if (fstat(handle.get()->data[i], &s) == -1) {
-                    MYLOGE("Failed to fstat %s: %s\n", kDumpstateBoardFiles[i].c_str(),
-                           strerror(errno));
-                    file_sizes[i] = -1;
-                    continue;
-                }
-                file_sizes[i] = s.st_size;
-            }
-            return file_sizes;
+            return true;
         });
+
     auto result = dumpstate_task.get_future();
     std::thread(std::move(dumpstate_task)).detach();
-    if (result.wait_for(30s) != std::future_status::ready) {
-        MYLOGE("dumpstateBoard timed out after 30s\n");
-        return;
+
+    constexpr size_t timeout_sec = 30;
+    if (result.wait_for(std::chrono::seconds(timeout_sec)) != std::future_status::ready) {
+        MYLOGE("dumpstateBoard timed out after %zus, killing dumpstate vendor HAL\n", timeout_sec);
+        if (!android::base::SetProperty("ctl.interface_restart",
+                                        android::base::StringPrintf("%s/default",
+                                                                    IDumpstateDevice::descriptor))) {
+            MYLOGE("Couldn't restart dumpstate HAL\n");
+        }
     }
-    std::unique_ptr<ssize_t[]> file_sizes = result.get();
-    if (file_sizes == nullptr) {
-        return;
+    // Wait some time for init to kill dumpstate vendor HAL
+    constexpr size_t killing_timeout_sec = 10;
+    if (result.wait_for(std::chrono::seconds(killing_timeout_sec)) != std::future_status::ready) {
+        MYLOGE("killing dumpstateBoard timed out after %zus, continue and "
+               "there might be racing in content\n", killing_timeout_sec);
+    }
+
+    auto file_sizes = std::make_unique<ssize_t[]>(paths.size());
+    for (size_t i = 0; i < paths.size(); i++) {
+        struct stat s;
+        if (fstat(handle.get()->data[i], &s) == -1) {
+            MYLOGE("Failed to fstat %s: %s\n", kDumpstateBoardFiles[i].c_str(),
+                   strerror(errno));
+            file_sizes[i] = -1;
+            continue;
+        }
+        file_sizes[i] = s.st_size;
     }
 
     for (size_t i = 0; i < paths.size(); i++) {
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 57f474b..7fd9d01 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -650,7 +650,7 @@
     }
 
     const HdrMetadata& metadata = mConsumer->getCurrentHdrMetadata();
-    error = hwcLayer->setHdrMetadata(metadata);
+    error = hwcLayer->setPerFrameMetadata(displayDevice->getSupportedPerFrameMetadata(), metadata);
     if (error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
         ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", mName.string(),
               to_string(error).c_str(), static_cast<int32_t>(error));
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index cd41662..7c6302e 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -79,6 +79,7 @@
         int displayHeight,
         bool hasWideColorGamut,
         const HdrCapabilities& hdrCapabilities,
+        const int32_t supportedPerFrameMetadata,
         int initialPowerMode)
     : lastCompositionHadVisibleLayers(false),
       mFlinger(flinger),
@@ -103,7 +104,8 @@
       mHasWideColorGamut(hasWideColorGamut),
       mHasHdr10(false),
       mHasHLG(false),
-      mHasDolbyVision(false)
+      mHasDolbyVision(false),
+      mSupportedPerFrameMetadata(supportedPerFrameMetadata)
 {
     // clang-format on
     for (Hdr hdrType : hdrCapabilities.getSupportedHdrTypes()) {
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index cd0bed6..df5d945 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -23,17 +23,16 @@
 
 #include <math/mat4.h>
 
-#include <ui/Region.h>
-
 #include <binder/IBinder.h>
+#include <gui/ISurfaceComposer.h>
+#include <hardware/hwcomposer_defs.h>
+#include <ui/GraphicTypes.h>
+#include <ui/Region.h>
 #include <utils/RefBase.h>
 #include <utils/Mutex.h>
 #include <utils/String8.h>
 #include <utils/Timers.h>
 
-#include <gui/ISurfaceComposer.h>
-#include <hardware/hwcomposer_defs.h>
-#include <ui/GraphicTypes.h>
 #include "RenderArea.h"
 #include "RenderEngine/Surface.h"
 
@@ -86,6 +85,7 @@
             int displayHeight,
             bool hasWideColorGamut,
             const HdrCapabilities& hdrCapabilities,
+            const int32_t supportedPerFrameMetadata,
             int initialPowerMode);
     // clang-format on
 
@@ -131,6 +131,8 @@
     int32_t                 getHwcDisplayId() const { return mHwcDisplayId; }
     const wp<IBinder>&      getDisplayToken() const { return mDisplayToken; }
 
+    int32_t getSupportedPerFrameMetadata() const { return mSupportedPerFrameMetadata; }
+
     // We pass in mustRecompose so we can keep VirtualDisplaySurface's state
     // machine happy without actually queueing a buffer if nothing has changed
     status_t beginFrame(bool mustRecompose) const;
@@ -259,6 +261,8 @@
     bool mHasHdr10;
     bool mHasHLG;
     bool mHasDolbyVision;
+
+    const int32_t mSupportedPerFrameMetadata;
 };
 
 struct DisplayDeviceState {
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index c94c290..37ba433 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -715,48 +715,6 @@
     return Error::NONE;
 }
 
-Error Composer::setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) {
-    if (!mClient_2_2) {
-        return Error::UNSUPPORTED;
-    }
-
-    mWriter.selectDisplay(display);
-    mWriter.selectLayer(layer);
-
-    std::vector<IComposerClient::PerFrameMetadata> composerMetadata;
-    using PerFrameMetadataKey = IComposerClient::PerFrameMetadataKey;
-    if (metadata.validTypes & HdrMetadata::SMPTE2086) {
-        composerMetadata
-                .insert(composerMetadata.end(),
-                        {{PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
-                          metadata.smpte2086.displayPrimaryRed.x},
-                         {PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
-                          metadata.smpte2086.displayPrimaryRed.y},
-                         {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
-                          metadata.smpte2086.displayPrimaryGreen.x},
-                         {PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
-                          metadata.smpte2086.displayPrimaryGreen.y},
-                         {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
-                          metadata.smpte2086.displayPrimaryBlue.x},
-                         {PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
-                          metadata.smpte2086.displayPrimaryBlue.y},
-                         {PerFrameMetadataKey::WHITE_POINT_X, metadata.smpte2086.whitePoint.x},
-                         {PerFrameMetadataKey::WHITE_POINT_Y, metadata.smpte2086.whitePoint.y},
-                         {PerFrameMetadataKey::MAX_LUMINANCE, metadata.smpte2086.maxLuminance},
-                         {PerFrameMetadataKey::MIN_LUMINANCE, metadata.smpte2086.minLuminance}});
-    }
-    if (metadata.validTypes & HdrMetadata::CTA861_3) {
-        composerMetadata.insert(composerMetadata.end(),
-                                {{PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
-                                  metadata.cta8613.maxContentLightLevel},
-                                 {PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
-                                  metadata.cta8613.maxFrameAverageLightLevel}});
-    }
-
-    mWriter.setLayerPerFrameMetadata(composerMetadata);
-    return Error::NONE;
-}
-
 Error Composer::setLayerDisplayFrame(Display display, Layer layer,
         const IComposerClient::Rect& frame)
 {
@@ -927,6 +885,18 @@
 
 // Composer HAL 2.2
 
+Error Composer::setLayerPerFrameMetadata(Display display, Layer layer,
+        const std::vector<IComposerClient::PerFrameMetadata>& perFrameMetadatas) {
+    if (!mClient_2_2) {
+        return Error::UNSUPPORTED;
+    }
+
+    mWriter.selectDisplay(display);
+    mWriter.selectLayer(layer);
+    mWriter.setLayerPerFrameMetadata(perFrameMetadatas);
+    return Error::NONE;
+}
+
 Error Composer::getPerFrameMetadataKeys(
         Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) {
     if (!mClient_2_2) {
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index e17fd67..beee539 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -64,6 +64,9 @@
 using V2_2::IComposer;
 using V2_2::IComposerClient;
 
+using PerFrameMetadata = IComposerClient::PerFrameMetadata;
+using PerFrameMetadataKey = IComposerClient::PerFrameMetadataKey;
+
 class Composer {
 public:
     virtual ~Composer() = 0;
@@ -160,8 +163,6 @@
     virtual Error setLayerCompositionType(Display display, Layer layer,
                                           IComposerClient::Composition type) = 0;
     virtual Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) = 0;
-    virtual Error setLayerHdrMetadata(Display display, Layer layer,
-                                      const HdrMetadata& metadata) = 0;
     virtual Error setLayerDisplayFrame(Display display, Layer layer,
                                        const IComposerClient::Rect& frame) = 0;
     virtual Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) = 0;
@@ -176,6 +177,9 @@
     virtual Error setLayerInfo(Display display, Layer layer, uint32_t type, uint32_t appId) = 0;
 
     // Composer HAL 2.2
+    virtual Error setLayerPerFrameMetadata(
+            Display display, Layer layer,
+            const std::vector<IComposerClient::PerFrameMetadata>& perFrameMetadatas) = 0;
     virtual Error getPerFrameMetadataKeys(
             Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) = 0;
     virtual Error getRenderIntents(Display display, ColorMode colorMode,
@@ -353,7 +357,6 @@
     Error setLayerCompositionType(Display display, Layer layer,
                                   IComposerClient::Composition type) override;
     Error setLayerDataspace(Display display, Layer layer, Dataspace dataspace) override;
-    Error setLayerHdrMetadata(Display display, Layer layer, const HdrMetadata& metadata) override;
     Error setLayerDisplayFrame(Display display, Layer layer,
                                const IComposerClient::Rect& frame) override;
     Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override;
@@ -368,6 +371,9 @@
     Error setLayerInfo(Display display, Layer layer, uint32_t type, uint32_t appId) override;
 
     // Composer HAL 2.2
+    Error setLayerPerFrameMetadata(
+            Display display, Layer layer,
+            const std::vector<IComposerClient::PerFrameMetadata>& perFrameMetadatas) override;
     Error getPerFrameMetadataKeys(
             Display display, std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override;
     Error getRenderIntents(Display display, ColorMode colorMode,
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 0667f8d..3947318 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -32,6 +32,7 @@
 
 #include <algorithm>
 #include <inttypes.h>
+#include <set>
 
 using android::Fence;
 using android::FloatRect;
@@ -54,6 +55,11 @@
 
 namespace {
 
+inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys,
+                           const Hwc2::PerFrameMetadataKey& key) {
+    return keys.find(key) != keys.end();
+}
+
 class ComposerCallbackBridge : public Hwc2::IComposerCallback {
 public:
     ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId)
@@ -370,6 +376,42 @@
     return static_cast<Error>(intError);
 }
 
+Error Display::getSupportedPerFrameMetadata(int32_t* outSupportedPerFrameMetadata) const
+{
+    *outSupportedPerFrameMetadata = 0;
+    std::vector<Hwc2::PerFrameMetadataKey> tmpKeys;
+    auto intError = mComposer.getPerFrameMetadataKeys(mId, &tmpKeys);
+    auto error = static_cast<Error>(intError);
+    if (error != Error::None) {
+        return error;
+    }
+
+    // Check whether a specific metadata type is supported. A metadata type is considered
+    // supported if and only if all required fields are supported.
+
+    // SMPTE2086
+    std::set<Hwc2::PerFrameMetadataKey> keys(tmpKeys.begin(), tmpKeys.end());
+    if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_X) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_Y) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_LUMINANCE) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MIN_LUMINANCE)) {
+        *outSupportedPerFrameMetadata |= HdrMetadata::Type::SMPTE2086;
+    }
+    // CTA861_3
+    if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL) &&
+        hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL)) {
+        *outSupportedPerFrameMetadata |= HdrMetadata::Type::CTA861_3;
+    }
+
+    return Error::None;
+}
+
 Error Display::getRenderIntents(ColorMode colorMode,
         std::vector<RenderIntent>* outRenderIntents) const
 {
@@ -784,13 +826,49 @@
     return static_cast<Error>(intError);
 }
 
-Error Layer::setHdrMetadata(const android::HdrMetadata& metadata) {
+Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
+        const android::HdrMetadata& metadata)
+{
     if (metadata == mHdrMetadata) {
         return Error::None;
     }
 
     mHdrMetadata = metadata;
-    auto intError = mComposer.setLayerHdrMetadata(mDisplayId, mId, metadata);
+    int validTypes = mHdrMetadata.validTypes & supportedPerFrameMetadata;
+    std::vector<Hwc2::PerFrameMetadata> perFrameMetadatas;
+    if (validTypes & HdrMetadata::SMPTE2086) {
+        perFrameMetadatas.insert(perFrameMetadatas.end(),
+                                 {{Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X,
+                                         mHdrMetadata.smpte2086.displayPrimaryRed.x},
+                                   {Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y,
+                                         mHdrMetadata.smpte2086.displayPrimaryRed.y},
+                                   {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X,
+                                         mHdrMetadata.smpte2086.displayPrimaryGreen.x},
+                                   {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y,
+                                         mHdrMetadata.smpte2086.displayPrimaryGreen.y},
+                                   {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X,
+                                         mHdrMetadata.smpte2086.displayPrimaryBlue.x},
+                                   {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y,
+                                         mHdrMetadata.smpte2086.displayPrimaryBlue.y},
+                                   {Hwc2::PerFrameMetadataKey::WHITE_POINT_X,
+                                         mHdrMetadata.smpte2086.whitePoint.x},
+                                   {Hwc2::PerFrameMetadataKey::WHITE_POINT_Y,
+                                         mHdrMetadata.smpte2086.whitePoint.y},
+                                   {Hwc2::PerFrameMetadataKey::MAX_LUMINANCE,
+                                         mHdrMetadata.smpte2086.maxLuminance},
+                                   {Hwc2::PerFrameMetadataKey::MIN_LUMINANCE,
+                                         mHdrMetadata.smpte2086.minLuminance}});
+    }
+
+    if (validTypes & HdrMetadata::CTA861_3) {
+        perFrameMetadatas.insert(perFrameMetadatas.end(),
+                                 {{Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL,
+                                         mHdrMetadata.cta8613.maxContentLightLevel},
+                                   {Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL,
+                                         mHdrMetadata.cta8613.maxFrameAverageLightLevel}});
+    }
+
+    auto intError = mComposer.setLayerPerFrameMetadata(mDisplayId, mId, perFrameMetadatas);
     return static_cast<Error>(intError);
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index aa907ea..3ac06ec 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -27,7 +27,6 @@
 #include <math/mat4.h>
 #include <ui/GraphicTypes.h>
 #include <ui/HdrCapabilities.h>
-
 #include <utils/Log.h>
 #include <utils/StrongPointer.h>
 #include <utils/Timers.h>
@@ -212,6 +211,10 @@
             std::unordered_map<Layer*, Composition>* outTypes);
     [[clang::warn_unused_result]] Error getColorModes(
             std::vector<android::ui::ColorMode>* outModes) const;
+    // outSupportedPerFrameMetadata is an opaque bitmask to the callers
+    // but contains HdrMetadata::Type::*.
+    [[clang::warn_unused_result]] Error getSupportedPerFrameMetadata(
+            int32_t* outSupportedPerFrameMetadata) const;
     [[clang::warn_unused_result]] Error getRenderIntents(
             android::ui::ColorMode colorMode,
             std::vector<android::ui::RenderIntent>* outRenderIntents) const;
@@ -318,7 +321,9 @@
     [[clang::warn_unused_result]] Error setCompositionType(Composition type);
     [[clang::warn_unused_result]] Error setDataspace(
             android::ui::Dataspace dataspace);
-    [[clang::warn_unused_result]] Error setHdrMetadata(const android::HdrMetadata& metadata);
+    [[clang::warn_unused_result]] Error setPerFrameMetadata(
+            const int32_t supportedPerFrameMetadata,
+            const android::HdrMetadata& metadata);
     [[clang::warn_unused_result]] Error setDisplayFrame(
             const android::Rect& frame);
     [[clang::warn_unused_result]] Error setPlaneAlpha(float alpha);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 0a3ac84..1bbf039 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -842,6 +842,25 @@
     return NO_ERROR;
 }
 
+int32_t HWComposer::getSupportedPerFrameMetadata(int32_t displayId) const {
+    if (!isValidDisplay(displayId)) {
+        ALOGE("getPerFrameMetadataKeys: Attempted to access invalid display %d",
+                displayId);
+        return 0;
+    }
+
+    int32_t supportedMetadata;
+    auto error = mDisplayData[displayId].hwcDisplay->getSupportedPerFrameMetadata(
+            &supportedMetadata);
+    if (error != HWC2::Error::None) {
+        ALOGE("getPerFrameMetadataKeys failed for display %d: %s (%d)", displayId,
+              to_string(error).c_str(), static_cast<int32_t>(error));
+        return 0;
+    }
+
+    return supportedMetadata;
+}
+
 std::vector<ui::RenderIntent> HWComposer::getRenderIntents(int32_t displayId,
         ui::ColorMode colorMode) const {
     if (!isValidDisplay(displayId)) {
@@ -853,7 +872,7 @@
     std::vector<ui::RenderIntent> renderIntents;
     auto error = mDisplayData[displayId].hwcDisplay->getRenderIntents(colorMode, &renderIntents);
     if (error != HWC2::Error::None) {
-        ALOGE("getColorModes failed for display %d: %s (%d)", displayId,
+        ALOGE("getRenderIntents failed for display %d: %s (%d)", displayId,
                 to_string(error).c_str(), static_cast<int32_t>(error));
         return std::vector<ui::RenderIntent>();
     }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 138e1f1..d7f3b08 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -24,7 +24,6 @@
 
 #include <ui/Fence.h>
 #include <ui/GraphicTypes.h>
-
 #include <utils/BitSet.h>
 #include <utils/Condition.h>
 #include <utils/Mutex.h>
@@ -137,6 +136,8 @@
     // Fetches the HDR capabilities of the given display
     status_t getHdrCapabilities(int32_t displayId, HdrCapabilities* outCapabilities);
 
+    int32_t getSupportedPerFrameMetadata(int32_t displayId) const;
+
     // Returns the available RenderIntent of the given display.
     std::vector<ui::RenderIntent> getRenderIntents(int32_t displayId, ui::ColorMode colorMode) const;
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 58e4fbe..e661f03 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2314,7 +2314,9 @@
     sp<DisplayDevice> hw =
             new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow,
                               dispSurface, std::move(renderSurface), displayWidth, displayHeight,
-                              hasWideColorGamut, hdrCapabilities, initialPowerMode);
+                              hasWideColorGamut, hdrCapabilities,
+                              getHwComposer().getSupportedPerFrameMetadata(hwcId),
+                              initialPowerMode);
 
     if (maxFrameBufferAcquiredBuffers >= 3) {
         nativeWindowSurface->preallocateBuffers();
diff --git a/services/surfaceflinger/tests/hwc2/Android.bp b/services/surfaceflinger/tests/hwc2/Android.bp
index 6c0e4ab..0957d6a 100644
--- a/services/surfaceflinger/tests/hwc2/Android.bp
+++ b/services/surfaceflinger/tests/hwc2/Android.bp
@@ -41,7 +41,6 @@
         "libmath",
     ],
     shared_libs: [
-        "android.hardware.graphics.common@1.0",
         "android.hardware.graphics.common@1.1",
         "libcutils",
         "libEGL",
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 7257b46..f39ca00 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -80,7 +80,7 @@
         sp<DisplayDevice> build() {
             return new DisplayDevice(mFlinger.mFlinger.get(), mType, mHwcId, false, mDisplayToken,
                                      mNativeWindow, mDisplaySurface, std::move(mRenderSurface), 0,
-                                     0, false, {}, HWC_POWER_MODE_NORMAL);
+                                     0, false, {}, 0, HWC_POWER_MODE_NORMAL);
         }
 
         FakeDisplayDeviceFactory& setNativeWindow(const sp<ANativeWindow>& nativeWindow) {
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 8be2779..267670a 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -99,7 +99,8 @@
     MOCK_METHOD3(setLayerColor, Error(Display, Layer, const IComposerClient::Color&));
     MOCK_METHOD3(setLayerCompositionType, Error(Display, Layer, IComposerClient::Composition));
     MOCK_METHOD3(setLayerDataspace, Error(Display, Layer, Dataspace));
-    MOCK_METHOD3(setLayerHdrMetadata, Error(Display, Layer, const HdrMetadata&));
+    MOCK_METHOD3(setLayerPerFrameMetadata,
+                 Error(Display, Layer, const std::vector<IComposerClient::PerFrameMetadata>&));
     MOCK_METHOD3(setLayerDisplayFrame, Error(Display, Layer, const IComposerClient::Rect&));
     MOCK_METHOD3(setLayerPlaneAlpha, Error(Display, Layer, float));
     MOCK_METHOD3(setLayerSidebandStream, Error(Display, Layer, const native_handle_t*));