Merge "Release buffers early after GL comp"
diff --git a/include/input/Input.h b/include/input/Input.h
index d397313..5015e68 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -801,6 +801,8 @@
 
     static std::string actionToString(int32_t action);
 
+    static vec2 calculateTransformedXY(uint32_t source, const ui::Transform&, const vec2& xy);
+
 protected:
     int32_t mAction;
     int32_t mActionButton;
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 65f6bc6..4465b8e 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -28,6 +28,7 @@
 
 #include <android-base/hex.h>
 #include <android-base/macros.h>
+#include <android-base/scopeguard.h>
 #include <android_runtime/vm.h>
 #include <binder/BpBinder.h>
 #include <binder/Parcel.h>
@@ -54,13 +55,13 @@
 RpcSession::RpcSession(std::unique_ptr<RpcTransportCtx> ctx) : mCtx(std::move(ctx)) {
     LOG_RPC_DETAIL("RpcSession created %p", this);
 
-    mState = std::make_unique<RpcState>();
+    mRpcBinderState = std::make_unique<RpcState>();
 }
 RpcSession::~RpcSession() {
     LOG_RPC_DETAIL("RpcSession destroyed %p", this);
 
     std::lock_guard<std::mutex> _l(mMutex);
-    LOG_ALWAYS_FATAL_IF(mIncomingConnections.size() != 0,
+    LOG_ALWAYS_FATAL_IF(mThreadState.mIncomingConnections.size() != 0,
                         "Should not be able to destroy a session with servers in use.");
 }
 
@@ -77,10 +78,12 @@
 
 void RpcSession::setMaxThreads(size_t threads) {
     std::lock_guard<std::mutex> _l(mMutex);
-    LOG_ALWAYS_FATAL_IF(!mOutgoingConnections.empty() || !mIncomingConnections.empty(),
+    LOG_ALWAYS_FATAL_IF(!mThreadState.mOutgoingConnections.empty() ||
+                                !mThreadState.mIncomingConnections.empty(),
                         "Must set max threads before setting up connections, but has %zu client(s) "
                         "and %zu server(s)",
-                        mOutgoingConnections.size(), mIncomingConnections.size());
+                        mThreadState.mOutgoingConnections.size(),
+                        mThreadState.mIncomingConnections.size());
     mMaxThreads = threads;
 }
 
@@ -194,11 +197,11 @@
         LOG_ALWAYS_FATAL_IF(mShutdownListener == nullptr, "Shutdown listener not installed");
         mShutdownListener->waitForShutdown(_l, sp<RpcSession>::fromExisting(this));
 
-        LOG_ALWAYS_FATAL_IF(!mThreads.empty(), "Shutdown failed");
+        LOG_ALWAYS_FATAL_IF(!mThreadState.mThreads.empty(), "Shutdown failed");
     }
 
     _l.unlock();
-    mState->clear();
+    mRpcBinderState->clear();
 
     return true;
 }
@@ -260,11 +263,11 @@
 
 void RpcSession::WaitForShutdownListener::waitForShutdown(std::unique_lock<std::mutex>& lock,
                                                           const sp<RpcSession>& session) {
-    while (session->mIncomingConnections.size() > 0) {
+    while (session->mThreadState.mIncomingConnections.size() > 0) {
         if (std::cv_status::timeout == mCv.wait_for(lock, std::chrono::seconds(1))) {
             ALOGE("Waiting for RpcSession to shut down (1s w/o progress): %zu incoming connections "
                   "still.",
-                  session->mIncomingConnections.size());
+                  session->mThreadState.mIncomingConnections.size());
         }
     }
 }
@@ -274,7 +277,7 @@
 
     {
         std::lock_guard<std::mutex> _l(mMutex);
-        mThreads[thread.get_id()] = std::move(thread);
+        mThreadState.mThreads[thread.get_id()] = std::move(thread);
     }
 }
 
