Merge changes Ibdd09f42,I624700a7 into main

* changes:
  [15/n Dispatcher refactor] Remove TouchState from setInputWindows
  [14/n Dispatcher refactor] Move TouchState methods
diff --git a/include/input/DisplayTopologyGraph.h b/include/input/DisplayTopologyGraph.h
index f3f5148..3ae865a 100644
--- a/include/input/DisplayTopologyGraph.h
+++ b/include/input/DisplayTopologyGraph.h
@@ -42,7 +42,9 @@
  */
 struct DisplayTopologyAdjacentDisplay {
     ui::LogicalDisplayId displayId = ui::LogicalDisplayId::INVALID;
+    // Position of the adjacent display, relative to the source display.
     DisplayTopologyPosition position;
+    // The offset in DP of the adjacent display, relative to the source display.
     float offsetDp;
 };
 
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index e88e3f3..170b2ad 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -2771,7 +2771,9 @@
 
 int main(int argc, char** argv) {
     ::testing::InitGoogleTest(&argc, argv);
+#ifndef __ANDROID__
     __android_log_set_logger(__android_log_stderr_logger);
+#endif
 
     return RUN_ALL_TESTS();
 }
diff --git a/libs/binder/tests/binderRpcTestService.cpp b/libs/binder/tests/binderRpcTestService.cpp
index aef9464..0084b9a 100644
--- a/libs/binder/tests/binderRpcTestService.cpp
+++ b/libs/binder/tests/binderRpcTestService.cpp
@@ -100,7 +100,9 @@
 };
 
 int main(int argc, char* argv[]) {
+#ifndef __ANDROID__
     __android_log_set_logger(__android_log_stderr_logger);
+#endif
 
     LOG_ALWAYS_FATAL_IF(argc != 3, "Invalid number of arguments: %d", argc);
     unique_fd writeEnd(atoi(argv[1]));
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 052b519..5ab31db 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -266,8 +266,6 @@
         "FenceMonitor.cpp",
         "Flags.cpp",
         "GLConsumer.cpp",
-        "IConsumerListener.cpp",
-        "IGraphicBufferConsumer.cpp",
         "IGraphicBufferProducer.cpp",
         "IProducerListener.cpp",
         "ISurfaceComposer.cpp",
diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp
deleted file mode 100644
index 939db59..0000000
--- a/libs/gui/IConsumerListener.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2013 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/IConsumerListener.h>
-
-#include <gui/BufferItem.h>
-
-namespace android {
-
-namespace { // Anonymous
-
-enum class Tag : uint32_t {
-    ON_DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
-    ON_FRAME_AVAILABLE,
-    ON_FRAME_REPLACED,
-    ON_BUFFERS_RELEASED,
-    ON_SIDEBAND_STREAM_CHANGED,
-    ON_FRAME_DEQUEUED,
-    ON_FRAME_CANCELLED,
-    ON_FRAME_DETACHED,
-    ON_SLOT_COUNT_CHANGED,
-    LAST = ON_SLOT_COUNT_CHANGED,
-};
-
-} // Anonymous namespace
-
-class BpConsumerListener : public SafeBpInterface<IConsumerListener> {
-public:
-    explicit BpConsumerListener(const sp<IBinder>& impl)
-          : SafeBpInterface<IConsumerListener>(impl, "BpConsumerListener") {}
-
-    ~BpConsumerListener() override;
-
-    void onDisconnect() override {
-        callRemoteAsync<decltype(&IConsumerListener::onDisconnect)>(Tag::ON_DISCONNECT);
-    }
-
-    void onFrameDequeued(const uint64_t bufferId) override {
-        callRemoteAsync<decltype(&IConsumerListener::onFrameDequeued)>(Tag::ON_FRAME_DEQUEUED,
-                                                                       bufferId);
-    }
-
-    void onFrameDetached(const uint64_t bufferId) override {
-        callRemoteAsync<decltype(&IConsumerListener::onFrameDetached)>(Tag::ON_FRAME_DETACHED,
-                                                                       bufferId);
-    }
-
-    void onFrameCancelled(const uint64_t bufferId) override {
-        callRemoteAsync<decltype(&IConsumerListener::onFrameCancelled)>(Tag::ON_FRAME_CANCELLED,
-                                                                        bufferId);
-    }
-
-    void onFrameAvailable(const BufferItem& item) override {
-        callRemoteAsync<decltype(&IConsumerListener::onFrameAvailable)>(Tag::ON_FRAME_AVAILABLE,
-                                                                        item);
-    }
-
-    void onFrameReplaced(const BufferItem& item) override {
-        callRemoteAsync<decltype(&IConsumerListener::onFrameReplaced)>(Tag::ON_FRAME_REPLACED,
-                                                                       item);
-    }
-
-    void onBuffersReleased() override {
-        callRemoteAsync<decltype(&IConsumerListener::onBuffersReleased)>(Tag::ON_BUFFERS_RELEASED);
-    }
-
-    void onSidebandStreamChanged() override {
-        callRemoteAsync<decltype(&IConsumerListener::onSidebandStreamChanged)>(
-                Tag::ON_SIDEBAND_STREAM_CHANGED);
-    }
-
-    void addAndGetFrameTimestamps(const NewFrameEventsEntry* /*newTimestamps*/,
-                                  FrameEventHistoryDelta* /*outDelta*/) override {
-        LOG_ALWAYS_FATAL("IConsumerListener::addAndGetFrameTimestamps cannot be proxied");
-    }
-
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
-    void onSlotCountChanged(int slotCount) override {
-        callRemoteAsync<
-                decltype(&IConsumerListener::onSlotCountChanged)>(Tag::ON_SLOT_COUNT_CHANGED,
-                                                                  slotCount);
-    }
-#endif
-};
-
-// Out-of-line virtual method definitions to trigger vtable emission in this translation unit (see
-// clang warning -Wweak-vtables)
-BpConsumerListener::~BpConsumerListener() = default;
-
-IMPLEMENT_META_INTERFACE(ConsumerListener, "android.gui.IConsumerListener");
-
-status_t BnConsumerListener::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-                                        uint32_t flags) {
-    if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) {
-        return BBinder::onTransact(code, data, reply, flags);
-    }
-    auto tag = static_cast<Tag>(code);
-    switch (tag) {
-        case Tag::ON_DISCONNECT:
-            return callLocalAsync(data, reply, &IConsumerListener::onDisconnect);
-        case Tag::ON_FRAME_AVAILABLE:
-            return callLocalAsync(data, reply, &IConsumerListener::onFrameAvailable);
-        case Tag::ON_FRAME_REPLACED:
-            return callLocalAsync(data, reply, &IConsumerListener::onFrameReplaced);
-        case Tag::ON_BUFFERS_RELEASED:
-            return callLocalAsync(data, reply, &IConsumerListener::onBuffersReleased);
-        case Tag::ON_SIDEBAND_STREAM_CHANGED:
-            return callLocalAsync(data, reply, &IConsumerListener::onSidebandStreamChanged);
-        case Tag::ON_FRAME_DEQUEUED:
-            return callLocalAsync(data, reply, &IConsumerListener::onFrameDequeued);
-        case Tag::ON_FRAME_CANCELLED:
-            return callLocalAsync(data, reply, &IConsumerListener::onFrameCancelled);
-        case Tag::ON_FRAME_DETACHED:
-            return callLocalAsync(data, reply, &IConsumerListener::onFrameDetached);
-        case Tag::ON_SLOT_COUNT_CHANGED: {
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
-            return callLocalAsync(data, reply, &IConsumerListener::onSlotCountChanged);
-#else
-            return INVALID_OPERATION;
-#endif
-        }
-    }
-}
-
-} // namespace android
diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp
deleted file mode 100644
index e133532..0000000
--- a/libs/gui/IGraphicBufferConsumer.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2013 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/IGraphicBufferConsumer.h>
-
-#include <com_android_graphics_libgui_flags.h>
-#include <gui/BufferItem.h>
-#include <gui/IConsumerListener.h>
-
-#include <binder/Parcel.h>
-
-#include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
-
-#include <utils/Errors.h>
-#include <utils/NativeHandle.h>
-#include <utils/String8.h>
-#include <cstdint>
-
-namespace android {
-
-namespace { // Anonymous namespace
-
-enum class Tag : uint32_t {
-    ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
-    DETACH_BUFFER,
-    ATTACH_BUFFER,
-    RELEASE_BUFFER,
-    CONSUMER_CONNECT,
-    CONSUMER_DISCONNECT,
-    GET_RELEASED_BUFFERS,
-    SET_DEFAULT_BUFFER_SIZE,
-    SET_MAX_BUFFER_COUNT,
-    SET_MAX_ACQUIRED_BUFFER_COUNT,
-    SET_CONSUMER_NAME,
-    SET_DEFAULT_BUFFER_FORMAT,
-    SET_DEFAULT_BUFFER_DATA_SPACE,
-    SET_CONSUMER_USAGE_BITS,
-    SET_CONSUMER_IS_PROTECTED,
-    SET_TRANSFORM_HINT,
-    GET_SIDEBAND_STREAM,
-    GET_OCCUPANCY_HISTORY,
-    DISCARD_FREE_BUFFERS,
-    DUMP_STATE,
-    ALLOW_UNLIMITED_SLOTS,
-    GET_RELEASED_BUFFERS_EXTENDED,
-    LAST = GET_RELEASED_BUFFERS_EXTENDED,
-};
-
-} // Anonymous namespace
-
-class BpGraphicBufferConsumer : public SafeBpInterface<IGraphicBufferConsumer> {
-public:
-    explicit BpGraphicBufferConsumer(const sp<IBinder>& impl)
-          : SafeBpInterface<IGraphicBufferConsumer>(impl, "BpGraphicBufferConsumer") {}
-
-    ~BpGraphicBufferConsumer() override;
-
-    status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen,
-                           uint64_t maxFrameNumber) override {
-        using Signature = decltype(&IGraphicBufferConsumer::acquireBuffer);
-        return callRemote<Signature>(Tag::ACQUIRE_BUFFER, buffer, presentWhen, maxFrameNumber);
-    }
-
-    status_t detachBuffer(int slot) override {
-        using Signature = decltype(&IGraphicBufferConsumer::detachBuffer);
-        return callRemote<Signature>(Tag::DETACH_BUFFER, slot);
-    }
-
-    status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) override {
-        using Signature = decltype(&IGraphicBufferConsumer::attachBuffer);
-        return callRemote<Signature>(Tag::ATTACH_BUFFER, slot, buffer);
-    }
-
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_GL_FENCE_CLEANUP)
-    status_t releaseBuffer(int buf, uint64_t frameNumber, const sp<Fence>& releaseFence) override {
-        using Signature = status_t (IGraphicBufferConsumer::*)(int, uint64_t, const sp<Fence>&);
-        return callRemote<Signature>(Tag::RELEASE_BUFFER, buf, frameNumber, releaseFence);
-    }
-#else
-    status_t releaseBuffer(int buf, uint64_t frameNumber,
-                           EGLDisplay display __attribute__((unused)),
-                           EGLSyncKHR fence __attribute__((unused)),
-                           const sp<Fence>& releaseFence) override {
-        using Signature = status_t (IGraphicBufferConsumer::*)(int, uint64_t, const sp<Fence>&);
-        return callRemote<Signature>(Tag::RELEASE_BUFFER, buf, frameNumber, releaseFence);
-    }
-#endif
-
-    status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) override {
-        using Signature = decltype(&IGraphicBufferConsumer::consumerConnect);
-        return callRemote<Signature>(Tag::CONSUMER_CONNECT, consumer, controlledByApp);
-    }
-
-    status_t consumerDisconnect() override {
-        return callRemote<decltype(&IGraphicBufferConsumer::consumerDisconnect)>(
-                Tag::CONSUMER_DISCONNECT);
-    }
-
-    status_t getReleasedBuffers(uint64_t* slotMask) override {
-        using Signature = decltype(&IGraphicBufferConsumer::getReleasedBuffers);
-        return callRemote<Signature>(Tag::GET_RELEASED_BUFFERS, slotMask);
-    }
-
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
-    status_t getReleasedBuffersExtended(std::vector<bool>* slotMask) override {
-        using Signature = decltype(&IGraphicBufferConsumer::getReleasedBuffersExtended);
-        return callRemote<Signature>(Tag::GET_RELEASED_BUFFERS_EXTENDED, slotMask);
-    }
-#endif
-
-    status_t setDefaultBufferSize(uint32_t width, uint32_t height) override {
-        using Signature = decltype(&IGraphicBufferConsumer::setDefaultBufferSize);
-        return callRemote<Signature>(Tag::SET_DEFAULT_BUFFER_SIZE, width, height);
-    }
-
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
-    status_t allowUnlimitedSlots(bool allowUnlimitedSlots) override {
-        using Signature = decltype(&IGraphicBufferConsumer::allowUnlimitedSlots);
-        return callRemote<Signature>(Tag::ALLOW_UNLIMITED_SLOTS, allowUnlimitedSlots);
-    }
-#endif
-
-    status_t setMaxBufferCount(int bufferCount) override {
-        using Signature = decltype(&IGraphicBufferConsumer::setMaxBufferCount);
-        return callRemote<Signature>(Tag::SET_MAX_BUFFER_COUNT, bufferCount);
-    }
-
-    status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) override {
-        using Signature = decltype(&IGraphicBufferConsumer::setMaxAcquiredBufferCount);
-        return callRemote<Signature>(Tag::SET_MAX_ACQUIRED_BUFFER_COUNT, maxAcquiredBuffers);
-    }
-
-    status_t setConsumerName(const String8& name) override {
-        using Signature = decltype(&IGraphicBufferConsumer::setConsumerName);
-        return callRemote<Signature>(Tag::SET_CONSUMER_NAME, name);
-    }
-
-    status_t setDefaultBufferFormat(PixelFormat defaultFormat) override {
-        using Signature = decltype(&IGraphicBufferConsumer::setDefaultBufferFormat);
-        return callRemote<Signature>(Tag::SET_DEFAULT_BUFFER_FORMAT, defaultFormat);
-    }
-
-    status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace) override {
-        using Signature = decltype(&IGraphicBufferConsumer::setDefaultBufferDataSpace);
-        return callRemote<Signature>(Tag::SET_DEFAULT_BUFFER_DATA_SPACE, defaultDataSpace);
-    }
-
-    status_t setConsumerUsageBits(uint64_t usage) override {
-        using Signature = decltype(&IGraphicBufferConsumer::setConsumerUsageBits);
-        return callRemote<Signature>(Tag::SET_CONSUMER_USAGE_BITS, usage);
-    }
-
-    status_t setConsumerIsProtected(bool isProtected) override {
-        using Signature = decltype(&IGraphicBufferConsumer::setConsumerIsProtected);
-        return callRemote<Signature>(Tag::SET_CONSUMER_IS_PROTECTED, isProtected);
-    }
-
-    status_t setTransformHint(uint32_t hint) override {
-        using Signature = decltype(&IGraphicBufferConsumer::setTransformHint);
-        return callRemote<Signature>(Tag::SET_TRANSFORM_HINT, hint);
-    }
-
-    status_t getSidebandStream(sp<NativeHandle>* outStream) const override {
-        using Signature = decltype(&IGraphicBufferConsumer::getSidebandStream);
-        return callRemote<Signature>(Tag::GET_SIDEBAND_STREAM, outStream);
-    }
-
-    status_t getOccupancyHistory(bool forceFlush,
-                                 std::vector<OccupancyTracker::Segment>* outHistory) override {
-        using Signature = decltype(&IGraphicBufferConsumer::getOccupancyHistory);
-        return callRemote<Signature>(Tag::GET_OCCUPANCY_HISTORY, forceFlush, outHistory);
-    }
-
-    status_t discardFreeBuffers() override {
-        return callRemote<decltype(&IGraphicBufferConsumer::discardFreeBuffers)>(
-                Tag::DISCARD_FREE_BUFFERS);
-    }
-
-    status_t dumpState(const String8& prefix, String8* outResult) const override {
-        using Signature = status_t (IGraphicBufferConsumer::*)(const String8&, String8*) const;
-        return callRemote<Signature>(Tag::DUMP_STATE, prefix, outResult);
-    }
-};
-
-// Out-of-line virtual method definition to trigger vtable emission in this translation unit
-// (see clang warning -Wweak-vtables)
-BpGraphicBufferConsumer::~BpGraphicBufferConsumer() = default;
-
-IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
-
-status_t BnGraphicBufferConsumer::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-                                             uint32_t flags) {
-    if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) {
-        return BBinder::onTransact(code, data, reply, flags);
-    }
-    auto tag = static_cast<Tag>(code);
-    switch (tag) {
-        case Tag::ACQUIRE_BUFFER:
-            return callLocal(data, reply, &IGraphicBufferConsumer::acquireBuffer);
-        case Tag::DETACH_BUFFER:
-            return callLocal(data, reply, &IGraphicBufferConsumer::detachBuffer);
-        case Tag::ATTACH_BUFFER:
-            return callLocal(data, reply, &IGraphicBufferConsumer::attachBuffer);
-        case Tag::RELEASE_BUFFER: {
-            using Signature = status_t (IGraphicBufferConsumer::*)(int, uint64_t, const sp<Fence>&);
-            return callLocal<Signature>(data, reply, &IGraphicBufferConsumer::releaseBuffer);
-        }
-        case Tag::CONSUMER_CONNECT:
-            return callLocal(data, reply, &IGraphicBufferConsumer::consumerConnect);
-        case Tag::CONSUMER_DISCONNECT:
-            return callLocal(data, reply, &IGraphicBufferConsumer::consumerDisconnect);
-        case Tag::GET_RELEASED_BUFFERS:
-            return callLocal(data, reply, &IGraphicBufferConsumer::getReleasedBuffers);
-        case Tag::SET_DEFAULT_BUFFER_SIZE:
-            return callLocal(data, reply, &IGraphicBufferConsumer::setDefaultBufferSize);
-        case Tag::SET_MAX_BUFFER_COUNT:
-            return callLocal(data, reply, &IGraphicBufferConsumer::setMaxBufferCount);
-        case Tag::SET_MAX_ACQUIRED_BUFFER_COUNT:
-            return callLocal(data, reply, &IGraphicBufferConsumer::setMaxAcquiredBufferCount);
-        case Tag::SET_CONSUMER_NAME:
-            return callLocal(data, reply, &IGraphicBufferConsumer::setConsumerName);
-        case Tag::SET_DEFAULT_BUFFER_FORMAT:
-            return callLocal(data, reply, &IGraphicBufferConsumer::setDefaultBufferFormat);
-        case Tag::SET_DEFAULT_BUFFER_DATA_SPACE:
-            return callLocal(data, reply, &IGraphicBufferConsumer::setDefaultBufferDataSpace);
-        case Tag::SET_CONSUMER_USAGE_BITS:
-            return callLocal(data, reply, &IGraphicBufferConsumer::setConsumerUsageBits);
-        case Tag::SET_CONSUMER_IS_PROTECTED:
-            return callLocal(data, reply, &IGraphicBufferConsumer::setConsumerIsProtected);
-        case Tag::SET_TRANSFORM_HINT:
-            return callLocal(data, reply, &IGraphicBufferConsumer::setTransformHint);
-        case Tag::GET_SIDEBAND_STREAM:
-            return callLocal(data, reply, &IGraphicBufferConsumer::getSidebandStream);
-        case Tag::GET_OCCUPANCY_HISTORY:
-            return callLocal(data, reply, &IGraphicBufferConsumer::getOccupancyHistory);
-        case Tag::DISCARD_FREE_BUFFERS:
-            return callLocal(data, reply, &IGraphicBufferConsumer::discardFreeBuffers);
-        case Tag::DUMP_STATE: {
-            using Signature = status_t (IGraphicBufferConsumer::*)(const String8&, String8*) const;
-            return callLocal<Signature>(data, reply, &IGraphicBufferConsumer::dumpState);
-        }
-        case Tag::GET_RELEASED_BUFFERS_EXTENDED: {
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
-            return callLocal(data, reply, &IGraphicBufferConsumer::getReleasedBuffersExtended);
-#else
-            return INVALID_OPERATION;
-#endif
-        }
-        case Tag::ALLOW_UNLIMITED_SLOTS: {
-#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_UNLIMITED_SLOTS)
-            return callLocal(data, reply, &IGraphicBufferConsumer::allowUnlimitedSlots);
-#else
-            return INVALID_OPERATION;
-#endif
-        }
-    }
-}
-
-} // namespace android
diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h
index f1c75d3..7b97e13 100644
--- a/libs/gui/include/gui/BufferQueue.h
+++ b/libs/gui/include/gui/BufferQueue.h
@@ -57,7 +57,7 @@
     // reference in the BufferQueue class is because we're planning to expose the
     // consumer side of a BufferQueue as a binder interface, which doesn't support
     // weak references.
