Merge "SF: Add defensive check on luma sampling"
diff --git a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
index 5b66b92..ccde12a 100644
--- a/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
+++ b/libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl
@@ -54,4 +54,9 @@
 
     long getVersionCodeForPackage(in String packageName);
 
+    /**
+     * Return if each app, identified by its package name allows its audio to be recorded.
+     * Unknown packages are mapped to false.
+     */
+    boolean[] isAudioPlaybackCaptureAllowed(in @utf8InCpp String[] packageNames);
 }
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index f83270d..400daf0 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -833,6 +833,33 @@
         }
         return reply.readInt32();
     }
+
+    virtual status_t getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
+                                              std::vector<int32_t>* outAllowedConfigs) {
+        if (!outAllowedConfigs) return BAD_VALUE;
+        Parcel data, reply;
+        status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        if (result != NO_ERROR) {
+            ALOGE("getAllowedDisplayConfigs failed to writeInterfaceToken: %d", result);
+            return result;
+        }
+        result = data.writeStrongBinder(displayToken);
+        if (result != NO_ERROR) {
+            ALOGE("getAllowedDisplayConfigs failed to writeStrongBinder: %d", result);
+            return result;
+        }
+        result = remote()->transact(BnSurfaceComposer::GET_ALLOWED_DISPLAY_CONFIGS, data, &reply);
+        if (result != NO_ERROR) {
+            ALOGE("getAllowedDisplayConfigs failed to transact: %d", result);
+            return result;
+        }
+        result = reply.readInt32Vector(outAllowedConfigs);
+        if (result != NO_ERROR) {
+            ALOGE("getAllowedDisplayConfigs failed to readInt32Vector: %d", result);
+            return result;
+        }
+        return reply.readInt32();
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -1354,6 +1381,15 @@
             reply->writeInt32(result);
             return result;
         }
+        case GET_ALLOWED_DISPLAY_CONFIGS: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IBinder> displayToken = data.readStrongBinder();
+            std::vector<int32_t> allowedConfigs;
+            status_t result = getAllowedDisplayConfigs(displayToken, &allowedConfigs);
+            reply->writeInt32Vector(allowedConfigs);
+            reply->writeInt32(result);
+            return result;
+        }
         default: {
             return BBinder::onTransact(code, data, reply, flags);
         }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index d583e6d..7a39222 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1388,6 +1388,12 @@
                                                                            allowedConfigs);
 }
 
+status_t SurfaceComposerClient::getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
+                                                         std::vector<int32_t>* outAllowedConfigs) {
+    return ComposerService::getComposerService()->getAllowedDisplayConfigs(displayToken,
+                                                                           outAllowedConfigs);
+}
+
 status_t SurfaceComposerClient::getDisplayColorModes(const sp<IBinder>& display,
         Vector<ColorMode>* outColorModes) {
     return ComposerService::getComposerService()->getDisplayColorModes(display, outColorModes);
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index eedd5f5..0e576ca 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -368,6 +368,14 @@
      */
     virtual status_t setAllowedDisplayConfigs(const sp<IBinder>& displayToken,
                                               const std::vector<int32_t>& allowedConfigs) = 0;
+
+    /*
+     * Returns the allowed display configurations currently set.
+     * The allowedConfigs in a vector of indexes corresponding to the configurations
+     * returned from getDisplayConfigs().
+     */
+    virtual status_t getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
+                                              std::vector<int32_t>* outAllowedConfigs) = 0;
 };
 
 // ----------------------------------------------------------------------------
@@ -416,6 +424,7 @@
         ADD_REGION_SAMPLING_LISTENER,
         REMOVE_REGION_SAMPLING_LISTENER,
         SET_ALLOWED_DISPLAY_CONFIGS,
+        GET_ALLOWED_DISPLAY_CONFIGS,
         // Always append new enum to the end.
     };
 
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 4621a34..e062339 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -117,6 +117,12 @@
     static status_t setAllowedDisplayConfigs(const sp<IBinder>& displayToken,
                                              const std::vector<int32_t>& allowedConfigs);
 
