Merge "SurfaceFlinger: Drop input for blacked out layers"
diff --git a/services/surfaceflinger/ClientCache.cpp b/services/surfaceflinger/ClientCache.cpp
index 1ef8f78..e7b8995 100644
--- a/services/surfaceflinger/ClientCache.cpp
+++ b/services/surfaceflinger/ClientCache.cpp
@@ -82,10 +82,13 @@
             return false;
         }
 
-        status_t err = token->linkToDeath(mDeathRecipient);
-        if (err != NO_ERROR) {
-            ALOGE("failed to cache buffer: could not link to death");
-            return false;
+        // Only call linkToDeath if not a local binder
+        if (token->localBinder() == nullptr) {
+            status_t err = token->linkToDeath(mDeathRecipient);
+            if (err != NO_ERROR) {
+                ALOGE("failed to cache buffer: could not link to death");
+                return false;
+            }
         }
         auto [itr, success] =
                 mBuffers.emplace(processToken,
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index 27146ab..e21b0da 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -283,8 +283,21 @@
     return Error::NONE;
 }
 
+bool Display::hasCapability(hal::DisplayCapability capability) const {
+    std::scoped_lock lock(mDisplayCapabilitiesMutex);
+    if (mDisplayCapabilities) {
+        return mDisplayCapabilities->count(capability) > 0;
+    }
+
+    ALOGW("Can't query capability %d."
+          " Display Capabilities were not queried from HWC yet",
+          static_cast<int>(capability));
+
+    return false;
+}
+
 Error Display::supportsDoze(bool* outSupport) const {
-    *outSupport = mDisplayCapabilities.count(DisplayCapability::DOZE) > 0;
+    *outSupport = hasCapability(DisplayCapability::DOZE);
     return Error::NONE;
 }
 
@@ -447,17 +460,21 @@
             auto error =
                     static_cast<Error>(mComposer.getDisplayCapabilities(mId, &tmpCapabilities));
             if (error == Error::NONE) {
+                std::scoped_lock lock(mDisplayCapabilitiesMutex);
+                mDisplayCapabilities.emplace();
                 for (auto capability : tmpCapabilities) {
-                    mDisplayCapabilities.emplace(static_cast<DisplayCapability>(capability));
+                    mDisplayCapabilities->emplace(static_cast<DisplayCapability>(capability));
                 }
             } else if (error == Error::UNSUPPORTED) {
+                std::scoped_lock lock(mDisplayCapabilitiesMutex);
+                mDisplayCapabilities.emplace();
                 if (mCapabilities.count(Capability::SKIP_CLIENT_COLOR_TRANSFORM)) {
-                    mDisplayCapabilities.emplace(DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
+                    mDisplayCapabilities->emplace(DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
                 }
                 bool dozeSupport = false;
                 error = static_cast<Error>(mComposer.getDozeSupport(mId, &dozeSupport));
                 if (error == Error::NONE && dozeSupport) {
-                    mDisplayCapabilities.emplace(DisplayCapability::DOZE);
+                    mDisplayCapabilities->emplace(DisplayCapability::DOZE);
                 }
             }
         });
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 871465d..a65efb2 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <android-base/expected.h>
+#include <android-base/thread_annotations.h>
 #include <gui/HdrMetadata.h>
 #include <math/mat4.h>
 #include <ui/HdrCapabilities.h>
@@ -79,7 +80,7 @@
     virtual hal::HWDisplayId getId() const = 0;
     virtual bool isConnected() const = 0;
     virtual void setConnected(bool connected) = 0; // For use by Device only
-    virtual const std::unordered_set<hal::DisplayCapability>& getCapabilities() const = 0;
+    virtual bool hasCapability(hal::DisplayCapability) const = 0;
     virtual bool isVsyncPeriodSwitchSupported() const = 0;
     virtual void onLayerDestroyed(hal::HWLayerId layerId) = 0;
 
@@ -175,7 +176,7 @@
             hal::DisplayRequest* outDisplayRequests,
             std::unordered_map<HWC2::Layer*, hal::LayerRequest>* outLayerRequests) override;
     hal::Error getConnectionType(ui::DisplayConnectionType*) const override;