@@ -289,7 +292,8 @@
     if (connection == nullptr) {
         status = DEAD_OBJECT;
     } else {
-        status = mState->readConnectionInit(connection, sp<RpcSession>::fromExisting(this));
+        status =
+                mRpcBinderState->readConnectionInit(connection, sp<RpcSession>::fromExisting(this));
     }
 
     return PreJoinSetupResult{
@@ -376,10 +380,10 @@
     sp<RpcSession::EventListener> listener;
     {
         std::lock_guard<std::mutex> _l(session->mMutex);
-        auto it = session->mThreads.find(std::this_thread::get_id());
-        LOG_ALWAYS_FATAL_IF(it == session->mThreads.end());
+        auto it = session->mThreadState.mThreads.find(std::this_thread::get_id());
+        LOG_ALWAYS_FATAL_IF(it == session->mThreadState.mThreads.end());
         it->second.detach();
-        session->mThreads.erase(it);
+        session->mThreadState.mThreads.erase(it);
 
         listener = session->mEventListener.promote();
     }
@@ -410,12 +414,34 @@
                                                               bool incoming)>& connectAndInit) {
     {
         std::lock_guard<std::mutex> _l(mMutex);
-        LOG_ALWAYS_FATAL_IF(mOutgoingConnections.size() != 0,
+        LOG_ALWAYS_FATAL_IF(mThreadState.mOutgoingConnections.size() != 0,
                             "Must only setup session once, but already has %zu clients",
-                            mOutgoingConnections.size());
+                            mThreadState.mOutgoingConnections.size());
     }
+
     if (auto status = initShutdownTrigger(); status != OK) return status;
 
+    auto oldProtocolVersion = mProtocolVersion;
+    auto cleanup = base::ScopeGuard([&] {
+        // if any threads are started, shut them down
+        (void)shutdownAndWait(true);
+
+        mShutdownListener = nullptr;
+        mEventListener.clear();
+
+        mId.clear();
+
+        mShutdownTrigger = nullptr;
+        mRpcBinderState = std::make_unique<RpcState>();
+
+        // protocol version may have been downgraded - if we reuse this object
+        // to connect to another server, force that server to request a
+        // downgrade again
+        mProtocolVersion = oldProtocolVersion;
+
+        mThreadState = {};
+    });
+
     if (status_t status = connectAndInit({}, false /*incoming*/); status != OK) return status;
 
     {
@@ -464,6 +490,8 @@
         if (status_t status = connectAndInit(mId, true /*incoming*/); status != OK) return status;
     }
 
+    cleanup.Disable();
+
     return OK;
 }
 
@@ -634,12 +662,12 @@
         std::lock_guard<std::mutex> _l(mMutex);
         connection->rpcTransport = std::move(rpcTransport);
         connection->exclusiveTid = gettid();