+    // Returns the allowed display configurations currently set.
+    // The allowedConfigs in a vector of indexes corresponding to the configurations
+    // returned from getDisplayConfigs().
+    static status_t getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
+                                             std::vector<int32_t>* outAllowedConfigs);
+
     // Gets the list of supported color modes for the given display
     static status_t getDisplayColorModes(const sp<IBinder>& display,
             Vector<ui::ColorMode>* outColorModes);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 7f1dc84..a7599e0 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -683,6 +683,10 @@
                                       const std::vector<int32_t>& /*allowedConfigs*/) override {
         return NO_ERROR;
     }
+    status_t getAllowedDisplayConfigs(const sp<IBinder>& /*displayToken*/,
+                                      std::vector<int32_t>* /*outAllowedConfigs*/) override {
+        return NO_ERROR;
+    }
 
 protected:
     IBinder* onAsBinder() override { return nullptr; }
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
index d7696f9..a73705b 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -23,6 +23,7 @@
 #include <binder/IResultReceiver.h>
 #include <binder/Parcel.h>
 #include <binder/PermissionCache.h>
+#include <cutils/properties.h>
 #include <private/android_filesystem_config.h>
 #include <utils/String8.h>
 #include <utils/Trace.h>
@@ -38,6 +39,7 @@
 namespace {
 status_t cmdHelp(int out);
 status_t cmdVkjson(int out, int err);
+void dumpGameDriverInfo(std::string* result);
 } // namespace
 
 const String16 sDump("android.permission.DUMP");
@@ -96,7 +98,11 @@
         }
 
         if (dumpAll) {
+            dumpGameDriverInfo(&result);
+            result.append("\n");
+
             mGpuStats->dump(Vector<String16>(), &result);
+            result.append("\n");
         }
     }
 
@@ -137,6 +143,18 @@
     return NO_ERROR;
 }
 
+void dumpGameDriverInfo(std::string* result) {
+    if (!result) return;
+
+    char stableGameDriver[PROPERTY_VALUE_MAX] = {};
+    property_get("ro.gfx.driver.0", stableGameDriver, "unsupported");
+    StringAppendF(result, "Stable Game Driver: %s\n", stableGameDriver);
+
+    char preReleaseGameDriver[PROPERTY_VALUE_MAX] = {};
+    property_get("ro.gfx.driver.1", preReleaseGameDriver, "unsupported");
+    StringAppendF(result, "Pre-release Game Driver: %s\n", preReleaseGameDriver);
+}
+
 } // anonymous namespace
 
 } // namespace android
diff --git a/services/surfaceflinger/AllowedDisplayConfigs.h b/services/surfaceflinger/AllowedDisplayConfigs.h
index e3b9c1f..7ca62ea 100644
--- a/services/surfaceflinger/AllowedDisplayConfigs.h
+++ b/services/surfaceflinger/AllowedDisplayConfigs.h
@@ -54,6 +54,12 @@
         return (std::find(mConfigs.begin(), mConfigs.end(), config) != mConfigs.end());
     }
 
+    void getAllowedConfigs(std::vector<int32_t>* outConfigs) const {
+        if (outConfigs) {
+            *outConfigs = mConfigs;
+        }
+    }
+
 private:
     // add a config to the allowed config set
     void addConfig(int32_t config) { mConfigs.push_back(config); }
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index 02383a6..2d6d33c 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -49,8 +49,6 @@
     Region::const_iterator const tail = region.end();
     // Use a lambda do avoid writing the object header when the object is empty
     RegionProto* regionProto = getRegionProto();
-    uint64_t address = reinterpret_cast<uint64_t>(&region);
-    regionProto->set_id(address);
     while (head != tail) {
         std::function<RectProto*()> getProtoRect = [&]() { return regionProto->add_rect(); };
         writeToProto(*head, getProtoRect);
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index cbc7ada..bd8548c 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -119,8 +119,9 @@
 }
 } // anonymous namespace
 
