Plumb HDR capabilities to Display

Bug: 25684127
Change-Id: I0a4fcdc59aa1a7b295c8df03699466685300e735
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 621efa6..e7a920b 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -722,7 +722,10 @@
      * @hide
      */
     public HdrCapabilities getHdrCapabilities() {
-        return new HdrCapabilities();
+        synchronized (this) {
+            updateDisplayInfoLocked();
+            return mDisplayInfo.hdrCapabilities;
+        }
     }
 
     /**
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index ee76274..27fe687c 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -178,6 +178,9 @@
     /** The list of supported color transforms */
     public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY;
 
+    /** The display's HDR capabilities */
+    public Display.HdrCapabilities hdrCapabilities;
+
     /**
      * The logical display density which is the basis for density-independent
      * pixels.
@@ -290,6 +293,7 @@
                 && defaultModeId == other.defaultModeId
                 && colorTransformId == other.colorTransformId
                 && defaultColorTransformId == other.defaultColorTransformId
+                && Objects.equal(hdrCapabilities, other.hdrCapabilities)
                 && logicalDensityDpi == other.logicalDensityDpi
                 && physicalXDpi == other.physicalXDpi
                 && physicalYDpi == other.physicalYDpi
@@ -332,6 +336,7 @@
         defaultColorTransformId = other.defaultColorTransformId;
         supportedColorTransforms = Arrays.copyOf(
                 other.supportedColorTransforms, other.supportedColorTransforms.length);
+        hdrCapabilities = other.hdrCapabilities;
         logicalDensityDpi = other.logicalDensityDpi;
         physicalXDpi = other.physicalXDpi;
         physicalYDpi = other.physicalYDpi;
@@ -375,6 +380,7 @@
         for (int i = 0; i < nColorTransforms; i++) {
             supportedColorTransforms[i] = Display.ColorTransform.CREATOR.createFromParcel(source);
         }
+        hdrCapabilities = Display.HdrCapabilities.CREATOR.createFromParcel(source);
         logicalDensityDpi = source.readInt();
         physicalXDpi = source.readFloat();
         physicalYDpi = source.readFloat();
@@ -418,6 +424,7 @@
         for (int i = 0; i < supportedColorTransforms.length; i++) {
             supportedColorTransforms[i].writeToParcel(dest, flags);
         }
+        hdrCapabilities.writeToParcel(dest, flags);
         dest.writeInt(logicalDensityDpi);
         dest.writeFloat(physicalXDpi);
         dest.writeFloat(physicalYDpi);
@@ -614,6 +621,8 @@
         sb.append(defaultColorTransformId);
         sb.append(", supportedColorTransforms ");
         sb.append(Arrays.toString(supportedColorTransforms));
+        sb.append(", hdrCapabilities ");
+        sb.append(hdrCapabilities);
         sb.append(", rotation ");
         sb.append(rotation);
         sb.append(", density ");
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index dc9014b..7b01267 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -88,6 +88,7 @@
     private static native void nativeSetOverrideScalingMode(long nativeObject,
             int scalingMode);
     private static native IBinder nativeGetHandle(long nativeObject);
+    private static native Display.HdrCapabilities nativeGetHdrCapabilities(IBinder displayToken);
 
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
@@ -656,6 +657,13 @@
         nativeSetDisplaySize(displayToken, width, height);
     }
 
+    public static Display.HdrCapabilities getHdrCapabilities(IBinder displayToken) {
+        if (displayToken == null) {
+            throw new IllegalArgumentException("displayToken must not be null");
+        }
+        return nativeGetHdrCapabilities(displayToken);
+    }
+
     public static IBinder createDisplay(String name, boolean secure) {
         if (name == null) {
             throw new IllegalArgumentException("name must not be null");
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 5d5f856..864a0bf 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -627,7 +627,7 @@
     auto typesArray = env->NewIntArray(types.size());
     env->SetIntArrayRegion(typesArray, 0, types.size(), types.data());
 
-    return env->NewObject(gHdrCapabilitiesClassInfo.clazz, gPhysicalDisplayInfoClassInfo.ctor,
+    return env->NewObject(gHdrCapabilitiesClassInfo.clazz, gHdrCapabilitiesClassInfo.ctor,
             typesArray, capabilities.getDesiredMaxLuminance(),
             capabilities.getDesiredMaxAverageLuminance(), capabilities.getDesiredMinLuminance());
 }
@@ -693,6 +693,8 @@
             (void*)nativeGetActiveConfig },
     {"nativeSetActiveConfig", "(Landroid/os/IBinder;I)Z",
             (void*)nativeSetActiveConfig },
+    {"nativeGetHdrCapabilities", "(Landroid/os/IBinder;)Landroid/view/Display$HdrCapabilities;",
+            (void*)nativeGetHdrCapabilities },
     {"nativeClearContentFrameStats", "(J)Z",
             (void*)nativeClearContentFrameStats },
     {"nativeGetContentFrameStats", "(JLandroid/view/WindowContentFrameStats;)Z",
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index 55ba302..5ce66fa 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -165,6 +165,11 @@
     public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY;
 
     /**
+     * The HDR capabilities this display claims to support.
+     */
+    public Display.HdrCapabilities hdrCapabilities;
+
+    /**
      * The nominal apparent density of the display in DPI used for layout calculations.
      * This density is sensitive to the viewing distance.  A big TV and a tablet may have
      * the same apparent density even though the pixels on the TV are much bigger than
@@ -288,6 +293,7 @@
                 || colorTransformId != other.colorTransformId
                 || defaultColorTransformId != other.defaultColorTransformId
                 || !Arrays.equals(supportedColorTransforms, other.supportedColorTransforms)
+                || !Objects.equal(hdrCapabilities, other.hdrCapabilities)
                 || densityDpi != other.densityDpi
                 || xDpi != other.xDpi
                 || yDpi != other.yDpi
@@ -321,6 +327,7 @@
         colorTransformId = other.colorTransformId;
         defaultColorTransformId = other.defaultColorTransformId;
         supportedColorTransforms = other.supportedColorTransforms;
+        hdrCapabilities = other.hdrCapabilities;
         densityDpi = other.densityDpi;
         xDpi = other.xDpi;
         yDpi = other.yDpi;
@@ -349,6 +356,7 @@
         sb.append(", colorTransformId ").append(colorTransformId);
         sb.append(", defaultColorTransformId ").append(defaultColorTransformId);
         sb.append(", supportedColorTransforms ").append(Arrays.toString(supportedColorTransforms));
+        sb.append(", HdrCapabilities ").append(hdrCapabilities);
         sb.append(", density ").append(densityDpi);
         sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
         sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 715d2d8..7b16ea6 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -158,6 +158,7 @@
         private int mDefaultColorTransformId;
         private int mActiveColorTransformId;
         private boolean mActiveColorTransformInvalid;
+        private Display.HdrCapabilities mHdrCapabilities;
 
         private  SurfaceControl.PhysicalDisplayInfo mDisplayInfos[];
 
@@ -172,6 +173,7 @@
             } else {
                 mBacklight = null;
             }
+            mHdrCapabilities = SurfaceControl.getHdrCapabilities(displayToken);
         }
 
         public boolean updatePhysicalDisplayInfoLocked(
@@ -368,6 +370,7 @@
                 for (int i = 0; i < mSupportedColorTransforms.size(); i++) {
                     mInfo.supportedColorTransforms[i] = mSupportedColorTransforms.valueAt(i);
                 }
+                mInfo.hdrCapabilities = mHdrCapabilities;
                 mInfo.appVsyncOffsetNanos = phys.appVsyncOffsetNanos;
                 mInfo.presentationDeadlineNanos = phys.presentationDeadlineNanos;
                 mInfo.state = mState;
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 6dae397..973f04c 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -241,6 +241,7 @@
             mBaseDisplayInfo.supportedColorTransforms = Arrays.copyOf(
                     deviceInfo.supportedColorTransforms,
                     deviceInfo.supportedColorTransforms.length);
+            mBaseDisplayInfo.hdrCapabilities = deviceInfo.hdrCapabilities;
             mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
             mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
             mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;