-    hal::Error supportsDoze(bool* outSupport) const override;
+    hal::Error supportsDoze(bool* outSupport) const override EXCLUDES(mDisplayCapabilitiesMutex);
     hal::Error getHdrCapabilities(android::HdrCapabilities* outCapabilities) const override;
     hal::Error getDisplayedContentSamplingAttributes(hal::PixelFormat* outFormat,
                                                      hal::Dataspace* outDataspace,
@@ -214,9 +215,7 @@
     hal::HWDisplayId getId() const override { return mId; }
     bool isConnected() const override { return mIsConnected; }
     void setConnected(bool connected) override; // For use by Device only
-    const std::unordered_set<hal::DisplayCapability>& getCapabilities() const override {
-        return mDisplayCapabilities;
-    };
+    bool hasCapability(hal::DisplayCapability) const override EXCLUDES(mDisplayCapabilitiesMutex);
     bool isVsyncPeriodSwitchSupported() const override;
     void onLayerDestroyed(hal::HWLayerId layerId) override;
 
@@ -243,8 +242,10 @@
     using Layers = std::unordered_map<hal::HWLayerId, std::weak_ptr<HWC2::impl::Layer>>;
     Layers mLayers;
 
+    mutable std::mutex mDisplayCapabilitiesMutex;
     std::once_flag mDisplayCapabilityQueryFlag;
-    std::unordered_set<hal::DisplayCapability> mDisplayCapabilities;
+    std::optional<std::unordered_set<hal::DisplayCapability>> mDisplayCapabilities
+            GUARDED_BY(mDisplayCapabilitiesMutex);
 };
 
 } // namespace impl
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 256bca9..c63ba0e 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -183,7 +183,7 @@
 bool HWComposer::hasDisplayCapability(HalDisplayId displayId,
                                       hal::DisplayCapability capability) const {
     RETURN_IF_INVALID_DISPLAY(displayId, false);
-    return mDisplayData.at(displayId).hwcDisplay->getCapabilities().count(capability) > 0;
+    return mDisplayData.at(displayId).hwcDisplay->hasCapability(capability);
 }
 
 std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hal::HWDisplayId hwcDisplayId,
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 0789e8d..ec81e63 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -30,6 +30,8 @@
 #include <SkRect.h>
 #include <SkSurface.h>
 #include <gui/IProducerListener.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/SurfaceControl.h>
 
 #undef LOG_TAG
 #define LOG_TAG "RefreshRateOverlay"