-std::vector<float> sampleBuffer(const sp<GraphicBuffer>& buffer, const Point& leftTop,
-                                const std::vector<RegionSamplingThread::Descriptor>& descriptors) {
+std::vector<float> RegionSamplingThread::sampleBuffer(
+        const sp<GraphicBuffer>& buffer, const Point& leftTop,
+        const std::vector<RegionSamplingThread::Descriptor>& descriptors) {
     void* data_raw = nullptr;
     buffer->lock(GRALLOC_USAGE_SW_READ_OFTEN, &data_raw);
     std::shared_ptr<uint32_t> data(reinterpret_cast<uint32_t*>(data_raw),
@@ -150,7 +151,7 @@
         descriptors.emplace_back(descriptor);
     }
 
-    Rect sampledArea = sampleRegion.bounds();
+    const Rect sampledArea = sampleRegion.bounds();
 
     sp<const DisplayDevice> device = mFlinger.getDefaultDisplayDevice();
     DisplayRenderArea renderArea(device, sampledArea, sampledArea.getWidth(),
@@ -174,8 +175,8 @@
             }
 
             // Compute the layer's position on the screen
-            Rect bounds = Rect(layer->getBounds());
-            ui::Transform transform = layer->getTransform();
+            const Rect bounds = Rect(layer->getBounds());
+            const ui::Transform transform = layer->getTransform();
             constexpr bool roundOutwards = true;
             Rect transformed = transform.transform(bounds, roundOutwards);
 
@@ -215,7 +216,7 @@
     //
     // To avoid this, we drop the mutex while we call into SF.
     mMutex.unlock();
-    mFlinger.captureScreenCore(renderArea, traverseLayers, buffer, false);
+    mFlinger.captureScreenCommon(renderArea, traverseLayers, buffer, false);
     mMutex.lock();
 
     std::vector<Descriptor> activeDescriptors;
@@ -229,6 +230,8 @@
     std::vector<float> lumas = sampleBuffer(buffer, sampledArea.leftTop(), activeDescriptors);
 
     if (lumas.size() != activeDescriptors.size()) {
+        ALOGW("collected %zu median luma values for %zu descriptors", lumas.size(),
+              activeDescriptors.size());
         return;
     }
 
diff --git a/services/surfaceflinger/RegionSamplingThread.h b/services/surfaceflinger/RegionSamplingThread.h
index bf59007..ab06513 100644
--- a/services/surfaceflinger/RegionSamplingThread.h
+++ b/services/surfaceflinger/RegionSamplingThread.h
@@ -38,11 +38,16 @@
     explicit RegionSamplingThread(SurfaceFlinger& flinger);
     ~RegionSamplingThread();
 
+    // Add a listener to receive luma notifications. The luma reported via listener will
+    // report the median luma for the layers under the stopLayerHandle, in the samplingArea region.
     void addListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle,
                      const sp<IRegionSamplingListener>& listener);
+    // Remove the listener to stop receiving median luma notifications.
     void removeListener(const sp<IRegionSamplingListener>& listener);
+    // Instruct the thread to perform a median luma sampling on the layers.
     void sampleNow();
 
+private:
     struct Descriptor {
         Rect area = Rect::EMPTY_RECT;
         wp<Layer> stopLayer;
@@ -54,8 +59,10 @@
             return std::hash<IBinder*>()(p.unsafe_get());
         }
     };
+    std::vector<float> sampleBuffer(
+            const sp<GraphicBuffer>& buffer, const Point& leftTop,
+            const std::vector<RegionSamplingThread::Descriptor>& descriptors);
 
-private:
     void binderDied(const wp<IBinder>& who) override;
 
     void captureSample() REQUIRES(mMutex);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8ec411f..cd63a0e 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4915,6 +4915,7 @@
         case GET_HDR_CAPABILITIES:
         case SET_ACTIVE_CONFIG:
         case SET_ALLOWED_DISPLAY_CONFIGS:
