Merge "Introduce InputConfig::SENSITIVE_FOR_TRACING" into main
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 42dd691..54457fc 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -44,6 +44,7 @@
 int BpBinder::sNumTrackedUids = 0;
 std::atomic_bool BpBinder::sCountByUidEnabled(false);
 binder_proxy_limit_callback BpBinder::sLimitCallback;
+binder_proxy_warning_callback BpBinder::sWarningCallback;
 bool BpBinder::sBinderProxyThrottleCreate = false;
 
 static StaticString16 kDescriptorUninit(u"");
@@ -52,6 +53,9 @@
 uint32_t BpBinder::sBinderProxyCountHighWatermark = 2500;
 // Another arbitrary value a binder count needs to drop below before another callback will be called
 uint32_t BpBinder::sBinderProxyCountLowWatermark = 2000;
+// Arbitrary value between low and high watermark on a bad behaving app to
+// trigger a warning callback.
+uint32_t BpBinder::sBinderProxyCountWarningWatermark = 2250;
 
 std::atomic<uint32_t> BpBinder::sBinderProxyCount(0);
 std::atomic<uint32_t> BpBinder::sBinderProxyCountWarned(0);
@@ -63,7 +67,8 @@
 
 enum {
     LIMIT_REACHED_MASK = 0x80000000,        // A flag denoting that the limit has been reached
-    COUNTING_VALUE_MASK = 0x7FFFFFFF,       // A mask of the remaining bits for the count value
+    WARNING_REACHED_MASK = 0x40000000,      // A flag denoting that the warning has been reached
+    COUNTING_VALUE_MASK = 0x3FFFFFFF,       // A mask of the remaining bits for the count value
 };
 
 BpBinder::ObjectManager::ObjectManager()