-        mOutgoingConnections.push_back(connection);
+        mThreadState.mOutgoingConnections.push_back(connection);
     }
 
     status_t status = OK;
     if (init) {
-        mState->sendConnectionInit(connection, sp<RpcSession>::fromExisting(this));
+        mRpcBinderState->sendConnectionInit(connection, sp<RpcSession>::fromExisting(this));
     }
 
     {
@@ -671,9 +699,9 @@
         std::unique_ptr<RpcTransport> rpcTransport) {
     std::lock_guard<std::mutex> _l(mMutex);
 
-    if (mIncomingConnections.size() >= mMaxThreads) {
+    if (mThreadState.mIncomingConnections.size() >= mMaxThreads) {
         ALOGE("Cannot add thread to session with %zu threads (max is set to %zu)",
-              mIncomingConnections.size(), mMaxThreads);
+              mThreadState.mIncomingConnections.size(), mMaxThreads);
         return nullptr;
     }
 
@@ -681,7 +709,7 @@
     // happens when new connections are still being established as part of a
     // very short-lived session which shuts down after it already started
     // accepting new connections.
-    if (mIncomingConnections.size() < mMaxIncomingConnections) {
+    if (mThreadState.mIncomingConnections.size() < mThreadState.mMaxIncomingConnections) {
         return nullptr;
     }
 
@@ -689,18 +717,19 @@
     session->rpcTransport = std::move(rpcTransport);
     session->exclusiveTid = gettid();
 
-    mIncomingConnections.push_back(session);
-    mMaxIncomingConnections = mIncomingConnections.size();
+    mThreadState.mIncomingConnections.push_back(session);
+    mThreadState.mMaxIncomingConnections = mThreadState.mIncomingConnections.size();
 
     return session;
 }
 
 bool RpcSession::removeIncomingConnection(const sp<RpcConnection>& connection) {
     std::unique_lock<std::mutex> _l(mMutex);
-    if (auto it = std::find(mIncomingConnections.begin(), mIncomingConnections.end(), connection);
-        it != mIncomingConnections.end()) {
-        mIncomingConnections.erase(it);
-        if (mIncomingConnections.size() == 0) {
+    if (auto it = std::find(mThreadState.mIncomingConnections.begin(),
+                            mThreadState.mIncomingConnections.end(), connection);
+        it != mThreadState.mIncomingConnections.end()) {
+        mThreadState.mIncomingConnections.erase(it);
+        if (mThreadState.mIncomingConnections.size() == 0) {
             sp<EventListener> listener = mEventListener.promote();
             if (listener) {
                 _l.unlock();
@@ -725,7 +754,7 @@
     pid_t tid = gettid();
     std::unique_lock<std::mutex> _l(session->mMutex);
 
-    session->mWaitingThreads++;
+    session->mThreadState.mWaitingThreads++;
     while (true) {
         sp<RpcConnection> exclusive;
         sp<RpcConnection> available;
@@ -733,8 +762,8 @@
         // CHECK FOR DEDICATED CLIENT SOCKET
         //
         // A server/looper should always use a dedicated connection if available
-        findConnection(tid, &exclusive, &available, session->mOutgoingConnections,
-                       session->mOutgoingConnectionsOffset);
+        findConnection(tid, &exclusive, &available, session->mThreadState.mOutgoingConnections,
+                       session->mThreadState.mOutgoingConnectionsOffset);
 
         // WARNING: this assumes a server cannot request its client to send
         // a transaction, as mIncomingConnections is excluded below.
@@ -747,8 +776,9 @@
         // command. So, we move to considering the second available thread
         // for subsequent calls.
         if (use == ConnectionUse::CLIENT_ASYNC && (exclusive != nullptr || available != nullptr)) {
-            session->mOutgoingConnectionsOffset = (session->mOutgoingConnectionsOffset + 1) %
-                    session->mOutgoingConnections.size();
+            session->mThreadState.mOutgoingConnectionsOffset =
+                    (session->mThreadState.mOutgoingConnectionsOffset + 1) %
+                    session->mThreadState.mOutgoingConnections.size();
         }
 
         // USE SERVING SOCKET (e.g. nested transaction)
@@ -756,7 +786,7 @@
             sp<RpcConnection> exclusiveIncoming;
             // server connections are always assigned to a thread
             findConnection(tid, &exclusiveIncoming, nullptr /*available*/,
-                           session->mIncomingConnections, 0 /* index hint */);
+                           session->mThreadState.mIncomingConnections, 0 /* index hint */);
 
             // asynchronous calls cannot be nested, we currently allow ref count
             // calls to be nested (so that you can use this without having extra
@@ -785,19 +815,20 @@
             break;
         }
 
-        if (session->mOutgoingConnections.size() == 0) {
+        if (session->mThreadState.mOutgoingConnections.size() == 0) {
             ALOGE("Session has no client connections. This is required for an RPC server to make "
                   "any non-nested (e.g. oneway or on another thread) calls. Use: %d. Server "
                   "connections: %zu",
-                  static_cast<int>(use), session->mIncomingConnections.size());
+                  static_cast<int>(use), session->mThreadState.mIncomingConnections.size());
             return WOULD_BLOCK;
         }
 
         LOG_RPC_DETAIL("No available connections (have %zu clients and %zu servers). Waiting...",
-                       session->mOutgoingConnections.size(), session->mIncomingConnections.size());
+                       session->mThreadState.mOutgoingConnections.size(),
+                       session->mThreadState.mIncomingConnections.size());
         session->mAvailableConnectionCv.wait(_l);
     }
-    session->mWaitingThreads--;
+    session->mThreadState.mWaitingThreads--;
 
     return OK;
 }
@@ -836,7 +867,7 @@
     if (!mReentrant && mConnection != nullptr) {
         std::unique_lock<std::mutex> _l(mSession->mMutex);
         mConnection->exclusiveTid = std::nullopt;
-        if (mSession->mWaitingThreads > 0) {
+        if (mSession->mThreadState.mWaitingThreads > 0) {
             _l.unlock();
             mSession->mAvailableConnectionCv.notify_one();
         }
diff --git a/libs/binder/include/binder/MemoryDealer.h b/libs/binder/include/binder/MemoryDealer.h
index e727772..3f7dd11 100644
--- a/libs/binder/include/binder/MemoryDealer.h
+++ b/libs/binder/include/binder/MemoryDealer.h
@@ -36,7 +36,6 @@
             uint32_t flags = 0 /* or bits such as MemoryHeapBase::READ_ONLY */ );
 
     virtual sp<IMemory> allocate(size_t size);
-    virtual void        deallocate(size_t offset);
     virtual void        dump(const char* what) const;
 
     // allocations are aligned to some value. return that value so clients can account for it.
@@ -48,6 +47,8 @@
     virtual ~MemoryDealer();
 
 private:
+    friend class Allocation;
+    virtual void                deallocate(size_t offset);
     const sp<IMemoryHeap>&      heap() const;
     SimpleBestFitAllocator*     allocator() const;
 
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index 12d448d..19888b7 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -168,7 +168,7 @@
     sp<RpcServer> server();
 
     // internal only
-    const std::unique_ptr<RpcState>& state() { return mState; }
+    const std::unique_ptr<RpcState>& state() { return mRpcBinderState; }
 
 private:
     friend sp<RpcSession>;
@@ -303,7 +303,7 @@
 
     std::unique_ptr<FdTrigger> mShutdownTrigger;
 
-    std::unique_ptr<RpcState> mState;
+    std::unique_ptr<RpcState> mRpcBinderState;
 
     std::mutex mMutex; // for all below
 
@@ -311,13 +311,16 @@
     std::optional<uint32_t> mProtocolVersion;
 
     std::condition_variable mAvailableConnectionCv; // for mWaitingThreads
-    size_t mWaitingThreads = 0;
-    // hint index into clients, ++ when sending an async transaction
-    size_t mOutgoingConnectionsOffset = 0;
-    std::vector<sp<RpcConnection>> mOutgoingConnections;
-    size_t mMaxIncomingConnections = 0;
-    std::vector<sp<RpcConnection>> mIncomingConnections;
-    std::map<std::thread::id, std::thread> mThreads;
+
+    struct ThreadState {
+        size_t mWaitingThreads = 0;
+        // hint index into clients, ++ when sending an async transaction
+        size_t mOutgoingConnectionsOffset = 0;
+        std::vector<sp<RpcConnection>> mOutgoingConnections;
+        size_t mMaxIncomingConnections = 0;
+        std::vector<sp<RpcConnection>> mIncomingConnections;
+        std::map<std::thread::id, std::thread> mThreads;
+    } mThreadState;
 };
 
 } // namespace android
diff --git a/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp b/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp
index f9dda8c..f5e3af5 100644
--- a/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp
+++ b/libs/binder/tests/unit_fuzzers/MemoryDealerFuzz.cpp
@@ -46,15 +46,6 @@
                 [&]() -> void { dealer->getAllocationAlignment(); },
                 [&]() -> void { dealer->getMemoryHeap(); },
                 [&]() -> void {
-                    size_t offset = fdp.ConsumeIntegral<size_t>();
-
-                    // Offset has already been freed, so return instead.
-                    if (free_list.find(offset) != free_list.end()) return;
-
-                    dealer->deallocate(offset);
-                    free_list.insert(offset);
-                },
-                [&]() -> void {
                     std::string randString = fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
                     dealer->dump(randString.c_str());
                 },
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 14ec948..2b17616 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -747,14 +747,26 @@
         std::unique_lock<std::mutex> lock(mMutex);
         while (!mDone) {
             while (!mRunnables.empty()) {
-                std::function<void()> runnable = mRunnables.front();
-                mRunnables.pop_front();
-                runnable();
+                std::deque<std::function<void()>> runnables = std::move(mRunnables);
+                mRunnables.clear();
+                lock.unlock();
+                // Run outside the lock since the runnable might trigger another
+                // post to the async worker.
+                execute(runnables);
+                lock.lock();
             }
             mCv.wait(lock);
         }
     }
 
+    void execute(std::deque<std::function<void()>>& runnables) {
+        while (!runnables.empty()) {
+            std::function<void()> runnable = runnables.front();
+            runnables.pop_front();
+            runnable();
+        }
+    }
+
 public:
     AsyncWorker() : Singleton<AsyncWorker>() { mThread = std::thread(&AsyncWorker::run, this); }
 
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index cf61209..f848e4f 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -50,7 +50,6 @@
         transform(0),
         transformToDisplayInverse(false),
         crop(Rect::INVALID_RECT),
-        orientedDisplaySpaceRect(Rect::INVALID_RECT),
         dataspace(ui::Dataspace::UNKNOWN),
         surfaceDamageRegion(),
         api(-1),
@@ -100,7 +99,6 @@
     SAFE_PARCEL(output.write, transparentRegion);
     SAFE_PARCEL(output.writeUint32, transform);
     SAFE_PARCEL(output.writeBool, transformToDisplayInverse);
-    SAFE_PARCEL(output.write, orientedDisplaySpaceRect);
 
     SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(dataspace));
     SAFE_PARCEL(output.write, hdrMetadata);