+        case GET_ALLOWED_DISPLAY_CONFIGS:
         case SET_ACTIVE_COLOR_MODE:
         case INJECT_VSYNC:
         case SET_POWER_MODE:
@@ -5498,13 +5499,13 @@
                                              static_cast<android_pixel_format>(reqPixelFormat), 1,
                                              usage, "screenshot");
 
-    return captureScreenCore(renderArea, traverseLayers, *outBuffer, useIdentityTransform);
+    return captureScreenCommon(renderArea, traverseLayers, *outBuffer, useIdentityTransform);
 }
 
-status_t SurfaceFlinger::captureScreenCore(RenderArea& renderArea,
-                                           TraverseLayersFunction traverseLayers,
-                                           const sp<GraphicBuffer>& buffer,
-                                           bool useIdentityTransform) {
+status_t SurfaceFlinger::captureScreenCommon(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;
@@ -5811,6 +5812,36 @@
     return NO_ERROR;
 }
 
+status_t SurfaceFlinger::getAllowedDisplayConfigs(const android::sp<android::IBinder>& displayToken,
+                                                  std::vector<int32_t>* outAllowedConfigs) {
+    ATRACE_CALL();
+
+    if (!displayToken) {
+        ALOGE("getAllowedDisplayConfigs: displayToken is null");
+        return BAD_VALUE;
+    }
+
+    if (!outAllowedConfigs) {
+        ALOGE("getAllowedDisplayConfigs: outAllowedConfigs is null");
+        return BAD_VALUE;
+    }
+
+    ConditionalLock stateLock(mStateLock, std::this_thread::get_id() != mMainThreadId);
+    const auto displayId = getPhysicalDisplayIdLocked(displayToken);
+    if (!displayId) {
+        ALOGE("getAllowedDisplayConfigs: display not found");
+        return NAME_NOT_FOUND;
+    }
+
+    std::lock_guard allowedConfigLock(mAllowedConfigsLock);
+    auto allowedConfigIterator = mAllowedConfigs.find(displayId.value());
+    if (allowedConfigIterator != mAllowedConfigs.end()) {
+        allowedConfigIterator->second->getAllowedConfigs(outAllowedConfigs);
+    }
+
+    return NO_ERROR;
+}
+
 // ----------------------------------------------------------------------------
 
 void SetInputWindowsListener::onSetInputWindowsFinished() {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 76d0675..8f80175 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -489,6 +489,8 @@
     status_t removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) override;
     status_t setAllowedDisplayConfigs(const sp<IBinder>& displayToken,
                                       const std::vector<int32_t>& allowedConfigs) override;
+    status_t getAllowedDisplayConfigs(const sp<IBinder>& displayToken,
+                                      std::vector<int32_t>* outAllowedConfigs) override;
 
     /* ------------------------------------------------------------------------
      * DeathRecipient interface
@@ -643,8 +645,8 @@
     status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
                                  sp<GraphicBuffer>* outBuffer, const ui::PixelFormat reqPixelFormat,
                                  bool useIdentityTransform);
-    status_t captureScreenCore(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
-                               const sp<GraphicBuffer>& buffer, bool useIdentityTransform);
+    status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
+                                 const sp<GraphicBuffer>& buffer, bool useIdentityTransform);
     status_t captureScreenImplLocked(const RenderArea& renderArea,
                                      TraverseLayersFunction traverseLayers,
                                      ANativeWindowBuffer* buffer, bool useIdentityTransform,
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
index 7ab57f9..7288232 100644
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
@@ -132,7 +132,6 @@
 
 LayerProtoParser::Region LayerProtoParser::generateRegion(const RegionProto& regionProto) {
     LayerProtoParser::Region region;
-    region.id = regionProto.id();
     for (int i = 0; i < regionProto.rect_size(); i++) {
         const RectProto& rectProto = regionProto.rect(i);
         region.rects.push_back(generateRect(rectProto));
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index a0fb0a0..fd4695e 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -117,7 +117,7 @@
 }
 
 message RegionProto {
-  uint64 id = 1;
+  reserved 1;  // Previously: uint64 id
   repeated RectProto rect = 2;
 }
 
diff --git a/services/surfaceflinger/tests/unittests/IdleTimerTest.cpp b/services/surfaceflinger/tests/unittests/IdleTimerTest.cpp
index 5e82225..ea39bf5 100644
--- a/services/surfaceflinger/tests/unittests/IdleTimerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/IdleTimerTest.cpp
@@ -140,7 +140,7 @@
                                                         mExpiredTimerCallback.getInvocable());
     // The start hasn't happened, so the callback does not happen.
     EXPECT_FALSE(mExpiredTimerCallback.waitForCall(waitTimeForUnexpected3msCallback).has_value());
-    EXPECT_FALSE(mResetTimerCallback.waitForCall(1us).has_value());
+    EXPECT_FALSE(mResetTimerCallback.waitForCall().has_value());
     mIdleTimer->stop();
     // Final quick check that no more callback were observed.
     EXPECT_FALSE(mExpiredTimerCallback.waitForCall(0ms).has_value());
@@ -159,7 +159,7 @@
     EXPECT_FALSE(mExpiredTimerCallback.waitForCall(waitTimeForUnexpected3msCallback).has_value());
     // Once reset, it should generate another
     mIdleTimer->reset();
-    EXPECT_TRUE(mResetTimerCallback.waitForCall(1ms).has_value());
+    EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
     EXPECT_TRUE(mExpiredTimerCallback.waitForCall(waitTimeForExpected3msCallback).has_value());
     mIdleTimer->stop();
     // Final quick check that no more callback were observed.
@@ -171,7 +171,7 @@
     mIdleTimer = std::make_unique<scheduler::IdleTimer>(3ms, mResetTimerCallback.getInvocable(),
                                                         mExpiredTimerCallback.getInvocable());
     mIdleTimer->start();
-    EXPECT_TRUE(mResetTimerCallback.waitForCall(1us).has_value());
+    EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
     EXPECT_TRUE(mExpiredTimerCallback.waitForCall(waitTimeForExpected3msCallback).has_value());
     mIdleTimer->stop();
 }
@@ -180,21 +180,21 @@
     mIdleTimer = std::make_unique<scheduler::IdleTimer>(3ms, mResetTimerCallback.getInvocable(),
                                                         mExpiredTimerCallback.getInvocable());
     mIdleTimer->start();
-    EXPECT_TRUE(mResetTimerCallback.waitForCall(1ms).has_value());
+    EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
     EXPECT_TRUE(mExpiredTimerCallback.waitForCall(waitTimeForExpected3msCallback).has_value());
 
     mIdleTimer->stop();
     clearPendingCallbacks();
     mIdleTimer->reset();
     EXPECT_FALSE(mExpiredTimerCallback.waitForCall(waitTimeForUnexpected3msCallback).has_value());
-    EXPECT_FALSE(mResetTimerCallback.waitForCall(1ms).has_value());
+    EXPECT_FALSE(mResetTimerCallback.waitForCall().has_value());
 }
 
 TEST_F(IdleTimerTest, noCallbacksAfterStopTest) {
     mIdleTimer = std::make_unique<scheduler::IdleTimer>(3ms, mResetTimerCallback.getInvocable(),
                                                         mExpiredTimerCallback.getInvocable());
     mIdleTimer->start();
-    EXPECT_TRUE(mResetTimerCallback.waitForCall(1ms).has_value());
+    EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value());
 
     mIdleTimer->stop();
     clearPendingCallbacks();
@@ -202,7 +202,7 @@
 
     // No more idle events should be observed
     EXPECT_FALSE(mExpiredTimerCallback.waitForCall(waitTimeForUnexpected3msCallback).has_value());
-    EXPECT_FALSE(mResetTimerCallback.waitForCall(1ms).has_value());
+    EXPECT_FALSE(mResetTimerCallback.waitForCall().has_value());
 }
 
 } // namespace