HDR layer info listener

Bug: 182312559
Test: SilkFX's layer listener

Change-Id: Iaaf5065f1adc871ce2890840e19756293dd21871
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 97f8f47..177f339 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -982,6 +982,34 @@
         return NO_ERROR;
     }
 
+    status_t addHdrLayerInfoListener(const sp<IBinder>& displayToken,
+                                     const sp<gui::IHdrLayerInfoListener>& listener) override {
+        Parcel data, reply;
+        SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
+        SAFE_PARCEL(data.writeStrongBinder, displayToken);
+        SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(listener));
+        const status_t error =
+                remote()->transact(BnSurfaceComposer::ADD_HDR_LAYER_INFO_LISTENER, data, &reply);
+        if (error != OK) {
+            ALOGE("addHdrLayerInfoListener: Failed to transact; error = %d", error);
+        }
+        return error;
+    }
+
+    status_t removeHdrLayerInfoListener(const sp<IBinder>& displayToken,
+                                        const sp<gui::IHdrLayerInfoListener>& listener) override {
+        Parcel data, reply;
+        SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
+        SAFE_PARCEL(data.writeStrongBinder, displayToken);
+        SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(listener));
+        const status_t error =
+                remote()->transact(BnSurfaceComposer::REMOVE_HDR_LAYER_INFO_LISTENER, data, &reply);
+        if (error != OK) {
+            ALOGE("removeHdrLayerInfoListener: Failed to transact; error = %d", error);
+        }
+        return error;
+    }
+
     status_t notifyPowerBoost(int32_t boostId) override {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -1862,6 +1890,38 @@
             }
             return setDisplayBrightness(displayToken, brightness);
         }
+        case ADD_HDR_LAYER_INFO_LISTENER: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IBinder> displayToken;
+            status_t error = data.readNullableStrongBinder(&displayToken);
+            if (error != NO_ERROR) {
+                ALOGE("addHdrLayerInfoListener: Failed to read display token");
+                return error;
+            }
+            sp<gui::IHdrLayerInfoListener> listener;
+            error = data.readNullableStrongBinder(&listener);
+            if (error != NO_ERROR) {
+                ALOGE("addHdrLayerInfoListener: Failed to read listener");
+                return error;
+            }
+            return addHdrLayerInfoListener(displayToken, listener);
+        }
+        case REMOVE_HDR_LAYER_INFO_LISTENER: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IBinder> displayToken;
+            status_t error = data.readNullableStrongBinder(&displayToken);
+            if (error != NO_ERROR) {
+                ALOGE("removeHdrLayerInfoListener: Failed to read display token");
+                return error;
+            }
+            sp<gui::IHdrLayerInfoListener> listener;
+            error = data.readNullableStrongBinder(&listener);
+            if (error != NO_ERROR) {
+                ALOGE("removeHdrLayerInfoListener: Failed to read listener");
+                return error;
+            }
+            return removeHdrLayerInfoListener(displayToken, listener);
+        }
         case NOTIFY_POWER_BOOST: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             int32_t boostId;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 0b01084..07618a4 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -2053,6 +2053,17 @@
     return ComposerService::getComposerService()->setDisplayBrightness(displayToken, brightness);
 }
 
+status_t SurfaceComposerClient::addHdrLayerInfoListener(
+        const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) {
+    return ComposerService::getComposerService()->addHdrLayerInfoListener(displayToken, listener);
+}
+
+status_t SurfaceComposerClient::removeHdrLayerInfoListener(
+        const sp<IBinder>& displayToken, const sp<gui::IHdrLayerInfoListener>& listener) {
+    return ComposerService::getComposerService()->removeHdrLayerInfoListener(displayToken,
+                                                                             listener);
+}
+
 status_t SurfaceComposerClient::notifyPowerBoost(int32_t boostId) {
     return ComposerService::getComposerService()->notifyPowerBoost(boostId);
 }
