[sf] Implement addSamplingListener

Implements ISurfaceComposer::addSamplingListener, which allows a client
to receive streaming median luma updates for a given region of the
screen.

Bug: 119639245
Test: Manual using SamplingDemo in libgui
Test: Automated libgui_test in Ic85a97f475a3414a79d3719bbd0b2b648bbccfb0
Change-Id: Ic52359aeab884e734a806372be0eb4e327c45298
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8530309..6d10986 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -401,6 +401,9 @@
     property_get("debug.sf.use_smart_90_for_video", value, "0");
     mUseSmart90ForVideo = atoi(value);
 
+    property_get("debug.sf.luma_sampling", value, "1");
+    mLumaSampling = atoi(value);
+
     const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
     mVsyncModulator.setPhaseOffsets(early, gl, late);
 
@@ -1308,17 +1311,20 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::addRegionSamplingListener(
-        const Rect& /*samplingArea*/, const sp<IBinder>& /*stopLayerHandle*/,
-        const sp<IRegionSamplingListener>& /*listener*/) {
+status_t SurfaceFlinger::addRegionSamplingListener(const Rect& samplingArea,
+                                                   const sp<IBinder>& stopLayerHandle,
+                                                   const sp<IRegionSamplingListener>& listener) {
+    if (!listener) {
+        return BAD_VALUE;
+    }
+    mRegionSamplingThread->addListener(samplingArea, stopLayerHandle, listener);
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeRegionSamplingListener(
-        const sp<IRegionSamplingListener>& /*listener*/) {
+status_t SurfaceFlinger::removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) {
+    mRegionSamplingThread->removeListener(listener);
     return NO_ERROR;
 }
-
 // ----------------------------------------------------------------------------
 
 sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
@@ -2172,6 +2178,10 @@
     mTransactionCompletedThread.addPresentFence(mPreviousPresentFence);
     mTransactionCompletedThread.sendCallbacks();
 
+    if (mLumaSampling) {
+        mRegionSamplingThread->sampleNow();
+    }
+
     ASSERT_ON_STACK_GUARD();
 }
 #pragma clang optimize on // b/119477596
@@ -5475,6 +5485,13 @@
                                              static_cast<android_pixel_format>(reqPixelFormat), 1,
                                              usage, "screenshot");
 
+    return captureScreenCore(renderArea, traverseLayers, *outBuffer, useIdentityTransform);
+}
+
+status_t SurfaceFlinger::captureScreenCore(RenderArea& renderArea,
+                                           TraverseLayersFunction traverseLayers,
+                                           const sp<GraphicBuffer>& buffer,
+                                           bool useIdentityTransform) {
     // This mutex protects syncFd and captureResult for communication of the return values from the
     // main thread back to this Binder thread
     std::mutex captureMutex;
@@ -5502,7 +5519,7 @@
         {
             Mutex::Autolock _l(mStateLock);
             renderArea.render([&] {
-                result = captureScreenImplLocked(renderArea, traverseLayers, (*outBuffer).get(),
+                result = captureScreenImplLocked(renderArea, traverseLayers, buffer.get(),
                                                  useIdentityTransform, forSystem, &fd);
             });
         }