Wire up colorMode="hdr" on VRI

Test: silkfx
Bug: 266628247
Change-Id: I6633436f38d83a0fc5bfa59a29e684a9f1712843
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index db72e29..f8f2663 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -350,7 +350,14 @@
      * @see android.R.attr#colorMode
      */
     public static final int COLOR_MODE_HDR = 2;
-    // 3 Corresponds to android::uirenderer::ColorMode::Hdr10.
+
+    /**
+     * Comparison point against COLOR_MODE_HDR that uses 1010102
+     * Only for internal test usages
+     * @hide
+     */
+    public static final int COLOR_MODE_HDR10 = 3;
+
     /**
      * Value of {@link #colorMode} indicating that the activity should use an
      * 8 bit alpha buffer if the presentation display supports it.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 480abe0..6b0f850 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -683,9 +683,10 @@
 
     private BLASTBufferQueue mBlastBufferQueue;
 
-    private boolean mUpdateSdrHdrRatioInfo = false;
-    private float mDesiredSdrHdrRatio = 1f;
-    private float mRenderSdrHdrRatio = 1f;
+    private boolean mUpdateHdrSdrRatioInfo = false;
+    private float mDesiredHdrSdrRatio = 1f;
+    private float mRenderHdrSdrRatio = 1f;
+    private Consumer<Display> mHdrSdrRatioChangedListener = null;
 
     /**
      * Child container layer of {@code mSurface} with the same bounds as its parent, and cropped to
@@ -1947,6 +1948,9 @@
     private void updateInternalDisplay(int displayId, Resources resources) {
         final Display preferredDisplay =
                 ResourcesManager.getInstance().getAdjustedDisplay(displayId, resources);
+        if (mHdrSdrRatioChangedListener != null && mDisplay != null) {
+            mDisplay.unregisterHdrSdrRatioChangedListener(mHdrSdrRatioChangedListener);
+        }
         if (preferredDisplay == null) {
             // Fallback to use default display.
             Slog.w(TAG, "Cannot get desired display with Id: " + displayId);
@@ -1955,6 +1959,9 @@
         } else {
             mDisplay = preferredDisplay;
         }
+        if (mHdrSdrRatioChangedListener != null && mDisplay != null) {
+            mDisplay.registerHdrSdrRatioChangedListener(mExecutor, mHdrSdrRatioChangedListener);
+        }
         mContext.updateDisplay(mDisplay.getDisplayId());
     }
 
@@ -4838,11 +4845,11 @@
 
                 useAsyncReport = true;
 
-                if (mUpdateSdrHdrRatioInfo) {
-                    mUpdateSdrHdrRatioInfo = false;
+                if (mUpdateHdrSdrRatioInfo) {
+                    mUpdateHdrSdrRatioInfo = false;
                     applyTransactionOnDraw(mTransaction.setExtendedRangeBrightness(
-                            getSurfaceControl(), mRenderSdrHdrRatio, mDesiredSdrHdrRatio));
-                    mAttachInfo.mThreadedRenderer.setTargetSdrHdrRatio(mRenderSdrHdrRatio);
+                            getSurfaceControl(), mRenderHdrSdrRatio, mDesiredHdrSdrRatio));
+                    mAttachInfo.mThreadedRenderer.setTargetHdrSdrRatio(mRenderHdrSdrRatio);
                 }
 
                 if (forceDraw) {
@@ -5372,6 +5379,10 @@
         if (mAttachInfo.mThreadedRenderer == null) {
             return;
         }
+        if ((colorMode == ActivityInfo.COLOR_MODE_HDR || colorMode == ActivityInfo.COLOR_MODE_HDR10)
+                && !mDisplay.isHdrSdrRatioAvailable()) {
+            colorMode = ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT;
+        }
         // TODO: Centralize this sanitization? Why do we let setting bad modes?
         // Alternatively, can we just let HWUI figure it out? Do we need to care here?
         if (colorMode != ActivityInfo.COLOR_MODE_A8
@@ -5379,17 +5390,28 @@
             colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
         }
         float desiredRatio = mAttachInfo.mThreadedRenderer.setColorMode(colorMode);
-        if (desiredRatio != mDesiredSdrHdrRatio) {
-            mDesiredSdrHdrRatio = desiredRatio;
-            mUpdateSdrHdrRatioInfo = true;
+        if (desiredRatio != mDesiredHdrSdrRatio) {
+            mDesiredHdrSdrRatio = desiredRatio;
+            mRenderHdrSdrRatio = mDisplay.getHdrSdrRatio();
+            mUpdateHdrSdrRatioInfo = true;
+
+            if (mDesiredHdrSdrRatio < 1.01f) {
+                mDisplay.unregisterHdrSdrRatioChangedListener(mHdrSdrRatioChangedListener);
+                mHdrSdrRatioChangedListener = null;
+            } else {
+                mHdrSdrRatioChangedListener = display -> {
+                    setTargetHdrSdrRatio(display.getHdrSdrRatio());
+                };
+                mDisplay.registerHdrSdrRatioChangedListener(mExecutor, mHdrSdrRatioChangedListener);
+            }
         }
     }
 
     /** happylint */