@@ -190,35 +192,30 @@
 }
 
 bool RefreshRateOverlay::createLayer() {
-    int32_t layerId;
-    const status_t ret =
-            mFlinger.createLayer(String8("RefreshRateOverlay"), mClient,
-                                 SevenSegmentDrawer::getWidth(), SevenSegmentDrawer::getHeight(),
-                                 PIXEL_FORMAT_RGBA_8888,
-                                 ISurfaceComposerClient::eFXSurfaceBufferState, LayerMetadata(),
-                                 &mIBinder, &mGbp, nullptr, &layerId);
-    if (ret) {
+    mSurfaceControl =
+            SurfaceComposerClient::getDefault()
+                    ->createSurface(String8("RefreshRateOverlay"), SevenSegmentDrawer::getWidth(),
+                                    SevenSegmentDrawer::getHeight(), PIXEL_FORMAT_RGBA_8888,
+                                    ISurfaceComposerClient::eFXSurfaceBufferState);
+
+    if (!mSurfaceControl) {
         ALOGE("failed to create buffer state layer");
         return false;
     }
 
-    mLayer = mClient->getLayerUser(mIBinder);
-    mLayer->setFrameRate(Layer::FrameRate(Fps(0.0f), Layer::FrameRateCompatibility::NoVote));
-    mLayer->setIsAtRoot(true);
-
-    // setting Layer's Z requires resorting layersSortedByZ
-    ssize_t idx = mFlinger.mDrawingState.layersSortedByZ.indexOf(mLayer);
-    if (mLayer->setLayer(INT32_MAX - 2) && idx >= 0) {
-        mFlinger.mDrawingState.layersSortedByZ.removeAt(idx);
-        mFlinger.mDrawingState.layersSortedByZ.add(mLayer);
-    }
+    SurfaceComposerClient::Transaction t;
+    t.setFrameRate(mSurfaceControl, 0.0f,
+                   static_cast<int8_t>(Layer::FrameRateCompatibility::NoVote),
+                   static_cast<int8_t>(scheduler::Seamlessness::OnlySeamless));
+    t.setLayer(mSurfaceControl, INT32_MAX - 2);
+    t.apply();
 
     return true;
 }
 
-const std::vector<std::shared_ptr<renderengine::ExternalTexture>>&
-RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) {
-    ui::Transform::RotationFlags transformHint = mLayer->getTransformHint();
+const std::vector<sp<GraphicBuffer>>& RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) {
+    ui::Transform::RotationFlags transformHint =
+            static_cast<ui::Transform::RotationFlags>(mSurfaceControl->getTransformHint());
     // Tell SurfaceFlinger about the pre-rotation on the buffer.
     const auto transform = [&] {
         switch (transformHint) {
@@ -230,7 +227,10 @@
                 return ui::Transform::ROT_0;
         }
     }();
-    mLayer->setTransform(transform);
+
+    SurfaceComposerClient::Transaction t;
+    t.setTransform(mSurfaceControl, transform);
+    t.apply();
 
     if (mBufferCache.find(transformHint) == mBufferCache.end() ||
         mBufferCache.at(transformHint).find(fps) == mBufferCache.at(transformHint).end()) {
@@ -249,16 +249,7 @@
         colorBase.fA = ALPHA;
         SkColor color = colorBase.toSkColor();
         auto buffers = SevenSegmentDrawer::draw(fps, color, transformHint, mShowSpinner);
-        std::vector<std::shared_ptr<renderengine::ExternalTexture>> textures;
-        std::transform(buffers.begin(), buffers.end(), std::back_inserter(textures),
-                       [&](const auto& buffer) -> std::shared_ptr<renderengine::ExternalTexture> {
-                           return std::make_shared<
-                                   renderengine::ExternalTexture>(buffer,
-                                                                  mFlinger.getRenderEngine(),
-                                                                  renderengine::ExternalTexture::
-                                                                          Usage::READABLE);
-                       });
-        mBufferCache[transformHint].emplace(fps, textures);
+        mBufferCache[transformHint].emplace(fps, buffers);
     }
 
     return mBufferCache[transformHint][fps];
@@ -271,30 +262,26 @@
     Rect frame((3 * width) >> 4, height >> 5);
     frame.offsetBy(width >> 5, height >> 4);
 
-    layer_state_t::matrix22_t matrix;
-    matrix.dsdx = frame.getWidth() / static_cast<float>(SevenSegmentDrawer::getWidth());
-    matrix.dtdx = 0;
-    matrix.dtdy = 0;
-    matrix.dsdy = frame.getHeight() / static_cast<float>(SevenSegmentDrawer::getHeight());
-    mLayer->setMatrix(matrix, true);
-    mLayer->setPosition(frame.left, frame.top);
-    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
+    SurfaceComposerClient::Transaction t;
+    t.setMatrix(mSurfaceControl,
+                frame.getWidth() / static_cast<float>(SevenSegmentDrawer::getWidth()), 0, 0,
+                frame.getHeight() / static_cast<float>(SevenSegmentDrawer::getHeight()));
+    t.setPosition(mSurfaceControl, frame.left, frame.top);
+    t.apply();
 }
 
 void RefreshRateOverlay::setLayerStack(ui::LayerStack stack) {
-    mLayer->setLayerStack(stack);
-    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
+    SurfaceComposerClient::Transaction t;
+    t.setLayerStack(mSurfaceControl, stack);
+    t.apply();
 }
 
 void RefreshRateOverlay::changeRefreshRate(const Fps& fps) {
     mCurrentFps = fps.getIntValue();
     auto buffer = getOrCreateBuffers(*mCurrentFps)[mFrame];
-    mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, true, {},
-                      mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */),
-                      std::nullopt /* dequeueTime */, FrameTimelineInfo{},
-                      nullptr /* releaseBufferListener */, nullptr /* releaseBufferEndpoint */);
-
-    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
+    SurfaceComposerClient::Transaction t;
+    t.setBuffer(mSurfaceControl, buffer);
+    t.apply();
 }
 
 void RefreshRateOverlay::onInvalidate() {
@@ -303,12 +290,9 @@
     const auto& buffers = getOrCreateBuffers(*mCurrentFps);
     mFrame = (mFrame + 1) % buffers.size();
     auto buffer = buffers[mFrame];
-    mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, true, {},
-                      mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */),
-                      std::nullopt /* dequeueTime */, FrameTimelineInfo{},
-                      nullptr /* releaseBufferListener */, nullptr /* releaseBufferEndpoint */);
-
-    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
+    SurfaceComposerClient::Transaction t;
+    t.setBuffer(mSurfaceControl, buffer);
+    t.apply();
 }
 
 } // namespace android
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index 63ae383..354510a 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -37,6 +37,7 @@
 class IGraphicBufferProducer;
 class Layer;
 class SurfaceFlinger;