-    class ProxyConsumerListener : public BnConsumerListener {
+    class ProxyConsumerListener : public IConsumerListener {
     public:
         explicit ProxyConsumerListener(const wp<ConsumerListener>& consumerListener);
         ~ProxyConsumerListener() override;
diff --git a/libs/gui/include/gui/BufferQueueConsumer.h b/libs/gui/include/gui/BufferQueueConsumer.h
index f99b54b..ab1231a 100644
--- a/libs/gui/include/gui/BufferQueueConsumer.h
+++ b/libs/gui/include/gui/BufferQueueConsumer.h
@@ -28,8 +28,7 @@
 
 class BufferQueueCore;
 
-class BufferQueueConsumer : public BnGraphicBufferConsumer {
-
+class BufferQueueConsumer : public IGraphicBufferConsumer {
 public:
     explicit BufferQueueConsumer(const sp<BufferQueueCore>& core);
     ~BufferQueueConsumer() override;
diff --git a/libs/gui/include/gui/IConsumerListener.h b/libs/gui/include/gui/IConsumerListener.h
index 1695aae..95e66c7 100644
--- a/libs/gui/include/gui/IConsumerListener.h
+++ b/libs/gui/include/gui/IConsumerListener.h
@@ -16,9 +16,6 @@
 
 #pragma once
 
-#include <binder/IInterface.h>
-#include <binder/SafeInterface.h>
-
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 
@@ -110,25 +107,6 @@
 #endif
 };
 
-#ifndef NO_BINDER
-class IConsumerListener : public ConsumerListener, public IInterface {
-public:
-    DECLARE_META_INTERFACE(ConsumerListener)
-};
-
-class BnConsumerListener : public SafeBnInterface<IConsumerListener> {
-public:
-    BnConsumerListener() : SafeBnInterface<IConsumerListener>("BnConsumerListener") {}
-
-    status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-                        uint32_t flags = 0) override;
-};
-
-#else
-class IConsumerListener : public ConsumerListener {
-};
-class BnConsumerListener : public IConsumerListener {
-};
-#endif
+class IConsumerListener : public ConsumerListener {};
 
 } // namespace android
diff --git a/libs/gui/include/gui/IGraphicBufferConsumer.h b/libs/gui/include/gui/IGraphicBufferConsumer.h
index f6b3e89..8272a59 100644
--- a/libs/gui/include/gui/IGraphicBufferConsumer.h
+++ b/libs/gui/include/gui/IGraphicBufferConsumer.h
@@ -40,15 +40,8 @@
 /*
  * See IGraphicBufferProducer for details on SLOT_COUNT.
  */
-#ifndef NO_BINDER
-class IGraphicBufferConsumer : public IInterface {
-public:
-    DECLARE_META_INTERFACE(GraphicBufferConsumer)
-#else
 class IGraphicBufferConsumer : public RefBase {
 public:
-#endif
-
     enum {
         // Returned by releaseBuffer, after which the consumer must free any references to the
         // just-released buffer that it might have.
@@ -322,18 +315,4 @@
     }
 };
 
-#ifndef NO_BINDER
-class BnGraphicBufferConsumer : public SafeBnInterface<IGraphicBufferConsumer> {
-public:
-    BnGraphicBufferConsumer()
-          : SafeBnInterface<IGraphicBufferConsumer>("BnGraphicBufferConsumer") {}
-
-    status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-                        uint32_t flags = 0) override;
-};
-#else
-class BnGraphicBufferConsumer : public IGraphicBufferConsumer {
-};
-#endif
-
 } // namespace android
