InputDispatcher: Remove gesture monitor implementation
Bug: 162194035
Test: atest inputflinger_tests
Change-Id: I4404c9625f879d805aabdbda6d502dac1d0cd881
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index aa3643c..a1ac229 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -417,20 +417,6 @@
return event;
}
-std::optional<int32_t> findMonitorPidByToken(
- const std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay,
- const sp<IBinder>& token) {
- for (const auto& it : monitorsByDisplay) {
- const std::vector<Monitor>& monitors = it.second;
- for (const Monitor& monitor : monitors) {
- if (monitor.inputChannel->getConnectionToken() == token) {
- return monitor.pid;
- }
- }
- }
- return std::nullopt;
-}
-
bool shouldReportMetricsForConnection(const Connection& connection) {
// Do not keep track of gesture monitors. They receive every event and would disproportionately
// affect the statistics.
@@ -948,15 +934,16 @@
return true;
}
- // Alternatively, maybe there's a gesture monitor that could handle this event
- for (const auto& monitor : getValueByKey(mGestureMonitorsByDisplay, displayId)) {
- sp<Connection> connection =
- getConnectionLocked(monitor.inputChannel->getConnectionToken());
+ // Alternatively, maybe there's a spy window that could handle this event.
+ const std::vector<sp<WindowInfoHandle>> touchedSpies =
+ findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
+ for (const auto& windowHandle : touchedSpies) {
+ const sp<Connection> connection = getConnectionLocked(windowHandle->getToken());
if (connection != nullptr && connection->responsive) {
- // This monitor could take more input. Drop all events preceding this
- // event, so that gesture monitor could get a chance to receive the stream
+ // This spy window could take more input. Drop all events preceding this
+ // event, so that the spy window can get a chance to receive the stream.
ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
- "responsive gesture monitor that may handle the event",
+ "responsive spy window that may handle the event.",
mAwaitedFocusedApplication->getName().c_str());
return true;
}
@@ -2104,6 +2091,13 @@
newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
}
+ if (newTouchedWindows.empty()) {
+ ALOGI("Dropping event because there is no touchable window at (%d, %d) on display %d.",
+ x, y, displayId);
+ injectionResult = InputEventInjectionResult::FAILED;
+ goto Failed;
+ }
+
for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
const WindowInfo& info = *windowHandle->getInfo();
@@ -2172,23 +2166,6 @@
tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds);
}
-
- const std::vector<Monitor> newGestureMonitors = isDown
- ? selectResponsiveMonitorsLocked(
- getValueByKey(mGestureMonitorsByDisplay, displayId))
- : std::vector<Monitor>{};
-
- if (newTouchedWindows.empty() && newGestureMonitors.empty() &&
- tempTouchState.gestureMonitors.empty()) {
- ALOGI("Dropping event because there is no touchable window or gesture monitor at "
- "(%d, %d) in display %" PRId32 ".",
- x, y, displayId);
- injectionResult = InputEventInjectionResult::FAILED;
- goto Failed;
- }
-
- tempTouchState.addGestureMonitors(newGestureMonitors);
-
} else {
/* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
@@ -2290,40 +2267,34 @@
}
}
- // Check permission to inject into all touched foreground windows and ensure there
- // is at least one touched foreground window.
- {
- bool haveForegroundOrSpyWindow = false;
- for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
- const bool isForeground =
- (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0;
- if (touchedWindow.windowHandle->getInfo()->isSpy()) {
- haveForegroundOrSpyWindow = true;
- LOG_ALWAYS_FATAL_IF(isForeground,
- "Spy window cannot be dispatched as a foreground window.");
- }
- if (isForeground) {
- haveForegroundOrSpyWindow = true;
- if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
- injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
- injectionPermission = INJECTION_PERMISSION_DENIED;
- goto Failed;
- }
- }
- }
- bool hasGestureMonitor = !tempTouchState.gestureMonitors.empty();
- if (!haveForegroundOrSpyWindow && !hasGestureMonitor) {
- ALOGI("Dropping event because there is no touched window in display "
- "%" PRId32 " or gesture monitor to receive it.",
- displayId);
- injectionResult = InputEventInjectionResult::FAILED;
- goto Failed;
- }
-
- // Permission granted to injection into all touched foreground windows.
- injectionPermission = INJECTION_PERMISSION_GRANTED;
+ // Ensure that we have at least one foreground or spy window. It's possible that we dropped some
+ // of the touched windows we previously found if they became paused or unresponsive or were
+ // removed.
+ if (std::none_of(tempTouchState.windows.begin(), tempTouchState.windows.end(),
+ [](const TouchedWindow& touchedWindow) {
+ return (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0 ||
+ touchedWindow.windowHandle->getInfo()->isSpy();
+ })) {
+ ALOGI("Dropping event because there is no touched window on display %d to receive it.",
+ displayId);
+ injectionResult = InputEventInjectionResult::FAILED;
+ goto Failed;
}
+ // Check permission to inject into all touched foreground windows.
+ if (std::any_of(tempTouchState.windows.begin(), tempTouchState.windows.end(),
+ [this, &entry](const TouchedWindow& touchedWindow) {
+ return (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) != 0 &&
+ !checkInjectionPermission(touchedWindow.windowHandle,
+ entry.injectionState);
+ })) {
+ injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
+ injectionPermission = INJECTION_PERMISSION_DENIED;
+ goto Failed;
+ }
+ // Permission granted to inject into all touched foreground windows.
+ injectionPermission = INJECTION_PERMISSION_GRANTED;
+
// Check whether windows listening for outside touches are owned by the same UID. If it is
// set the policy flag that we will not reveal coordinate information to this window.
if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
@@ -2380,10 +2351,6 @@
touchedWindow.pointerIds, inputTargets);
}
- for (const auto& monitor : tempTouchState.gestureMonitors) {
- addMonitoringTargetLocked(monitor, displayId, inputTargets);
- }
-
// Drop the outside or hover touch windows since we will not care about them
// in the next iteration.
tempTouchState.filterNonAsIsTouchWindows();
@@ -2584,32 +2551,21 @@
void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
int32_t displayId) {
- std::unordered_map<int32_t, std::vector<Monitor>>::const_iterator it =
- mGlobalMonitorsByDisplay.find(displayId);
+ auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
+ if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
- if (it != mGlobalMonitorsByDisplay.end()) {
- const std::vector<Monitor>& monitors = it->second;
- for (const Monitor& monitor : monitors) {
- addMonitoringTargetLocked(monitor, displayId, inputTargets);
+ for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
+ InputTarget target;
+ target.inputChannel = monitor.inputChannel;
+ target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
+ if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
+ target.displayTransform = it->second.transform;
}
+ target.setDefaultPointerTransform(target.displayTransform);
+ inputTargets.push_back(target);
}
}
-void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, int32_t displayId,
- std::vector<InputTarget>& inputTargets) {
- InputTarget target;
- target.inputChannel = monitor.inputChannel;
- target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
- ui::Transform t;
- if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
- const auto& displayTransform = it->second.transform;
- target.displayTransform = displayTransform;
- t = displayTransform;
- }
- target.setDefaultPointerTransform(t);
- inputTargets.push_back(target);
-}
-
bool InputDispatcher::checkInjectionPermission(const sp<WindowInfoHandle>& windowHandle,
const InjectionState* injectionState) {
if (injectionState &&
@@ -3573,15 +3529,7 @@
void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
const CancelationOptions& options) {
- synthesizeCancelationEventsForMonitorsLocked(options, mGlobalMonitorsByDisplay);
- synthesizeCancelationEventsForMonitorsLocked(options, mGestureMonitorsByDisplay);
-}
-
-void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
- const CancelationOptions& options,
- std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
- for (const auto& it : monitorsByDisplay) {
- const std::vector<Monitor>& monitors = it.second;
+ for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
for (const Monitor& monitor : monitors) {
synthesizeCancelationEventsForInputChannelLocked(monitor.inputChannel, options);
}
@@ -5266,22 +5214,16 @@
dump += INDENT "Displays: <none>\n";
}
- if (!mGlobalMonitorsByDisplay.empty() || !mGestureMonitorsByDisplay.empty()) {
- for (auto& it : mGlobalMonitorsByDisplay) {
- const std::vector<Monitor>& monitors = it.second;
- dump += StringPrintf(INDENT "Global monitors in display %" PRId32 ":\n", it.first);
- dumpMonitors(dump, monitors);
- }
- for (auto& it : mGestureMonitorsByDisplay) {
- const std::vector<Monitor>& monitors = it.second;
- dump += StringPrintf(INDENT "Gesture monitors in display %" PRId32 ":\n", it.first);
+ if (!mGlobalMonitorsByDisplay.empty()) {
+ for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
+ dump += StringPrintf(INDENT "Global monitors on display %d:\n", displayId);
dumpMonitors(dump, monitors);
}
} else {
- dump += INDENT "Monitors: <none>\n";
+ dump += INDENT "Global Monitors: <none>\n";
}
- nsecs_t currentTime = now();
+ const nsecs_t currentTime = now();
// Dump recently dispatched or dropped events from oldest to newest.
if (!mRecentQueue.empty()) {
@@ -5439,7 +5381,6 @@
}
Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(int32_t displayId,
- bool isGestureMonitor,
const std::string& name,
int32_t pid) {
std::shared_ptr<InputChannel> serverChannel;
@@ -5468,13 +5409,9 @@
std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
this, std::placeholders::_1, token);
- auto& monitorsByDisplay =
- isGestureMonitor ? mGestureMonitorsByDisplay : mGlobalMonitorsByDisplay;
- monitorsByDisplay[displayId].emplace_back(serverChannel, pid);
+ mGlobalMonitorsByDisplay[displayId].emplace_back(serverChannel, pid);
mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
- ALOGI("Created monitor %s for display %" PRId32 ", gesture=%s, pid=%" PRId32, name.c_str(),
- displayId, toString(isGestureMonitor), pid);
}
// Wake the looper because some connections have changed.
@@ -5522,26 +5459,14 @@
}
void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
- removeMonitorChannelLocked(connectionToken, mGlobalMonitorsByDisplay);
- removeMonitorChannelLocked(connectionToken, mGestureMonitorsByDisplay);
-}
+ for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
+ auto& [displayId, monitors] = *it;
+ std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
+ return monitor.inputChannel->getConnectionToken() == connectionToken;
+ });
-void InputDispatcher::removeMonitorChannelLocked(
- const sp<IBinder>& connectionToken,
- std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) {
- for (auto it = monitorsByDisplay.begin(); it != monitorsByDisplay.end();) {
- std::vector<Monitor>& monitors = it->second;
- const size_t numMonitors = monitors.size();
- for (size_t i = 0; i < numMonitors; i++) {
- if (monitors[i].inputChannel->getConnectionToken() == connectionToken) {
- ALOGI("Erasing monitor %s on display %" PRId32 ", pid=%" PRId32,
- monitors[i].inputChannel->getName().c_str(), it->first, monitors[i].pid);
- monitors.erase(monitors.begin() + i);
- break;
- }
- }
if (monitors.empty()) {
- it = monitorsByDisplay.erase(it);
+ it = mGlobalMonitorsByDisplay.erase(it);
} else {
++it;
}
@@ -5549,81 +5474,45 @@
}
status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
- { // acquire lock
- std::scoped_lock _l(mLock);
+ std::scoped_lock _l(mLock);
- TouchState* statePtr = nullptr;
- std::shared_ptr<InputChannel> requestingChannel;
- int32_t displayId;
- int32_t deviceId;
- const std::optional<int32_t> foundGestureMonitorDisplayId =
- findGestureMonitorDisplayByTokenLocked(token);
-
- // TODO: Optimize this function for pilfering from windows when removing gesture monitors.
- if (foundGestureMonitorDisplayId) {
- // A gesture monitor has requested to pilfer pointers.
- displayId = *foundGestureMonitorDisplayId;
- auto stateIt = mTouchStatesByDisplay.find(displayId);
- if (stateIt == mTouchStatesByDisplay.end()) {
- ALOGW("Failed to pilfer pointers: no pointers on display %" PRId32 ".", displayId);
- return BAD_VALUE;
- }
- statePtr = &stateIt->second;
-
- for (const auto& monitor : statePtr->gestureMonitors) {
- if (monitor.inputChannel->getConnectionToken() == token) {
- requestingChannel = monitor.inputChannel;
- deviceId = statePtr->deviceId;
- }
- }
- } else {
- // Check if a window has requested to pilfer pointers.
- for (auto& [curDisplayId, state] : mTouchStatesByDisplay) {
- const sp<WindowInfoHandle>& windowHandle = state.getWindow(token);
- if (windowHandle != nullptr) {
- displayId = curDisplayId;
- requestingChannel = getInputChannelLocked(token);
- deviceId = state.deviceId;
- statePtr = &state;
- break;
- }
- }
- }
-
- if (requestingChannel == nullptr) {
- ALOGW("Attempted to pilfer pointers from an un-registered channel or invalid token");
- return BAD_VALUE;
- }
- TouchState& state = *statePtr;
- if (!state.down) {
- ALOGW("Attempted to pilfer points from a channel without any on-going pointer streams."
- " Ignoring.");
- return BAD_VALUE;
- }
-
- // Send cancel events to all the input channels we're stealing from.
- CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
- "input channel stole pointer stream");
- options.deviceId = deviceId;
- options.displayId = displayId;
- std::string canceledWindows;
- for (const TouchedWindow& window : state.windows) {
- std::shared_ptr<InputChannel> channel =
- getInputChannelLocked(window.windowHandle->getToken());
- if (channel != nullptr && channel->getConnectionToken() != token) {
- synthesizeCancelationEventsForInputChannelLocked(channel, options);
- canceledWindows += canceledWindows.empty() ? "[" : ", ";
- canceledWindows += channel->getName();
- }
- }
- canceledWindows += canceledWindows.empty() ? "[]" : "]";
- 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;
- state.filterWindowsExcept(token);
+ const std::shared_ptr<InputChannel> requestingChannel = getInputChannelLocked(token);
+ if (!requestingChannel) {
+ ALOGW("Attempted to pilfer pointers from an un-registered channel or invalid token");
+ return BAD_VALUE;
}
+
+ auto [statePtr, windowPtr] = findTouchStateAndWindowLocked(token);
+ if (statePtr == nullptr || windowPtr == nullptr || !statePtr->down) {
+ ALOGW("Attempted to pilfer points from a channel without any on-going pointer streams."
+ " Ignoring.");
+ return BAD_VALUE;
+ }
+
+ TouchState& state = *statePtr;
+
+ // Send cancel events to all the input channels we're stealing from.
+ CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
+ "input channel stole pointer stream");
+ options.deviceId = state.deviceId;
+ options.displayId = state.displayId;
+ std::string canceledWindows;
+ for (const TouchedWindow& window : state.windows) {
+ const std::shared_ptr<InputChannel> channel =
+ getInputChannelLocked(window.windowHandle->getToken());
+ if (channel != nullptr && channel->getConnectionToken() != token) {
+ synthesizeCancelationEventsForInputChannelLocked(channel, options);
+ canceledWindows += canceledWindows.empty() ? "[" : ", ";
+ canceledWindows += channel->getName();
+ }
+ }
+ canceledWindows += canceledWindows.empty() ? "[]" : "]";
+ 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;
+ state.filterWindowsExcept(token);
return OK;
}
@@ -5677,27 +5566,17 @@
} // release lock
}
-std::optional<int32_t> InputDispatcher::findGestureMonitorDisplayByTokenLocked(
- const sp<IBinder>& token) {
- for (const auto& it : mGestureMonitorsByDisplay) {
- const std::vector<Monitor>& monitors = it.second;
+std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
+ for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
for (const Monitor& monitor : monitors) {
if (monitor.inputChannel->getConnectionToken() == token) {
- return it.first;
+ return monitor.pid;
}
}
}
return std::nullopt;
}
-std::optional<int32_t> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
- std::optional<int32_t> gesturePid = findMonitorPidByToken(mGestureMonitorsByDisplay, token);
- if (gesturePid.has_value()) {
- return gesturePid;
- }
- return findMonitorPidByToken(mGlobalMonitorsByDisplay, token);
-}
-
sp<Connection> InputDispatcher::getConnectionLocked(const sp<IBinder>& inputConnectionToken) const {
if (inputConnectionToken == nullptr) {
return nullptr;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index bff6cac..0a70385 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -129,7 +129,6 @@
const std::string& name) override;
void setFocusedWindow(const android::gui::FocusRequest&) override;
base::Result<std::unique_ptr<InputChannel>> createInputMonitor(int32_t displayId,
- bool isGestureMonitor,
const std::string& name,
int32_t pid) override;
status_t removeInputChannel(const sp<IBinder>& connectionToken) override;
@@ -260,21 +259,12 @@
std::unordered_map<sp<IBinder>, sp<Connection>, StrongPointerHash<IBinder>> mConnectionsByToken
GUARDED_BY(mLock);
- // Finds the display ID of the gesture monitor identified by the provided token.
- std::optional<int32_t> findGestureMonitorDisplayByTokenLocked(const sp<IBinder>& token)
- REQUIRES(mLock);
// Find a monitor pid by the provided token.
std::optional<int32_t> findMonitorPidByTokenLocked(const sp<IBinder>& token) REQUIRES(mLock);
// Input channels that will receive a copy of all input events sent to the provided display.
std::unordered_map<int32_t, std::vector<Monitor>> mGlobalMonitorsByDisplay GUARDED_BY(mLock);
- // Input channels that will receive pointer events that start within the corresponding display.
- // These are a bit special when compared to global monitors since they'll cause gesture streams
- // to continue even when there isn't a touched window,and have the ability to steal the rest of
- // the pointer stream in order to claim it for a system gesture.
- std::unordered_map<int32_t, std::vector<Monitor>> mGestureMonitorsByDisplay GUARDED_BY(mLock);
-
const HmacKeyManager mHmacKeyManager;
const std::array<uint8_t, 32> getSignature(const MotionEntry& motionEntry,
const DispatchEntry& dispatchEntry) const;
@@ -530,7 +520,6 @@
sp<android::gui::WindowInfoHandle> mLastHoverWindowHandle GUARDED_BY(mLock);
void cancelEventsForAnrLocked(const sp<Connection>& connection) REQUIRES(mLock);
- nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime) REQUIRES(mLock);
// If a focused application changes, we should stop counting down the "no focused window" time,
// because we will have no way of knowing when the previous application actually added a window.
// This also means that we will miss cases like pulling down notification shade when the
@@ -551,8 +540,6 @@
void addWindowTargetLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
int32_t targetFlags, BitSet32 pointerIds,
std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
- void addMonitoringTargetLocked(const Monitor& monitor, int32_t displayId,
- std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId)
REQUIRES(mLock);
void pokeUserActivityLocked(const EventEntry& eventEntry) REQUIRES(mLock);
@@ -618,9 +605,6 @@
REQUIRES(mLock);
void synthesizeCancelationEventsForMonitorsLocked(const CancelationOptions& options)
REQUIRES(mLock);
- void synthesizeCancelationEventsForMonitorsLocked(
- const CancelationOptions& options,
- std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) REQUIRES(mLock);
void synthesizeCancelationEventsForInputChannelLocked(
const std::shared_ptr<InputChannel>& channel, const CancelationOptions& options)
REQUIRES(mLock);
@@ -646,9 +630,6 @@
// Registration.
void removeMonitorChannelLocked(const sp<IBinder>& connectionToken) REQUIRES(mLock);
- void removeMonitorChannelLocked(
- const sp<IBinder>& connectionToken,
- std::unordered_map<int32_t, std::vector<Monitor>>& monitorsByDisplay) REQUIRES(mLock);
status_t removeInputChannelLocked(const sp<IBinder>& connectionToken, bool notify)
REQUIRES(mLock);
diff --git a/services/inputflinger/dispatcher/TouchState.cpp b/services/inputflinger/dispatcher/TouchState.cpp
index 08c7826..ab86196 100644
--- a/services/inputflinger/dispatcher/TouchState.cpp
+++ b/services/inputflinger/dispatcher/TouchState.cpp
@@ -37,7 +37,6 @@
source = 0;
displayId = ADISPLAY_ID_NONE;
windows.clear();
- gestureMonitors.clear();
}
void TouchState::copyFrom(const TouchState& other) {
@@ -47,7 +46,6 @@
source = other.source;
displayId = other.displayId;
windows = other.windows;
- gestureMonitors = other.gestureMonitors;
}
void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, int32_t targetFlags,
@@ -75,13 +73,6 @@
windows.push_back(touchedWindow);
}
-void TouchState::addGestureMonitors(const std::vector<Monitor>& newMonitors) {
- const size_t newSize = gestureMonitors.size() + newMonitors.size();
- gestureMonitors.reserve(newSize);
- gestureMonitors.insert(std::end(gestureMonitors), std::begin(newMonitors),
- std::end(newMonitors));
-}
-
void TouchState::removeWindowByToken(const sp<IBinder>& token) {
for (size_t i = 0; i < windows.size(); i++) {
if (windows[i].windowHandle->getToken() == token) {
diff --git a/services/inputflinger/dispatcher/TouchState.h b/services/inputflinger/dispatcher/TouchState.h
index 83ca901..e154ed3 100644
--- a/services/inputflinger/dispatcher/TouchState.h
+++ b/services/inputflinger/dispatcher/TouchState.h
@@ -36,15 +36,12 @@
int32_t displayId; // id to the display that currently has a touch, others are rejected
std::vector<TouchedWindow> windows;
- std::vector<Monitor> gestureMonitors;
-
TouchState();
~TouchState();
void reset();
void copyFrom(const TouchState& other);
void addOrUpdateWindow(const sp<android::gui::WindowInfoHandle>& windowHandle,
int32_t targetFlags, BitSet32 pointerIds);
- void addGestureMonitors(const std::vector<Monitor>& monitors);
void removeWindowByToken(const sp<IBinder>& token);
void filterNonAsIsTouchWindows();
void filterWindowsExcept(const sp<IBinder>& token);
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 16a6f16..44ce8ec 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -169,16 +169,14 @@
const std::string& name) = 0;
/**
- * Creates an input channel to be used to monitor input events.
+ * Creates an input channel to be used to monitor all input events on a display.
*
* Each monitor must target a specific display and will only receive input events sent to that
- * display. If the monitor is a gesture monitor, it will only receive pointer events on the
- * targeted display.
+ * display.
*
* This method may be called on any thread (usually by the input manager).
*/
virtual base::Result<std::unique_ptr<InputChannel>> createInputMonitor(int32_t displayId,
- bool gestureMonitor,
const std::string& name,
int32_t pid) = 0;
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 7d8b58f..e2f0343 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -1126,6 +1126,16 @@
expectedFlags);
}
+ void consumeMotionOutsideWithZeroedCoords(int32_t expectedDisplayId = ADISPLAY_ID_DEFAULT,
+ int32_t expectedFlags = 0) {
+ InputEvent* event = consume();
+ ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType());
+ const MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
+ EXPECT_EQ(AMOTION_EVENT_ACTION_OUTSIDE, motionEvent.getActionMasked());
+ EXPECT_EQ(0.f, motionEvent.getRawPointerCoords(0)->getX());
+ EXPECT_EQ(0.f, motionEvent.getRawPointerCoords(0)->getY());
+ }
+
void consumeFocusEvent(bool hasFocus, bool inTouchMode = true) {
ASSERT_NE(mInputReceiver, nullptr)
<< "Cannot consume events from a window with no receiver";
@@ -2768,8 +2778,7 @@
FakeMonitorReceiver(const std::unique_ptr<InputDispatcher>& dispatcher, const std::string name,
int32_t displayId) {
base::Result<std::unique_ptr<InputChannel>> channel =
- dispatcher->createInputMonitor(displayId, false /*isGestureMonitor*/, name,
- MONITOR_PID);
+ dispatcher->createInputMonitor(displayId, name, MONITOR_PID);
mInputReceiver = std::make_unique<FakeInputReceiver>(std::move(*channel), name);
}
@@ -5612,11 +5621,7 @@
touch();
- InputEvent* event = w->consume();
- ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType());
- MotionEvent& motionEvent = static_cast<MotionEvent&>(*event);
- EXPECT_EQ(0.0f, motionEvent.getRawPointerCoords(0)->getX());
- EXPECT_EQ(0.0f, motionEvent.getRawPointerCoords(0)->getY());
+ w->consumeMotionOutsideWithZeroedCoords();
}
TEST_F(InputDispatcherUntrustedTouchesTest, WindowWithOpacityBelowThreshold_AllowsTouch) {
@@ -6424,20 +6429,23 @@
/**
* A spy window can listen for touches outside its touchable region using the WATCH_OUTSIDE_TOUCHES
- * flag.
+ * flag, but it will get zero-ed out coordinates if the foreground has a different owner.
*/
TEST_F(InputDispatcherSpyWindowTest, WatchOutsideTouches) {
auto window = createForeground();
+ window->setOwnerInfo(12, 34);
auto spy = createSpy(WindowInfo::Flag::NOT_TOUCH_MODAL | WindowInfo::Flag::WATCH_OUTSIDE_TOUCH);
+ spy->setOwnerInfo(56, 78);
spy->setFrame(Rect{0, 0, 20, 20});
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {spy, window}}});
// Inject an event outside the spy window's frame and touchable region.
ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
- injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
+ {100, 200}))
<< "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
window->consumeMotionDown();
- spy->consumeMotionOutside();
+ spy->consumeMotionOutsideWithZeroedCoords();
}
/**