DisplayManager: Add color sampling hardware query

Add calls to SurfaceControl JNI interface that allow
the DisplayManager to drive color histogram functionality.

Fixes: 112756444

Test: Boot
Test: additional test in 'atest FrameworksServicesTests:DisplayManagerServiceTest'
Change-Id: Ifa46dab53b09db62da79ad82e9687d9155ddc6da
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index ea6e017..c745c16 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -37,6 +37,7 @@
 #include <stdio.h>
 #include <system/graphics.h>
 #include <ui/DisplayInfo.h>
+#include <ui/DisplayedFrameStats.h>
 #include <ui/FrameStats.h>
 #include <ui/GraphicTypes.h>
 #include <ui/HdrCapabilities.h>
@@ -97,6 +98,16 @@
     jmethodID builder;
 } gGraphicBufferClassInfo;
 
+static struct {
+    jclass clazz;
+    jmethodID ctor;
+} gDisplayedContentSampleClassInfo;
+
+static struct {
+    jclass clazz;
+    jmethodID ctor;
+} gDisplayedContentSamplingAttributesClassInfo;
+
 // ----------------------------------------------------------------------------
 
 static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
@@ -398,6 +409,73 @@
     return javaObjectForIBinder(env, token);
 }
 
+static jobject nativeGetDisplayedContentSamplingAttributes(JNIEnv* env, jclass clazz,
+        jobject tokenObj) {
+    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+
+    ui::PixelFormat format;
+    ui::Dataspace dataspace;
+    uint8_t componentMask;
+    status_t err = SurfaceComposerClient::getDisplayedContentSamplingAttributes(
+            token, &format, &dataspace, &componentMask);
+    if (err != OK) {
+        return nullptr;
+    }
+    return env->NewObject(gDisplayedContentSamplingAttributesClassInfo.clazz,
+                          gDisplayedContentSamplingAttributesClassInfo.ctor,
+                          format, dataspace, componentMask);
+}
+
+static jboolean nativeSetDisplayedContentSamplingEnabled(JNIEnv* env, jclass clazz,
+        jobject tokenObj, jboolean enable, jint componentMask, jint maxFrames) {
+    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+    return SurfaceComposerClient::setDisplayContentSamplingEnabled(
+            token, enable, componentMask, maxFrames);
+}
+
+static jobject nativeGetDisplayedContentSample(JNIEnv* env, jclass clazz, jobject tokenObj,
+    jlong maxFrames, jlong timestamp) {
+    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+
+    DisplayedFrameStats stats;
+    status_t err = SurfaceComposerClient::getDisplayedContentSample(
+            token, maxFrames, timestamp, &stats);
+    if (err != OK) {
+        return nullptr;
+    }
+
+    jlongArray histogramComponent0 = env->NewLongArray(stats.component_0_sample.size());
+    jlongArray histogramComponent1 = env->NewLongArray(stats.component_1_sample.size());
+    jlongArray histogramComponent2 = env->NewLongArray(stats.component_2_sample.size());
+    jlongArray histogramComponent3 = env->NewLongArray(stats.component_3_sample.size());
+    if ((histogramComponent0 == nullptr) ||
+        (histogramComponent1 == nullptr) ||
+        (histogramComponent2 == nullptr) ||
+        (histogramComponent3 == nullptr)) {
+        return JNI_FALSE;
+    }
+
+    env->SetLongArrayRegion(histogramComponent0, 0,
+            stats.component_0_sample.size(),
+            reinterpret_cast<jlong*>(stats.component_0_sample.data()));
+    env->SetLongArrayRegion(histogramComponent1, 0,
+            stats.component_1_sample.size(),
+            reinterpret_cast<jlong*>(stats.component_1_sample.data()));
+    env->SetLongArrayRegion(histogramComponent2, 0,
+            stats.component_2_sample.size(),
+            reinterpret_cast<jlong*>(stats.component_2_sample.data()));
+    env->SetLongArrayRegion(histogramComponent3, 0,
+            stats.component_3_sample.size(),
+            reinterpret_cast<jlong*>(stats.component_3_sample.data()));
+    return env->NewObject(gDisplayedContentSampleClassInfo.clazz,
+                          gDisplayedContentSampleClassInfo.ctor,
+                          stats.numFrames,
+                          histogramComponent0,
+                          histogramComponent1,
+                          histogramComponent2,
+                          histogramComponent3);
+}
+
 static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj,
         jboolean secure) {
     ScopedUtfChars name(env, nameObj);
@@ -955,6 +1033,14 @@
             (void*)nativeCaptureLayers },
     {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
      (void*)nativeSetInputWindowInfo },
+    {"nativeGetDisplayedContentSamplingAttributes",
+            "(Landroid/os/IBinder;)Landroid/hardware/display/DisplayedContentSamplingAttributes;",
+            (void*)nativeGetDisplayedContentSamplingAttributes },
+    {"nativeSetDisplayedContentSamplingEnabled", "(Landroid/os/IBinder;ZII)Z",
+            (void*)nativeSetDisplayedContentSamplingEnabled },
+    {"nativeGetDisplayedContentSample",
+            "(Landroid/os/IBinder;JJ)Landroid/hardware/display/DisplayedContentSample;",
+            (void*)nativeGetDisplayedContentSample },
 };
 
 int register_android_view_SurfaceControl(JNIEnv* env)
@@ -1009,6 +1095,18 @@
     gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz,
             "createFromExisting", "(IIIIJ)Landroid/graphics/GraphicBuffer;");
 
+    jclass displayedContentSampleClazz = FindClassOrDie(env,
+            "android/hardware/display/DisplayedContentSample");
+    gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz);
+    gDisplayedContentSampleClassInfo.ctor = GetMethodIDOrDie(env,
+            displayedContentSampleClazz, "<init>", "(J[J[J[J[J)V");
+
+    jclass displayedContentSamplingAttributesClazz = FindClassOrDie(env,
+            "android/hardware/display/DisplayedContentSamplingAttributes");
+    gDisplayedContentSamplingAttributesClassInfo.clazz = MakeGlobalRefOrDie(env,
+            displayedContentSamplingAttributesClazz);
+    gDisplayedContentSamplingAttributesClassInfo.ctor = GetMethodIDOrDie(env,
+            displayedContentSamplingAttributesClazz, "<init>", "(III)V");
     return err;
 }