InputDispatcher: Allow spy window to receive entire gesture after pilfer
After a spy window pilfers pointers, it should be albe to receive any
new pointers within its touchable bounds.
Bug: 217376964
Test: atest inputflinger_tests
Change-Id: Iab8360f2f8e3db978cf6c68f19a538b28f7dfac1
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index a1ac229..dc46f30 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -1987,7 +1987,7 @@
TouchState tempTouchState;
if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
oldState = &(it->second);
- tempTouchState.copyFrom(*oldState);
+ tempTouchState = *oldState;
}
bool isSplit = tempTouchState.split;
@@ -5510,9 +5510,9 @@
ALOGI("Channel %s is stealing touch from %s", requestingChannel->getName().c_str(),
canceledWindows.c_str());
- // Then clear the current touch state so we stop dispatching to them as well.
- state.split = false;
+ // Prevent the gesture from being sent to any other windows.
state.filterWindowsExcept(token);
+ state.preventNewTargets = true;
return OK;
}
diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp
index ab86196..b63fe10 100644
--- a/services/inputflinger/dispatcher/TouchState.cpp
+++ b/services/inputflinger/dispatcher/TouchState.cpp
@@ -25,27 +25,8 @@
namespace android::inputdispatcher {
-TouchState::TouchState()
- : down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {}
-
-TouchState::~TouchState() {}
-
void TouchState::reset() {
- down = false;
- split = false;
- deviceId = -1;
- source = 0;
- displayId = ADISPLAY_ID_NONE;
- windows.clear();
-}
-
-void TouchState::copyFrom(const TouchState& other) {
- down = other.down;
- split = other.split;
- deviceId = other.deviceId;
- source = other.source;
- displayId = other.displayId;
- windows = other.windows;
+ *this = TouchState();
}
void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags,
@@ -66,6 +47,8 @@
}
}
+ if (preventNewTargets) return; // Don't add new TouchedWindows.
+
TouchedWindow touchedWindow;
touchedWindow.windowHandle = windowHandle;
touchedWindow.targetFlags = targetFlags;
diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h
index e154ed3..9efb280 100644
--- a/services/inputflinger/dispatcher/TouchState.h
+++ b/services/inputflinger/dispatcher/TouchState.h
@@ -29,17 +29,24 @@
namespace inputdispatcher {
struct TouchState {
- bool down;
- bool split;
- int32_t deviceId; // id of the device that is currently down, others are rejected
- uint32_t source; // source of the device that is current down, others are rejected
- int32_t displayId; // id to the display that currently has a touch, others are rejected
+ bool down = false;
+ bool split = false;
+ bool preventNewTargets = false;
+
+ // id of the device that is currently down, others are rejected
+ int32_t deviceId = -1;
+ // source of the device that is current down, others are rejected
+ uint32_t source = 0;
+ // id to the display that currently has a touch, others are rejected
+ int32_t displayId = ADISPLAY_ID_NONE;
+
std::vector<TouchedWindow> windows;
- TouchState();
- ~TouchState();
+ TouchState() = default;
+ ~TouchState() = default;
+ TouchState& operator=(const TouchState&) = default;
+
void reset();
- void copyFrom(const TouchState& other);
void addOrUpdateWindow(const sp<android::gui::WindowInfoHandle>& windowHandle,
int32_t targetFlags, BitSet32 pointerIds);
void removeWindowByToken(const sp<IBinder>& token);