@@ -181,7 +186,13 @@
                 sLastLimitCallbackMap[trackedUid] = trackedValue;
             }
         } else {
-            if ((trackedValue & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) {
+            uint32_t currentValue = trackedValue & COUNTING_VALUE_MASK;
+            if (currentValue >= sBinderProxyCountWarningWatermark
+                    && currentValue < sBinderProxyCountHighWatermark
+                    && ((trackedValue & WARNING_REACHED_MASK) == 0)) [[unlikely]] {
+                sTrackingMap[trackedUid] |= WARNING_REACHED_MASK;
+                if (sWarningCallback) sWarningCallback(trackedUid);
+            } else if (currentValue >= sBinderProxyCountHighWatermark) {
                 ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)",
                       getuid(), trackedUid, trackedValue);
                 sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK;
@@ -609,11 +620,11 @@
                   binderHandle());
         } else {
             auto countingValue = trackedValue & COUNTING_VALUE_MASK;
-            if ((trackedValue & LIMIT_REACHED_MASK) &&
+            if ((trackedValue & (LIMIT_REACHED_MASK | WARNING_REACHED_MASK)) &&
                 (countingValue <= sBinderProxyCountLowWatermark)) [[unlikely]] {
                 ALOGI("Limit reached bit reset for uid %d (fewer than %d proxies from uid %d held)",
                       getuid(), sBinderProxyCountLowWatermark, mTrackedUid);
-                sTrackingMap[mTrackedUid] &= ~LIMIT_REACHED_MASK;
+                sTrackingMap[mTrackedUid] &= ~(LIMIT_REACHED_MASK | WARNING_REACHED_MASK);
                 sLastLimitCallbackMap.erase(mTrackedUid);
             }
             if (--sTrackingMap[mTrackedUid] == 0) {
@@ -730,15 +741,18 @@
 void BpBinder::disableCountByUid() { sCountByUidEnabled.store(false); }
 void BpBinder::setCountByUidEnabled(bool enable) { sCountByUidEnabled.store(enable); }
 
-void BpBinder::setLimitCallback(binder_proxy_limit_callback cb) {
+void BpBinder::setBinderProxyCountEventCallback(binder_proxy_limit_callback cbl,
+                                                binder_proxy_warning_callback cbw) {
     RpcMutexUniqueLock _l(sTrackingLock);
-    sLimitCallback = cb;
+    sLimitCallback = std::move(cbl);
+    sWarningCallback = std::move(cbw);
 }
 
-void BpBinder::setBinderProxyCountWatermarks(int high, int low) {
+void BpBinder::setBinderProxyCountWatermarks(int high, int low, int warning) {
     RpcMutexUniqueLock _l(sTrackingLock);
     sBinderProxyCountHighWatermark = high;
     sBinderProxyCountLowWatermark = low;
+    sBinderProxyCountWarningWatermark = warning;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 89a4d27..9f03907 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -35,7 +35,8 @@
 }
 class ProcessState;
 
-using binder_proxy_limit_callback = void(*)(int);
+using binder_proxy_limit_callback = std::function<void(int)>;
+using binder_proxy_warning_callback = std::function<void(int)>;
 
 class BpBinder : public IBinder
 {
@@ -86,8 +87,9 @@
     static void         enableCountByUid();
     static void         disableCountByUid();
     static void         setCountByUidEnabled(bool enable);
-    static void         setLimitCallback(binder_proxy_limit_callback cb);
-    static void         setBinderProxyCountWatermarks(int high, int low);
+    static void         setBinderProxyCountEventCallback(binder_proxy_limit_callback cbl,
+                                                         binder_proxy_warning_callback cbw);
+    static void         setBinderProxyCountWatermarks(int high, int low, int warning);
     static uint32_t     getBinderProxyCount();
 
     std::optional<int32_t> getDebugBinderHandle() const;
@@ -212,6 +214,8 @@
     static std::unordered_map<int32_t,uint32_t> sLastLimitCallbackMap;
     static std::atomic<uint32_t>                sBinderProxyCount;
     static std::atomic<uint32_t>                sBinderProxyCountWarned;
+    static binder_proxy_warning_callback        sWarningCallback;
+    static uint32_t                             sBinderProxyCountWarningWatermark;
 };
 
 } // namespace android
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 0ee96e7..2cea14f 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -115,6 +115,7 @@
     BINDER_LIB_TEST_GET_SCHEDULING_POLICY,
     BINDER_LIB_TEST_NOP_TRANSACTION_WAIT,
     BINDER_LIB_TEST_GETPID,
+    BINDER_LIB_TEST_GETUID,
     BINDER_LIB_TEST_ECHO_VECTOR,
     BINDER_LIB_TEST_GET_NON_BLOCKING_FD,
     BINDER_LIB_TEST_REJECT_OBJECTS,
@@ -1477,6 +1478,86 @@
     EXPECT_EQ(BpBinder::getBinderProxyCount(), initialCount);
 }
 
+static constexpr int kBpCountHighWatermark = 20;
+static constexpr int kBpCountLowWatermark = 10;
+static constexpr int kBpCountWarningWatermark = 15;
+static constexpr int kInvalidUid = -1;
+
+TEST_F(BinderLibTest, BinderProxyCountCallback) {
+    Parcel data, reply;
+    sp<IBinder> server = addServer();
+    ASSERT_NE(server, nullptr);
+
+    BpBinder::enableCountByUid();
+    EXPECT_THAT(m_server->transact(BINDER_LIB_TEST_GETUID, data, &reply), StatusEq(NO_ERROR));
+    int32_t uid = reply.readInt32();
+    ASSERT_NE(uid, kInvalidUid);
+
+    uint32_t initialCount = BpBinder::getBinderProxyCount();
+    {
+        uint32_t count = initialCount;
+        BpBinder::setBinderProxyCountWatermarks(kBpCountHighWatermark,
+                                                kBpCountLowWatermark,
+                                                kBpCountWarningWatermark);
+        int limitCallbackUid = kInvalidUid;
+        int warningCallbackUid = kInvalidUid;
+        BpBinder::setBinderProxyCountEventCallback([&](int uid) { limitCallbackUid = uid; },
+                                                   [&](int uid) { warningCallbackUid = uid; });
+
+        std::vector<sp<IBinder> > proxies;
+        auto createProxyOnce = [&](int expectedWarningCallbackUid, int expectedLimitCallbackUid) {
+            warningCallbackUid = limitCallbackUid = kInvalidUid;
+            ASSERT_THAT(server->transact(BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION, data, &reply),
+                        StatusEq(NO_ERROR));
+            proxies.push_back(reply.readStrongBinder());
+            EXPECT_EQ(BpBinder::getBinderProxyCount(), ++count);
+            EXPECT_EQ(warningCallbackUid, expectedWarningCallbackUid);
+            EXPECT_EQ(limitCallbackUid, expectedLimitCallbackUid);
+        };
+        auto removeProxyOnce = [&](int expectedWarningCallbackUid, int expectedLimitCallbackUid) {
+            warningCallbackUid = limitCallbackUid = kInvalidUid;
+            proxies.pop_back();
+            EXPECT_EQ(BpBinder::getBinderProxyCount(), --count);
+            EXPECT_EQ(warningCallbackUid, expectedWarningCallbackUid);
+            EXPECT_EQ(limitCallbackUid, expectedLimitCallbackUid);
+        };
+
+        // Test the increment/decrement of the binder proxies.
+        for (int i = 1; i <= kBpCountWarningWatermark; i++) {
+            createProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(uid, kInvalidUid); // Warning callback should have been triggered.
+        for (int i = kBpCountWarningWatermark + 2; i <= kBpCountHighWatermark; i++) {
+            createProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(kInvalidUid, uid); // Limit callback should have been triggered.
+        createProxyOnce(kInvalidUid, kInvalidUid);
+        for (int i = kBpCountHighWatermark + 2; i >= kBpCountHighWatermark; i--) {
+            removeProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(kInvalidUid, kInvalidUid);
+
+        // Go down below the low watermark.
+        for (int i = kBpCountHighWatermark; i >= kBpCountLowWatermark; i--) {
+            removeProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        for (int i = kBpCountLowWatermark; i <= kBpCountWarningWatermark; i++) {
+            createProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(uid, kInvalidUid); // Warning callback should have been triggered.
+        for (int i = kBpCountWarningWatermark + 2; i <= kBpCountHighWatermark; i++) {
+            createProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(kInvalidUid, uid); // Limit callback should have been triggered.
+        createProxyOnce(kInvalidUid, kInvalidUid);
+        for (int i = kBpCountHighWatermark + 2; i >= kBpCountHighWatermark; i--) {
+            removeProxyOnce(kInvalidUid, kInvalidUid);
+        }
+        createProxyOnce(kInvalidUid, kInvalidUid);
+    }
+    EXPECT_EQ(BpBinder::getBinderProxyCount(), initialCount);
+}
+
 class BinderLibRpcTestBase : public BinderLibTest {
 public:
     void SetUp() override {
@@ -1680,6 +1761,9 @@
             case BINDER_LIB_TEST_GETPID:
                 reply->writeInt32(getpid());
                 return NO_ERROR;
+            case BINDER_LIB_TEST_GETUID:
+                reply->writeInt32(getuid());
+                return NO_ERROR;
             case BINDER_LIB_TEST_NOP_TRANSACTION_WAIT:
                 usleep(5000);
                 [[fallthrough]];
diff --git a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
index 0a584bf..83d0ca7 100644
--- a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
@@ -95,14 +95,16 @@
                  },
                  [](FuzzedDataProvider*, const sp<BpBinder>& bpbinder,
                     const sp<IBinder::DeathRecipient>&) -> void {
-                     binder_proxy_limit_callback cb = binder_proxy_limit_callback();
-                     bpbinder->setLimitCallback(cb);
+                     binder_proxy_limit_callback cbl = binder_proxy_limit_callback();
+                     binder_proxy_warning_callback cbw = binder_proxy_warning_callback();
+                     bpbinder->setBinderProxyCountEventCallback(cbl, cbw);
                  },
                  [](FuzzedDataProvider* fdp, const sp<BpBinder>& bpbinder,
                     const sp<IBinder::DeathRecipient>&) -> void {
                      int high = fdp->ConsumeIntegral<int>();
                      int low = fdp->ConsumeIntegral<int>();
-                     bpbinder->setBinderProxyCountWatermarks(high, low);
+                     int warning = fdp->ConsumeIntegral<int>();
+                     bpbinder->setBinderProxyCountWatermarks(high, low, warning);
                  }};
 
 } // namespace android
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 70cb36b..b70e80e 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -241,7 +241,6 @@
         "IProducerListener.cpp",
         "ISurfaceComposer.cpp",
         "ITransactionCompletedListener.cpp",
-        "LayerDebugInfo.cpp",
         "LayerMetadata.cpp",
         "LayerStatePermissions.cpp",
         "LayerState.cpp",
diff --git a/libs/gui/LayerDebugInfo.cpp b/libs/gui/LayerDebugInfo.cpp
deleted file mode 100644
index 15b2221..0000000
--- a/libs/gui/LayerDebugInfo.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gui/LayerDebugInfo.h>
-
-#include <android-base/stringprintf.h>
-
-#include <ui/DebugUtils.h>
-
-#include <binder/Parcel.h>
-
-using namespace android;
-using android::base::StringAppendF;
-
-#define RETURN_ON_ERROR(X) do {status_t res = (X); if (res != NO_ERROR) return res;} while(false)
-
-namespace android::gui {
-
-status_t LayerDebugInfo::writeToParcel(Parcel* parcel) const {
-    RETURN_ON_ERROR(parcel->writeCString(mName.c_str()));
-    RETURN_ON_ERROR(parcel->writeCString(mParentName.c_str()));
-    RETURN_ON_ERROR(parcel->writeCString(mType.c_str()));
-    RETURN_ON_ERROR(parcel->write(mTransparentRegion));
-    RETURN_ON_ERROR(parcel->write(mVisibleRegion));
-    RETURN_ON_ERROR(parcel->write(mSurfaceDamageRegion));
-    RETURN_ON_ERROR(parcel->writeUint32(mLayerStack));
-    RETURN_ON_ERROR(parcel->writeFloat(mX));
-    RETURN_ON_ERROR(parcel->writeFloat(mY));
-    RETURN_ON_ERROR(parcel->writeUint32(mZ));
-    RETURN_ON_ERROR(parcel->writeInt32(mWidth));
-    RETURN_ON_ERROR(parcel->writeInt32(mHeight));
-    RETURN_ON_ERROR(parcel->write(mCrop));
-    RETURN_ON_ERROR(parcel->writeFloat(mColor.r));
-    RETURN_ON_ERROR(parcel->writeFloat(mColor.g));
-    RETURN_ON_ERROR(parcel->writeFloat(mColor.b));
-    RETURN_ON_ERROR(parcel->writeFloat(mColor.a));
-    RETURN_ON_ERROR(parcel->writeUint32(mFlags));
-    RETURN_ON_ERROR(parcel->writeInt32(mPixelFormat));
-    RETURN_ON_ERROR(parcel->writeUint32(static_cast<uint32_t>(mDataSpace)));
-    for (size_t index = 0; index < 4; index++) {
-        RETURN_ON_ERROR(parcel->writeFloat(mMatrix[index / 2][index % 2]));
-    }
-    RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferWidth));
-    RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferHeight));
-    RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferStride));
-    RETURN_ON_ERROR(parcel->writeInt32(mActiveBufferFormat));
-    RETURN_ON_ERROR(parcel->writeInt32(mNumQueuedFrames));
-    RETURN_ON_ERROR(parcel->writeBool(mIsOpaque));
-    RETURN_ON_ERROR(parcel->writeBool(mContentDirty));
-    RETURN_ON_ERROR(parcel->write(mStretchEffect));
-    return NO_ERROR;
-}
-
-status_t LayerDebugInfo::readFromParcel(const Parcel* parcel) {
-    mName = parcel->readCString();
-    RETURN_ON_ERROR(parcel->errorCheck());
-    mParentName = parcel->readCString();
-    RETURN_ON_ERROR(parcel->errorCheck());
-    mType = parcel->readCString();
-    RETURN_ON_ERROR(parcel->errorCheck());
-    RETURN_ON_ERROR(parcel->read(mTransparentRegion));
-    RETURN_ON_ERROR(parcel->read(mVisibleRegion));
-    RETURN_ON_ERROR(parcel->read(mSurfaceDamageRegion));
-    RETURN_ON_ERROR(parcel->readUint32(&mLayerStack));
-    RETURN_ON_ERROR(parcel->readFloat(&mX));
-    RETURN_ON_ERROR(parcel->readFloat(&mY));
-    RETURN_ON_ERROR(parcel->readUint32(&mZ));
-    RETURN_ON_ERROR(parcel->readInt32(&mWidth));
-    RETURN_ON_ERROR(parcel->readInt32(&mHeight));
-    RETURN_ON_ERROR(parcel->read(mCrop));
-    mColor.r = parcel->readFloat();
-    RETURN_ON_ERROR(parcel->errorCheck());
-    mColor.g = parcel->readFloat();
-    RETURN_ON_ERROR(parcel->errorCheck());
-    mColor.b = parcel->readFloat();
-    RETURN_ON_ERROR(parcel->errorCheck());
-    mColor.a = parcel->readFloat();
-    RETURN_ON_ERROR(parcel->errorCheck());
-    RETURN_ON_ERROR(parcel->readUint32(&mFlags));
-    RETURN_ON_ERROR(parcel->readInt32(&mPixelFormat));
-    // \todo [2017-07-25 kraita]: Static casting mDataSpace pointer to an uint32 does work. Better ways?
-    mDataSpace = static_cast<android_dataspace>(parcel->readUint32());
-    RETURN_ON_ERROR(parcel->errorCheck());
-    for (size_t index = 0; index < 4; index++) {
-        RETURN_ON_ERROR(parcel->readFloat(&mMatrix[index / 2][index % 2]));
-    }
-    RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferWidth));
-    RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferHeight));
-    RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferStride));
-    RETURN_ON_ERROR(parcel->readInt32(&mActiveBufferFormat));
-    RETURN_ON_ERROR(parcel->readInt32(&mNumQueuedFrames));
-    RETURN_ON_ERROR(parcel->readBool(&mIsOpaque));
-    RETURN_ON_ERROR(parcel->readBool(&mContentDirty));
-    RETURN_ON_ERROR(parcel->read(mStretchEffect));
-    return NO_ERROR;
-}
-
-std::string to_string(const LayerDebugInfo& info) {
-    std::string result;
-
-    StringAppendF(&result, "+ %s (%s)\n", info.mType.c_str(), info.mName.c_str());
-    info.mTransparentRegion.dump(result, "TransparentRegion");
-    info.mVisibleRegion.dump(result, "VisibleRegion");
-    info.mSurfaceDamageRegion.dump(result, "SurfaceDamageRegion");
-    if (info.mStretchEffect.hasEffect()) {
-        const auto& se = info.mStretchEffect;
-        StringAppendF(&result,
-                      "  StretchEffect width = %f, height = %f vec=(%f, %f) "
-                      "maxAmount=(%f, %f)\n",
-                      se.width, se.height,
-                      se.vectorX, se.vectorY, se.maxAmountX, se.maxAmountY);
-    }
-
-    StringAppendF(&result, "      layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), ",
-                  info.mLayerStack, info.mZ, static_cast<double>(info.mX),
-                  static_cast<double>(info.mY), info.mWidth, info.mHeight);
-
-    StringAppendF(&result, "crop=%s, ", to_string(info.mCrop).c_str());
-    StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", info.mIsOpaque, info.mContentDirty);
-    StringAppendF(&result, "dataspace=%s, ", dataspaceDetails(info.mDataSpace).c_str());
-    StringAppendF(&result, "pixelformat=%s, ", decodePixelFormat(info.mPixelFormat).c_str());
-    StringAppendF(&result, "color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
-                  static_cast<double>(info.mColor.r), static_cast<double>(info.mColor.g),
-                  static_cast<double>(info.mColor.b), static_cast<double>(info.mColor.a),
-                  info.mFlags);
-    StringAppendF(&result, "tr=[%.2f, %.2f][%.2f, %.2f]", static_cast<double>(info.mMatrix[0][0]),
-                  static_cast<double>(info.mMatrix[0][1]), static_cast<double>(info.mMatrix[1][0]),
-                  static_cast<double>(info.mMatrix[1][1]));
-    result.append("\n");
-    StringAppendF(&result, "      parent=%s\n", info.mParentName.c_str());
-    StringAppendF(&result, "      activeBuffer=[%4ux%4u:%4u,%s],", info.mActiveBufferWidth,
-                  info.mActiveBufferHeight, info.mActiveBufferStride,
-                  decodePixelFormat(info.mActiveBufferFormat).c_str());
-    StringAppendF(&result, " queued-frames=%d", info.mNumQueuedFrames);
-    result.append("\n");
-    return result;
-}
-
-} // namespace android::gui
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
index 51e0193..a2549e7 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -43,7 +43,6 @@
 import android.gui.IWindowInfosListener;
 import android.gui.IWindowInfosPublisher;
 import android.gui.LayerCaptureArgs;