@@ -195,7 +193,6 @@
     SAFE_PARCEL(input.read, transparentRegion);
     SAFE_PARCEL(input.readUint32, &transform);
     SAFE_PARCEL(input.readBool, &transformToDisplayInverse);
-    SAFE_PARCEL(input.read, orientedDisplaySpaceRect);
 
     uint32_t tmpUint32 = 0;
     SAFE_PARCEL(input.readUint32, &tmpUint32);
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 1f5d289..b01eed4 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -206,7 +206,6 @@
     uint32_t transform;
     bool transformToDisplayInverse;
     Rect crop;
-    Rect orientedDisplaySpaceRect;
     BufferData bufferData;
     ui::Dataspace dataspace;
     HdrMetadata hdrMetadata;
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index a1542c8..390ff96 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -65,8 +65,8 @@
     return result;
 }
 
-vec2 transformWithoutTranslation(const ui::Transform& transform, float x, float y) {
-    const vec2 transformedXy = transform.transform(x, y);
+vec2 transformWithoutTranslation(const ui::Transform& transform, const vec2& xy) {
+    const vec2 transformedXy = transform.transform(xy);
     const vec2 transformedOrigin = transform.transform(0, 0);
     return transformedXy - transformedOrigin;
 }
@@ -501,21 +501,16 @@
     const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
 
     if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
-        // For compatibility, convert raw coordinates into logical display space.
-        const vec2 xy = shouldDisregardTranslation(mSource)
-                ? transformWithoutTranslation(mRawTransform, coords->getX(), coords->getY())
-                : mRawTransform.transform(coords->getX(), coords->getY());
+        const vec2 xy = calculateTransformedXY(mSource, mRawTransform, coords->getXYValue());
         static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
         return xy[axis];
     }
 
     if (axis == AMOTION_EVENT_AXIS_RELATIVE_X || axis == AMOTION_EVENT_AXIS_RELATIVE_Y) {
-        // For compatibility, since we report raw coordinates in logical display space, we
-        // need to convert the relative axes into the same orientation for consistency.
         const vec2 relativeXy =
                 transformWithoutTranslation(mRawTransform,
-                                            coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
-                                            coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
+                                            {coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
+                                             coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)});
         return axis == AMOTION_EVENT_AXIS_RELATIVE_X ? relativeXy.x : relativeXy.y;
     }
 
