[SurfaceFlinger] add getDisplayedContentSample i/f

Add interface to ISurfaceComposer that can query the
graphics.composer for statistics on the displayed pixel content.

Bug: 116028618
Test: Boot
Test: ran test client, see data collected
Change-Id: Ide9b81b80c3399e7d648c7b611514e0d699120de
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 3b7ed15..d6237cb 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -1079,6 +1079,31 @@
                                                            maxFrames);
 }
 
+Error Composer::getDisplayedContentSample(Display display, uint64_t maxFrames, uint64_t timestamp,
+                                          DisplayedFrameStats* outStats) {
+    if (!outStats) {
+        return Error::BAD_PARAMETER;
+    }
+    if (!mClient_2_3) {
+        return Error::UNSUPPORTED;
+    }
+    Error error = kDefaultError;
+    mClient_2_3->getDisplayedContentSample(display, maxFrames, timestamp,
+                                           [&](const auto tmpError, auto tmpNumFrames,
+                                               const auto& tmpSamples0, const auto& tmpSamples1,
+                                               const auto& tmpSamples2, const auto& tmpSamples3) {
+                                               error = tmpError;
+                                               if (error == Error::NONE) {
+                                                   outStats->numFrames = tmpNumFrames;
+                                                   outStats->component_0_sample = tmpSamples0;
+                                                   outStats->component_1_sample = tmpSamples1;
+                                                   outStats->component_2_sample = tmpSamples2;
+                                                   outStats->component_3_sample = tmpSamples3;
+                                               }
+                                           });
+    return error;
+}
+
 CommandReader::~CommandReader()
 {
     resetData();
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 0db12a1..38ee7ad 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -30,6 +30,7 @@
 #include <composer-command-buffer/2.3/ComposerCommandBuffer.h>
 #include <gui/HdrMetadata.h>
 #include <math/mat4.h>
+#include <ui/DisplayedFrameStats.h>
 #include <ui/GraphicBuffer.h>
 #include <utils/StrongPointer.h>
 
@@ -194,6 +195,8 @@
                                                         uint8_t* outComponentMask) = 0;
     virtual Error setDisplayContentSamplingEnabled(Display display, bool enabled,
                                                    uint8_t componentMask, uint64_t maxFrames) = 0;
+    virtual Error getDisplayedContentSample(Display display, uint64_t maxFrames, uint64_t timestamp,
+                                            DisplayedFrameStats* outStats) = 0;
     virtual Error getDisplayCapabilities(Display display,
                                          std::vector<DisplayCapability>* outCapabilities) = 0;
 };
@@ -400,6 +403,8 @@
                                                 uint8_t* outComponentMask) override;
     Error setDisplayContentSamplingEnabled(Display display, bool enabled, uint8_t componentMask,
                                            uint64_t maxFrames) override;
+    Error getDisplayedContentSample(Display display, uint64_t maxFrames, uint64_t timestamp,
+                                    DisplayedFrameStats* outStats) override;
     Error getDisplayCapabilities(Display display,
                                  std::vector<DisplayCapability>* outCapabilities) override;
 
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 733a5da..d2aa4ad 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -562,6 +562,12 @@
     return static_cast<Error>(intError);
 }
 