-import android.gui.LayerDebugInfo;
 import android.gui.OverlayProperties;
 import android.gui.PullAtomData;
 import android.gui.ScreenCaptureResults;
@@ -289,13 +288,6 @@
     PullAtomData onPullAtom(int atomId);
 
     /**
-     * Gets the list of active layers in Z order for debugging purposes
-     *
-     * Requires the ACCESS_SURFACE_FLINGER permission.
-     */
-    List<LayerDebugInfo> getLayerDebugInfo();
-
-    /**
      * Gets the composition preference of the default data space and default pixel format,
      * as well as the wide color gamut data space and wide color gamut pixel format.
      * If the wide color gamut data space is V0_SRGB, then it implies that the platform
diff --git a/libs/gui/aidl/android/gui/LayerDebugInfo.aidl b/libs/gui/aidl/android/gui/LayerDebugInfo.aidl
deleted file mode 100644
index faca980..0000000
--- a/libs/gui/aidl/android/gui/LayerDebugInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.gui;
-
-parcelable LayerDebugInfo cpp_header "gui/LayerDebugInfo.h";
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index a836f46..738c73a 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -74,7 +74,6 @@
 
 struct DisplayCaptureArgs;
 struct LayerCaptureArgs;
-class LayerDebugInfo;
 
 } // namespace gui
 
diff --git a/libs/gui/include/gui/LayerDebugInfo.h b/libs/gui/include/gui/LayerDebugInfo.h
deleted file mode 100644
index dbb80e5..0000000
--- a/libs/gui/include/gui/LayerDebugInfo.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <binder/Parcelable.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/Region.h>
-#include <ui/StretchEffect.h>
-
-#include <string>
-#include <math/vec4.h>
-
-namespace android::gui {
-
-/* Class for transporting debug info from SurfaceFlinger to authorized
- * recipients.  The class is intended to be a data container. There are
- * no getters or setters.
- */
-class LayerDebugInfo : public Parcelable {
-public:
-    LayerDebugInfo() = default;
-    LayerDebugInfo(const LayerDebugInfo&) = default;
-    virtual ~LayerDebugInfo() = default;
-
-    virtual status_t writeToParcel(Parcel* parcel) const;
-    virtual status_t readFromParcel(const Parcel* parcel);
-
-    std::string mName = std::string("NOT FILLED");
-    std::string mParentName = std::string("NOT FILLED");
-    std::string mType = std::string("NOT FILLED");
-    Region mTransparentRegion = Region::INVALID_REGION;
-    Region mVisibleRegion = Region::INVALID_REGION;
-    Region mSurfaceDamageRegion = Region::INVALID_REGION;
-    uint32_t mLayerStack = 0;
-    float mX = 0.f;
-    float mY = 0.f;
-    uint32_t mZ = 0 ;
-    int32_t mWidth = -1;
-    int32_t mHeight = -1;
-    android::Rect mCrop = android::Rect::INVALID_RECT;
-    half4 mColor = half4(1.0_hf, 1.0_hf, 1.0_hf, 0.0_hf);
-    uint32_t mFlags = 0;
-    PixelFormat mPixelFormat = PIXEL_FORMAT_NONE;
-    android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN;
-    // Row-major transform matrix (SurfaceControl::setMatrix())
-    float mMatrix[2][2] = {{0.f, 0.f}, {0.f, 0.f}};
-    int32_t mActiveBufferWidth = -1;
-    int32_t mActiveBufferHeight = -1;
-    int32_t mActiveBufferStride = 0;
-    PixelFormat mActiveBufferFormat = PIXEL_FORMAT_NONE;
-    int32_t mNumQueuedFrames = -1;
-    bool mIsOpaque = false;
-    bool mContentDirty = false;
-    StretchEffect mStretchEffect = {};
-};
-
-std::string to_string(const LayerDebugInfo& info);
-
-} // namespace android::gui
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 577d239..93bf4fa 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -815,10 +815,6 @@
         return binder::Status::ok();
     }
 