@@ -527,9 +522,7 @@
     const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex);
 
     if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) {
-        const vec2 xy = shouldDisregardTranslation(mSource)
-                ? transformWithoutTranslation(mTransform, coords->getX(), coords->getY())
-                : mTransform.transform(coords->getXYValue());
+        const vec2 xy = calculateTransformedXY(mSource, mTransform, coords->getXYValue());
         static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1);
         return xy[axis];
     }
@@ -537,8 +530,8 @@
     if (axis == AMOTION_EVENT_AXIS_RELATIVE_X || axis == AMOTION_EVENT_AXIS_RELATIVE_Y) {
         const vec2 relativeXy =
                 transformWithoutTranslation(mTransform,
-                                            coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
-                                            coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
+                                            {coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X),
+                                             coords->getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y)});
         return axis == AMOTION_EVENT_AXIS_RELATIVE_X ? relativeXy.x : relativeXy.y;
     }
 
@@ -815,6 +808,12 @@
     return android::base::StringPrintf("%" PRId32, action);
 }
 
+vec2 MotionEvent::calculateTransformedXY(uint32_t source, const ui::Transform& transform,
+                                         const vec2& xy) {
+    return shouldDisregardTranslation(source) ? transformWithoutTranslation(transform, xy)
+                                              : transform.transform(xy);
+}
+
 // --- FocusEvent ---
 
 void FocusEvent::initialize(int32_t id, bool hasFocus, bool inTouchMode) {
@@ -969,6 +968,13 @@
             return;
         }
         break;