+class SurfaceControl;
 
 class RefreshRateOverlay {
 public:
@@ -70,18 +71,16 @@
     };
 
     bool createLayer();
-    const std::vector<std::shared_ptr<renderengine::ExternalTexture>>& getOrCreateBuffers(
-            uint32_t fps);
+
+    const std::vector<sp<GraphicBuffer>>& getOrCreateBuffers(uint32_t fps);
 
     SurfaceFlinger& mFlinger;
     const sp<Client> mClient;
-    sp<Layer> mLayer;
     sp<IBinder> mIBinder;
     sp<IGraphicBufferProducer> mGbp;
 
-    std::unordered_map<
-            ui::Transform::RotationFlags,
-            std::unordered_map<int, std::vector<std::shared_ptr<renderengine::ExternalTexture>>>>
+    std::unordered_map<ui::Transform::RotationFlags,
+                       std::unordered_map<int, std::vector<sp<GraphicBuffer>>>>
             mBufferCache;
     std::optional<int> mCurrentFps;
     int mFrame = 0;
@@ -94,6 +93,8 @@
     // Interpolate the colors between these values.
     const uint32_t mLowFps;
     const uint32_t mHighFps;
+
+    sp<SurfaceControl> mSurfaceControl;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
index c3919d9..fe1544e 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockHWC2.h
@@ -30,8 +30,7 @@
     MOCK_METHOD(hal::HWDisplayId, getId, (), (const, override));
     MOCK_METHOD(bool, isConnected, (), (const, override));
     MOCK_METHOD(void, setConnected, (bool), (override));
-    MOCK_METHOD(const std::unordered_set<hal::DisplayCapability> &, getCapabilities, (),
-                (const, override));
+    MOCK_METHOD(bool, hasCapability, (hal::DisplayCapability), (const, override));
     MOCK_METHOD(bool, isVsyncPeriodSwitchSupported, (), (const, override));
     MOCK_METHOD(void, onLayerDestroyed, (hal::HWLayerId), (override));