From e535f979b82fdabf351c758b0a0f8861baa0df67 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Fri, 29 Mar 2024 14:55:21 -0700 Subject: Log dispatch state when addPointers hits unexpected state Propagate errors from TouchedWindow's addTouchingPointers to the InputDispatcher, so that we can look at the event history. Currently, this condition is not getting triggered in the dispatcher tests, but it seems achievable in the libgui_test, according to the logs. Once we figure out the failure mode, we can remove this error reporting to simplify the code. Bug: 331747627 Test: TEST=inputflinger_tests; m $TEST && $ANDROID_HOST_OUT/nativetest64/$TEST/$TEST Change-Id: I668b2db8c3d20b7af81ad89e85608783db631309 --- services/inputflinger/dispatcher/InputDispatcher.cpp | 18 +++++++++++++----- services/inputflinger/dispatcher/TouchState.cpp | 18 ++++++++++-------- services/inputflinger/dispatcher/TouchState.h | 10 +++++----- services/inputflinger/dispatcher/TouchedWindow.cpp | 12 ++++++++---- services/inputflinger/dispatcher/TouchedWindow.h | 3 ++- 5 files changed, 38 insertions(+), 23 deletions(-) (limited to 'services') diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 48219bdb04..fa62fa41d5 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -2539,11 +2539,19 @@ std::vector InputDispatcher::findTouchedWindowTargetsLocked( if (!isHoverAction) { const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN || maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN; - tempTouchState.addOrUpdateWindow(windowHandle, InputTarget::DispatchMode::AS_IS, - targetFlags, entry.deviceId, {pointer}, - isDownOrPointerDown - ? std::make_optional(entry.eventTime) - : std::nullopt); + Result addResult = + tempTouchState.addOrUpdateWindow(windowHandle, + InputTarget::DispatchMode::AS_IS, + targetFlags, entry.deviceId, {pointer}, + isDownOrPointerDown + ? std::make_optional( + entry.eventTime) + : std::nullopt); + if (!addResult.ok()) { + LOG(ERROR) << "Error while processing " << entry << " for " + << windowHandle->getName(); + logDispatchStateLocked(); + } // If this is the pointer going down and the touched window has a wallpaper // then also add the touched wallpaper windows so they are locked in for the // duration of the touch gesture. We do not collect wallpapers during HOVER_MOVE or diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp index f8aa62500e..0caa5e1402 100644 --- a/services/inputflinger/dispatcher/TouchState.cpp +++ b/services/inputflinger/dispatcher/TouchState.cpp @@ -70,14 +70,14 @@ void TouchState::clearWindowsWithoutPointers() { }); } -void TouchState::addOrUpdateWindow(const sp& windowHandle, - InputTarget::DispatchMode dispatchMode, - ftl::Flags targetFlags, DeviceId deviceId, - const std::vector& touchingPointers, - std::optional firstDownTimeInTarget) { +android::base::Result TouchState::addOrUpdateWindow( + const sp& windowHandle, InputTarget::DispatchMode dispatchMode, + ftl::Flags targetFlags, DeviceId deviceId, + const std::vector& touchingPointers, + std::optional firstDownTimeInTarget) { if (touchingPointers.empty()) { LOG(FATAL) << __func__ << "No pointers specified for " << windowHandle->getName(); - return; + return android::base::Error(); } for (TouchedWindow& touchedWindow : windows) { // We do not compare windows by token here because two windows that share the same token @@ -91,11 +91,12 @@ void TouchState::addOrUpdateWindow(const sp& windowHandle, // For cases like hover enter/exit or DISPATCH_AS_OUTSIDE a touch window might not have // downTime set initially. Need to update existing window when a pointer is down for the // window. - touchedWindow.addTouchingPointers(deviceId, touchingPointers); + android::base::Result addResult = + touchedWindow.addTouchingPointers(deviceId, touchingPointers); if (firstDownTimeInTarget) { touchedWindow.trySetDownTimeInTarget(deviceId, *firstDownTimeInTarget); } - return; + return addResult; } } TouchedWindow touchedWindow; @@ -107,6 +108,7 @@ void TouchState::addOrUpdateWindow(const sp& windowHandle, touchedWindow.trySetDownTimeInTarget(deviceId, *firstDownTimeInTarget); } windows.push_back(touchedWindow); + return {}; } void TouchState::addHoveringPointerToWindow(const sp& windowHandle, diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h index 3d534bc71d..559a3fd041 100644 --- a/services/inputflinger/dispatcher/TouchState.h +++ b/services/inputflinger/dispatcher/TouchState.h @@ -43,11 +43,11 @@ struct TouchState { void removeTouchingPointer(DeviceId deviceId, int32_t pointerId); void removeTouchingPointerFromWindow(DeviceId deviceId, int32_t pointerId, const sp& windowHandle); - void addOrUpdateWindow(const sp& windowHandle, - InputTarget::DispatchMode dispatchMode, - ftl::Flags targetFlags, DeviceId deviceId, - const std::vector& touchingPointers, - std::optional firstDownTimeInTarget = std::nullopt); + android::base::Result addOrUpdateWindow( + const sp& windowHandle, + InputTarget::DispatchMode dispatchMode, ftl::Flags targetFlags, + DeviceId deviceId, const std::vector& touchingPointers, + std::optional firstDownTimeInTarget = std::nullopt); void addHoveringPointerToWindow(const sp& windowHandle, DeviceId deviceId, const PointerProperties& pointer); void removeHoveringPointer(DeviceId deviceId, int32_t pointerId); diff --git a/services/inputflinger/dispatcher/TouchedWindow.cpp b/services/inputflinger/dispatcher/TouchedWindow.cpp index 037d7c8e99..1f86f6635a 100644 --- a/services/inputflinger/dispatcher/TouchedWindow.cpp +++ b/services/inputflinger/dispatcher/TouchedWindow.cpp @@ -20,6 +20,7 @@ #include #include +using android::base::Result; using android::base::StringPrintf; namespace android { @@ -89,8 +90,8 @@ void TouchedWindow::addHoveringPointer(DeviceId deviceId, const PointerPropertie hoveringPointers.push_back(pointer); } -void TouchedWindow::addTouchingPointers(DeviceId deviceId, - const std::vector& pointers) { +Result TouchedWindow::addTouchingPointers(DeviceId deviceId, + const std::vector& pointers) { std::vector& touchingPointers = mDeviceStates[deviceId].touchingPointers; const size_t initialSize = touchingPointers.size(); for (const PointerProperties& pointer : pointers) { @@ -98,11 +99,14 @@ void TouchedWindow::addTouchingPointers(DeviceId deviceId, return properties.id == pointer.id; }); } - if (touchingPointers.size() != initialSize) { + const bool foundInconsistentState = touchingPointers.size() != initialSize; + touchingPointers.insert(touchingPointers.end(), pointers.begin(), pointers.end()); + if (foundInconsistentState) { LOG(ERROR) << __func__ << ": " << dumpVector(pointers, streamableToString) << ", device " << deviceId << " already in " << *this; + return android::base::Error(); } - touchingPointers.insert(touchingPointers.end(), pointers.begin(), pointers.end()); + return {}; } bool TouchedWindow::hasTouchingPointers() const { diff --git a/services/inputflinger/dispatcher/TouchedWindow.h b/services/inputflinger/dispatcher/TouchedWindow.h index 0d1531f8ff..4f0ad1628a 100644 --- a/services/inputflinger/dispatcher/TouchedWindow.h +++ b/services/inputflinger/dispatcher/TouchedWindow.h @@ -46,7 +46,8 @@ struct TouchedWindow { bool hasTouchingPointers() const; bool hasTouchingPointers(DeviceId deviceId) const; std::vector getTouchingPointers(DeviceId deviceId) const; - void addTouchingPointers(DeviceId deviceId, const std::vector& pointers); + android::base::Result addTouchingPointers(DeviceId deviceId, + const std::vector& pointers); void removeTouchingPointer(DeviceId deviceId, int32_t pointerId); void removeTouchingPointers(DeviceId deviceId, std::bitset pointers); bool hasActiveStylus() const; -- cgit v1.2.3-59-g8ed1b