Loading services/inputflinger/dispatcher/Entry.h +7 −0 Original line number Diff line number Diff line Loading @@ -125,10 +125,17 @@ struct KeyEntry : EventEntry { bool syntheticRepeat; // set to true for synthetic key repeats enum class InterceptKeyResult { // The interception result is unknown. UNKNOWN, // The event should be skipped and not sent to the application. SKIP, // The event should be sent to the application. CONTINUE, // The event should eventually be sent to the application, after a delay. TRY_AGAIN_LATER, // The event should not be initially sent to the application, but instead go through // post-processing to generate a fallback key event and then sent to the application. FALLBACK, }; // These are special fields that may need to be modified while the event is being dispatched. mutable InterceptKeyResult interceptKeyResult; // set based on the interception result Loading services/inputflinger/dispatcher/InputDispatcher.cpp +65 −2 Original line number Diff line number Diff line Loading @@ -952,7 +952,7 @@ InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy, new LatencyAggregatorWithHistograms())) : std::move(std::unique_ptr<InputEventTimelineProcessor>( new LatencyAggregator()))), mLatencyTracker(*mInputEventTimelineProcessor) { mLatencyTracker(*mInputEventTimelineProcessor, mInputDevices) { mReporter = createInputReporter(); mWindowInfoListener = sp<DispatcherWindowListener>::make(*this); Loading Loading @@ -1961,11 +1961,74 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con } } if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::FALLBACK) { findAndDispatchFallbackEvent(currentTime, entry, inputTargets); // Drop the key. return true; } // Dispatch the key. dispatchEventLocked(currentTime, entry, inputTargets); return true; } void InputDispatcher::findAndDispatchFallbackEvent(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry, std::vector<InputTarget>& inputTargets) { // Find the fallback associated with the incoming key event and dispatch it. KeyEvent event = createKeyEvent(*entry); const int32_t originalKeyCode = entry->keyCode; // Fetch the fallback event. KeyCharacterMap::FallbackAction fallback; for (const InputDeviceInfo& deviceInfo : mInputDevices) { if (deviceInfo.getId() == entry->deviceId) { const KeyCharacterMap* map = deviceInfo.getKeyCharacterMap(); LOG_ALWAYS_FATAL_IF(map == nullptr, "No KeyCharacterMap for device %d", entry->deviceId); map->getFallbackAction(entry->keyCode, entry->metaState, &fallback); break; } } if (fallback.keyCode == AKEYCODE_UNKNOWN) { // No fallback detected. return; } std::unique_ptr<KeyEntry> fallbackKeyEntry = std::make_unique<KeyEntry>(mIdGenerator.nextId(), entry->injectionState, event.getEventTime(), event.getDeviceId(), event.getSource(), event.getDisplayId(), entry->policyFlags, entry->action, event.getFlags() | AKEY_EVENT_FLAG_FALLBACK, fallback.keyCode, event.getScanCode(), /*metaState=*/0, event.getRepeatCount(), event.getDownTime()); if (mTracer) { fallbackKeyEntry->traceTracker = mTracer->traceDerivedEvent(*fallbackKeyEntry, *entry->traceTracker); } for (const InputTarget& inputTarget : inputTargets) { std::shared_ptr<Connection> connection = inputTarget.connection; if (!connection->responsive || (connection->status != Connection::Status::NORMAL)) { return; } connection->inputState.setFallbackKey(originalKeyCode, fallback.keyCode); if (entry->action == AKEY_EVENT_ACTION_UP) { connection->inputState.removeFallbackKey(originalKeyCode); } if (mTracer) { mTracer->dispatchToTargetHint(*fallbackKeyEntry->traceTracker, inputTarget); } enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection, std::move(fallbackKeyEntry), inputTarget); } } void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) { LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) << prefix << "eventTime=" << entry.eventTime << ", deviceId=" << entry.deviceId Loading Loading @@ -4346,7 +4409,7 @@ void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedA std::scoped_lock _l(mLock); // Reset key repeating in case a keyboard device was added or removed or something. resetKeyRepeatLocked(); mLatencyTracker.setInputDevices(args.inputDeviceInfos); mInputDevices = args.inputDeviceInfos; } void InputDispatcher::notifyKey(const NotifyKeyArgs& args) { Loading services/inputflinger/dispatcher/InputDispatcher.h +4 −0 Original line number Diff line number Diff line Loading @@ -918,10 +918,14 @@ private: std::unique_ptr<const KeyEntry> afterKeyEventLockedInterruptable( const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry, bool handled) REQUIRES(mLock); void findAndDispatchFallbackEvent(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry, std::vector<InputTarget>& inputTargets) REQUIRES(mLock); // Statistics gathering. nsecs_t mLastStatisticPushTime = 0; std::unique_ptr<InputEventTimelineProcessor> mInputEventTimelineProcessor GUARDED_BY(mLock); // Must outlive `mLatencyTracker`. std::vector<InputDeviceInfo> mInputDevices; LatencyTracker mLatencyTracker GUARDED_BY(mLock); void traceInboundQueueLengthLocked() REQUIRES(mLock); void traceOutboundQueueLength(const Connection& connection); Loading services/inputflinger/dispatcher/LatencyTracker.cpp +3 −6 Original line number Diff line number Diff line Loading @@ -67,8 +67,9 @@ static void eraseByValue(std::multimap<K, V>& map, const V& value) { } // namespace LatencyTracker::LatencyTracker(InputEventTimelineProcessor& processor) : mTimelineProcessor(&processor) {} LatencyTracker::LatencyTracker(InputEventTimelineProcessor& processor, std::vector<InputDeviceInfo>& inputDevices) : mTimelineProcessor(&processor), mInputDevices(inputDevices) {} void LatencyTracker::trackListener(const NotifyArgs& args) { if (const NotifyKeyArgs* keyArgs = std::get_if<NotifyKeyArgs>(&args)) { Loading Loading @@ -248,8 +249,4 @@ std::string LatencyTracker::dump(const char* prefix) const { StringPrintf("%s mEventTimes.size() = %zu\n", prefix, mEventTimes.size()); } void LatencyTracker::setInputDevices(const std::vector<InputDeviceInfo>& inputDevices) { mInputDevices = inputDevices; } } // namespace android::inputdispatcher services/inputflinger/dispatcher/LatencyTracker.h +6 −3 Original line number Diff line number Diff line Loading @@ -20,9 +20,11 @@ #include <map> #include <unordered_map> #include <vector> #include <binder/IBinder.h> #include <input/Input.h> #include <input/InputDevice.h> #include "InputEventTimeline.h" #include "NotifyArgs.h" Loading @@ -41,8 +43,10 @@ public: /** * Create a LatencyTracker. * param reportingFunction: the function that will be called in order to report full latency. * param inputDevices: input devices relevant for tracking. */ LatencyTracker(InputEventTimelineProcessor& processor); LatencyTracker(InputEventTimelineProcessor& processor, std::vector<InputDeviceInfo>& inputDevices); /** * Start keeping track of an event identified by the args. This must be called first. * If duplicate events are encountered (events that have the same eventId), none of them will be Loading @@ -60,7 +64,6 @@ public: std::array<nsecs_t, GraphicsTimeline::SIZE> timeline); std::string dump(const char* prefix) const; void setInputDevices(const std::vector<InputDeviceInfo>& inputDevices); private: /** Loading @@ -81,7 +84,7 @@ private: std::multimap<nsecs_t /*eventTime*/, int32_t /*inputEventId*/> mEventTimes; InputEventTimelineProcessor* mTimelineProcessor; std::vector<InputDeviceInfo> mInputDevices; std::vector<InputDeviceInfo>& mInputDevices; void trackListener(int32_t inputEventId, nsecs_t eventTime, nsecs_t readTime, DeviceId deviceId, const std::set<InputDeviceUsageSource>& sources, int32_t inputEventAction, Loading Loading
services/inputflinger/dispatcher/Entry.h +7 −0 Original line number Diff line number Diff line Loading @@ -125,10 +125,17 @@ struct KeyEntry : EventEntry { bool syntheticRepeat; // set to true for synthetic key repeats enum class InterceptKeyResult { // The interception result is unknown. UNKNOWN, // The event should be skipped and not sent to the application. SKIP, // The event should be sent to the application. CONTINUE, // The event should eventually be sent to the application, after a delay. TRY_AGAIN_LATER, // The event should not be initially sent to the application, but instead go through // post-processing to generate a fallback key event and then sent to the application. FALLBACK, }; // These are special fields that may need to be modified while the event is being dispatched. mutable InterceptKeyResult interceptKeyResult; // set based on the interception result Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +65 −2 Original line number Diff line number Diff line Loading @@ -952,7 +952,7 @@ InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy, new LatencyAggregatorWithHistograms())) : std::move(std::unique_ptr<InputEventTimelineProcessor>( new LatencyAggregator()))), mLatencyTracker(*mInputEventTimelineProcessor) { mLatencyTracker(*mInputEventTimelineProcessor, mInputDevices) { mReporter = createInputReporter(); mWindowInfoListener = sp<DispatcherWindowListener>::make(*this); Loading Loading @@ -1961,11 +1961,74 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con } } if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::FALLBACK) { findAndDispatchFallbackEvent(currentTime, entry, inputTargets); // Drop the key. return true; } // Dispatch the key. dispatchEventLocked(currentTime, entry, inputTargets); return true; } void InputDispatcher::findAndDispatchFallbackEvent(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry, std::vector<InputTarget>& inputTargets) { // Find the fallback associated with the incoming key event and dispatch it. KeyEvent event = createKeyEvent(*entry); const int32_t originalKeyCode = entry->keyCode; // Fetch the fallback event. KeyCharacterMap::FallbackAction fallback; for (const InputDeviceInfo& deviceInfo : mInputDevices) { if (deviceInfo.getId() == entry->deviceId) { const KeyCharacterMap* map = deviceInfo.getKeyCharacterMap(); LOG_ALWAYS_FATAL_IF(map == nullptr, "No KeyCharacterMap for device %d", entry->deviceId); map->getFallbackAction(entry->keyCode, entry->metaState, &fallback); break; } } if (fallback.keyCode == AKEYCODE_UNKNOWN) { // No fallback detected. return; } std::unique_ptr<KeyEntry> fallbackKeyEntry = std::make_unique<KeyEntry>(mIdGenerator.nextId(), entry->injectionState, event.getEventTime(), event.getDeviceId(), event.getSource(), event.getDisplayId(), entry->policyFlags, entry->action, event.getFlags() | AKEY_EVENT_FLAG_FALLBACK, fallback.keyCode, event.getScanCode(), /*metaState=*/0, event.getRepeatCount(), event.getDownTime()); if (mTracer) { fallbackKeyEntry->traceTracker = mTracer->traceDerivedEvent(*fallbackKeyEntry, *entry->traceTracker); } for (const InputTarget& inputTarget : inputTargets) { std::shared_ptr<Connection> connection = inputTarget.connection; if (!connection->responsive || (connection->status != Connection::Status::NORMAL)) { return; } connection->inputState.setFallbackKey(originalKeyCode, fallback.keyCode); if (entry->action == AKEY_EVENT_ACTION_UP) { connection->inputState.removeFallbackKey(originalKeyCode); } if (mTracer) { mTracer->dispatchToTargetHint(*fallbackKeyEntry->traceTracker, inputTarget); } enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection, std::move(fallbackKeyEntry), inputTarget); } } void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) { LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS) << prefix << "eventTime=" << entry.eventTime << ", deviceId=" << entry.deviceId Loading Loading @@ -4346,7 +4409,7 @@ void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedA std::scoped_lock _l(mLock); // Reset key repeating in case a keyboard device was added or removed or something. resetKeyRepeatLocked(); mLatencyTracker.setInputDevices(args.inputDeviceInfos); mInputDevices = args.inputDeviceInfos; } void InputDispatcher::notifyKey(const NotifyKeyArgs& args) { Loading
services/inputflinger/dispatcher/InputDispatcher.h +4 −0 Original line number Diff line number Diff line Loading @@ -918,10 +918,14 @@ private: std::unique_ptr<const KeyEntry> afterKeyEventLockedInterruptable( const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry, bool handled) REQUIRES(mLock); void findAndDispatchFallbackEvent(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry, std::vector<InputTarget>& inputTargets) REQUIRES(mLock); // Statistics gathering. nsecs_t mLastStatisticPushTime = 0; std::unique_ptr<InputEventTimelineProcessor> mInputEventTimelineProcessor GUARDED_BY(mLock); // Must outlive `mLatencyTracker`. std::vector<InputDeviceInfo> mInputDevices; LatencyTracker mLatencyTracker GUARDED_BY(mLock); void traceInboundQueueLengthLocked() REQUIRES(mLock); void traceOutboundQueueLength(const Connection& connection); Loading
services/inputflinger/dispatcher/LatencyTracker.cpp +3 −6 Original line number Diff line number Diff line Loading @@ -67,8 +67,9 @@ static void eraseByValue(std::multimap<K, V>& map, const V& value) { } // namespace LatencyTracker::LatencyTracker(InputEventTimelineProcessor& processor) : mTimelineProcessor(&processor) {} LatencyTracker::LatencyTracker(InputEventTimelineProcessor& processor, std::vector<InputDeviceInfo>& inputDevices) : mTimelineProcessor(&processor), mInputDevices(inputDevices) {} void LatencyTracker::trackListener(const NotifyArgs& args) { if (const NotifyKeyArgs* keyArgs = std::get_if<NotifyKeyArgs>(&args)) { Loading Loading @@ -248,8 +249,4 @@ std::string LatencyTracker::dump(const char* prefix) const { StringPrintf("%s mEventTimes.size() = %zu\n", prefix, mEventTimes.size()); } void LatencyTracker::setInputDevices(const std::vector<InputDeviceInfo>& inputDevices) { mInputDevices = inputDevices; } } // namespace android::inputdispatcher
services/inputflinger/dispatcher/LatencyTracker.h +6 −3 Original line number Diff line number Diff line Loading @@ -20,9 +20,11 @@ #include <map> #include <unordered_map> #include <vector> #include <binder/IBinder.h> #include <input/Input.h> #include <input/InputDevice.h> #include "InputEventTimeline.h" #include "NotifyArgs.h" Loading @@ -41,8 +43,10 @@ public: /** * Create a LatencyTracker. * param reportingFunction: the function that will be called in order to report full latency. * param inputDevices: input devices relevant for tracking. */ LatencyTracker(InputEventTimelineProcessor& processor); LatencyTracker(InputEventTimelineProcessor& processor, std::vector<InputDeviceInfo>& inputDevices); /** * Start keeping track of an event identified by the args. This must be called first. * If duplicate events are encountered (events that have the same eventId), none of them will be Loading @@ -60,7 +64,6 @@ public: std::array<nsecs_t, GraphicsTimeline::SIZE> timeline); std::string dump(const char* prefix) const; void setInputDevices(const std::vector<InputDeviceInfo>& inputDevices); private: /** Loading @@ -81,7 +84,7 @@ private: std::multimap<nsecs_t /*eventTime*/, int32_t /*inputEventId*/> mEventTimes; InputEventTimelineProcessor* mTimelineProcessor; std::vector<InputDeviceInfo> mInputDevices; std::vector<InputDeviceInfo>& mInputDevices; void trackListener(int32_t inputEventId, nsecs_t eventTime, nsecs_t readTime, DeviceId deviceId, const std::set<InputDeviceUsageSource>& sources, int32_t inputEventAction, Loading