-    binder::Status getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* /*outLayers*/) override {
-        return binder::Status::ok();
-    }
-
     binder::Status getCompositionPreference(gui::CompositionPreference* /*outPref*/) override {
         return binder::Status::ok();
     }
diff --git a/libs/ui/include/ui/LayerStack.h b/libs/ui/include/ui/LayerStack.h
index d6ffeb7..f4c8ba2 100644
--- a/libs/ui/include/ui/LayerStack.h
+++ b/libs/ui/include/ui/LayerStack.h
@@ -55,6 +55,10 @@
     return lhs.id > rhs.id;
 }
 
+inline bool operator<(LayerStack lhs, LayerStack rhs) {
+    return lhs.id < rhs.id;
+}
+
 // A LayerFilter determines if a layer is included for output to a display.
 struct LayerFilter {
     LayerStack layerStack;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 25632fe..0463f28 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4855,7 +4855,7 @@
             const bool isPointerEvent =
                     isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
             // If a pointer event has no displayId specified, inject it to the default display.
-            const uint32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
+            const int32_t displayId = isPointerEvent && (event->getDisplayId() == ADISPLAY_ID_NONE)
                     ? ADISPLAY_ID_DEFAULT
                     : event->getDisplayId();
             int32_t flags = motionEvent.getFlags();
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index cd2120e..80eee15 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -15,7 +15,7 @@
  */
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
-#include "TransactionCallbackInvoker.h"
+
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wconversion"
 
@@ -24,8 +24,6 @@
 #define LOG_TAG "Layer"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
-#include "Layer.h"
-
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <binder/IPCThreadState.h>
@@ -40,7 +38,6 @@
 #include <ftl/enum.h>
 #include <ftl/fake_guard.h>
 #include <gui/BufferItem.h>
-#include <gui/LayerDebugInfo.h>
 #include <gui/Surface.h>
 #include <gui/TraceUtils.h>
 #include <math.h>
@@ -74,10 +71,12 @@
 #include "FrameTracer/FrameTracer.h"
 #include "FrontEnd/LayerCreationArgs.h"
 #include "FrontEnd/LayerHandle.h"
+#include "Layer.h"
 #include "LayerProtoHelper.h"
 #include "MutexUtils.h"
 #include "SurfaceFlinger.h"
 #include "TimeStats/TimeStats.h"
+#include "TransactionCallbackInvoker.h"
 #include "TunnelModeEnabledReporter.h"
 #include "Utils/FenceUtils.h"
 
@@ -1566,53 +1565,6 @@
 // debugging
 // ----------------------------------------------------------------------------
 
-// TODO(marissaw): add new layer state info to layer debugging
-gui::LayerDebugInfo Layer::getLayerDebugInfo(const DisplayDevice* display) const {
-    using namespace std::string_literals;
-
-    gui::LayerDebugInfo info;
-    const State& ds = getDrawingState();
-    info.mName = getName();
-    sp<Layer> parent = mDrawingParent.promote();
-    info.mParentName = parent ? parent->getName() : "none"s;
-    info.mType = getType();
-
-    info.mVisibleRegion = getVisibleRegion(display);
-    info.mSurfaceDamageRegion = surfaceDamageRegion;
-    info.mLayerStack = getLayerStack().id;
-    info.mX = ds.transform.tx();
-    info.mY = ds.transform.ty();
-    info.mZ = ds.z;
-    info.mCrop = ds.crop;
-    info.mColor = ds.color;
-    info.mFlags = ds.flags;
-    info.mPixelFormat = getPixelFormat();
-    info.mDataSpace = static_cast<android_dataspace>(getDataSpace());
-    info.mMatrix[0][0] = ds.transform[0][0];
-    info.mMatrix[0][1] = ds.transform[0][1];
-    info.mMatrix[1][0] = ds.transform[1][0];
-    info.mMatrix[1][1] = ds.transform[1][1];
-    {
-        sp<const GraphicBuffer> buffer = getBuffer();
-        if (buffer != 0) {
-            info.mActiveBufferWidth = buffer->getWidth();
-            info.mActiveBufferHeight = buffer->getHeight();
-            info.mActiveBufferStride = buffer->getStride();
-            info.mActiveBufferFormat = buffer->format;
-        } else {
-            info.mActiveBufferWidth = 0;
-            info.mActiveBufferHeight = 0;
-            info.mActiveBufferStride = 0;
-            info.mActiveBufferFormat = 0;
-        }
-    }
-    info.mNumQueuedFrames = getQueuedFrameCount();
-    info.mIsOpaque = isOpaque(ds);
-    info.mContentDirty = contentDirty;
-    info.mStretchEffect = getStretchEffect();
-    return info;
-}
-
 void Layer::miniDumpHeader(std::string& result) {
     result.append(kDumpTableRowLength, '-');
     result.append("\n");
@@ -2937,26 +2889,13 @@
         ch->previousReleaseFences.emplace_back(std::move(futureFenceResult));
         ch->name = mName;
     } else {
-        // If we didn't get a release callback yet, e.g. some scenarios when capturing
-        // screenshots asynchronously, then make sure we don't drop the fence.
-        mAdditionalPreviousReleaseFences.emplace_back(std::move(futureFenceResult));
-        std::vector<ftl::Future<FenceResult>> mergedFences;
-        sp<Fence> prevFence = nullptr;
-        // For a layer that's frequently screenshotted, try to merge fences to make sure we
-        // don't grow unbounded.
-        for (auto& futureReleaseFence : mAdditionalPreviousReleaseFences) {
-            auto result = futureReleaseFence.wait_for(0s);
-            if (result != std::future_status::ready) {
-                mergedFences.emplace_back(std::move(futureReleaseFence));
-                continue;
-            }
-            mergeFence(getDebugName(), futureReleaseFence.get().value_or(Fence::NO_FENCE),
-                       prevFence);
-        }
-        if (prevFence != nullptr) {
-            mergedFences.emplace_back(ftl::yield(FenceResult(std::move(prevFence))));
-        }
-        mAdditionalPreviousReleaseFences.swap(mergedFences);
+        // If we didn't get a release callback yet (e.g. some scenarios when capturing
+        // screenshots asynchronously) then make sure we don't drop the fence.
+        // Older fences for the same layer stack can be dropped when a new fence arrives.
+        // An assumption here is that RenderEngine performs work sequentially, so an
+        // incoming fence will not fire before an existing fence.
+        mAdditionalPreviousReleaseFences.emplace_or_replace(layerStack,
+                                                            std::move(futureFenceResult));
     }
 
     if (mBufferInfo.mBuffer) {
@@ -3506,10 +3445,10 @@
             handle->previousFrameNumber = mDrawingState.previousFrameNumber;
             if (FlagManager::getInstance().ce_fence_promise() &&
                 mPreviousReleaseBufferEndpoint == handle->listener) {
-                // Add fences from previous screenshots now so that they can be dispatched to the
+                // Add fence from previous screenshot now so that it can be dispatched to the
                 // client.
-                for (auto& futureReleaseFence : mAdditionalPreviousReleaseFences) {
-                    handle->previousReleaseFences.emplace_back(std::move(futureReleaseFence));
+                for (auto& [_, future] : mAdditionalPreviousReleaseFences) {
+                    handle->previousReleaseFences.emplace_back(std::move(future));
                 }
                 mAdditionalPreviousReleaseFences.clear();
             } else if (FlagManager::getInstance().screenshot_fence_preservation() &&
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index d283d6f..c094aa1 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -18,6 +18,7 @@
 
 #include <android/gui/DropInputMode.h>
 #include <android/gui/ISurfaceComposerClient.h>
+#include <ftl/small_map.h>
 #include <gui/BufferQueue.h>
 #include <gui/LayerState.h>
 #include <gui/WindowInfo.h>
@@ -25,9 +26,11 @@
 #include <math/vec4.h>
 #include <sys/types.h>
 #include <ui/BlurRegion.h>
+#include <ui/DisplayMap.h>
 #include <ui/FloatRect.h>
 #include <ui/FrameStats.h>
 #include <ui/GraphicBuffer.h>
+#include <ui/LayerStack.h>
 #include <ui/PixelFormat.h>
 #include <ui/Region.h>
 #include <ui/StretchEffect.h>
@@ -71,10 +74,6 @@
 struct LayerFECompositionState;
 }
 
-namespace gui {
-class LayerDebugInfo;
-}
-
 namespace frametimeline {
 class SurfaceFrame;
 } // namespace frametimeline
@@ -703,8 +702,6 @@
     inline const State& getDrawingState() const { return mDrawingState; }
     inline State& getDrawingState() { return mDrawingState; }
 
-    gui::LayerDebugInfo getLayerDebugInfo(const DisplayDevice*) const;
-
     void miniDumpLegacy(std::string& result, const DisplayDevice&) const;
     void miniDump(std::string& result, const frontend::LayerSnapshot&, const DisplayDevice&) const;
     void dumpFrameStats(std::string& result) const;
@@ -958,8 +955,11 @@
     // screenshots asynchronously. There may be no buffer update for the
     // layer, but the layer will still be composited on the screen in every
     // frame. Kepping track of these fences ensures that they are not dropped
-    // and can be dispatched to the client at a later time.
-    std::vector<ftl::Future<FenceResult>> mAdditionalPreviousReleaseFences;
+    // and can be dispatched to the client at a later time. Older fences are
+    // dropped when a layer stack receives a new fence.
+    // TODO(b/300533018): Track fence per multi-instance RenderEngine
+    ftl::SmallMap<ui::LayerStack, ftl::Future<FenceResult>, ui::kDisplayCapacity>
+            mAdditionalPreviousReleaseFences;
 
     // Exposed so SurfaceFlinger can assert that it's held
     const sp<SurfaceFlinger> mFlinger;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4164dc5..4474355 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -65,7 +65,6 @@
 #include <gui/BufferQueue.h>
 #include <gui/DebugEGLImageTracker.h>
 #include <gui/IProducerListener.h>
-#include <gui/LayerDebugInfo.h>
 #include <gui/LayerMetadata.h>
 #include <gui/LayerState.h>
 #include <gui/Surface.h>
@@ -1842,19 +1841,6 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers) {
-    outLayers->clear();
-    auto future = mScheduler->schedule([=, this] {
-        const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
-        mDrawingState.traverseInZOrder([&](Layer* layer) {
-            outLayers->push_back(layer->getLayerDebugInfo(display.get()));
-        });
-    });
-
-    future.wait();
-    return NO_ERROR;
-}
-
 status_t SurfaceFlinger::getCompositionPreference(
         Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
         Dataspace* outWideColorGamutDataspace,
@@ -2259,7 +2245,7 @@
     outTransactionsAreEmpty = !needsTraversal;
     const bool shouldCommit = (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal;
     if (shouldCommit) {
-        commitTransactions();
+        commitTransactionsLegacy();
     }
 
     bool mustComposite = latchBuffers() || shouldCommit;
@@ -2383,8 +2369,14 @@
         mLayerHierarchyBuilder.update(mLayerLifecycleManager);
     }
 
+    // Keep a copy of the drawing state (that is going to be overwritten
+    // by commitTransactionsLocked) outside of mStateLock so that the side
+    // effects of the State assignment don't happen with mStateLock held,
+    // which can cause deadlocks.
+    State drawingState(mDrawingState);
+    Mutex::Autolock lock(mStateLock);
     bool mustComposite = false;
-    mustComposite |= applyAndCommitDisplayTransactionStates(update.transactions);
+    mustComposite |= applyAndCommitDisplayTransactionStatesLocked(update.transactions);
 
     {
         ATRACE_NAME("LayerSnapshotBuilder:update");
@@ -2423,7 +2415,7 @@
     bool newDataLatched = false;
     if (!mLegacyFrontEndEnabled) {
         ATRACE_NAME("DisplayCallbackAndStatsUpdates");
-        mustComposite |= applyTransactions(update.transactions, vsyncId);
+        mustComposite |= applyTransactionsLocked(update.transactions, vsyncId);
         traverseLegacyLayers([&](Layer* layer) { layer->commitTransaction(); });
         const nsecs_t latchTime = systemTime();
         bool unused = false;
@@ -3298,6 +3290,19 @@
 
 void SurfaceFlinger::commitTransactions() {
     ATRACE_CALL();
+    mDebugInTransaction = systemTime();
+
+    // Here we're guaranteed that some transaction flags are set
+    // so we can call commitTransactionsLocked unconditionally.
+    // We clear the flags with mStateLock held to guarantee that
+    // mCurrentState won't change until the transaction is committed.
+    mScheduler->modulateVsync({}, &VsyncModulator::onTransactionCommit);
+    commitTransactionsLocked(clearTransactionFlags(eTransactionMask));
+    mDebugInTransaction = 0;
+}
+
+void SurfaceFlinger::commitTransactionsLegacy() {
+    ATRACE_CALL();
 
     // Keep a copy of the drawing state (that is going to be overwritten
     // by commitTransactionsLocked) outside of mStateLock so that the side
@@ -5267,9 +5272,8 @@
     return needsTraversal;
 }
 
-bool SurfaceFlinger::applyAndCommitDisplayTransactionStates(
+bool SurfaceFlinger::applyAndCommitDisplayTransactionStatesLocked(
         std::vector<TransactionState>& transactions) {
-    Mutex::Autolock lock(mStateLock);
     bool needsTraversal = false;
     uint32_t transactionFlags = 0;
     for (auto& transaction : transactions) {
@@ -6052,7 +6056,8 @@
     if (mLegacyFrontEndEnabled) {
         applyTransactions(transactions, VsyncId{0});
     } else {
-        applyAndCommitDisplayTransactionStates(transactions);
+        Mutex::Autolock lock(mStateLock);
+        applyAndCommitDisplayTransactionStatesLocked(transactions);
     }
 
     {
@@ -8287,7 +8292,11 @@
         Mutex::Autolock lock(mStateLock);
         const DisplayDevice* display = nullptr;
         if (parent) {
-            display = findDisplay([layerStack = parent->getLayerStack()](const auto& display) {
+            const frontend::LayerSnapshot* snapshot = mLayerLifecycleManagerEnabled
+                    ? mLayerSnapshotBuilder.getSnapshot(parent->sequence)
+                    : parent->getLayerSnapshot();
+            display = findDisplay([layerStack =
+                                           snapshot->outputFilter.layerStack](const auto& display) {
                           return display.getLayerStack() == layerStack;
                       }).get();
         }
@@ -9903,22 +9912,6 @@
     return binderStatusFromStatusT(status);
 }
 
-binder::Status SurfaceComposerAIDL::getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers) {
-    if (!outLayers) {
-        return binderStatusFromStatusT(UNEXPECTED_NULL);
-    }
-
-    IPCThreadState* ipc = IPCThreadState::self();
-    const int pid = ipc->getCallingPid();
-    const int uid = ipc->getCallingUid();
-    if ((uid != AID_SHELL) && !PermissionCache::checkPermission(sDump, pid, uid)) {
-        ALOGE("Layer debug info permission denied for pid=%d, uid=%d", pid, uid);
-        return binderStatusFromStatusT(PERMISSION_DENIED);
-    }
-    status_t status = mFlinger->getLayerDebugInfo(outLayers);
-    return binderStatusFromStatusT(status);
-}
-
 binder::Status SurfaceComposerAIDL::getCompositionPreference(gui::CompositionPreference* outPref) {
     ui::Dataspace dataspace;
     ui::PixelFormat pixelFormat;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c106abd..4a44be6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -38,7 +38,6 @@
 #include <gui/FrameTimestamps.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/ITransactionCompletedListener.h>
-#include <gui/LayerDebugInfo.h>
 #include <gui/LayerState.h>
 #include <layerproto/LayerProtoHeader.h>
 #include <math/mat4.h>
@@ -599,7 +598,6 @@
     status_t overrideHdrTypes(const sp<IBinder>& displayToken,
                               const std::vector<ui::Hdr>& hdrTypes);
     status_t onPullAtom(const int32_t atomId, std::vector<uint8_t>* pulledData, bool* success);
-    status_t getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers);
     status_t getCompositionPreference(ui::Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
                                       ui::Dataspace* outWideColorGamutDataspace,
                                       ui::PixelFormat* outWideColorGamutPixelFormat) const;
@@ -760,7 +758,8 @@
                                             bool force = false)
             REQUIRES(mStateLock, kMainThreadContext);
 
-    void commitTransactions() EXCLUDES(mStateLock) REQUIRES(kMainThreadContext);
+    void commitTransactionsLegacy() EXCLUDES(mStateLock) REQUIRES(kMainThreadContext);
+    void commitTransactions() REQUIRES(kMainThreadContext, mStateLock);
     void commitTransactionsLocked(uint32_t transactionFlags)
             REQUIRES(mStateLock, kMainThreadContext);
     void doCommitTransactions() REQUIRES(mStateLock);
@@ -810,8 +809,8 @@
     bool flushTransactionQueues(VsyncId) REQUIRES(kMainThreadContext);
 
     bool applyTransactions(std::vector<TransactionState>&, VsyncId) REQUIRES(kMainThreadContext);
-    bool applyAndCommitDisplayTransactionStates(std::vector<TransactionState>& transactions)
-            REQUIRES(kMainThreadContext);
+    bool applyAndCommitDisplayTransactionStatesLocked(std::vector<TransactionState>& transactions)
+            REQUIRES(kMainThreadContext, mStateLock);
 
     // Returns true if there is at least one transaction that needs to be flushed
     bool transactionFlushNeeded();
@@ -1601,7 +1600,6 @@
     binder::Status overrideHdrTypes(const sp<IBinder>& display,
                                     const std::vector<int32_t>& hdrTypes) override;
     binder::Status onPullAtom(int32_t atomId, gui::PullAtomData* outPullData) override;
-    binder::Status getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* outLayers) override;
     binder::Status getCompositionPreference(gui::CompositionPreference* outPref) override;
     binder::Status getDisplayedContentSamplingAttributes(
             const sp<IBinder>& display, gui::ContentSamplingAttributes* outAttrs) override;
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index 9b83713..3b6a51a 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -21,7 +21,6 @@
 #include <android/gui/ISurfaceComposer.h>
 #include <gtest/gtest.h>
 #include <gui/AidlStatusUtil.h>
-#include <gui/LayerDebugInfo.h>
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
 #include <private/android_filesystem_config.h>
@@ -36,7 +35,6 @@
 namespace android {
 
 using Transaction = SurfaceComposerClient::Transaction;
-using gui::LayerDebugInfo;
 using gui::aidl_utils::statusTFromBinderStatus;
 using ui::ColorMode;
 
@@ -292,35 +290,6 @@
 /**
  * The following tests are for methods accessible directly through SurfaceFlinger.
  */
-TEST_F(CredentialsTest, GetLayerDebugInfo) {
-    setupBackgroundSurface();
-    sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
-
-    // Historically, only root and shell can access the getLayerDebugInfo which
-    // is called when we call dumpsys. I don't see a reason why we should change this.
-    std::vector<LayerDebugInfo> outLayers;
-    binder::Status status = binder::Status::ok();
-    // Check with root.
-    {
-        UIDFaker f(AID_ROOT);
-        status = sf->getLayerDebugInfo(&outLayers);
-        ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
-    }
-
-    // Check as a shell.
-    {
-        UIDFaker f(AID_SHELL);
-        status = sf->getLayerDebugInfo(&outLayers);
-        ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
-    }
-
-    // Check as anyone else.
-    {
-        UIDFaker f(AID_BIN);
-        status = sf->getLayerDebugInfo(&outLayers);
-        ASSERT_EQ(PERMISSION_DENIED, statusTFromBinderStatus(status));
-    }
-}
 
 TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) {
     const auto display = getFirstDisplayToken();