diff options
| author | 2023-11-02 18:05:36 +0000 | |
|---|---|---|
| committer | 2023-11-03 21:54:00 +0000 | |
| commit | b9dd164bea3b6855517ac1b17fd02a68aa297c90 (patch) | |
| tree | 8c0a0b4f78867e123042ede13c8c9f498b08bc1b | |
| parent | a8cdbe17cded8d5747fccdf43552fdcef8392526 (diff) | |
Do not re-use the same EventEntry and DispatchEntry for fallback keys
Re-using the same EventEntry and DispatchEntry for fallbacks is
incorrect. A fallback can be thought of as a completely new event
generated for a channel, in which case it should not share the same
eventId as the original event.
Re-using the same DispatchEntry leads to the incorrect behavior, since
the expected flags in the event will be overridden by the the
resolvedFlags (and other resolved fields) from the old DispatchEntry.
This CL also fixed this incorrect behavior, which is verified with the
new tests added in the following CL.
Bug: 210460522
Test: atest inputflinger_tests
Change-Id: I30fd72a7da85043ea19fedaace41e79b20c85645
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 66 | ||||
| -rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.h | 10 |
2 files changed, 30 insertions, 46 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 219b5670f9..c8528e1a03 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -6169,7 +6169,7 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime, uint32_t seq, bool handled, nsecs_t consumeTime) { // Handle post-event policy actions. - bool restartEvent; + std::unique_ptr<KeyEntry> fallbackKeyEntry; { // Start critical section auto dispatchEntryIt = @@ -6193,15 +6193,9 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime, } if (dispatchEntry.eventEntry->type == EventEntry::Type::KEY) { - KeyEntry& keyEntry = static_cast<KeyEntry&>(*(dispatchEntry.eventEntry)); - restartEvent = + const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*(dispatchEntry.eventEntry)); + fallbackKeyEntry = afterKeyEventLockedInterruptable(connection, dispatchEntry, keyEntry, handled); - } else if (dispatchEntry.eventEntry->type == EventEntry::Type::MOTION) { - MotionEntry& motionEntry = static_cast<MotionEntry&>(*(dispatchEntry.eventEntry)); - restartEvent = afterMotionEventLockedInterruptable(connection, dispatchEntry, - motionEntry, handled); - } else { - restartEvent = false; } } // End critical section: The -LockedInterruptable methods may have released the lock. @@ -6225,12 +6219,13 @@ void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime, } } traceWaitQueueLength(*connection); - if (restartEvent && connection->status == Connection::Status::NORMAL) { - connection->outboundQueue.emplace_front(std::move(dispatchEntry)); - traceOutboundQueueLength(*connection); - } else { - releaseDispatchEntry(std::move(dispatchEntry)); + if (fallbackKeyEntry && connection->status == Connection::Status::NORMAL) { + const InputTarget target{.inputChannel = connection->inputChannel, + .flags = dispatchEntry->targetFlags}; + enqueueDispatchEntryLocked(connection, std::move(fallbackKeyEntry), target, + InputTarget::Flags::DISPATCH_AS_IS); } + releaseDispatchEntry(std::move(dispatchEntry)); } // Start the next dispatch cycle for this connection. @@ -6415,15 +6410,15 @@ void InputDispatcher::processConnectionResponsiveLocked(const Connection& connec sendWindowResponsiveCommandLocked(connectionToken, pid); } -bool InputDispatcher::afterKeyEventLockedInterruptable( +std::unique_ptr<KeyEntry> InputDispatcher::afterKeyEventLockedInterruptable( const std::shared_ptr<Connection>& connection, DispatchEntry& dispatchEntry, - KeyEntry& keyEntry, bool handled) { + const KeyEntry& keyEntry, bool handled) { if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) { if (!handled) { // Report the key as unhandled, since the fallback was not handled. mReporter->reportUnhandledKey(keyEntry.id); } - return false; + return {}; } // Get the fallback key state. @@ -6483,7 +6478,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptable( "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x", originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags); } - return false; + return {}; } // Dispatch the unhandled key to the policy. @@ -6508,7 +6503,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptable( if (connection->status != Connection::Status::NORMAL) { connection->inputState.removeFallbackKey(originalKeyCode); - return false; + return {}; } // Latch the fallback keycode for this key on an initial down. @@ -6569,25 +6564,22 @@ bool InputDispatcher::afterKeyEventLockedInterruptable( } if (fallback) { - // Restart the dispatch cycle using the fallback key. - keyEntry.eventTime = event.getEventTime(); - keyEntry.deviceId = event.getDeviceId(); - keyEntry.source = event.getSource(); - keyEntry.displayId = event.getDisplayId(); - keyEntry.flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK; - keyEntry.keyCode = *fallbackKeyCode; - keyEntry.scanCode = event.getScanCode(); - keyEntry.metaState = event.getMetaState(); - keyEntry.repeatCount = event.getRepeatCount(); - keyEntry.downTime = event.getDownTime(); - keyEntry.syntheticRepeat = false; - + // Return the fallback key that we want dispatched to the channel. + std::unique_ptr<KeyEntry> newEntry = + std::make_unique<KeyEntry>(mIdGenerator.nextId(), keyEntry.injectionState, + event.getEventTime(), event.getDeviceId(), + event.getSource(), event.getDisplayId(), + keyEntry.policyFlags, keyEntry.action, + event.getFlags() | AKEY_EVENT_FLAG_FALLBACK, + *fallbackKeyCode, event.getScanCode(), + event.getMetaState(), event.getRepeatCount(), + event.getDownTime()); if (DEBUG_OUTBOUND_EVENT_DETAILS) { ALOGD("Unhandled key event: Dispatching fallback key. " "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x", originalKeyCode, *fallbackKeyCode, keyEntry.metaState); } - return true; // restart the event + return newEntry; } else { if (DEBUG_OUTBOUND_EVENT_DETAILS) { ALOGD("Unhandled key event: No fallback key."); @@ -6597,13 +6589,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptable( mReporter->reportUnhandledKey(keyEntry.id); } } - return false; -} - -bool InputDispatcher::afterMotionEventLockedInterruptable( - const std::shared_ptr<Connection>& connection, DispatchEntry& dispatchEntry, - MotionEntry& motionEntry, bool handled) { - return false; + return {}; } void InputDispatcher::traceInboundQueueLengthLocked() { diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index e428c4e915..f0f67721e7 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -660,12 +660,10 @@ private: void updateLastAnrStateLocked(const std::string& windowLabel, const std::string& reason) REQUIRES(mLock); std::map<int32_t /*displayId*/, InputVerifier> mVerifiersByDisplay; - bool afterKeyEventLockedInterruptable(const std::shared_ptr<Connection>& connection, - DispatchEntry& dispatchEntry, KeyEntry& keyEntry, - bool handled) REQUIRES(mLock); - bool afterMotionEventLockedInterruptable(const std::shared_ptr<Connection>& connection, - DispatchEntry& dispatchEntry, MotionEntry& motionEntry, - bool handled) REQUIRES(mLock); + // Returns a fallback KeyEntry that should be sent to the connection, if required. + std::unique_ptr<KeyEntry> afterKeyEventLockedInterruptable( + const std::shared_ptr<Connection>& connection, DispatchEntry& dispatchEntry, + const KeyEntry& keyEntry, bool handled) REQUIRES(mLock); // Find touched state and touched window by token. std::tuple<TouchState*, TouchedWindow*, int32_t /*displayId*/> |