diff options
| author | 2024-03-09 05:59:49 +0000 | |
|---|---|---|
| committer | 2024-03-09 05:59:49 +0000 | |
| commit | 67cf0027b4f05681eae77ce60e443b86d8fd44c0 (patch) | |
| tree | 5f1d330bb84b067fc34379879533d23278abd95b | |
| parent | 7fcacac5f8f955e47f7d21604069343aa33f4d1a (diff) | |
| parent | d6b2b05f75fc82bd9817878d0feb2a6f425dc57d (diff) | |
Merge changes I3417aee3,I22885650 into main
* changes:
InputTracer: Create tracker for tracing synthetic events
InputTracer: Consolidate logic for marking event processing complete
6 files changed, 167 insertions, 55 deletions
diff --git a/services/inputflinger/dispatcher/CancelationOptions.h b/services/inputflinger/dispatcher/CancelationOptions.h index 83e6a60602..9c73f03dc8 100644 --- a/services/inputflinger/dispatcher/CancelationOptions.h +++ b/services/inputflinger/dispatcher/CancelationOptions.h @@ -16,6 +16,8 @@ #pragma once +#include "trace/EventTrackerInterface.h" + #include <input/Input.h> #include <bitset> #include <optional> @@ -51,7 +53,13 @@ struct CancelationOptions { // The specific pointers to cancel, or nullopt to cancel all pointer events std::optional<std::bitset<MAX_POINTER_ID + 1>> pointerIds = std::nullopt; - CancelationOptions(Mode mode, const char* reason) : mode(mode), reason(reason) {} + const std::unique_ptr<trace::EventTrackerInterface>& traceTracker; + + explicit CancelationOptions(Mode mode, const char* reason, + const std::unique_ptr<trace::EventTrackerInterface>& traceTracker) + : mode(mode), reason(reason), traceTracker(traceTracker) {} + CancelationOptions(const CancelationOptions&) = delete; + CancelationOptions operator=(const CancelationOptions&) = delete; }; } // namespace inputdispatcher diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 56b0c8f12c..f06caa6a40 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -862,6 +862,30 @@ std::pair<bool /*cancelPointers*/, bool /*cancelNonPointers*/> expandCancellatio } } +class ScopedSyntheticEventTracer { +public: + ScopedSyntheticEventTracer(std::unique_ptr<trace::InputTracerInterface>& tracer) + : mTracer(tracer) { + if (mTracer) { + mEventTracker = mTracer->createTrackerForSyntheticEvent(); + } + } + + ~ScopedSyntheticEventTracer() { + if (mTracer) { + mTracer->eventProcessingComplete(*mEventTracker); + } + } + + const std::unique_ptr<trace::EventTrackerInterface>& getTracker() const { + return mEventTracker; + } + +private: + std::unique_ptr<trace::InputTracerInterface>& mTracer; + std::unique_ptr<trace::EventTrackerInterface> mEventTracker; +}; + } // namespace // --- InputDispatcher --- @@ -1479,8 +1503,9 @@ void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason switch (entry.type) { case EventEntry::Type::KEY: { - CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, reason); const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry); + CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, reason, + keyEntry.traceTracker); options.displayId = keyEntry.displayId; options.deviceId = keyEntry.deviceId; synthesizeCancelationEventsForAllConnectionsLocked(options); @@ -1489,13 +1514,14 @@ void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason case EventEntry::Type::MOTION: { const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry); if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) { - CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, reason); + CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, reason, + motionEntry.traceTracker); options.displayId = motionEntry.displayId; options.deviceId = motionEntry.deviceId; synthesizeCancelationEventsForAllConnectionsLocked(options); } else { CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, - reason); + reason, motionEntry.traceTracker); options.displayId = motionEntry.displayId; options.deviceId = motionEntry.deviceId; synthesizeCancelationEventsForAllConnectionsLocked(options); @@ -1630,7 +1656,9 @@ bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, resetKeyRepeatLocked(); } - CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, "device was reset"); + ScopedSyntheticEventTracer traceContext(mTracer); + CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, "device was reset", + traceContext.getTracker()); options.deviceId = entry.deviceId; synthesizeCancelationEventsForAllConnectionsLocked(options); @@ -2019,7 +2047,7 @@ bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, CancelationOptions::Mode mode( isPointerEvent ? CancelationOptions::Mode::CANCEL_POINTER_EVENTS : CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS); - CancelationOptions options(mode, "input event injection failed"); + CancelationOptions options(mode, "input event injection failed", entry->traceTracker); options.displayId = entry->displayId; synthesizeCancelationEventsForMonitorsLocked(options); return true; @@ -2125,8 +2153,9 @@ void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection> if (connection->status != Connection::Status::NORMAL) { return; } + ScopedSyntheticEventTracer traceContext(mTracer); CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, - "application not responding"); + "application not responding", traceContext.getTracker()); sp<WindowInfoHandle> windowHandle; if (!connection->monitor) { @@ -3521,6 +3550,10 @@ void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connectio LOG(INFO) << "Canceling pointers for device " << resolvedMotion->deviceId << " in " << connection->getInputChannelName() << " with event " << cancelEvent->getDescription(); + if (mTracer) { + static_cast<MotionEntry&>(*cancelEvent).traceTracker = + mTracer->traceDerivedEvent(*cancelEvent, *resolvedMotion->traceTracker); + } std::unique_ptr<DispatchEntry> cancelDispatchEntry = createDispatchEntry(mIdGenerator, inputTarget, std::move(cancelEvent), ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId, @@ -3758,7 +3791,8 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, keyEntry.metaState, keyEntry.repeatCount, keyEntry.downTime, keyEntry.eventTime); if (mTracer) { - mTracer->traceEventDispatch(*dispatchEntry, keyEntry.traceTracker.get()); + ensureEventTraced(keyEntry); + mTracer->traceEventDispatch(*dispatchEntry, *keyEntry.traceTracker); } break; } @@ -3771,7 +3805,8 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry); status = publishMotionEvent(*connection, *dispatchEntry); if (mTracer) { - mTracer->traceEventDispatch(*dispatchEntry, motionEntry.traceTracker.get()); + ensureEventTraced(motionEntry); + mTracer->traceEventDispatch(*dispatchEntry, *motionEntry.traceTracker); } break; } @@ -4150,6 +4185,11 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( switch (cancelationEventEntry->type) { case EventEntry::Type::KEY: { + if (mTracer) { + static_cast<KeyEntry&>(*cancelationEventEntry).traceTracker = + mTracer->traceDerivedEvent(*cancelationEventEntry, + *options.traceTracker); + } const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry); if (window) { addWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS, @@ -4161,6 +4201,11 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( break; } case EventEntry::Type::MOTION: { + if (mTracer) { + static_cast<MotionEntry&>(*cancelationEventEntry).traceTracker = + mTracer->traceDerivedEvent(*cancelationEventEntry, + *options.traceTracker); + } const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry); if (window) { std::bitset<MAX_POINTER_ID + 1> pointerIds; @@ -4208,6 +4253,9 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( } if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created"; + if (mTracer) { + mTracer->dispatchToTargetHint(*options.traceTracker, targets[0]); + } enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), targets[0]); } @@ -4219,7 +4267,8 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( const nsecs_t downTime, const std::shared_ptr<Connection>& connection, - ftl::Flags<InputTarget::Flags> targetFlags) { + ftl::Flags<InputTarget::Flags> targetFlags, + const std::unique_ptr<trace::EventTrackerInterface>& traceTracker) { if (connection->status != Connection::Status::NORMAL) { return; } @@ -4248,6 +4297,10 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( std::vector<InputTarget> targets{}; switch (downEventEntry->type) { case EventEntry::Type::MOTION: { + if (mTracer) { + static_cast<MotionEntry&>(*downEventEntry).traceTracker = + mTracer->traceDerivedEvent(*downEventEntry, *traceTracker); + } const auto& motionEntry = static_cast<const MotionEntry&>(*downEventEntry); if (windowHandle != nullptr) { std::bitset<MAX_POINTER_ID + 1> pointerIds; @@ -4285,6 +4338,9 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked( } if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created"; + if (mTracer) { + mTracer->dispatchToTargetHint(*traceTracker, targets[0]); + } enqueueDispatchEntryLocked(connection, std::move(downEventEntry), targets[0]); } @@ -5222,6 +5278,7 @@ void InputDispatcher::setInputWindowsLocked( } LOG(INFO) << "setInputWindows displayId=" << displayId << " " << windowList; } + ScopedSyntheticEventTracer traceContext(mTracer); // Check preconditions for new input windows for (const sp<WindowInfoHandle>& window : windowInfoHandles) { @@ -5261,7 +5318,7 @@ void InputDispatcher::setInputWindowsLocked( std::optional<FocusResolver::FocusChanges> changes = mFocusResolver.setInputWindows(displayId, windowHandles); if (changes) { - onFocusChangedLocked(*changes, removedFocusedWindowHandle); + onFocusChangedLocked(*changes, traceContext.getTracker(), removedFocusedWindowHandle); } std::unordered_map<int32_t, TouchState>::iterator stateIt = @@ -5274,7 +5331,7 @@ void InputDispatcher::setInputWindowsLocked( LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName() << " in display %" << displayId; CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, - "touched window was removed"); + "touched window was removed", traceContext.getTracker()); synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options); // Since we are about to drop the touch, cancel the events for the wallpaper as // well. @@ -5375,6 +5432,7 @@ void InputDispatcher::setFocusedDisplay(int32_t displayId) { } { // acquire lock std::scoped_lock _l(mLock); + ScopedSyntheticEventTracer traceContext(mTracer); if (mFocusedDisplayId != displayId) { sp<IBinder> oldFocusedWindowToken = @@ -5387,7 +5445,8 @@ void InputDispatcher::setFocusedDisplay(int32_t displayId) { } CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, - "The display which contains this window no longer has focus."); + "The display which contains this window no longer has focus.", + traceContext.getTracker()); options.displayId = ADISPLAY_ID_NONE; synthesizeCancelationEventsForWindowLocked(windowHandle, options); } @@ -5612,19 +5671,22 @@ bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const s } // Synthesize cancel for old window and down for new window. + ScopedSyntheticEventTracer traceContext(mTracer); std::shared_ptr<Connection> fromConnection = getConnectionLocked(fromToken); std::shared_ptr<Connection> toConnection = getConnectionLocked(toToken); if (fromConnection != nullptr && toConnection != nullptr) { fromConnection->inputState.mergePointerStateTo(toConnection->inputState); CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, - "transferring touch from this window to another window"); + "transferring touch from this window to another window", + traceContext.getTracker()); synthesizeCancelationEventsForWindowLocked(fromWindowHandle, options, fromConnection); synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection, - newTargetFlags); + newTargetFlags, + traceContext.getTracker()); // Check if the wallpaper window should deliver the corresponding event. transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle, - *state, deviceId, pointers); + *state, deviceId, pointers, traceContext.getTracker()); } } // release lock @@ -5692,7 +5754,9 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) { ALOGD("Resetting and dropping all events (%s).", reason); } - CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason); + ScopedSyntheticEventTracer traceContext(mTracer); + CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason, + traceContext.getTracker()); synthesizeCancelationEventsForAllConnectionsLocked(options); resetKeyRepeatLocked(); @@ -6087,12 +6151,13 @@ status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) { return BAD_VALUE; } + ScopedSyntheticEventTracer traceContext(mTracer); for (const DeviceId deviceId : deviceIds) { TouchState& state = *statePtr; TouchedWindow& window = *windowPtr; // Send cancel events to all the input channels we're stealing from. CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, - "input channel stole pointer stream"); + "input channel stole pointer stream", traceContext.getTracker()); options.deviceId = deviceId; options.displayId = displayId; std::vector<PointerProperties> pointers = window.getTouchingPointers(deviceId); @@ -6516,7 +6581,8 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS, "application handled the original non-fallback key " "or is no longer a foreground target, " - "canceling previously dispatched fallback key"); + "canceling previously dispatched fallback key", + keyEntry.traceTracker); options.keyCode = *fallbackKeyCode; synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection); } @@ -6598,7 +6664,8 @@ std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptabl const auto windowHandle = getWindowHandleLocked(connection->getToken()); if (windowHandle != nullptr) { CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS, - "canceling fallback, policy no longer desires it"); + "canceling fallback, policy no longer desires it", + keyEntry.traceTracker); options.keyCode = *fallbackKeyCode; synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection); } @@ -6736,16 +6803,19 @@ void InputDispatcher::setFocusedWindow(const FocusRequest& request) { std::scoped_lock _l(mLock); std::optional<FocusResolver::FocusChanges> changes = mFocusResolver.setFocusedWindow(request, getWindowHandlesLocked(request.displayId)); + ScopedSyntheticEventTracer traceContext(mTracer); if (changes) { - onFocusChangedLocked(*changes); + onFocusChangedLocked(*changes, traceContext.getTracker()); } } // release lock // Wake up poll loop since it may need to make new input dispatching choices. mLooper->wake(); } -void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& changes, - const sp<WindowInfoHandle> removedFocusedWindowHandle) { +void InputDispatcher::onFocusChangedLocked( + const FocusResolver::FocusChanges& changes, + const std::unique_ptr<trace::EventTrackerInterface>& traceTracker, + const sp<WindowInfoHandle> removedFocusedWindowHandle) { if (changes.oldFocus) { const auto resolvedWindow = removedFocusedWindowHandle != nullptr ? removedFocusedWindowHandle @@ -6754,7 +6824,7 @@ void InputDispatcher::onFocusChangedLocked(const FocusResolver::FocusChanges& ch LOG(FATAL) << __func__ << ": Previously focused token did not have a window"; } CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, - "focus left window"); + "focus left window", traceTracker); synthesizeCancelationEventsForWindowLocked(resolvedWindow, options); enqueueFocusEventLocked(changes.oldFocus, /*hasFocus=*/false, changes.reason); } @@ -6907,9 +6977,10 @@ void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged( void InputDispatcher::cancelCurrentTouch() { { std::scoped_lock _l(mLock); + ScopedSyntheticEventTracer traceContext(mTracer); ALOGD("Canceling all ongoing pointer gestures on all displays."); CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, - "cancel current touch"); + "cancel current touch", traceContext.getTracker()); synthesizeCancelationEventsForAllConnectionsLocked(options); mTouchStatesByDisplay.clear(); @@ -6959,12 +7030,12 @@ void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFl } } -void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags, - ftl::Flags<InputTarget::Flags> newTargetFlags, - const sp<WindowInfoHandle> fromWindowHandle, - const sp<WindowInfoHandle> toWindowHandle, - TouchState& state, int32_t deviceId, - const std::vector<PointerProperties>& pointers) { +void InputDispatcher::transferWallpaperTouch( + ftl::Flags<InputTarget::Flags> oldTargetFlags, + ftl::Flags<InputTarget::Flags> newTargetFlags, const sp<WindowInfoHandle> fromWindowHandle, + const sp<WindowInfoHandle> toWindowHandle, TouchState& state, int32_t deviceId, + const std::vector<PointerProperties>& pointers, + const std::unique_ptr<trace::EventTrackerInterface>& traceTracker) { const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) && fromWindowHandle->getInfo()->inputConfig.test( gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER); @@ -6982,7 +7053,7 @@ void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldT if (oldWallpaper != nullptr) { CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, - "transferring touch focus to another window"); + "transferring touch focus to another window", traceTracker); state.removeWindowByToken(oldWallpaper->getToken()); synthesizeCancelationEventsForWindowLocked(oldWallpaper, options); } @@ -7002,7 +7073,7 @@ void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldT getConnectionLocked(toWindowHandle->getToken()); toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState); synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, wallpaperConnection, - wallpaperFlags); + wallpaperFlags, traceTracker); } } } diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h index 269bfddb8c..d6eba64dd0 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.h +++ b/services/inputflinger/dispatcher/InputDispatcher.h @@ -628,7 +628,8 @@ private: void synthesizePointerDownEventsForConnectionLocked( const nsecs_t downTime, const std::shared_ptr<Connection>& connection, - ftl::Flags<InputTarget::Flags> targetFlags) REQUIRES(mLock); + ftl::Flags<InputTarget::Flags> targetFlags, + const std::unique_ptr<trace::EventTrackerInterface>& traceTracker) REQUIRES(mLock); // Splitting motion events across windows. When splitting motion event for a target, // splitDownTime refers to the time of first 'down' event on that particular target @@ -657,6 +658,7 @@ private: void doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken, const KeyEntry& entry) REQUIRES(mLock); void onFocusChangedLocked(const FocusResolver::FocusChanges& changes, + const std::unique_ptr<trace::EventTrackerInterface>& traceTracker, const sp<gui::WindowInfoHandle> removedFocusedWindowHandle = nullptr) REQUIRES(mLock); void sendFocusChangedCommandLocked(const sp<IBinder>& oldToken, const sp<IBinder>& newToken) @@ -704,7 +706,9 @@ private: const sp<android::gui::WindowInfoHandle> fromWindowHandle, const sp<android::gui::WindowInfoHandle> toWindowHandle, TouchState& state, int32_t deviceId, - const std::vector<PointerProperties>& pointers) REQUIRES(mLock); + const std::vector<PointerProperties>& pointers, + const std::unique_ptr<trace::EventTrackerInterface>& traceTracker) + REQUIRES(mLock); sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow( const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock); diff --git a/services/inputflinger/dispatcher/trace/InputTracer.cpp b/services/inputflinger/dispatcher/trace/InputTracer.cpp index 3b5a09694c..83ed452d6e 100644 --- a/services/inputflinger/dispatcher/trace/InputTracer.cpp +++ b/services/inputflinger/dispatcher/trace/InputTracer.cpp @@ -65,6 +65,10 @@ void writeEventToBackend(const TracedEvent& event, InputTracingBackendInterface& event); } +inline auto getId(const trace::TracedEvent& v) { + return std::visit([](const auto& event) { return event.id; }, v); +} + } // namespace // --- InputTracer --- @@ -89,6 +93,12 @@ std::unique_ptr<EventTrackerInterface> InputTracer::traceInboundEvent(const Even return std::make_unique<EventTrackerImpl>(std::move(eventState), /*isDerived=*/false); } +std::unique_ptr<EventTrackerInterface> InputTracer::createTrackerForSyntheticEvent() { + // Create a new EventState to track events derived from this tracker. + return std::make_unique<EventTrackerImpl>(std::make_shared<EventState>(*this), + /*isDerived=*/false); +} + void InputTracer::dispatchToTargetHint(const EventTrackerInterface& cookie, const InputTarget& target) { if (isDerivedCookie(cookie)) { @@ -111,11 +121,7 @@ void InputTracer::eventProcessingComplete(const EventTrackerInterface& cookie) { LOG(FATAL) << "Traced event was already logged. " "eventProcessingComplete() was likely called more than once."; } - - for (const auto& event : eventState->events) { - writeEventToBackend(event, *mBackend); - } - eventState->isEventProcessingComplete = true; + eventState->onEventProcessingComplete(); } std::unique_ptr<EventTrackerInterface> InputTracer::traceDerivedEvent( @@ -144,7 +150,8 @@ std::unique_ptr<EventTrackerInterface> InputTracer::traceDerivedEvent( } void InputTracer::traceEventDispatch(const DispatchEntry& dispatchEntry, - const EventTrackerInterface* cookie) { + const EventTrackerInterface& cookie) { + auto& eventState = getState(cookie); const EventEntry& entry = *dispatchEntry.eventEntry; // TODO(b/328618922): Remove resolved key repeats after making repeatCount non-mutable. // The KeyEntry's repeatCount is mutable and can be modified after an event is initially traced, @@ -163,9 +170,13 @@ void InputTracer::traceEventDispatch(const DispatchEntry& dispatchEntry, LOG(FATAL) << "Cannot trace EventEntry of type: " << ftl::enum_string(entry.type); } - if (!cookie) { - // This event was not tracked as an inbound event, so trace it now. - writeEventToBackend(traced, *mBackend); + auto tracedEventIt = + std::find_if(eventState->events.begin(), eventState->events.end(), + [&traced](const auto& event) { return getId(traced) == getId(event); }); + if (tracedEventIt == eventState->events.end()) { + LOG(FATAL) + << __func__ + << ": Failed to find a previously traced event that matches the dispatched event"; } // The vsyncId only has meaning if the event is targeting a window. @@ -189,18 +200,24 @@ bool InputTracer::isDerivedCookie(const EventTrackerInterface& cookie) { // --- InputTracer::EventState --- +void InputTracer::EventState::onEventProcessingComplete() { + // Write all of the events known so far to the trace. + for (const auto& event : events) { + writeEventToBackend(event, *tracer.mBackend); + } + isEventProcessingComplete = true; +} + 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. - for (const auto& event : events) { - writeEventToBackend(event, *tracer.mBackend); - } - isEventProcessingComplete = true; + // We should never end up here in normal operation. However, in tests, it's possible that we + // stop and destroy InputDispatcher without waiting for it to finish processing events, at + // which point an event (and thus its EventState) may be destroyed before processing finishes. + onEventProcessingComplete(); } } // namespace android::inputdispatcher::trace::impl diff --git a/services/inputflinger/dispatcher/trace/InputTracer.h b/services/inputflinger/dispatcher/trace/InputTracer.h index ccff30e59d..529c0fafed 100644 --- a/services/inputflinger/dispatcher/trace/InputTracer.h +++ b/services/inputflinger/dispatcher/trace/InputTracer.h @@ -42,11 +42,12 @@ public: InputTracer& operator=(const InputTracer&) = delete; std::unique_ptr<EventTrackerInterface> traceInboundEvent(const EventEntry&) override; + std::unique_ptr<EventTrackerInterface> createTrackerForSyntheticEvent() 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; + void traceEventDispatch(const DispatchEntry&, const EventTrackerInterface&) override; private: std::unique_ptr<InputTracingBackendInterface> mBackend; @@ -56,6 +57,8 @@ private: explicit inline EventState(InputTracer& tracer) : tracer(tracer){}; ~EventState(); + void onEventProcessingComplete(); + InputTracer& tracer; std::vector<const TracedEvent> events; bool isEventProcessingComplete{false}; diff --git a/services/inputflinger/dispatcher/trace/InputTracerInterface.h b/services/inputflinger/dispatcher/trace/InputTracerInterface.h index daf716f993..609d10c0f7 100644 --- a/services/inputflinger/dispatcher/trace/InputTracerInterface.h +++ b/services/inputflinger/dispatcher/trace/InputTracerInterface.h @@ -52,6 +52,15 @@ public: * to track the event's lifecycle inside InputDispatcher. */ virtual std::unique_ptr<EventTrackerInterface> traceInboundEvent(const EventEntry&) = 0; + + /** + * Create a trace tracker for a synthetic event that does not stem from an inbound input event. + * This includes things like generating cancellations or down events for various reasons, + * such as ANR, pilfering, transfer touch, etc. Any key or motion events generated for this + * synthetic event should be traced as a derived event using {@link #traceDerivedEvent}. + */ + virtual std::unique_ptr<EventTrackerInterface> createTrackerForSyntheticEvent() = 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, @@ -89,11 +98,11 @@ public: /** * 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 - * previously traced. For inbound events that were previously traced, the EventTracker cookie - * must be provided. For events that were not previously traced, the cookie must be null. + * be a previously traced inbound event, or it may be a synthesized event. All dispatched events + * must have been previously traced, so the trace tracker associated with the event must be + * provided. */ - virtual void traceEventDispatch(const DispatchEntry&, const EventTrackerInterface*) = 0; + virtual void traceEventDispatch(const DispatchEntry&, const EventTrackerInterface&) = 0; }; } // namespace android::inputdispatcher::trace |