Loading services/inputflinger/dispatcher/InputDispatcher.cpp +42 −18 Original line number Diff line number Diff line Loading @@ -399,7 +399,8 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerato const InputTarget& inputTarget, std::shared_ptr<const EventEntry> eventEntry, ftl::Flags<InputTarget::Flags> inputTargetFlags, int64_t vsyncId) { int64_t vsyncId, trace::InputTracerInterface* tracer) { const bool zeroCoords = inputTargetFlags.test(InputTarget::Flags::ZERO_COORDS); const sp<WindowInfoHandle> win = inputTarget.windowHandle; const std::optional<int32_t> windowId = Loading Loading @@ -462,6 +463,10 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerato motionEntry.xCursorPosition, motionEntry.yCursorPosition, motionEntry.downTime, motionEntry.pointerProperties, pointerCoords); if (tracer) { combinedMotionEntry->traceTracker = tracer->traceDerivedEvent(*combinedMotionEntry, *motionEntry.traceTracker); } std::unique_ptr<DispatchEntry> dispatchEntry = std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags, Loading Loading @@ -3386,7 +3391,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio // Enqueue a new dispatch entry onto the outbound queue for this connection. std::unique_ptr<DispatchEntry> dispatchEntry = createDispatchEntry(mIdGenerator, inputTarget, eventEntry, inputTarget.flags, mWindowInfosVsyncId); mWindowInfosVsyncId, mTracer.get()); // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a // different EventEntry than what was passed in. Loading Loading @@ -3469,9 +3474,10 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio usingCoords = pointerInfo->second; } } // Generate a new MotionEntry with a new eventId using the resolved action and // flags. resolvedMotion = std::make_shared< { // Generate a new MotionEntry with a new eventId using the resolved action // and flags, and set it as the resolved entry. auto newEntry = std::make_shared< MotionEntry>(mIdGenerator.nextId(), motionEntry.injectionState, motionEntry.eventTime, motionEntry.deviceId, motionEntry.source, motionEntry.displayId, Loading @@ -3480,10 +3486,19 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio motionEntry.metaState, motionEntry.buttonState, motionEntry.classification, motionEntry.edgeFlags, motionEntry.xPrecision, motionEntry.yPrecision, motionEntry.xCursorPosition, motionEntry.yCursorPosition, motionEntry.downTime, usingProperties.value_or(motionEntry.pointerProperties), motionEntry.xCursorPosition, motionEntry.yCursorPosition, motionEntry.downTime, usingProperties.value_or( motionEntry.pointerProperties), usingCoords.value_or(motionEntry.pointerCoords)); if (mTracer) { ensureEventTraced(motionEntry); newEntry->traceTracker = mTracer->traceDerivedEvent(*newEntry, *motionEntry.traceTracker); } resolvedMotion = newEntry; } if (ATRACE_ENABLED()) { std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32 ") to MotionEvent(id=0x%" PRIx32 ").", Loading @@ -3508,7 +3523,8 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio << cancelEvent->getDescription(); std::unique_ptr<DispatchEntry> cancelDispatchEntry = createDispatchEntry(mIdGenerator, inputTarget, std::move(cancelEvent), ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId); ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId, mTracer.get()); // Send these cancel events to the queue before sending the event from the new // device. Loading Loading @@ -4316,6 +4332,10 @@ std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent( originalMotionEntry.xCursorPosition, originalMotionEntry.yCursorPosition, splitDownTime, pointerProperties, pointerCoords); if (mTracer) { splitMotionEntry->traceTracker = mTracer->traceDerivedEvent(*splitMotionEntry, *originalMotionEntry.traceTracker); } return splitMotionEntry; } Loading Loading @@ -6614,6 +6634,10 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl *fallbackKeyCode, event.getScanCode(), event.getMetaState(), event.getRepeatCount(), event.getDownTime()); if (mTracer) { newEntry->traceTracker = mTracer->traceDerivedEvent(*newEntry, *keyEntry.traceTracker); } if (DEBUG_OUTBOUND_EVENT_DETAILS) { ALOGD("Unhandled key event: Dispatching fallback key. " "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x", Loading services/inputflinger/dispatcher/trace/InputTracer.cpp +63 −24 Original line number Diff line number Diff line Loading @@ -59,6 +59,12 @@ TracedEvent createTracedEvent(const KeyEntry& e) { e.downTime, e.flags, e.repeatCount}; } void writeEventToBackend(const TracedEvent& event, InputTracingBackendInterface& backend) { std::visit(Visitor{[&](const TracedMotionEvent& e) { backend.traceMotionEvent(e); }, [&](const TracedKeyEvent& e) { backend.traceKeyEvent(e); }}, event); } } // namespace // --- InputTracer --- Loading @@ -67,41 +73,74 @@ InputTracer::InputTracer(std::unique_ptr<InputTracingBackendInterface> backend) : mBackend(std::move(backend)) {} std::unique_ptr<EventTrackerInterface> InputTracer::traceInboundEvent(const EventEntry& entry) { TracedEvent traced; // This is a newly traced inbound event. Create a new state to track it and its derived events. auto eventState = std::make_shared<EventState>(*this); if (entry.type == EventEntry::Type::MOTION) { const auto& motion = static_cast<const MotionEntry&>(entry); traced = createTracedEvent(motion); eventState->events.emplace_back(createTracedEvent(motion)); } else if (entry.type == EventEntry::Type::KEY) { const auto& key = static_cast<const KeyEntry&>(entry); traced = createTracedEvent(key); eventState->events.emplace_back(createTracedEvent(key)); } else { LOG(FATAL) << "Cannot trace EventEntry of type: " << ftl::enum_string(entry.type); } return std::make_unique<EventTrackerImpl>(*this, std::move(traced)); return std::make_unique<EventTrackerImpl>(std::move(eventState), /*isDerived=*/false); } void InputTracer::dispatchToTargetHint(const EventTrackerInterface& cookie, const InputTarget& target) { if (isDerivedCookie(cookie)) { LOG(FATAL) << "Event target cannot be updated from a derived cookie."; } auto& eventState = getState(cookie); if (eventState.isEventProcessingComplete) { LOG(FATAL) << "dispatchToTargetHint() should not be called after eventProcessingComplete()"; if (eventState->isEventProcessingComplete) { // TODO(b/210460522): Disallow adding new targets after eventProcessingComplete() is called. return; } // TODO(b/210460522): Determine if the event is sensitive based on the target. } void InputTracer::eventProcessingComplete(const EventTrackerInterface& cookie) { if (isDerivedCookie(cookie)) { LOG(FATAL) << "Event processing cannot be set from a derived cookie."; } auto& eventState = getState(cookie); if (eventState.isEventProcessingComplete) { if (eventState->isEventProcessingComplete) { LOG(FATAL) << "Traced event was already logged. " "eventProcessingComplete() was likely called more than once."; } std::visit(Visitor{[&](const TracedMotionEvent& e) { mBackend->traceMotionEvent(e); }, [&](const TracedKeyEvent& e) { mBackend->traceKeyEvent(e); }}, eventState.event); eventState.isEventProcessingComplete = true; for (const auto& event : eventState->events) { writeEventToBackend(event, *mBackend); } eventState->isEventProcessingComplete = true; } std::unique_ptr<EventTrackerInterface> InputTracer::traceDerivedEvent( const EventEntry& entry, const EventTrackerInterface& originalEventCookie) { // This is an event derived from an already-established event. Use the same state to track // this event too. auto eventState = getState(originalEventCookie); if (entry.type == EventEntry::Type::MOTION) { const auto& motion = static_cast<const MotionEntry&>(entry); eventState->events.emplace_back(createTracedEvent(motion)); } else if (entry.type == EventEntry::Type::KEY) { const auto& key = static_cast<const KeyEntry&>(entry); eventState->events.emplace_back(createTracedEvent(key)); } else { LOG(FATAL) << "Cannot trace EventEntry of type: " << ftl::enum_string(entry.type); } if (eventState->isEventProcessingComplete) { // It is possible for a derived event to be dispatched some time after the original event // is dispatched, such as in the case of key fallback events. To account for these cases, // derived events can be traced after the processing is complete for the original event. writeEventToBackend(eventState->events.back(), *mBackend); } return std::make_unique<EventTrackerImpl>(std::move(eventState), /*isDerived=*/true); } void InputTracer::traceEventDispatch(const DispatchEntry& dispatchEntry, Loading @@ -126,9 +165,7 @@ void InputTracer::traceEventDispatch(const DispatchEntry& dispatchEntry, if (!cookie) { // This event was not tracked as an inbound event, so trace it now. std::visit(Visitor{[&](const TracedMotionEvent& e) { mBackend->traceMotionEvent(e); }, [&](const TracedKeyEvent& e) { mBackend->traceKeyEvent(e); }}, traced); writeEventToBackend(traced, *mBackend); } // The vsyncId only has meaning if the event is targeting a window. Loading @@ -141,27 +178,29 @@ void InputTracer::traceEventDispatch(const DispatchEntry& dispatchEntry, /*hmac=*/{}, resolvedKeyRepeatCount}); } InputTracer::EventState& InputTracer::getState(const EventTrackerInterface& cookie) { std::shared_ptr<InputTracer::EventState>& InputTracer::getState( const EventTrackerInterface& cookie) { return static_cast<const EventTrackerImpl&>(cookie).mState; } // --- InputTracer::EventTrackerImpl --- bool InputTracer::isDerivedCookie(const EventTrackerInterface& cookie) { return static_cast<const EventTrackerImpl&>(cookie).mIsDerived; } InputTracer::EventTrackerImpl::EventTrackerImpl(InputTracer& tracer, TracedEvent&& event) : mTracer(tracer), mState(event) {} // --- InputTracer::EventState --- InputTracer::EventTrackerImpl::~EventTrackerImpl() { if (mState.isEventProcessingComplete) { InputTracer::EventState::~EventState() { if (isEventProcessingComplete) { // This event has already been written to the trace as expected. return; } // The event processing was never marked as complete, so do it now. // TODO(b/210460522): Determine why/where the event is being destroyed before // eventProcessingComplete() is called. std::visit(Visitor{[&](const TracedMotionEvent& e) { mTracer.mBackend->traceMotionEvent(e); }, [&](const TracedKeyEvent& e) { mTracer.mBackend->traceKeyEvent(e); }}, mState.event); mState.isEventProcessingComplete = true; for (const auto& event : events) { writeEventToBackend(event, *tracer.mBackend); } isEventProcessingComplete = true; } } // namespace android::inputdispatcher::trace::impl services/inputflinger/dispatcher/trace/InputTracer.h +16 −9 Original line number Diff line number Diff line Loading @@ -44,36 +44,43 @@ public: std::unique_ptr<EventTrackerInterface> traceInboundEvent(const EventEntry&) override; void dispatchToTargetHint(const EventTrackerInterface&, const InputTarget&) override; void eventProcessingComplete(const EventTrackerInterface&) override; std::unique_ptr<EventTrackerInterface> traceDerivedEvent(const EventEntry&, const EventTrackerInterface&) override; void traceEventDispatch(const DispatchEntry&, const EventTrackerInterface*) override; private: std::unique_ptr<InputTracingBackendInterface> mBackend; // The state of a tracked event. // The state of a tracked event, shared across all events derived from the original event. struct EventState { explicit inline EventState(TracedEvent event) : event(std::move(event)){}; explicit inline EventState(InputTracer& tracer) : tracer(tracer){}; ~EventState(); const TracedEvent event; InputTracer& tracer; std::vector<const TracedEvent> events; bool isEventProcessingComplete{false}; // TODO(b/210460522): Add additional args for tracking event sensitivity and // dispatch target UIDs. }; // Get the event state associated with a tracking cookie. EventState& getState(const EventTrackerInterface&); std::shared_ptr<EventState>& getState(const EventTrackerInterface&); bool isDerivedCookie(const EventTrackerInterface&); // Implementation of the event tracker cookie. The cookie holds the event state directly for // convenience to avoid the overhead of tracking the state separately in InputTracer. class EventTrackerImpl : public EventTrackerInterface { public: explicit EventTrackerImpl(InputTracer&, TracedEvent&& entry); virtual ~EventTrackerImpl() override; inline EventTrackerImpl(const std::shared_ptr<EventState>& state, bool isDerivedEvent) : mState(state), mIsDerived(isDerivedEvent) {} EventTrackerImpl(const EventTrackerImpl&) = default; private: InputTracer& mTracer; mutable EventState mState; mutable std::shared_ptr<EventState> mState; const bool mIsDerived; friend EventState& InputTracer::getState(const EventTrackerInterface&); friend std::shared_ptr<EventState>& InputTracer::getState(const EventTrackerInterface&); friend bool InputTracer::isDerivedCookie(const EventTrackerInterface&); }; }; Loading services/inputflinger/dispatcher/trace/InputTracerInterface.h +13 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ public: * to track the event's lifecycle inside InputDispatcher. */ virtual std::unique_ptr<EventTrackerInterface> traceInboundEvent(const EventEntry&) = 0; /** * Notify the tracer that the traced event will be sent to the given InputTarget. * The tracer may change how the event is logged depending on the target. For example, Loading @@ -75,6 +74,19 @@ public: */ virtual void eventProcessingComplete(const EventTrackerInterface&) = 0; /** * Trace an input event that is derived from another event. This is used in cases where an event * is modified from the original, such as when a touch is split across multiple windows, or * when a HOVER_MOVE event is modified to be a HOVER_EXIT, etc. The original event's tracker * must be provided, and a new EventTracker is returned that should be used to track the event's * lifecycle. * * NOTE: The derived tracker cannot be used to change the targets of the original event, meaning * it cannot be used with {@link #dispatchToTargetHint} or {@link eventProcessingComplete}. */ virtual std::unique_ptr<EventTrackerInterface> traceDerivedEvent( const EventEntry&, const EventTrackerInterface& originalEventTracker) = 0; /** * Trace an input event being successfully dispatched to a window. The dispatched event may * be a previously traced inbound event, or it may be a synthesized event that has not been Loading Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +42 −18 Original line number Diff line number Diff line Loading @@ -399,7 +399,8 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerato const InputTarget& inputTarget, std::shared_ptr<const EventEntry> eventEntry, ftl::Flags<InputTarget::Flags> inputTargetFlags, int64_t vsyncId) { int64_t vsyncId, trace::InputTracerInterface* tracer) { const bool zeroCoords = inputTargetFlags.test(InputTarget::Flags::ZERO_COORDS); const sp<WindowInfoHandle> win = inputTarget.windowHandle; const std::optional<int32_t> windowId = Loading Loading @@ -462,6 +463,10 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerato motionEntry.xCursorPosition, motionEntry.yCursorPosition, motionEntry.downTime, motionEntry.pointerProperties, pointerCoords); if (tracer) { combinedMotionEntry->traceTracker = tracer->traceDerivedEvent(*combinedMotionEntry, *motionEntry.traceTracker); } std::unique_ptr<DispatchEntry> dispatchEntry = std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags, Loading Loading @@ -3386,7 +3391,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio // Enqueue a new dispatch entry onto the outbound queue for this connection. std::unique_ptr<DispatchEntry> dispatchEntry = createDispatchEntry(mIdGenerator, inputTarget, eventEntry, inputTarget.flags, mWindowInfosVsyncId); mWindowInfosVsyncId, mTracer.get()); // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a // different EventEntry than what was passed in. Loading Loading @@ -3469,9 +3474,10 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio usingCoords = pointerInfo->second; } } // Generate a new MotionEntry with a new eventId using the resolved action and // flags. resolvedMotion = std::make_shared< { // Generate a new MotionEntry with a new eventId using the resolved action // and flags, and set it as the resolved entry. auto newEntry = std::make_shared< MotionEntry>(mIdGenerator.nextId(), motionEntry.injectionState, motionEntry.eventTime, motionEntry.deviceId, motionEntry.source, motionEntry.displayId, Loading @@ -3480,10 +3486,19 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio motionEntry.metaState, motionEntry.buttonState, motionEntry.classification, motionEntry.edgeFlags, motionEntry.xPrecision, motionEntry.yPrecision, motionEntry.xCursorPosition, motionEntry.yCursorPosition, motionEntry.downTime, usingProperties.value_or(motionEntry.pointerProperties), motionEntry.xCursorPosition, motionEntry.yCursorPosition, motionEntry.downTime, usingProperties.value_or( motionEntry.pointerProperties), usingCoords.value_or(motionEntry.pointerCoords)); if (mTracer) { ensureEventTraced(motionEntry); newEntry->traceTracker = mTracer->traceDerivedEvent(*newEntry, *motionEntry.traceTracker); } resolvedMotion = newEntry; } if (ATRACE_ENABLED()) { std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32 ") to MotionEvent(id=0x%" PRIx32 ").", Loading @@ -3508,7 +3523,8 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio << cancelEvent->getDescription(); std::unique_ptr<DispatchEntry> cancelDispatchEntry = createDispatchEntry(mIdGenerator, inputTarget, std::move(cancelEvent), ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId); ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId, mTracer.get()); // Send these cancel events to the queue before sending the event from the new // device. Loading Loading @@ -4316,6 +4332,10 @@ std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent( originalMotionEntry.xCursorPosition, originalMotionEntry.yCursorPosition, splitDownTime, pointerProperties, pointerCoords); if (mTracer) { splitMotionEntry->traceTracker = mTracer->traceDerivedEvent(*splitMotionEntry, *originalMotionEntry.traceTracker); } return splitMotionEntry; } Loading Loading @@ -6614,6 +6634,10 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl *fallbackKeyCode, event.getScanCode(), event.getMetaState(), event.getRepeatCount(), event.getDownTime()); if (mTracer) { newEntry->traceTracker = mTracer->traceDerivedEvent(*newEntry, *keyEntry.traceTracker); } if (DEBUG_OUTBOUND_EVENT_DETAILS) { ALOGD("Unhandled key event: Dispatching fallback key. " "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x", Loading
services/inputflinger/dispatcher/trace/InputTracer.cpp +63 −24 Original line number Diff line number Diff line Loading @@ -59,6 +59,12 @@ TracedEvent createTracedEvent(const KeyEntry& e) { e.downTime, e.flags, e.repeatCount}; } void writeEventToBackend(const TracedEvent& event, InputTracingBackendInterface& backend) { std::visit(Visitor{[&](const TracedMotionEvent& e) { backend.traceMotionEvent(e); }, [&](const TracedKeyEvent& e) { backend.traceKeyEvent(e); }}, event); } } // namespace // --- InputTracer --- Loading @@ -67,41 +73,74 @@ InputTracer::InputTracer(std::unique_ptr<InputTracingBackendInterface> backend) : mBackend(std::move(backend)) {} std::unique_ptr<EventTrackerInterface> InputTracer::traceInboundEvent(const EventEntry& entry) { TracedEvent traced; // This is a newly traced inbound event. Create a new state to track it and its derived events. auto eventState = std::make_shared<EventState>(*this); if (entry.type == EventEntry::Type::MOTION) { const auto& motion = static_cast<const MotionEntry&>(entry); traced = createTracedEvent(motion); eventState->events.emplace_back(createTracedEvent(motion)); } else if (entry.type == EventEntry::Type::KEY) { const auto& key = static_cast<const KeyEntry&>(entry); traced = createTracedEvent(key); eventState->events.emplace_back(createTracedEvent(key)); } else { LOG(FATAL) << "Cannot trace EventEntry of type: " << ftl::enum_string(entry.type); } return std::make_unique<EventTrackerImpl>(*this, std::move(traced)); return std::make_unique<EventTrackerImpl>(std::move(eventState), /*isDerived=*/false); } void InputTracer::dispatchToTargetHint(const EventTrackerInterface& cookie, const InputTarget& target) { if (isDerivedCookie(cookie)) { LOG(FATAL) << "Event target cannot be updated from a derived cookie."; } auto& eventState = getState(cookie); if (eventState.isEventProcessingComplete) { LOG(FATAL) << "dispatchToTargetHint() should not be called after eventProcessingComplete()"; if (eventState->isEventProcessingComplete) { // TODO(b/210460522): Disallow adding new targets after eventProcessingComplete() is called. return; } // TODO(b/210460522): Determine if the event is sensitive based on the target. } void InputTracer::eventProcessingComplete(const EventTrackerInterface& cookie) { if (isDerivedCookie(cookie)) { LOG(FATAL) << "Event processing cannot be set from a derived cookie."; } auto& eventState = getState(cookie); if (eventState.isEventProcessingComplete) { if (eventState->isEventProcessingComplete) { LOG(FATAL) << "Traced event was already logged. " "eventProcessingComplete() was likely called more than once."; } std::visit(Visitor{[&](const TracedMotionEvent& e) { mBackend->traceMotionEvent(e); }, [&](const TracedKeyEvent& e) { mBackend->traceKeyEvent(e); }}, eventState.event); eventState.isEventProcessingComplete = true; for (const auto& event : eventState->events) { writeEventToBackend(event, *mBackend); } eventState->isEventProcessingComplete = true; } std::unique_ptr<EventTrackerInterface> InputTracer::traceDerivedEvent( const EventEntry& entry, const EventTrackerInterface& originalEventCookie) { // This is an event derived from an already-established event. Use the same state to track // this event too. auto eventState = getState(originalEventCookie); if (entry.type == EventEntry::Type::MOTION) { const auto& motion = static_cast<const MotionEntry&>(entry); eventState->events.emplace_back(createTracedEvent(motion)); } else if (entry.type == EventEntry::Type::KEY) { const auto& key = static_cast<const KeyEntry&>(entry); eventState->events.emplace_back(createTracedEvent(key)); } else { LOG(FATAL) << "Cannot trace EventEntry of type: " << ftl::enum_string(entry.type); } if (eventState->isEventProcessingComplete) { // It is possible for a derived event to be dispatched some time after the original event // is dispatched, such as in the case of key fallback events. To account for these cases, // derived events can be traced after the processing is complete for the original event. writeEventToBackend(eventState->events.back(), *mBackend); } return std::make_unique<EventTrackerImpl>(std::move(eventState), /*isDerived=*/true); } void InputTracer::traceEventDispatch(const DispatchEntry& dispatchEntry, Loading @@ -126,9 +165,7 @@ void InputTracer::traceEventDispatch(const DispatchEntry& dispatchEntry, if (!cookie) { // This event was not tracked as an inbound event, so trace it now. std::visit(Visitor{[&](const TracedMotionEvent& e) { mBackend->traceMotionEvent(e); }, [&](const TracedKeyEvent& e) { mBackend->traceKeyEvent(e); }}, traced); writeEventToBackend(traced, *mBackend); } // The vsyncId only has meaning if the event is targeting a window. Loading @@ -141,27 +178,29 @@ void InputTracer::traceEventDispatch(const DispatchEntry& dispatchEntry, /*hmac=*/{}, resolvedKeyRepeatCount}); } InputTracer::EventState& InputTracer::getState(const EventTrackerInterface& cookie) { std::shared_ptr<InputTracer::EventState>& InputTracer::getState( const EventTrackerInterface& cookie) { return static_cast<const EventTrackerImpl&>(cookie).mState; } // --- InputTracer::EventTrackerImpl --- bool InputTracer::isDerivedCookie(const EventTrackerInterface& cookie) { return static_cast<const EventTrackerImpl&>(cookie).mIsDerived; } InputTracer::EventTrackerImpl::EventTrackerImpl(InputTracer& tracer, TracedEvent&& event) : mTracer(tracer), mState(event) {} // --- InputTracer::EventState --- InputTracer::EventTrackerImpl::~EventTrackerImpl() { if (mState.isEventProcessingComplete) { InputTracer::EventState::~EventState() { if (isEventProcessingComplete) { // This event has already been written to the trace as expected. return; } // The event processing was never marked as complete, so do it now. // TODO(b/210460522): Determine why/where the event is being destroyed before // eventProcessingComplete() is called. std::visit(Visitor{[&](const TracedMotionEvent& e) { mTracer.mBackend->traceMotionEvent(e); }, [&](const TracedKeyEvent& e) { mTracer.mBackend->traceKeyEvent(e); }}, mState.event); mState.isEventProcessingComplete = true; for (const auto& event : events) { writeEventToBackend(event, *tracer.mBackend); } isEventProcessingComplete = true; } } // namespace android::inputdispatcher::trace::impl
services/inputflinger/dispatcher/trace/InputTracer.h +16 −9 Original line number Diff line number Diff line Loading @@ -44,36 +44,43 @@ public: std::unique_ptr<EventTrackerInterface> traceInboundEvent(const EventEntry&) override; void dispatchToTargetHint(const EventTrackerInterface&, const InputTarget&) override; void eventProcessingComplete(const EventTrackerInterface&) override; std::unique_ptr<EventTrackerInterface> traceDerivedEvent(const EventEntry&, const EventTrackerInterface&) override; void traceEventDispatch(const DispatchEntry&, const EventTrackerInterface*) override; private: std::unique_ptr<InputTracingBackendInterface> mBackend; // The state of a tracked event. // The state of a tracked event, shared across all events derived from the original event. struct EventState { explicit inline EventState(TracedEvent event) : event(std::move(event)){}; explicit inline EventState(InputTracer& tracer) : tracer(tracer){}; ~EventState(); const TracedEvent event; InputTracer& tracer; std::vector<const TracedEvent> events; bool isEventProcessingComplete{false}; // TODO(b/210460522): Add additional args for tracking event sensitivity and // dispatch target UIDs. }; // Get the event state associated with a tracking cookie. EventState& getState(const EventTrackerInterface&); std::shared_ptr<EventState>& getState(const EventTrackerInterface&); bool isDerivedCookie(const EventTrackerInterface&); // Implementation of the event tracker cookie. The cookie holds the event state directly for // convenience to avoid the overhead of tracking the state separately in InputTracer. class EventTrackerImpl : public EventTrackerInterface { public: explicit EventTrackerImpl(InputTracer&, TracedEvent&& entry); virtual ~EventTrackerImpl() override; inline EventTrackerImpl(const std::shared_ptr<EventState>& state, bool isDerivedEvent) : mState(state), mIsDerived(isDerivedEvent) {} EventTrackerImpl(const EventTrackerImpl&) = default; private: InputTracer& mTracer; mutable EventState mState; mutable std::shared_ptr<EventState> mState; const bool mIsDerived; friend EventState& InputTracer::getState(const EventTrackerInterface&); friend std::shared_ptr<EventState>& InputTracer::getState(const EventTrackerInterface&); friend bool InputTracer::isDerivedCookie(const EventTrackerInterface&); }; }; Loading
services/inputflinger/dispatcher/trace/InputTracerInterface.h +13 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ public: * to track the event's lifecycle inside InputDispatcher. */ virtual std::unique_ptr<EventTrackerInterface> traceInboundEvent(const EventEntry&) = 0; /** * Notify the tracer that the traced event will be sent to the given InputTarget. * The tracer may change how the event is logged depending on the target. For example, Loading @@ -75,6 +74,19 @@ public: */ virtual void eventProcessingComplete(const EventTrackerInterface&) = 0; /** * Trace an input event that is derived from another event. This is used in cases where an event * is modified from the original, such as when a touch is split across multiple windows, or * when a HOVER_MOVE event is modified to be a HOVER_EXIT, etc. The original event's tracker * must be provided, and a new EventTracker is returned that should be used to track the event's * lifecycle. * * NOTE: The derived tracker cannot be used to change the targets of the original event, meaning * it cannot be used with {@link #dispatchToTargetHint} or {@link eventProcessingComplete}. */ virtual std::unique_ptr<EventTrackerInterface> traceDerivedEvent( const EventEntry&, const EventTrackerInterface& originalEventTracker) = 0; /** * Trace an input event being successfully dispatched to a window. The dispatched event may * be a previously traced inbound event, or it may be a synthesized event that has not been Loading