summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp18
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.h2
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,