diff options
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 18 | ||||
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.h | 2 |
2 files changed, 14 insertions, 6 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index da461285f5..7ece4bffe3 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -5730,9 +5730,7 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime, bool restartEvent; if (dispatchEntry->eventEntry->type == EventEntry::Type::KEY) { - KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry->eventEntry)); - restartEvent = - afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled); + restartEvent = afterKeyEventLockedInterruptable(connection, dispatchEntry, handled); } else if (dispatchEntry->eventEntry->type == EventEntry::Type::MOTION) { MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry->eventEntry)); restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, motionEntry, @@ -5960,7 +5958,17 @@ void InputDispatcher::processConnectionResponsiveLocked(const Connection& connec bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& connection, DispatchEntry* dispatchEntry, - KeyEntry& keyEntry, bool handled) { + bool handled) { + // The dispatchEntry is currently valid, but it might point to a deleted object after we release + // the lock. For simplicity, make copies of the data of interest here and assume that + // 'dispatchEntry' is not valid after this section. + // Hold a strong reference to the EventEntry to ensure it's valid for the duration of this + // function, even if the DispatchEntry gets destroyed and releases its share of the ownership. + std::shared_ptr<EventEntry> eventEntry = dispatchEntry->eventEntry; + const bool hasForegroundTarget = dispatchEntry->hasForegroundTarget(); + KeyEntry& keyEntry = static_cast<KeyEntry&>(*(eventEntry)); + // To prevent misuse, ensure dispatchEntry is no longer valid. + dispatchEntry = nullptr; if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) { if (!handled) { // Report the key as unhandled, since the fallback was not handled. @@ -5977,7 +5985,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptable(const sp<Connection>& con connection->inputState.removeFallbackKey(originalKeyCode); } - if (handled || !dispatchEntry->hasForegroundTarget()) { + if (handled || !hasForegroundTarget) { // If the application handles the original key for which we previously // generated a fallback or if the window is not a foreground window, // then cancel the associated fallback key, if any. diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index ed89ed0b0f..088e25e24d 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -662,7 +662,7 @@ private: void updateLastAnrStateLocked(const std::string& windowLabel, const std::string& reason) REQUIRES(mLock); bool afterKeyEventLockedInterruptable(const sp<Connection>& connection, - DispatchEntry* dispatchEntry, KeyEntry& keyEntry, + DispatchEntry* dispatchEntry, bool handled) REQUIRES(mLock); bool afterMotionEventLockedInterruptable(const sp<Connection>& connection, DispatchEntry* dispatchEntry, MotionEntry& motionEntry, |