diff --git a/libs/gui/aidl/android/gui/IHdrLayerInfoListener.aidl b/libs/gui/aidl/android/gui/IHdrLayerInfoListener.aidl
new file mode 100644
index 0000000..fc809c4
--- /dev/null
+++ b/libs/gui/aidl/android/gui/IHdrLayerInfoListener.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+oneway interface IHdrLayerInfoListener {
+    // Callback with the total number of HDR layers, the dimensions of the largest layer,
+    // and a placeholder flags
+    // TODO (b/182312559): Define the flags (likely need an indicator that a UDFPS layer is present)
+    void onHdrLayerInfoChanged(int numberOfHdrLayers, int maxW, int maxH, int flags);
+}
\ No newline at end of file
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 9f9ca74..50198c6 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -18,6 +18,7 @@
 
 #include <android/gui/DisplayBrightness.h>
 #include <android/gui/IFpsListener.h>
+#include <android/gui/IHdrLayerInfoListener.h>
 #include <android/gui/IScreenCaptureListener.h>
 #include <android/gui/ITransactionTraceListener.h>
 #include <binder/IBinder.h>
@@ -431,6 +432,25 @@
                                           const gui::DisplayBrightness& brightness) = 0;
 
     /*
+     * Adds a listener that receives HDR layer information. This is used in combination
+     * with setDisplayBrightness to adjust the display brightness depending on factors such
+     * as whether or not HDR is in use.
+     *
+     * Returns NO_ERROR upon success or NAME_NOT_FOUND if the display is invalid.
+     */
+    virtual status_t addHdrLayerInfoListener(const sp<IBinder>& displayToken,
+                                             const sp<gui::IHdrLayerInfoListener>& listener) = 0;
+    /*
+     * Removes a listener that was added with addHdrLayerInfoListener.
+     *
+     * Returns NO_ERROR upon success, NAME_NOT_FOUND if the display is invalid, and BAD_VALUE if
+     *     the listener wasn't registered.
+     *
+     */
+    virtual status_t removeHdrLayerInfoListener(const sp<IBinder>& displayToken,
+                                                const sp<gui::IHdrLayerInfoListener>& listener) = 0;
+
+    /*
      * Sends a power boost to the composer. This function is asynchronous.
      *
      * boostId
@@ -578,6 +598,8 @@
         ADD_FPS_LISTENER,
         REMOVE_FPS_LISTENER,
         OVERRIDE_HDR_TYPES,
+        ADD_HDR_LAYER_INFO_LISTENER,
+        REMOVE_HDR_LAYER_INFO_LISTENER,
         // Always append new enum to the end.
     };
 
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index c38375c..7bf2e2d 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -215,6 +215,11 @@
     static status_t setDisplayBrightness(const sp<IBinder>& displayToken,
                                          const gui::DisplayBrightness& brightness);
 
+    static status_t addHdrLayerInfoListener(const sp<IBinder>& displayToken,
+                                            const sp<gui::IHdrLayerInfoListener>& listener);
+    static status_t removeHdrLayerInfoListener(const sp<IBinder>& displayToken,
+                                               const sp<gui::IHdrLayerInfoListener>& listener);
+
     /*
      * Sends a power boost to the composer. This function is asynchronous.
      *
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 5ac3f19..9da731a 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -819,6 +819,16 @@
         return NO_ERROR;
     }
 
+    status_t addHdrLayerInfoListener(const sp<IBinder>&,
+                                     const sp<gui::IHdrLayerInfoListener>&) override {
+        return NO_ERROR;
+    }
+
+    status_t removeHdrLayerInfoListener(const sp<IBinder>&,
+                                        const sp<gui::IHdrLayerInfoListener>&) override {
+        return NO_ERROR;
+    }
+
     status_t addRegionSamplingListener(const Rect& /*samplingArea*/,
                                        const sp<IBinder>& /*stopLayerHandle*/,
                                        const sp<IRegionSamplingListener>& /*listener*/) override {