diff --git a/libs/gui/include/gui/StreamSplitter.h b/libs/gui/include/gui/StreamSplitter.h
index b4eef29..28237b6 100644
--- a/libs/gui/include/gui/StreamSplitter.h
+++ b/libs/gui/include/gui/StreamSplitter.h
@@ -37,7 +37,7 @@
 // BufferQueue, where each buffer queued to the input is available to be
 // acquired by each of the outputs, and is able to be dequeued by the input
 // again only once all of the outputs have released it.
-class StreamSplitter : public BnConsumerListener {
+class StreamSplitter : public IConsumerListener {
 public:
     // createSplitter creates a new splitter, outSplitter, using inputQueue as
     // the input BufferQueue. Output BufferQueues must be added using addOutput
diff --git a/libs/gui/include/gui/mock/GraphicBufferConsumer.h b/libs/gui/include/gui/mock/GraphicBufferConsumer.h
index 8dfd3cb..24d26b1 100644
--- a/libs/gui/include/gui/mock/GraphicBufferConsumer.h
+++ b/libs/gui/include/gui/mock/GraphicBufferConsumer.h
@@ -26,10 +26,10 @@
 namespace android {
 namespace mock {
 
-class GraphicBufferConsumer : public BnGraphicBufferConsumer, public virtual android::RefBase {
+class GraphicBufferConsumer : public IGraphicBufferConsumer {
 public:
     GraphicBufferConsumer();
-    ~GraphicBufferConsumer() override;
+    ~GraphicBufferConsumer();
 
     MOCK_METHOD3(acquireBuffer, status_t(BufferItem*, nsecs_t, uint64_t));
     MOCK_METHOD1(detachBuffer, status_t(int));
@@ -41,7 +41,9 @@
 #endif
     MOCK_METHOD2(consumerConnect, status_t(const sp<IConsumerListener>&, bool));
     MOCK_METHOD0(consumerDisconnect, status_t());
+    MOCK_METHOD1(allowUnlimitedSlots, status_t(bool));
     MOCK_METHOD1(getReleasedBuffers, status_t(uint64_t*));
+    MOCK_METHOD1(getReleasedBuffersExtended, status_t(std::vector<bool>*));
     MOCK_METHOD2(setDefaultBufferSize, status_t(uint32_t, uint32_t));
     MOCK_METHOD1(setMaxBufferCount, status_t(int));
     MOCK_METHOD1(setMaxAcquiredBufferCount, status_t(int));
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 77b4ae8..cfbb2e7 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -32,6 +32,7 @@
 #include <ui/PictureProfileHandle.h>
 
 #include <android-base/properties.h>
+#include <android-base/unique_fd.h>
 
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
@@ -45,6 +46,7 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
+#include <csignal>
 #include <future>
 #include <optional>
 #include <thread>
@@ -65,6 +67,15 @@
 
 public:
 protected:
+    void TearDown() override {
+        std::vector<std::function<void()>> teardownFns;
+        teardownFns.swap(mTeardownFns);
+
+        for (auto& fn : teardownFns) {
+            fn();
+        }
+    }
+
     void GetMinUndequeuedBufferCount(int* bufferCount) {
         ASSERT_TRUE(bufferCount != nullptr);
         ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
@@ -99,6 +110,7 @@
 
     sp<IGraphicBufferProducer> mProducer;
     sp<IGraphicBufferConsumer> mConsumer;
+    std::vector<std::function<void()>> mTeardownFns;
 };
 
 static const uint32_t TEST_DATA = 0x12345678u;
@@ -106,12 +118,14 @@
 // XXX: Tests that fork a process to hold the BufferQueue must run before tests
 // that use a local BufferQueue, or else Binder will get unhappy
 //
-// In one instance this was a crash in the createBufferQueue where the
-// binder call to create a buffer allocator apparently got garbage back.
-// See b/36592665.
+// TODO(b/392945118): In one instance this was a crash in the createBufferQueue
+// where the binder call to create a buffer allocator apparently got garbage
+// back. See b/36592665.
 TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) {
     const String16 PRODUCER_NAME = String16("BQTestProducer");
-    const String16 CONSUMER_NAME = String16("BQTestConsumer");
+
+    base::unique_fd readfd, writefd;
+    ASSERT_TRUE(base::Pipe(&readfd, &writefd));
 
     pid_t forkPid = fork();
     ASSERT_NE(forkPid, -1);
@@ -123,23 +137,51 @@
         BufferQueue::createBufferQueue(&producer, &consumer);
         sp<IServiceManager> serviceManager = defaultServiceManager();
         serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
-        serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
+
+        class ChildConsumerListener : public IConsumerListener {
+        public:
+            ChildConsumerListener(const sp<IGraphicBufferConsumer>& consumer,
+                                  base::unique_fd&& writeFd)
+                  : mConsumer(consumer), mWriteFd(std::move(writeFd)) {}
+
+            virtual void onFrameAvailable(const BufferItem&) override {
+                BufferItem item;
+                ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
+
+                uint32_t* dataOut;
+                ASSERT_EQ(OK,
+                          item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
+                                                    reinterpret_cast<void**>(&dataOut)));
+                ASSERT_EQ(*dataOut, TEST_DATA);
+                ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
+
+                bool isOk = true;
+                write(mWriteFd, &isOk, sizeof(bool));
+            }
+            virtual void onBuffersReleased() override {}
+            virtual void onSidebandStreamChanged() override {}
+
+        private:
+            sp<IGraphicBufferConsumer> mConsumer;
+            base::unique_fd mWriteFd;
+        };
+
+        sp<ChildConsumerListener> mc =
+                sp<ChildConsumerListener>::make(consumer, std::move(writefd));
+        ASSERT_EQ(OK, consumer->consumerConnect(mc, false));
+
         ProcessState::self()->startThreadPool();
         IPCThreadState::self()->joinThreadPool();
         LOG_ALWAYS_FATAL("Shouldn't be here");
+    } else {
+        mTeardownFns.emplace_back([forkPid]() { kill(forkPid, SIGTERM); });
     }
 
     sp<IServiceManager> serviceManager = defaultServiceManager();
     sp<IBinder> binderProducer = serviceManager->waitForService(PRODUCER_NAME);
     mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
     EXPECT_TRUE(mProducer != nullptr);
-    sp<IBinder> binderConsumer =
-        serviceManager->getService(CONSUMER_NAME);
-    mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
-    EXPECT_TRUE(mConsumer != nullptr);
 
-    sp<MockConsumer> mc(new MockConsumer);
-    ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
     IGraphicBufferProducer::QueueBufferOutput output;
     ASSERT_EQ(OK,
             mProducer->connect(nullptr, NATIVE_WINDOW_API_CPU, false, &output));
@@ -163,14 +205,9 @@
             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
 
-    BufferItem item;
-    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
-
-    uint32_t* dataOut;
-    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
-            reinterpret_cast<void**>(&dataOut)));
-    ASSERT_EQ(*dataOut, TEST_DATA);
-    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
+    bool isOk;
+    read(readfd, &isOk, sizeof(bool));
+    ASSERT_TRUE(isOk);
 }
 
 TEST_F(BufferQueueTest, GetMaxBufferCountInQueueBufferOutput_Succeeds) {
diff --git a/libs/gui/tests/DisconnectWaiter.h b/libs/gui/tests/DisconnectWaiter.h
index 6e6915b..3d5f633 100644
--- a/libs/gui/tests/DisconnectWaiter.h
+++ b/libs/gui/tests/DisconnectWaiter.h
@@ -29,7 +29,7 @@
 // no way to forward the events.  This DisconnectWaiter will not let the
 // disconnect finish until finishDisconnect() is called.  It will
 // also block until a disconnect is called
-class DisconnectWaiter : public BnConsumerListener {
+class DisconnectWaiter : public IConsumerListener {
 public:
     DisconnectWaiter () :
         mWaitForDisconnect(false),
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 8062a2e..cf05fd4 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -1231,7 +1231,7 @@
         consumer->setConsumerName(String8("Virtual disp consumer (MultiDisplayTests)"));
         consumer->setDefaultBufferSize(width, height);
 
-        class StubConsumerListener : public BnConsumerListener {
+        class StubConsumerListener : public IConsumerListener {
             virtual void onFrameAvailable(const BufferItem&) override {}
             virtual void onBuffersReleased() override {}
             virtual void onSidebandStreamChanged() override {}
diff --git a/libs/gui/tests/Malicious.cpp b/libs/gui/tests/Malicious.cpp
index 376420c..cc16383 100644
--- a/libs/gui/tests/Malicious.cpp
+++ b/libs/gui/tests/Malicious.cpp
@@ -129,7 +129,7 @@
     int32_t mExpectedSlot = 0;
 };
 
-class FakeListener : public BnConsumerListener {
+class FakeListener : public IConsumerListener {
 public:
     void onFrameAvailable(const BufferItem&) override {}
     void onBuffersReleased() override {}
diff --git a/libs/gui/tests/MockConsumer.h b/libs/gui/tests/MockConsumer.h
index 4a6c51c..2e8bc63 100644
--- a/libs/gui/tests/MockConsumer.h
+++ b/libs/gui/tests/MockConsumer.h
@@ -18,7 +18,7 @@
 
 namespace android {
 
-struct MockConsumer : public BnConsumerListener {
+struct MockConsumer : public IConsumerListener {
     void onFrameAvailable(const BufferItem& /* item */) override {}
     void onBuffersReleased() override {}
     void onSidebandStreamChanged() override {}
diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp
index 1c439cd..9570a36 100644
--- a/libs/gui/tests/StreamSplitter_test.cpp
+++ b/libs/gui/tests/StreamSplitter_test.cpp
@@ -32,7 +32,7 @@
 
 class StreamSplitterTest : public ::testing::Test {};
 
-struct FakeListener : public BnConsumerListener {
+struct FakeListener : public IConsumerListener {
     virtual void onFrameAvailable(const BufferItem& /* item */) {}
     virtual void onBuffersReleased() {}
     virtual void onSidebandStreamChanged() {}
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 646e30e..98d1329 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -603,7 +603,7 @@
     ASSERT_GE(after, lastDequeueTime);
 }
 
-class FakeConsumer : public BnConsumerListener {
+class FakeConsumer : public IConsumerListener {
 public:
     void onFrameAvailable(const BufferItem& /*item*/) override {}
     void onBuffersReleased() override {}
diff --git a/libs/gui/tests/testserver/TestServer.cpp b/libs/gui/tests/testserver/TestServer.cpp
index cd8824e..17d1b4a 100644
--- a/libs/gui/tests/testserver/TestServer.cpp
+++ b/libs/gui/tests/testserver/TestServer.cpp
@@ -45,7 +45,7 @@
 namespace android {
 
 namespace {
-class TestConsumerListener : public BnConsumerListener {
+class TestConsumerListener : public IConsumerListener {
     virtual void onFrameAvailable(const BufferItem&) override {}
     virtual void onBuffersReleased() override {}
     virtual void onSidebandStreamChanged() override {}
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 389fb7f..cd6fe90 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -27,9 +27,9 @@
     name: "inputconstants_aidl",
     srcs: [
         "android/os/IInputConstants.aidl",
+        "android/os/InputConfig.aidl",
         "android/os/InputEventInjectionResult.aidl",
         "android/os/InputEventInjectionSync.aidl",
-        "android/os/InputConfig.aidl",
         "android/os/MotionEventFlag.aidl",
         "android/os/PointerIconType.aidl",
     ],
@@ -85,56 +85,56 @@
     source_stem: "bindings",
 
     bindgen_flags: [
-        "--verbose",
-        "--allowlist-var=AMOTION_EVENT_ACTION_CANCEL",
-        "--allowlist-var=AMOTION_EVENT_ACTION_UP",
-        "--allowlist-var=AMOTION_EVENT_ACTION_POINTER_DOWN",
-        "--allowlist-var=AMOTION_EVENT_ACTION_DOWN",
-        "--allowlist-var=AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT",
-        "--allowlist-var=MAX_POINTER_ID",
-        "--allowlist-var=AINPUT_SOURCE_CLASS_NONE",
-        "--allowlist-var=AINPUT_SOURCE_CLASS_BUTTON",
-        "--allowlist-var=AINPUT_SOURCE_CLASS_POINTER",
-        "--allowlist-var=AINPUT_SOURCE_CLASS_NAVIGATION",
-        "--allowlist-var=AINPUT_SOURCE_CLASS_POSITION",
-        "--allowlist-var=AINPUT_SOURCE_CLASS_JOYSTICK",
-        "--allowlist-var=AINPUT_SOURCE_UNKNOWN",
-        "--allowlist-var=AINPUT_SOURCE_KEYBOARD",
-        "--allowlist-var=AINPUT_SOURCE_DPAD",
-        "--allowlist-var=AINPUT_SOURCE_GAMEPAD",
-        "--allowlist-var=AINPUT_SOURCE_TOUCHSCREEN",
-        "--allowlist-var=AINPUT_SOURCE_MOUSE",
-        "--allowlist-var=AINPUT_SOURCE_STYLUS",
-        "--allowlist-var=AINPUT_SOURCE_BLUETOOTH_STYLUS",
-        "--allowlist-var=AINPUT_SOURCE_TRACKBALL",
-        "--allowlist-var=AINPUT_SOURCE_MOUSE_RELATIVE",
-        "--allowlist-var=AINPUT_SOURCE_TOUCHPAD",
-        "--allowlist-var=AINPUT_SOURCE_TOUCH_NAVIGATION",
-        "--allowlist-var=AINPUT_SOURCE_JOYSTICK",
-        "--allowlist-var=AINPUT_SOURCE_HDMI",
-        "--allowlist-var=AINPUT_SOURCE_SENSOR",
-        "--allowlist-var=AINPUT_SOURCE_ROTARY_ENCODER",
+        "--allowlist-var=AINPUT_KEYBOARD_TYPE_ALPHABETIC",
         "--allowlist-var=AINPUT_KEYBOARD_TYPE_NONE",
         "--allowlist-var=AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC",
-        "--allowlist-var=AINPUT_KEYBOARD_TYPE_ALPHABETIC",
-        "--allowlist-var=AMETA_NONE",
-        "--allowlist-var=AMETA_ALT_ON",
+        "--allowlist-var=AINPUT_SOURCE_BLUETOOTH_STYLUS",
+        "--allowlist-var=AINPUT_SOURCE_CLASS_BUTTON",
+        "--allowlist-var=AINPUT_SOURCE_CLASS_JOYSTICK",
+        "--allowlist-var=AINPUT_SOURCE_CLASS_NAVIGATION",
+        "--allowlist-var=AINPUT_SOURCE_CLASS_NONE",
+        "--allowlist-var=AINPUT_SOURCE_CLASS_POINTER",
+        "--allowlist-var=AINPUT_SOURCE_CLASS_POSITION",
+        "--allowlist-var=AINPUT_SOURCE_DPAD",
+        "--allowlist-var=AINPUT_SOURCE_GAMEPAD",
+        "--allowlist-var=AINPUT_SOURCE_HDMI",
+        "--allowlist-var=AINPUT_SOURCE_JOYSTICK",
+        "--allowlist-var=AINPUT_SOURCE_KEYBOARD",
+        "--allowlist-var=AINPUT_SOURCE_MOUSE",
+        "--allowlist-var=AINPUT_SOURCE_MOUSE_RELATIVE",
+        "--allowlist-var=AINPUT_SOURCE_ROTARY_ENCODER",
+        "--allowlist-var=AINPUT_SOURCE_SENSOR",
+        "--allowlist-var=AINPUT_SOURCE_STYLUS",
+        "--allowlist-var=AINPUT_SOURCE_TOUCHPAD",
+        "--allowlist-var=AINPUT_SOURCE_TOUCHSCREEN",
+        "--allowlist-var=AINPUT_SOURCE_TOUCH_NAVIGATION",
+        "--allowlist-var=AINPUT_SOURCE_TRACKBALL",
+        "--allowlist-var=AINPUT_SOURCE_UNKNOWN",
         "--allowlist-var=AMETA_ALT_LEFT_ON",
+        "--allowlist-var=AMETA_ALT_ON",
         "--allowlist-var=AMETA_ALT_RIGHT_ON",
-        "--allowlist-var=AMETA_SHIFT_ON",
-        "--allowlist-var=AMETA_SHIFT_LEFT_ON",
-        "--allowlist-var=AMETA_SHIFT_RIGHT_ON",
-        "--allowlist-var=AMETA_SYM_ON",
-        "--allowlist-var=AMETA_FUNCTION_ON",
-        "--allowlist-var=AMETA_CTRL_ON",
-        "--allowlist-var=AMETA_CTRL_LEFT_ON",
-        "--allowlist-var=AMETA_CTRL_RIGHT_ON",
-        "--allowlist-var=AMETA_META_ON",
-        "--allowlist-var=AMETA_META_LEFT_ON",
-        "--allowlist-var=AMETA_META_RIGHT_ON",
         "--allowlist-var=AMETA_CAPS_LOCK_ON",
+        "--allowlist-var=AMETA_CTRL_LEFT_ON",
+        "--allowlist-var=AMETA_CTRL_ON",
+        "--allowlist-var=AMETA_CTRL_RIGHT_ON",
+        "--allowlist-var=AMETA_FUNCTION_ON",
+        "--allowlist-var=AMETA_META_LEFT_ON",
+        "--allowlist-var=AMETA_META_ON",
+        "--allowlist-var=AMETA_META_RIGHT_ON",
+        "--allowlist-var=AMETA_NONE",
         "--allowlist-var=AMETA_NUM_LOCK_ON",
         "--allowlist-var=AMETA_SCROLL_LOCK_ON",
+        "--allowlist-var=AMETA_SHIFT_LEFT_ON",
+        "--allowlist-var=AMETA_SHIFT_ON",
+        "--allowlist-var=AMETA_SHIFT_RIGHT_ON",
+        "--allowlist-var=AMETA_SYM_ON",
+        "--allowlist-var=AMOTION_EVENT_ACTION_CANCEL",
+        "--allowlist-var=AMOTION_EVENT_ACTION_DOWN",
+        "--allowlist-var=AMOTION_EVENT_ACTION_POINTER_DOWN",
+        "--allowlist-var=AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT",
+        "--allowlist-var=AMOTION_EVENT_ACTION_UP",
+        "--allowlist-var=MAX_POINTER_ID",
+        "--verbose",
     ],
 
     static_libs: [
@@ -143,9 +143,9 @@
     ],
     shared_libs: ["libc++"],
     header_libs: [
-        "native_headers",
-        "jni_headers",
         "flatbuffer_headers",
+        "jni_headers",
+        "native_headers",
     ],
 }
 
@@ -179,8 +179,8 @@
     host_supported: true,
     cflags: [
         "-Wall",
-        "-Wextra",
         "-Werror",
+        "-Wextra",
     ],
     srcs: [
         "FromRustToCpp.cpp",
@@ -205,15 +205,15 @@
     cpp_std: "c++20",
     host_supported: true,
     cflags: [
+        "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
         "-Wall",
-        "-Wextra",
         "-Werror",
+        "-Wextra",
         "-Wno-unused-parameter",
-        "-Wthread-safety",
         "-Wshadow",
         "-Wshadow-field-in-constructor-modified",
         "-Wshadow-uncaptured-local",
-        "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+        "-Wthread-safety",
     ],
     srcs: [
         "AccelerationCurve.cpp",
@@ -225,10 +225,10 @@
         "InputEventLabels.cpp",
         "InputTransport.cpp",
         "InputVerifier.cpp",
-        "Keyboard.cpp",
         "KeyCharacterMap.cpp",
-        "KeyboardClassifier.cpp",
         "KeyLayoutMap.cpp",
+        "Keyboard.cpp",
+        "KeyboardClassifier.cpp",
         "MotionPredictor.cpp",
         "MotionPredictorMetricsManager.cpp",
         "OneEuroFilter.cpp",
@@ -262,13 +262,13 @@
 
     shared_libs: [
         "android.companion.virtualdevice.flags-aconfig-cc",
+        "libPlatformProperties",
         "libaconfig_storage_read_api_cc",
         "libbase",
         "libbinder",
         "libbinder_ndk",
         "libcutils",
         "liblog",
-        "libPlatformProperties",
         "libtinyxml2",
         "libutils",
         "libz", // needed by libkernelconfigs
@@ -287,15 +287,15 @@
 
     static_libs: [
         "inputconstants-cpp",
-        "libui-types",
-        "libtflite_static",
         "libkernelconfigs",
+        "libtflite_static",
+        "libui-types",
     ],
 
     whole_static_libs: [
         "com.android.input.flags-aconfig-cc",
-        "libinput_rust_ffi",
         "iinputflinger_aidl_lib_static",
+        "libinput_rust_ffi",
     ],
 
     export_static_lib_headers: [
@@ -310,8 +310,8 @@
     target: {
         android: {
             required: [
-                "motion_predictor_model_prebuilt",
                 "motion_predictor_model_config",
+                "motion_predictor_model_prebuilt",
             ],
             static_libs: [
                 "libstatslog_libinput",
@@ -372,9 +372,9 @@
     cpp_std: "c++20",
     host_supported: true,
     shared_libs: [
-        "libutils",
         "libbase",
         "liblog",
+        "libutils",
     ],
 }
 
diff --git a/libs/input/rust/Android.bp b/libs/input/rust/Android.bp
index 63853f7..fae9074 100644
--- a/libs/input/rust/Android.bp
+++ b/libs/input/rust/Android.bp
@@ -18,12 +18,12 @@
     srcs: ["lib.rs"],
     host_supported: true,
     rustlibs: [
+        "inputconstants-rust",
         "libbitflags",
         "libcxx",
         "libinput_bindgen",
-        "liblogger",
         "liblog_rust",
-        "inputconstants-rust",
+        "liblogger",
         "libserde",
         "libserde_json",
     ],
diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp
index 85a37fe..968fa5f 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -16,16 +16,16 @@
         "BlockingQueue_test.cpp",
         "IdGenerator_test.cpp",
         "InputChannel_test.cpp",
-        "InputConsumer_test.cpp",
         "InputConsumerFilteredResampling_test.cpp",
         "InputConsumerResampling_test.cpp",
+        "InputConsumer_test.cpp",
         "InputDevice_test.cpp",
         "InputEvent_test.cpp",
-        "InputPublisherAndConsumer_test.cpp",
         "InputPublisherAndConsumerNoResampling_test.cpp",
+        "InputPublisherAndConsumer_test.cpp",
         "InputVerifier_test.cpp",
-        "MotionPredictor_test.cpp",
         "MotionPredictorMetricsManager_test.cpp",
+        "MotionPredictor_test.cpp",
         "OneEuroFilter_test.cpp",
         "Resampler_test.cpp",
         "RingBuffer_test.cpp",
@@ -53,8 +53,8 @@
     ],
     cflags: [
         "-Wall",
-        "-Wextra",
         "-Werror",
+        "-Wextra",
         "-Wno-unused-parameter",
     ],
     sanitize: {
@@ -68,26 +68,26 @@
             memtag_heap: true,
             undefined: true,
             misc_undefined: [
-                "bounds",
                 "all",
+                "bounds",
             ],
         },
     },
     shared_libs: [
+        "libPlatformProperties",
         "libaconfig_storage_read_api_cc",
         "libbase",
         "libbinder",
         "libcutils",
         "liblog",
-        "libPlatformProperties",
         "libstatslog",
         "libtinyxml2",
         "libutils",
         "server_configurable_flags",
     ],
     data: [
-        "data/*",
         ":motion_predictor_model",
+        "data/*",
     ],
     test_options: {
         unit_test: true,
@@ -117,10 +117,10 @@
         "-Wextra",
     ],
     shared_libs: [
-        "libinput",
-        "libcutils",
-        "libutils",
-        "libbinder",
         "libbase",
+        "libbinder",
+        "libcutils",
+        "libinput",
+        "libutils",
     ],
 }
diff --git a/libs/input/tests/TestEventMatchers.h b/libs/input/tests/TestEventMatchers.h
index 56eaefd..8dbdcb3 100644
--- a/libs/input/tests/TestEventMatchers.h
+++ b/libs/input/tests/TestEventMatchers.h
@@ -27,12 +27,8 @@
 
 namespace android {
 
-namespace {
-
 using ::testing::Matcher;
 
-} // namespace
-
 /**
  * This file contains a copy of Matchers from .../inputflinger/tests/TestEventMatchers.h. Ideally,
  * implementations must not be duplicated.
diff --git a/libs/tracing_perfetto/tracing_perfetto_internal.cpp b/libs/tracing_perfetto/tracing_perfetto_internal.cpp
index f92f6df..4478732 100644
--- a/libs/tracing_perfetto/tracing_perfetto_internal.cpp
+++ b/libs/tracing_perfetto/tracing_perfetto_internal.cpp
@@ -14,15 +14,16 @@
  * limitations under the License.
  */
 
+// Should match the definitions in: frameworks/native/cmds/atrace/atrace.cpp
 #define FRAMEWORK_CATEGORIES(C)                                  \
   C(always, "always", "Always category")                         \
-  C(graphics, "graphics", "Graphics category")                   \
+  C(graphics, "gfx", "Graphics category")                        \
   C(input, "input", "Input category")                            \
   C(view, "view", "View category")                               \
   C(webview, "webview", "WebView category")                      \
   C(windowmanager, "wm", "WindowManager category")               \
   C(activitymanager, "am", "ActivityManager category")           \
-  C(syncmanager, "syncmanager", "SyncManager category")          \
+  C(syncmanager, "sm", "SyncManager category")                   \
   C(audio, "audio", "Audio category")                            \
   C(video, "video", "Video category")                            \
   C(camera, "camera", "Camera category")                         \
@@ -33,7 +34,7 @@
   C(rs, "rs", "RS category")                                     \
   C(bionic, "bionic", "Bionic category")                         \
   C(power, "power", "Power category")                            \
-  C(packagemanager, "packagemanager", "PackageManager category") \
+  C(packagemanager, "pm", "PackageManager category")             \
   C(systemserver, "ss", "System Server category")                \
   C(database, "database", "Database category")                   \
   C(network, "network", "Network category")                      \
diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp
index 839a5ca..ebdc629 100644
--- a/opengl/tests/EGLTest/EGL_test.cpp
+++ b/opengl/tests/EGLTest/EGL_test.cpp
@@ -141,7 +141,7 @@
     };
     EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs));
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -261,7 +261,7 @@
     EXPECT_EQ(components[2], 8);
     EXPECT_EQ(components[3], 8);
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -309,7 +309,7 @@
 
     get8BitConfig(config);
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -406,7 +406,7 @@
     EXPECT_EQ(components[2], 10);
     EXPECT_EQ(components[3], 2);
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -578,7 +578,7 @@
 
     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -630,7 +630,7 @@
 
     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -713,7 +713,7 @@
     EXPECT_GE(components[2], 16);
     EXPECT_GE(components[3], 16);
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -742,7 +742,7 @@
 
     ASSERT_TRUE(hasEglExtension(mEglDisplay, "EGL_KHR_no_config_context"));
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -841,7 +841,7 @@
     EXPECT_EQ(components[2], 10);
     EXPECT_EQ(components[3], 2);
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -867,7 +867,7 @@
 
     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -920,7 +920,7 @@
     ASSERT_EQ(EGL_UNSIGNED_TRUE, success);
     ASSERT_EQ(1, numConfigs);
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -951,7 +951,7 @@
 
     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
@@ -997,7 +997,7 @@
 
     ASSERT_NO_FATAL_FAILURE(get8BitConfig(config));
 
-    struct MockConsumer : public BnConsumerListener {
+    struct MockConsumer : public IConsumerListener {
         void onFrameAvailable(const BufferItem& /* item */) override {}
         void onBuffersReleased() override {}
         void onSidebandStreamChanged() override {}
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index ca92ab5..107fd20 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -32,15 +32,15 @@
     host_supported: true,
     cpp_std: "c++20",
     cflags: [
+        "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
         "-Wall",
-        "-Wextra",
         "-Werror",
+        "-Wextra",
         "-Wno-unused-parameter",
-        "-Wthread-safety",
         "-Wshadow",
         "-Wshadow-field-in-constructor-modified",
         "-Wshadow-uncaptured-local",
-        "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
+        "-Wthread-safety",
     ],
     sanitize: {
         misc_undefined: [
@@ -62,8 +62,8 @@
                     memtag_heap: true,
                     undefined: true,
                     misc_undefined: [
-                        "bounds",
                         "all",
+                        "bounds",
                     ],
                 },
             },
@@ -114,16 +114,16 @@
         "liblog",
         "libprotobuf-cpp-lite",
         "libstatslog",
-        "libutils",
         "libstatspull",
         "libstatssocket",
+        "libutils",
         "packagemanager_aidl-cpp",
         "server_configurable_flags",
     ],
     static_libs: [
         "libattestation",
-        "libperfetto_client_experimental",
         "libpalmrejection",
+        "libperfetto_client_experimental",
         "libui-types",
     ],
     generated_headers: [
@@ -161,10 +161,10 @@
     shared_libs: [
         // This should consist only of dependencies from inputflinger. Other dependencies should be
         // in cc_defaults so that they are included in the tests.
+        "libPlatformProperties",
         "libinputflinger_base",
         "libinputreader",
         "libinputreporter",
-        "libPlatformProperties",
     ],
     static_libs: [
         "libinputdispatcher",
@@ -185,8 +185,8 @@
     name: "libinputflinger_headers",
     host_supported: true,
     export_include_dirs: [
-        "include",
         ".",
+        "include",
     ],
     header_libs: [
         "libchrome-gestures_headers",
@@ -247,49 +247,40 @@
 phony {
     name: "checkinput",
     required: [
-        // native targets
-        "libgui_test",
-        "libinput",
-        "libinputreader_static",
-        "libinputflinger",
-        "inputflinger_tests",
-        "inputflinger_benchmarks",
-        "libinput_tests",
-        "libpalmrejection_test",
-        "libandroid_runtime",
-        "libinputservice_test",
         "Bug-115739809",
-        "StructLayout_test",
-
-        // jni
-        "libservices.core",
-
-        // rust targets
-        "libinput_rust_test",
-
-        // native fuzzers
-        "inputflinger_latencytracker_fuzzer",
-        "inputflinger_cursor_input_fuzzer",
-        "inputflinger_keyboard_input_fuzzer",
-        "inputflinger_multitouch_input_fuzzer",
-        "inputflinger_switch_input_fuzzer",
-        "inputflinger_touchpad_input_fuzzer",
-        "inputflinger_input_reader_fuzzer",
-        "inputflinger_blocking_queue_fuzzer",
-        "inputflinger_input_classifier_fuzzer",
-        "inputflinger_input_dispatcher_fuzzer",
-
-        // Java/Kotlin targets
-        "CtsWindowManagerDeviceWindow",
-        "InputTests",
         "CtsHardwareTestCases",
         "CtsInputTestCases",
+        "CtsSecurityBulletinHostTestCases",
+        "CtsSecurityTestCases",
         "CtsViewTestCases",
         "CtsWidgetTestCases",
+        "CtsWindowManagerDeviceWindow",
         "FrameworksCoreTests",
         "FrameworksServicesTests",
-        "CtsSecurityTestCases",
-        "CtsSecurityBulletinHostTestCases",
+        "InputTests",
+        "StructLayout_test",
+        "inputflinger_benchmarks",
+        "inputflinger_blocking_queue_fuzzer",
+        "inputflinger_cursor_input_fuzzer",
+        "inputflinger_input_classifier_fuzzer",
+        "inputflinger_input_dispatcher_fuzzer",
+        "inputflinger_input_reader_fuzzer",
+        "inputflinger_keyboard_input_fuzzer",
+        "inputflinger_latencytracker_fuzzer",
+        "inputflinger_multitouch_input_fuzzer",
+        "inputflinger_switch_input_fuzzer",
+        "inputflinger_tests",
+        "inputflinger_touchpad_input_fuzzer",
+        "libandroid_runtime",
+        "libgui_test",
+        "libinput",
+        "libinput_rust_test",
+        "libinput_tests",
+        "libinputflinger",
+        "libinputreader_static",
+        "libinputservice_test",
+        "libpalmrejection_test",
+        "libservices.core",
         "monkey_test",
     ],
 }
diff --git a/services/inputflinger/InputFilter.cpp b/services/inputflinger/InputFilter.cpp
index 2ef94fb..bb4e617 100644
--- a/services/inputflinger/InputFilter.cpp
+++ b/services/inputflinger/InputFilter.cpp
@@ -56,7 +56,7 @@
 void InputFilter::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
     mDeviceInfos.clear();
     mDeviceInfos.reserve(args.inputDeviceInfos.size());
-    for (auto info : args.inputDeviceInfos) {
+    for (const auto& info : args.inputDeviceInfos) {
         AidlDeviceInfo& aidlInfo = mDeviceInfos.emplace_back();
         aidlInfo.deviceId = info.getId();
         aidlInfo.external = info.isExternal();
diff --git a/services/inputflinger/PointerChoreographer.cpp b/services/inputflinger/PointerChoreographer.cpp
index 9f91285..3140dc8 100644
--- a/services/inputflinger/PointerChoreographer.cpp
+++ b/services/inputflinger/PointerChoreographer.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "PointerChoreographer"
 
 #include <android-base/logging.h>
+#include <android/configuration.h>
 #include <com_android_input_flags.h>
 #if defined(__ANDROID__)
 #include <gui/SurfaceComposerClient.h>
@@ -114,6 +115,17 @@
     }
 }
 
+// The standardised medium display density for which 1 px  = 1 dp
+constexpr int32_t DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM;
+
+inline float pxToDp(int px, int dpi) {
+    return static_cast<float>(px * DENSITY_MEDIUM) / static_cast<float>(dpi);
+}
+
+inline int dpToPx(float dp, int dpi) {
+    return static_cast<int>((dp * dpi) / DENSITY_MEDIUM);
+}
+
 } // namespace
 
 // --- PointerChoreographer ---
@@ -385,8 +397,7 @@
     pc.fade(PointerControllerInterface::Transition::IMMEDIATE);
     pc.setDisplayViewport(destinationViewport);
     vec2 destinationPosition =
-            calculatePositionOnDestinationViewport(destinationViewport,
-                                                   cursorOffset - destinationOffset,
+            calculatePositionOnDestinationViewport(destinationViewport, destinationOffset,
                                                    sourceBoundary);
 
     // Transform position back to un-rotated coordinate space before sending it to controller
@@ -990,10 +1001,10 @@
     return ConstructorDelegate(std::move(ctor));
 }
 
-std::optional<std::pair<const DisplayViewport*, float /*offset*/>>
+std::optional<std::pair<const DisplayViewport*, float /*offsetPx*/>>
 PointerChoreographer::findDestinationDisplayLocked(const ui::LogicalDisplayId sourceDisplayId,
                                                    const DisplayTopologyPosition sourceBoundary,
-                                                   float cursorOffset) const {
+                                                   int32_t sourceCursorOffsetPx) const {
     const auto& sourceNode = mTopology.graph.find(sourceDisplayId);
     if (sourceNode == mTopology.graph.end()) {
         // Topology is likely out of sync with viewport info, wait for it to be updated
@@ -1004,22 +1015,32 @@
         if (adjacentDisplay.position != sourceBoundary) {
             continue;
         }
-        const DisplayViewport* destinationViewport =
-                findViewportByIdLocked(adjacentDisplay.displayId);
-        if (destinationViewport == nullptr) {
+        const DisplayViewport* adjacentViewport = findViewportByIdLocked(adjacentDisplay.displayId);
+        if (adjacentViewport == nullptr) {
             // Topology is likely out of sync with viewport info, wait for them to be updated
             LOG(WARNING) << "Cannot find viewport for adjacent display "
                          << adjacentDisplay.displayId << "of source display " << sourceDisplayId;
             continue;
         }
-        // target position must be within target display boundary
-        const int32_t edgeSize = sourceBoundary == DisplayTopologyPosition::TOP ||
+        // As displays can have different densities we need to do all calculations in
+        // density-independent-pixels a.k.a. dp values.
+        const int sourceDensity = mTopology.displaysDensity.at(sourceDisplayId);
+        const int adjacentDisplayDensity = mTopology.displaysDensity.at(adjacentDisplay.displayId);
+        const float sourceCursorOffsetDp = pxToDp(sourceCursorOffsetPx, sourceDensity);
+        const int32_t edgeSizePx = sourceBoundary == DisplayTopologyPosition::TOP ||
                         sourceBoundary == DisplayTopologyPosition::BOTTOM
-                ? (destinationViewport->logicalRight - destinationViewport->logicalLeft)
-                : (destinationViewport->logicalBottom - destinationViewport->logicalTop);
-        if (cursorOffset >= adjacentDisplay.offsetDp &&
-            cursorOffset <= adjacentDisplay.offsetDp + edgeSize) {
-            return std::make_pair(destinationViewport, adjacentDisplay.offsetDp);
+                ? (adjacentViewport->logicalRight - adjacentViewport->logicalLeft)
+                : (adjacentViewport->logicalBottom - adjacentViewport->logicalTop);
+        const float adjacentEdgeSizeDp = pxToDp(edgeSizePx, adjacentDisplayDensity);
+        // Target position must be within target display boundary.
+        // Cursor should also be able to cross displays when only display corners are touching and
+        // there may be zero overlapping pixels. To accommodate this we have margin of one pixel
+        // around the end of the overlapping edge.
+        if (sourceCursorOffsetDp >= adjacentDisplay.offsetDp &&
+            sourceCursorOffsetDp <= adjacentDisplay.offsetDp + adjacentEdgeSizeDp) {
+            const int destinationOffsetPx =
+                    dpToPx(sourceCursorOffsetDp - adjacentDisplay.offsetDp, adjacentDisplayDensity);
+            return std::make_pair(adjacentViewport, destinationOffsetPx);
         }
     }
     return std::nullopt;
diff --git a/services/inputflinger/PointerChoreographer.h b/services/inputflinger/PointerChoreographer.h
index c2f5ec0..a9d971a 100644
--- a/services/inputflinger/PointerChoreographer.h
+++ b/services/inputflinger/PointerChoreographer.h
@@ -163,10 +163,10 @@
     void handleUnconsumedDeltaLocked(PointerControllerInterface& pc, const vec2& unconsumedDelta)
             REQUIRES(getLock());
 
-    std::optional<std::pair<const DisplayViewport*, float /*offset*/>> findDestinationDisplayLocked(
-            const ui::LogicalDisplayId sourceDisplayId,
-            const DisplayTopologyPosition sourceBoundary, float cursorOffset) const
-            REQUIRES(getLock());
+    std::optional<std::pair<const DisplayViewport*, float /*offsetPx*/>>
+    findDestinationDisplayLocked(const ui::LogicalDisplayId sourceDisplayId,
+                                 const DisplayTopologyPosition sourceBoundary,
+                                 int32_t sourceCursorOffsetPx) const REQUIRES(getLock());
 
     /* Topology is initialized with default-constructed value, which is an empty topology. Till we
      * receive setDisplayTopology call.
diff --git a/services/inputflinger/dispatcher/Android.bp b/services/inputflinger/dispatcher/Android.bp
index 8b2b843..1aa8b2b 100644
--- a/services/inputflinger/dispatcher/Android.bp
+++ b/services/inputflinger/dispatcher/Android.bp
@@ -49,8 +49,8 @@
         "LatencyAggregatorWithHistograms.cpp",
         "LatencyTracker.cpp",
         "Monitor.cpp",
-        "TouchedWindow.cpp",
         "TouchState.cpp",
+        "TouchedWindow.cpp",
         "trace/*.cpp",
     ],
 }
@@ -71,9 +71,9 @@
         "liblog",
         "libprotobuf-cpp-lite",
         "libstatslog",
-        "libutils",
         "libstatspull",
         "libstatssocket",
+        "libutils",
         "packagemanager_aidl-cpp",
         "server_configurable_flags",
     ],
diff --git a/services/inputflinger/rust/Android.bp b/services/inputflinger/rust/Android.bp
index 5b7cc2d..78674e5 100644
--- a/services/inputflinger/rust/Android.bp
+++ b/services/inputflinger/rust/Android.bp
@@ -40,14 +40,14 @@
     crate_name: "inputflinger",
     srcs: ["lib.rs"],
     rustlibs: [
-        "libcxx",
-        "com.android.server.inputflinger-rust",
         "android.hardware.input.common-V1-rust",
+        "com.android.server.inputflinger-rust",
         "libbinder_rs",
+        "libcxx",
+        "libinput_rust",
         "liblog_rust",
         "liblogger",
         "libnix",
-        "libinput_rust",
     ],
     host_supported: true,
 }
diff --git a/services/inputflinger/tests/PointerChoreographer_test.cpp b/services/inputflinger/tests/PointerChoreographer_test.cpp
index 1ca2998..1286a36 100644
--- a/services/inputflinger/tests/PointerChoreographer_test.cpp
+++ b/services/inputflinger/tests/PointerChoreographer_test.cpp
@@ -2617,12 +2617,17 @@
     static constexpr ui::LogicalDisplayId DISPLAY_BOTTOM_ID = ui::LogicalDisplayId{40};
     static constexpr ui::LogicalDisplayId DISPLAY_LEFT_ID = ui::LogicalDisplayId{50};
     static constexpr ui::LogicalDisplayId DISPLAY_TOP_RIGHT_CORNER_ID = ui::LogicalDisplayId{60};
+    static constexpr ui::LogicalDisplayId DISPLAY_HIGH_DENSITY_ID = ui::LogicalDisplayId{70};
+
+    static constexpr int DENSITY_MEDIUM = 160;
+    static constexpr int DENSITY_HIGH = 320;
 
     PointerChoreographerDisplayTopologyTestFixture() {
         com::android::input::flags::connected_displays_cursor(true);
     }
 
 protected:
+    // Note: viewport size is in pixels and offsets in topology are in dp
     std::vector<DisplayViewport> mViewports{
             createViewport(DISPLAY_CENTER_ID, /*width*/ 100, /*height*/ 100, ui::ROTATION_0),
             createViewport(DISPLAY_TOP_ID, /*width*/ 90, /*height*/ 90, ui::ROTATION_0),
@@ -2631,16 +2636,28 @@
             createViewport(DISPLAY_LEFT_ID, /*width*/ 90, /*height*/ 90, ui::ROTATION_270),
             createViewport(DISPLAY_TOP_RIGHT_CORNER_ID, /*width*/ 90, /*height*/ 90,
                            ui::ROTATION_0),
+            // Create a high density display size 100x100 dp i.e. 200x200 px
+            createViewport(DISPLAY_HIGH_DENSITY_ID, /*width*/ 200, /*height*/ 200, ui::ROTATION_0),
     };
 
-    DisplayTopologyGraph mTopology{DISPLAY_CENTER_ID,
-                                   {{DISPLAY_CENTER_ID,
-                                     {{DISPLAY_TOP_ID, DisplayTopologyPosition::TOP, 10.0f},
-                                      {DISPLAY_RIGHT_ID, DisplayTopologyPosition::RIGHT, 10.0f},
-                                      {DISPLAY_BOTTOM_ID, DisplayTopologyPosition::BOTTOM, 10.0f},
-                                      {DISPLAY_LEFT_ID, DisplayTopologyPosition::LEFT, 10.0f},
-                                      {DISPLAY_TOP_RIGHT_CORNER_ID, DisplayTopologyPosition::RIGHT,
-                                       -90.0f}}}}};
+    DisplayTopologyGraph
+            mTopology{DISPLAY_CENTER_ID,
+                      {{DISPLAY_CENTER_ID,
+                        {{DISPLAY_TOP_ID, DisplayTopologyPosition::TOP, 50.0f},
+                         // Place a high density display on the left of DISPLAY_TOP_ID with 25 dp
+                         // gap
+                         {DISPLAY_HIGH_DENSITY_ID, DisplayTopologyPosition::TOP, -75.0f},
+                         {DISPLAY_RIGHT_ID, DisplayTopologyPosition::RIGHT, 10.0f},
+                         {DISPLAY_BOTTOM_ID, DisplayTopologyPosition::BOTTOM, 10.0f},
+                         {DISPLAY_LEFT_ID, DisplayTopologyPosition::LEFT, 10.0f},
+                         {DISPLAY_TOP_RIGHT_CORNER_ID, DisplayTopologyPosition::RIGHT, -90.0f}}}},
+                      {{DISPLAY_CENTER_ID, DENSITY_MEDIUM},
+                       {DISPLAY_TOP_ID, DENSITY_MEDIUM},
+                       {DISPLAY_RIGHT_ID, DENSITY_MEDIUM},
+                       {DISPLAY_BOTTOM_ID, DENSITY_MEDIUM},
+                       {DISPLAY_LEFT_ID, DENSITY_MEDIUM},
+                       {DISPLAY_TOP_RIGHT_CORNER_ID, DENSITY_MEDIUM},
+                       {DISPLAY_HIGH_DENSITY_ID, DENSITY_HIGH}}};
 
 private:
     DisplayViewport createViewport(ui::LogicalDisplayId displayId, int32_t width, int32_t height,
@@ -2731,7 +2748,7 @@
                                 ToolType::FINGER, vec2(50, 50) /* initial x/y */,
                                 vec2(25, -100) /* delta x/y */,
                                 PointerChoreographerDisplayTopologyTestFixture::DISPLAY_TOP_ID,
-                                vec2(50 + 25 - 10,
+                                vec2(50 + 25 - 50,
                                      90) /* Bottom edge: (source + delta - offset, height) */),
                 std::make_tuple("TransitionToBottomDisplay",
                                 AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD, ControllerType::MOUSE,
@@ -2739,11 +2756,12 @@
                                 vec2(25, 100) /* delta x/y */,
                                 PointerChoreographerDisplayTopologyTestFixture::DISPLAY_BOTTOM_ID,
                                 vec2(50 + 25 - 10, 0) /* Top edge: (source + delta - offset, 0) */),
+                // move towards 25 dp gap between DISPLAY_HIGH_DENSITY_ID and DISPLAY_TOP_ID
                 std::make_tuple("NoTransitionAtTopOffset", AINPUT_SOURCE_MOUSE,
                                 ControllerType::MOUSE, ToolType::MOUSE,
-                                vec2(5, 50) /* initial x/y */, vec2(0, -100) /* Move Up */,
+                                vec2(35, 50) /* initial x/y */, vec2(0, -100) /* Move Up */,
                                 PointerChoreographerDisplayTopologyTestFixture::DISPLAY_CENTER_ID,
-                                vec2(5, 0) /* Top edge */),
+                                vec2(35, 0) /* Top edge */),
                 std::make_tuple("NoTransitionAtRightOffset", AINPUT_SOURCE_MOUSE,
                                 ControllerType::MOUSE, ToolType::MOUSE,
                                 vec2(95, 5) /* initial x/y */, vec2(100, 0) /* Move Right */,
@@ -2764,9 +2782,16 @@
                 std::make_tuple(
                         "TransitionAtTopRightCorner", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD,
                         ControllerType::MOUSE, ToolType::FINGER, vec2(95, 5) /* initial x/y */,
-                        vec2(10, -10) /* Move dignally to top right corner */,
+                        vec2(10, -10) /* Move diagonally to top right corner */,
                         PointerChoreographerDisplayTopologyTestFixture::DISPLAY_TOP_RIGHT_CORNER_ID,
-                        vec2(0, 90) /* bottom left corner */)),
+                        vec2(0, 90) /* bottom left corner */),
+                std::make_tuple(
+                        "TransitionToHighDpDisplay", AINPUT_SOURCE_MOUSE | AINPUT_SOURCE_TOUCHPAD,
+                        ControllerType::MOUSE, ToolType::MOUSE, vec2(20, 20) /* initial x/y */,
+                        vec2(0, -50) /* delta x/y */,
+                        PointerChoreographerDisplayTopologyTestFixture::DISPLAY_HIGH_DENSITY_ID,
+                        /* Bottom edge: ((source + delta - offset) * density, height) */
+                        vec2((20 + 0 + 75) * 2, 200))),
         [](const testing::TestParamInfo<PointerChoreographerDisplayTopologyTestFixtureParam>& p) {
             return std::string{std::get<0>(p.param)};
         });
diff --git a/services/inputflinger/tests/TestEventMatchers.h b/services/inputflinger/tests/TestEventMatchers.h
index 65bc278..1262af7 100644
--- a/services/inputflinger/tests/TestEventMatchers.h
+++ b/services/inputflinger/tests/TestEventMatchers.h
@@ -32,7 +32,13 @@
 
 namespace android {
 
-namespace {
+struct PointF {
+    float x;
+    float y;
+    auto operator<=>(const PointF&) const = default;
+};
+
+namespace internal {
 
 template <typename T>
 static bool valuesMatch(T value1, T value2) {
@@ -43,17 +49,11 @@
     }
 }
 
-struct PointF {
-    float x;
-    float y;
-    auto operator<=>(const PointF&) const = default;
-};
-
 inline std::string pointFToString(const PointF& p) {
     return std::string("(") + std::to_string(p.x) + ", " + std::to_string(p.y) + ")";
 }
 
-} // namespace
+} // namespace internal
 
 /// Source
 class WithSourceMatcher {
@@ -453,8 +453,10 @@
         }
 
         if (mPointers != actualPointers) {
-            *os << "expected pointers " << dumpMap(mPointers, constToString, pointFToString)
-                << ", but got " << dumpMap(actualPointers, constToString, pointFToString);
+            *os << "expected pointers "
+                << dumpMap(mPointers, constToString, internal::pointFToString)
+                << ", but got "
+                << dumpMap(actualPointers, constToString, internal::pointFToString);
             return false;
         }
         return true;
@@ -469,15 +471,17 @@
         }
 
         if (mPointers != actualPointers) {
-            *os << "expected pointers " << dumpMap(mPointers, constToString, pointFToString)
-                << ", but got " << dumpMap(actualPointers, constToString, pointFToString);
+            *os << "expected pointers "
+                << dumpMap(mPointers, constToString, internal::pointFToString)
+                << ", but got "
+                << dumpMap(actualPointers, constToString, internal::pointFToString);
             return false;
         }
         return true;
     }
 
     void DescribeTo(std::ostream* os) const {
-        *os << "with pointers " << dumpMap(mPointers, constToString, pointFToString);
+        *os << "with pointers " << dumpMap(mPointers, constToString, internal::pointFToString);
     }
 
     void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointers"; }
@@ -721,8 +725,9 @@
         }
 
         const PointerCoords& coords = event.pointerCoords[mPointerIndex];
-        bool matches = valuesMatch(mRelX, coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X)) &&
-                valuesMatch(mRelY, coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
+        bool matches =
+            internal::valuesMatch(mRelX, coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X)) &&
+                internal::valuesMatch(mRelY, coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
         if (!matches) {
             *os << "expected relative motion (" << mRelX << ", " << mRelY << ") at pointer index "
                 << mPointerIndex << ", but got ("
diff --git a/services/inputflinger/tests/fuzzers/Android.bp b/services/inputflinger/tests/fuzzers/Android.bp
index 48e1954..5000db7 100644
--- a/services/inputflinger/tests/fuzzers/Android.bp
+++ b/services/inputflinger/tests/fuzzers/Android.bp
@@ -33,8 +33,8 @@
         "frameworks/native/services/inputflinger",
     ],
     shared_libs: [
-        "libinputreader",
         "libinputflinger_base",
+        "libinputreader",
     ],
     sanitize: {
         hwaddress: true,
diff --git a/services/inputflinger/tests/fuzzers/FuzzedInputStream.h b/services/inputflinger/tests/fuzzers/FuzzedInputStream.h
index 812969b..767f9cd 100644
--- a/services/inputflinger/tests/fuzzers/FuzzedInputStream.h
+++ b/services/inputflinger/tests/fuzzers/FuzzedInputStream.h
@@ -18,10 +18,8 @@
 
 namespace android {
 
-namespace {
 static constexpr int32_t MAX_RANDOM_POINTERS = 4;
 static constexpr int32_t MAX_RANDOM_DEVICES = 4;
-} // namespace
 
 int getFuzzedMotionAction(FuzzedDataProvider& fdp) {
     int actionMasked = fdp.PickValueInArray<int>({
diff --git a/services/sensorservice/Android.bp b/services/sensorservice/Android.bp
index 8c80dd8..9ecd101 100644
--- a/services/sensorservice/Android.bp
+++ b/services/sensorservice/Android.bp
@@ -11,7 +11,7 @@
     name: "sensorservice_flags",
     package: "com.android.frameworks.sensorservice.flags",
     container: "system",
-    srcs: ["senserservice_flags.aconfig"],
+    srcs: ["sensorservice_flags.aconfig"],
 }
 
 cc_aconfig_library {
@@ -61,38 +61,38 @@
     ],
 
     shared_libs: [
-        "libcutils",
-        "libhardware",
-        "libhardware_legacy",
-        "libutils",
-        "liblog",
-        "libactivitymanager_aidl",
-        "libbatterystats_aidl",
-        "libbinder",
-        "libsensor",
-        "libsensorprivacy",
-        "libpermission",
-        "libprotoutil",
-        "libcrypto",
-        "libbase",
-        "libhidlbase",
-        "libfmq",
-        "libbinder_ndk",
-        "packagemanager_aidl-cpp",
+        "android.hardware.common-V2-ndk",
+        "android.hardware.common.fmq-V1-ndk",
         "android.hardware.sensors@1.0",
         "android.hardware.sensors@2.0",
         "android.hardware.sensors@2.1",
-        "android.hardware.common-V2-ndk",
-        "android.hardware.common.fmq-V1-ndk",
-        "server_configurable_flags",
         "libaconfig_storage_read_api_cc",
+        "libactivitymanager_aidl",
+        "libbase",
+        "libbatterystats_aidl",
+        "libbinder",
+        "libbinder_ndk",
+        "libcrypto",
+        "libcutils",
+        "libfmq",
+        "libhardware",
+        "libhardware_legacy",
+        "libhidlbase",
+        "liblog",
+        "libpermission",
+        "libprotoutil",
+        "libsensor",
+        "libsensorprivacy",
+        "libutils",
+        "packagemanager_aidl-cpp",
+        "server_configurable_flags",
     ],
 
     static_libs: [
-        "libaidlcommonsupport",
-        "android.hardware.sensors@1.0-convert",
         "android.hardware.sensors-V1-convert",
         "android.hardware.sensors-V3-ndk",
+        "android.hardware.sensors@1.0-convert",
+        "libaidlcommonsupport",
         "sensorservice_flags_c_lib",
     ],
 
@@ -100,9 +100,9 @@
 
     export_shared_lib_headers: [
         "libactivitymanager_aidl",
+        "libpermission",
         "libsensor",
         "libsensorprivacy",
-        "libpermission",
     ],
 
     afdo: true,
@@ -120,9 +120,9 @@
     srcs: ["main_sensorservice.cpp"],
 
     shared_libs: [
-        "libsensorservice",
-        "libsensorprivacy",
         "libbinder",
+        "libsensorprivacy",
+        "libsensorservice",
         "libutils",
     ],
 
diff --git a/services/sensorservice/senserservice_flags.aconfig b/services/sensorservice/sensorservice_flags.aconfig
similarity index 79%
rename from services/sensorservice/senserservice_flags.aconfig
rename to services/sensorservice/sensorservice_flags.aconfig
index 7abfbaa..452b428 100644
--- a/services/sensorservice/senserservice_flags.aconfig
+++ b/services/sensorservice/sensorservice_flags.aconfig
@@ -28,3 +28,13 @@
   description: "When this flag is enabled, sensor service will only erase dynamic sensor data at the end of the threadLoop to prevent race condition."
   bug: "329020894"
 }
+
+flag {
+  name: "enforce_permissions_for_all_target_sdk"
+  namespace: "sensors"
+  description: "When this flag is enabled, sensor service will enforce permissions for all target sdks."
+  bug: "389176817"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
\ No newline at end of file
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index fece312..008b057 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -654,7 +654,7 @@
             // We try to do this by moving the deadline. Since the queue could be stuffed by more
             // than one buffer, we take the last latch time as reference and give one vsync
             // worth of time for the frame to be ready.
-            nsecs_t adjustedDeadline = mLastLatchTime + refreshRate.getPeriodNsecs();
+            nsecs_t adjustedDeadline = mLastLatchTime + displayFrameRenderRate.getPeriodNsecs();
             if (adjustedDeadline > mActuals.endTime) {
                 mFrameReadyMetadata = FrameReadyMetadata::OnTimeFinish;
             } else {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d117753..eecdd72 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2978,22 +2978,21 @@
     }
 
     int index = 0;
-    std::array<char, WorkloadTracer::COMPOSITION_SUMMARY_SIZE> compositionSummary = {0};
+    ftl::StaticVector<char, WorkloadTracer::COMPOSITION_SUMMARY_SIZE> compositionSummary;
     auto lastLayerStack = ui::INVALID_LAYER_STACK;
     for (auto& [layer, layerFE] : layers) {
         CompositionResult compositionResult{layerFE->stealCompositionResult()};
-        if (index < compositionSummary.size()) {
-            if (lastLayerStack != ui::INVALID_LAYER_STACK &&
-                lastLayerStack != layerFE->mSnapshot->outputFilter.layerStack) {
+        if (lastLayerStack != layerFE->mSnapshot->outputFilter.layerStack) {
+            if (lastLayerStack != ui::INVALID_LAYER_STACK) {
                 // add a space to separate displays
-                compositionSummary[index++] = ' ';
+                compositionSummary.push_back(' ');
             }
             lastLayerStack = layerFE->mSnapshot->outputFilter.layerStack;
-            compositionSummary[index++] = layerFE->mSnapshot->classifyCompositionForDebug(
-                    layerFE->getHwcCompositionType());
-            if (layerFE->mSnapshot->hasEffect()) {
-                compositedWorkload |= adpf::Workload::EFFECTS;
-            }
+        }
+        compositionSummary.push_back(
+                layerFE->mSnapshot->classifyCompositionForDebug(layerFE->getHwcCompositionType()));
+        if (layerFE->mSnapshot->hasEffect()) {
+            compositedWorkload |= adpf::Workload::EFFECTS;
         }
 
         if (compositionResult.lastClientCompositionFence) {
@@ -3010,7 +3009,8 @@
     SFTRACE_INSTANT_FOR_TRACK(WorkloadTracer::TRACK_NAME,
                               ftl::Concat("Layers: ", layers.size(), " ",
                                           ftl::truncated<WorkloadTracer::COMPOSITION_SUMMARY_SIZE>(
-                                                  compositionSummary.data()))
+                                                  std::string_view(compositionSummary.begin(),
+                                                                   compositionSummary.size())))
                                       .c_str());
 
     mPowerAdvisor->setCompositedWorkload(compositedWorkload);
@@ -4605,27 +4605,6 @@
 status_t SurfaceFlinger::addClientLayer(LayerCreationArgs& args, const sp<IBinder>& handle,
                                         const sp<Layer>& layer, const wp<Layer>& parent,
                                         uint32_t* outTransformHint) {
-    if (mNumLayers >= MAX_LAYERS) {
-        static std::atomic<nsecs_t> lasttime{0};
-        nsecs_t now = systemTime();
-        if (lasttime != 0 && ns2s(now - lasttime.load()) < 10) {
-            ALOGE("AddClientLayer already dumped 10s before");
-            return NO_MEMORY;
-        } else {
-            lasttime = now;
-        }
-
-        ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
-              MAX_LAYERS);
-        static_cast<void>(mScheduler->schedule([&]() FTL_FAKE_GUARD(kMainThreadContext) {
-            ALOGE("Dumping on-screen layers.");
-            mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getHierarchy());
-            ALOGE("Dumping off-screen layers.");
-            mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getOffscreenHierarchy());
-        }));
-        return NO_MEMORY;
-    }
-
     if (outTransformHint) {
         *outTransformHint = mActiveDisplayTransformHint;
     }
@@ -5408,14 +5387,13 @@
         mirrorArgs.addToRoot = true;
         mirrorArgs.layerStackToMirror = layerStack;
         result = createEffectLayer(mirrorArgs, &outResult.handle, &rootMirrorLayer);
+        if (result != NO_ERROR) {
+            return result;
+        }
         outResult.layerId = rootMirrorLayer->sequence;
         outResult.layerName = String16(rootMirrorLayer->getDebugName());
-        result |= addClientLayer(mirrorArgs, outResult.handle, rootMirrorLayer /* layer */,
-                                 nullptr /* parent */, nullptr /* outTransformHint */);
-    }
-
-    if (result != NO_ERROR) {
-        return result;
+        addClientLayer(mirrorArgs, outResult.handle, rootMirrorLayer /* layer */,
+                       nullptr /* parent */, nullptr /* outTransformHint */);
     }
 
     setTransactionFlags(eTransactionFlushNeeded);
@@ -5435,6 +5413,9 @@
             [[fallthrough]];
         case ISurfaceComposerClient::eFXSurfaceEffect: {
             result = createBufferStateLayer(args, &outResult.handle, &layer);
+            if (result != NO_ERROR) {
+                return result;
+            }
             std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
             if (pendingBufferCounter) {
                 std::string counterName = layer->getPendingBufferCounterName();
@@ -5475,6 +5456,9 @@
 
 status_t SurfaceFlinger::createBufferStateLayer(LayerCreationArgs& args, sp<IBinder>* handle,
                                                 sp<Layer>* outLayer) {
+    if (checkLayerLeaks() != NO_ERROR) {
+        return NO_MEMORY;
+    }
     *outLayer = getFactory().createBufferStateLayer(args);
     *handle = (*outLayer)->getHandle();
     return NO_ERROR;
@@ -5482,11 +5466,38 @@
 
 status_t SurfaceFlinger::createEffectLayer(const LayerCreationArgs& args, sp<IBinder>* handle,
                                            sp<Layer>* outLayer) {
+    if (checkLayerLeaks() != NO_ERROR) {
+        return NO_MEMORY;
+    }
     *outLayer = getFactory().createEffectLayer(args);
     *handle = (*outLayer)->getHandle();
     return NO_ERROR;
 }
 
+status_t SurfaceFlinger::checkLayerLeaks() {
+    if (mNumLayers >= MAX_LAYERS) {
+        static std::atomic<nsecs_t> lasttime{0};
+        nsecs_t now = systemTime();
+        if (lasttime != 0 && ns2s(now - lasttime.load()) < 10) {
+            ALOGE("CreateLayer already dumped 10s before");
+            return NO_MEMORY;
+        } else {
+            lasttime = now;
+        }
+
+        ALOGE("CreateLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(),
+              MAX_LAYERS);
+        static_cast<void>(mScheduler->schedule([&]() FTL_FAKE_GUARD(kMainThreadContext) {
+            ALOGE("Dumping on-screen layers.");
+            mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getHierarchy());
+            ALOGE("Dumping off-screen layers.");
+            mLayerHierarchyBuilder.dumpLayerSample(mLayerHierarchyBuilder.getOffscreenHierarchy());
+        }));
+        return NO_MEMORY;
+    }
+    return NO_ERROR;
+}
+
 void SurfaceFlinger::onHandleDestroyed(sp<Layer>& layer, uint32_t layerId) {
     {
         // Used to remove stalled transactions which uses an internal lock.
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index a99b39a..b3a3aad 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -845,6 +845,9 @@
     status_t createEffectLayer(const LayerCreationArgs& args, sp<IBinder>* outHandle,
                                sp<Layer>* outLayer);
 
+    // Checks if there are layer leaks before creating layer
+    status_t checkLayerLeaks();
+
     status_t mirrorLayer(const LayerCreationArgs& args, const sp<IBinder>& mirrorFromHandle,
                          gui::CreateSurfaceResult& outResult);
 
diff --git a/services/surfaceflinger/tests/MultiDisplay_test.cpp b/services/surfaceflinger/tests/MultiDisplay_test.cpp
index 54bb253..cf6d328 100644
--- a/services/surfaceflinger/tests/MultiDisplay_test.cpp
+++ b/services/surfaceflinger/tests/MultiDisplay_test.cpp
@@ -51,7 +51,7 @@
         mConsumer->setDefaultBufferSize(mMainDisplayMode.resolution.getWidth(),
                                         mMainDisplayMode.resolution.getHeight());
 
-        class StubConsumerListener : public BnConsumerListener {
+        class StubConsumerListener : public IConsumerListener {
             virtual void onFrameAvailable(const BufferItem&) override {}
             virtual void onBuffersReleased() override {}
             virtual void onSidebandStreamChanged() override {}