+    case AINPUT_EVENT_TYPE_TOUCH_MODE:
+        if (mTouchModeEventPool.size() < mMaxPoolSize) {
+            mTouchModeEventPool.push(
+                    std::unique_ptr<TouchModeEvent>(static_cast<TouchModeEvent*>(event)));
+            return;
+        }
+        break;
     }
     delete event;
 }
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index bcb0071..c03581d 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -40,14 +40,15 @@
             entry.repeatCount};
 }
 
-VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry) {
-    const float rawX = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X);
-    const float rawY = entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y);
+VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry,
+                                                       const ui::Transform& rawTransform) {
+    const vec2 rawXY = MotionEvent::calculateTransformedXY(entry.source, rawTransform,
+                                                           entry.pointerCoords[0].getXYValue());
     const int actionMasked = entry.action & AMOTION_EVENT_ACTION_MASK;
     return {{VerifiedInputEvent::Type::MOTION, entry.deviceId, entry.eventTime, entry.source,
              entry.displayId},
-            rawX,
-            rawY,
+            rawXY.x,
+            rawXY.y,
             actionMasked,
             entry.downTime,
             entry.flags & VERIFIED_MOTION_EVENT_FLAGS,
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index 7a121ce..477781a 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -254,7 +254,8 @@
 };
 
 VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry);
-VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry);
+VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry,
+                                                       const ui::Transform& rawTransform);
 
 } // namespace android::inputdispatcher
 
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 695dd17..1baa100 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -915,7 +915,7 @@
  */
 bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) {
     const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
-            (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER);
+            isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
 
     // Optimize case where the current application is unresponsive and the user
     // decides to touch a window in a different application.
@@ -1609,7 +1609,7 @@
         return true;
     }
 
-    bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
+    const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
 
     // Identify targets.
     std::vector<InputTarget> inputTargets;
@@ -1995,7 +1995,7 @@
                           maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
     bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN ||
                        maskedAction == AMOTION_EVENT_ACTION_SCROLL || isHoverAction);