-    public void setTargetSdrHdrRatio(float ratio) {
-        if (mRenderSdrHdrRatio != ratio) {
-            mRenderSdrHdrRatio = ratio;
-            mUpdateSdrHdrRatioInfo = true;
+    public void setTargetHdrSdrRatio(float ratio) {
+        if (mRenderHdrSdrRatio != ratio) {
+            mRenderHdrSdrRatio = ratio;
+            mUpdateHdrSdrRatioInfo = true;
             invalidate();
         }
     }
@@ -5965,6 +5987,9 @@
     }
 
     final ViewRootHandler mHandler = new ViewRootHandler();
+    private final Executor mExecutor = (Runnable r) -> {
+        mHandler.post(r);
+    };
 
     /**
      * Something in the current window tells us we need to change the touch mode.  For
@@ -8950,6 +8975,10 @@
     private void destroyHardwareRenderer() {
         ThreadedRenderer hardwareRenderer = mAttachInfo.mThreadedRenderer;
 
+        if (mHdrSdrRatioChangedListener != null) {
+            mDisplay.unregisterHdrSdrRatioChangedListener(mHdrSdrRatioChangedListener);
+        }
+
         if (hardwareRenderer != null) {
             if (mHardwareRendererObserver != null) {
                 hardwareRenderer.removeObserver(mHardwareRendererObserver);
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index 0488b9d..9ed3d9c 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -667,7 +667,7 @@
     }
 
     /** @hide */
-    public void setTargetSdrHdrRatio(float ratio) {
+    public void setTargetHdrSdrRatio(float ratio) {
         if (ratio < 1.f || !Float.isFinite(ratio)) ratio = 1.f;
         nSetTargetSdrHdrRatio(mNativeProxy, ratio);
     }
diff --git a/tests/SilkFX/src/com/android/test/silkfx/common/ColorModeControls.kt b/tests/SilkFX/src/com/android/test/silkfx/common/ColorModeControls.kt
index 1bd8f6a..56ab755 100644
--- a/tests/SilkFX/src/com/android/test/silkfx/common/ColorModeControls.kt
+++ b/tests/SilkFX/src/com/android/test/silkfx/common/ColorModeControls.kt
@@ -18,10 +18,10 @@
 
 import android.content.Context
 import android.content.pm.ActivityInfo
-import android.hardware.display.DisplayManager
 import android.util.AttributeSet
 import android.util.Log
 import android.view.Display
+import android.view.View
 import android.view.Window
 import android.widget.Button
 import android.widget.LinearLayout
@@ -31,22 +31,11 @@
 import java.util.function.Consumer
 
 class ColorModeControls : LinearLayout, WindowObserver {
-    private val COLOR_MODE_HDR10 = 3
-    private val SDR_WHITE_POINTS = floatArrayOf(200f, 250f, 300f, 350f, 400f, 100f, 150f)
-
     constructor(context: Context) : this(context, null)
-    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
-        displayManager = context.getSystemService(DisplayManager::class.java)!!
-        displayId = context.getDisplayId()
-    }
+    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
 
     private var window: Window? = null
     private var currentModeDisplay: TextView? = null
-    private val displayManager: DisplayManager
-    private var targetSdrWhitePointIndex = 0
-    private var displayId: Int
-
-    private val whitePoint get() = SDR_WHITE_POINTS[targetSdrWhitePointIndex]
 
     override fun onFinishInflate() {
         super.onFinishInflate()
@@ -65,88 +54,53 @@
             setColorMode(ActivityInfo.COLOR_MODE_HDR)
         }
         findViewById<Button>(R.id.mode_hdr10)!!.setOnClickListener {
-            setColorMode(COLOR_MODE_HDR10)
+            setColorMode(ActivityInfo.COLOR_MODE_HDR10)
         }
     }
 
-    private val hdrsdrListener = Consumer<Display> { display ->
+    private val hdrSdrListener = Consumer<Display> { display ->
         Log.d("SilkFX", "HDR/SDR changed ${display.hdrSdrRatio}")
-    }
-
-    private val displayChangedListener = object : DisplayManager.DisplayListener {
-        override fun onDisplayAdded(displayId: Int) {
-            Log.d("SilkFX", "onDisplayAdded")
-        }
-
-        override fun onDisplayRemoved(displayId: Int) {
-            Log.d("SilkFX", "onDisplayRemoved")
-        }
-
-        override fun onDisplayChanged(displayId: Int) {
-            Log.d("SilkFX", "onDisplayChanged")
+        post {
+            updateModeInfoDisplay()
         }
     }
 
     override fun onAttachedToWindow() {
         super.onAttachedToWindow()
-        Log.d("SilkFX", "is hdr/sdr available: ${display.isHdrSdrRatioAvailable}; " +
-                "current ration = ${display.hdrSdrRatio}")
-        display.registerHdrSdrRatioChangedListener({ it.run() }, hdrsdrListener)
-        displayManager.registerDisplayListener(displayChangedListener, handler)
+        val hdrVis = if (display.isHdrSdrRatioAvailable) {
+            display.registerHdrSdrRatioChangedListener({ it.run() }, hdrSdrListener)
+            View.VISIBLE
+        } else {
+            View.GONE
+        }
+        findViewById<Button>(R.id.mode_hdr)!!.visibility = hdrVis
+        findViewById<Button>(R.id.mode_hdr10)!!.visibility = hdrVis
     }
 
     override fun onDetachedFromWindow() {
         super.onDetachedFromWindow()
-        display.unregisterHdrSdrRatioChangedListener(hdrsdrListener)
-        displayManager.unregisterDisplayListener(displayChangedListener)
+        display.unregisterHdrSdrRatioChangedListener(hdrSdrListener)
     }
 
     private fun setColorMode(newMode: Int) {
-        val window = window!!
-        var sdrWhitepointChanged = false
-        // Need to do this before setting the colorMode, as setting the colorMode will
-        // trigger the attribute change listener
-        if (newMode == ActivityInfo.COLOR_MODE_HDR ||
-                newMode == COLOR_MODE_HDR10) {
-            if (window.colorMode == newMode) {
-                targetSdrWhitePointIndex = (targetSdrWhitePointIndex + 1) % SDR_WHITE_POINTS.size
-                sdrWhitepointChanged = true
-            }
-            setBrightness(1.0f)
-        } else {
-            setBrightness(.4f)
-        }
-        window.colorMode = newMode
-        if (sdrWhitepointChanged) {
-            threadedRenderer?.setColorMode(newMode, whitePoint)
-        }
-        val whitePoint = whitePoint.toInt()
-        currentModeDisplay?.run {
-            text = "Current Mode: " + when (newMode) {
-                ActivityInfo.COLOR_MODE_DEFAULT -> "Default/SRGB"
-                ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT -> "Wide Gamut"
-                ActivityInfo.COLOR_MODE_HDR -> "HDR (sdr white point $whitePoint)"
-                COLOR_MODE_HDR10 -> "HDR10 (sdr white point $whitePoint)"
-                else -> "Unknown"
-            }
-        }
+        window!!.colorMode = newMode
+        updateModeInfoDisplay()
     }
 
     override fun setWindow(window: Window) {
         this.window = window
     }
 
-    private fun setBrightness(level: Float) {
-        // To keep window state in sync
-        window?.attributes?.screenBrightness = level
-        invalidate()
-        // To force an 'immediate' snap to what we want
-        // Imperfect, but close enough, synchronization by waiting for frame commit to set the value
-        viewTreeObserver.registerFrameCommitCallback {
-            try {
-                displayManager.setTemporaryBrightness(displayId, level)
-            } catch (ex: Exception) {
-                // Ignore a permission denied rejection - it doesn't meaningfully change much
+    private fun updateModeInfoDisplay() {
+        val sdrHdrRatio = display?.hdrSdrRatio ?: 1.0f
+        val colormode = window!!.colorMode
+        currentModeDisplay?.run {
+            text = "Current Mode: " + when (colormode) {
+                ActivityInfo.COLOR_MODE_DEFAULT -> "Default/SRGB"
+                ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT -> "Wide Gamut"
+                ActivityInfo.COLOR_MODE_HDR -> "HDR (sdr/hdr ratio $sdrHdrRatio)"
+                ActivityInfo.COLOR_MODE_HDR10 -> "HDR10 (sdr/hdr ratio $sdrHdrRatio)"
+                else -> "Unknown"
             }
         }
     }