+Error Display::getDisplayedContentSample(uint64_t maxFrames, uint64_t timestamp,
+                                         android::DisplayedFrameStats* outStats) const {
+    auto intError = mComposer.getDisplayedContentSample(mId, maxFrames, timestamp, outStats);
+    return static_cast<Error>(intError);
+}
+
 Error Display::getReleaseFences(
         std::unordered_map<Layer*, sp<Fence>>* outFences) const
 {
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 2d65051..f5cb97e 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -40,6 +40,7 @@
 #include "PowerAdvisor.h"
 
 namespace android {
+    struct DisplayedFrameStats;
     class Fence;
     class FloatRect;
     class GraphicBuffer;
@@ -243,6 +244,8 @@
     [[clang::warn_unused_result]] Error setDisplayContentSamplingEnabled(bool enabled,
                                                                          uint8_t componentMask,
                                                                          uint64_t maxFrames) const;
+    [[clang::warn_unused_result]] Error getDisplayedContentSample(
+            uint64_t maxFrames, uint64_t timestamp, android::DisplayedFrameStats* outStats) const;
     [[clang::warn_unused_result]] Error getReleaseFences(
             std::unordered_map<Layer*,
                     android::sp<android::Fence>>* outFences) const;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index b27344d..dc6faad 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -770,6 +770,16 @@
     return NO_ERROR;
 }
 
+status_t HWComposer::getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames,
+                                               uint64_t timestamp, DisplayedFrameStats* outStats) {
+    RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
+    const auto error =
+            mDisplayData[displayId].hwcDisplay->getDisplayedContentSample(maxFrames, timestamp,
+                                                                          outStats);
+    RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
+    return NO_ERROR;
+}
+
 bool HWComposer::isUsingVrComposer() const {
     return getComposer()->isUsingVrComposer();
 }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 3f1328e..4d0694e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -36,6 +36,7 @@
 
 namespace android {
 
+struct DisplayedFrameStats;
 class GraphicBuffer;
 class String8;
 class TestableSurfaceFlinger;
@@ -133,6 +134,8 @@
                                                    uint8_t* outComponentMask);
     status_t setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
                                               uint8_t componentMask, uint64_t maxFrames);
+    status_t getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames, uint64_t timestamp,
+                                       DisplayedFrameStats* outStats);
 
     // Events handling ---------------------------------------------------------
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0bda020..90eccd2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1145,6 +1145,19 @@
                                                             componentMask, maxFrames);
 }
 
+status_t SurfaceFlinger::getDisplayedContentSample(const sp<IBinder>& displayToken,
+                                                   uint64_t maxFrames, uint64_t timestamp,
+                                                   DisplayedFrameStats* outStats) const {
+    const auto display = getDisplayDevice(displayToken);
+    if (!display || !display->getId()) {
+        ALOGE("getDisplayContentSample: Bad display token: %p", displayToken.get());
+        return BAD_VALUE;
+    }
+
+    return getHwComposer().getDisplayedContentSample(*display->getId(), maxFrames, timestamp,
+                                                     outStats);
+}
+
 status_t SurfaceFlinger::enableVSyncInjections(bool enable) {
     postMessageSync(new LambdaMessage([&] {
         Mutex::Autolock _l(mStateLock);
@@ -4791,7 +4804,8 @@
         case INJECT_VSYNC:
         case SET_POWER_MODE:
         case GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES:
-        case SET_DISPLAY_CONTENT_SAMPLING_ENABLED: {
+        case SET_DISPLAY_CONTENT_SAMPLING_ENABLED:
+        case GET_DISPLAYED_CONTENT_SAMPLE: {
             if (!callingThreadHasUnscopedSurfaceFlingerAccess()) {
                 IPCThreadState* ipc = IPCThreadState::self();
                 ALOGE("Permission Denial: can't access SurfaceFlinger pid=%d, uid=%d",
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index fe2f1c26..ba92a8f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -486,6 +486,9 @@
     virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
                                                       uint8_t componentMask,
                                                       uint64_t maxFrames) const override;
+    virtual status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames,
+                                               uint64_t timestamp,
+                                               DisplayedFrameStats* outStats) const override;
 
     /* ------------------------------------------------------------------------
      * DeathRecipient interface
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 68fd8b4..dfdda09 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -116,6 +116,8 @@
     MOCK_METHOD4(getDisplayedContentSamplingAttributes,
                  Error(Display, PixelFormat*, Dataspace*, uint8_t*));
     MOCK_METHOD4(setDisplayContentSamplingEnabled, Error(Display, bool, uint8_t, uint64_t));
+    MOCK_METHOD4(getDisplayedContentSample,
+                 Error(Display, uint64_t, uint64_t, DisplayedFrameStats*));
     MOCK_METHOD2(getDisplayCapabilities, Error(Display, std::vector<DisplayCapability>*));
 };