-    const bool isFromMouse = entry.source == AINPUT_SOURCE_MOUSE;
+    const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
     bool wrongDevice = false;
     if (newGesture) {
         bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
@@ -3360,16 +3360,18 @@
 
 const std::array<uint8_t, 32> InputDispatcher::getSignature(
         const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
-    int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
-    if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
+    const int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
+    if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
         // Only sign events up and down events as the purely move events
         // are tied to their up/down counterparts so signing would be redundant.
-        VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
-        verifiedEvent.actionMasked = actionMasked;
-        verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
-        return sign(verifiedEvent);
+        return INVALID_HMAC;
     }
-    return INVALID_HMAC;
+
+    VerifiedMotionEvent verifiedEvent =
+            verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
+    verifiedEvent.actionMasked = actionMasked;
+    verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
+    return sign(verifiedEvent);
 }
 
 const std::array<uint8_t, 32> InputDispatcher::getSignature(
@@ -4190,12 +4192,17 @@
 
         case AINPUT_EVENT_TYPE_MOTION: {
             const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
-            int32_t action = motionEvent.getAction();
-            size_t pointerCount = motionEvent.getPointerCount();
+            const int32_t action = motionEvent.getAction();
+            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)
+                    ? ADISPLAY_ID_DEFAULT
+                    : event->getDisplayId();
+            const size_t pointerCount = motionEvent.getPointerCount();
             const PointerProperties* pointerProperties = motionEvent.getPointerProperties();
-            int32_t actionButton = motionEvent.getActionButton();
+            const int32_t actionButton = motionEvent.getActionButton();
             int32_t flags = motionEvent.getFlags();
-            int32_t displayId = motionEvent.getDisplayId();
             if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
                 return InputEventInjectionResult::FAILED;
             }
@@ -4220,8 +4227,8 @@
             std::unique_ptr<MotionEntry> injectedEntry =
                     std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
                                                   resolvedDeviceId, motionEvent.getSource(),
-                                                  motionEvent.getDisplayId(), policyFlags, action,
-                                                  actionButton, flags, motionEvent.getMetaState(),
+                                                  displayId, policyFlags, action, actionButton,
+                                                  flags, motionEvent.getMetaState(),
                                                   motionEvent.getButtonState(),
                                                   motionEvent.getClassification(),
                                                   motionEvent.getEdgeFlags(),
@@ -4241,9 +4248,8 @@
                 std::unique_ptr<MotionEntry> nextInjectedEntry =
                         std::make_unique<MotionEntry>(motionEvent.getId(), *sampleEventTimes,
                                                       resolvedDeviceId, motionEvent.getSource(),
-                                                      motionEvent.getDisplayId(), policyFlags,
-                                                      action, actionButton, flags,
-                                                      motionEvent.getMetaState(),
+                                                      displayId, policyFlags, action, actionButton,
+                                                      flags, motionEvent.getMetaState(),
                                                       motionEvent.getButtonState(),
                                                       motionEvent.getClassification(),
                                                       motionEvent.getEdgeFlags(),
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 42d3e58..ca77d7a 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -2801,7 +2801,14 @@
 
     mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
 
-    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
+    ui::Transform transform;
+    transform.set({1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 0, 0, 1});
+
+    gui::DisplayInfo displayInfo;
+    displayInfo.displayId = ADISPLAY_ID_DEFAULT;
+    displayInfo.transform = transform;
+
+    mDispatcher->onWindowInfosChanged({*window->getInfo()}, {displayInfo});
 
     NotifyMotionArgs motionArgs =
             generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -2822,8 +2829,11 @@
 
     const VerifiedMotionEvent& verifiedMotion = static_cast<const VerifiedMotionEvent&>(*verified);
 
-    EXPECT_EQ(motionArgs.pointerCoords[0].getX(), verifiedMotion.rawX);
-    EXPECT_EQ(motionArgs.pointerCoords[0].getY(), verifiedMotion.rawY);
+    const vec2 rawXY =
+            MotionEvent::calculateTransformedXY(motionArgs.source, transform,
+                                                motionArgs.pointerCoords[0].getXYValue());
+    EXPECT_EQ(rawXY.x, verifiedMotion.rawX);
+    EXPECT_EQ(rawXY.y, verifiedMotion.rawY);
     EXPECT_EQ(motionArgs.action & AMOTION_EVENT_ACTION_MASK, verifiedMotion.actionMasked);
     EXPECT_EQ(motionArgs.downTime, verifiedMotion.downTimeNanos);
     EXPECT_EQ(motionArgs.flags & VERIFIED_MOTION_EVENT_FLAGS, verifiedMotion.flags);