[SurfaceControl] Add API to query composition color spaces.

To facilitate the need of returning color spaces about the composition
pipeline, add an API to query this information. This API will be used by Canvas
and Display, etc.

BUG: 120904891
Test: Build, flash and boot. Verify by checking returned values.
Change-Id: I97123ba1488ca76888a4c004128b4100a7c1f76c
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index ff5120d..4b4da93 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -30,6 +30,7 @@
 import android.annotation.Size;
 import android.annotation.UnsupportedAppUsage;
 import android.graphics.Bitmap;
+import android.graphics.ColorSpace;
 import android.graphics.GraphicBuffer;
 import android.graphics.Matrix;
 import android.graphics.PixelFormat;
@@ -141,6 +142,7 @@
     private static native int nativeGetActiveConfig(IBinder displayToken);
     private static native boolean nativeSetActiveConfig(IBinder displayToken, int id);
     private static native int[] nativeGetDisplayColorModes(IBinder displayToken);
+    private static native int[] nativeGetCompositionDataspaces();
     private static native int nativeGetActiveColorMode(IBinder displayToken);
     private static native boolean nativeSetActiveColorMode(IBinder displayToken,
             int colorMode);
@@ -374,6 +376,13 @@
      */
     public static final int WINDOW_TYPE_DONT_SCREENSHOT = 441731;
 
+    /**
+     * internal representation of how to interpret pixel value, used only to convert to ColorSpace.
+     */
+    private static final int INTERNAL_DATASPACE_SRGB = 142671872;
+    private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696;
+    private static final int INTERNAL_DATASPACE_SCRGB = 411107328;
+
     private void assignNativeObject(long nativeObject) {
         if (mNativeObject != 0) {
             release();
@@ -1516,6 +1525,35 @@
     }
 
     /**
+     * Returns an array of color spaces with 2 elements. The first color space is the
+     * default color space and second one is wide color gamut color space.
+     * @hide
+     */
+    public static ColorSpace[] getCompositionColorSpaces() {
+        int[] dataspaces = nativeGetCompositionDataspaces();
+        ColorSpace srgb = ColorSpace.get(ColorSpace.Named.SRGB);
+        ColorSpace[] colorSpaces = { srgb, srgb };
+        if (dataspaces.length == 2) {
+            for (int i = 0; i < 2; ++i) {
+                switch(dataspaces[i]) {
+                    case INTERNAL_DATASPACE_DISPLAY_P3:
+                        colorSpaces[i] = ColorSpace.get(ColorSpace.Named.DISPLAY_P3);
+                        break;
+                    case INTERNAL_DATASPACE_SCRGB:
+                        colorSpaces[i] = ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB);
+                        break;
+                    case INTERNAL_DATASPACE_SRGB:
+                    // Other dataspace is not recognized, use SRGB color space instead,
+                    // the default value of the array is already SRGB, thus do nothing.
+                    default:
+                        break;
+                }
+            }
+        }
+        return colorSpaces;
+    }
+
+    /**
      * @hide
      */
     @UnsupportedAppUsage
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 9ce6df1..9475daa 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -642,6 +642,27 @@
     return static_cast<jint>(SurfaceComposerClient::getActiveColorMode(token));
 }
 
+static jintArray nativeGetCompositionDataspaces(JNIEnv* env, jclass) {
+    ui::Dataspace defaultDataspace, wcgDataspace;
+    ui::PixelFormat defaultPixelFormat, wcgPixelFormat;
+    if (SurfaceComposerClient::getCompositionPreference(&defaultDataspace,
+                                                        &defaultPixelFormat,
+                                                        &wcgDataspace,
+                                                        &wcgPixelFormat) != NO_ERROR) {
+        return nullptr;
+    }
+    jintArray array = env->NewIntArray(2);
+    if (array == nullptr) {
+        jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
+        return nullptr;
+    }
+    jint* arrayValues = env->GetIntArrayElements(array, 0);
+    arrayValues[0] = static_cast<jint>(defaultDataspace);
+    arrayValues[1] = static_cast<jint>(wcgDataspace);
+    env->ReleaseIntArrayElements(array, arrayValues, 0);
+    return array;
+}
+
 static jboolean nativeSetActiveColorMode(JNIEnv* env, jclass,
         jobject tokenObj, jint colorMode) {
     sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
@@ -1016,6 +1037,8 @@
             (void*)nativeGetActiveColorMode},
     {"nativeSetActiveColorMode", "(Landroid/os/IBinder;I)Z",
             (void*)nativeSetActiveColorMode},
+    {"nativeGetCompositionDataspaces", "()[I",
+            (void*)nativeGetCompositionDataspaces},
     {"nativeGetHdrCapabilities", "(Landroid/os/IBinder;)Landroid/view/Display$HdrCapabilities;",
             (void*)nativeGetHdrCapabilities },
     {"nativeClearContentFrameStats", "(J)Z",