Prevent targeted injection into non-owned windows
Before this CL, it was possible to send ACTION_OUTSIDE events to
non-owned windows even during targeted injection.
However:
1) It's not clear why we actually need this behaviour, and it requires
extra work to support this
2) The block of code that we used to "support" this didn't actually do
anything.
3) During targeted injection, you should only be allowed to affect owned
windows. If you want to affect the entire system, you:
a) Should use global rather than targeted injection
b) Must be very careful to clean up any remaining state that you
cause
In this CL, we remove the block of code that did nothing, and also add
an explicit target pass to remove any non-owned windows.
This should allow further future refactors.
Bug: 211379801
Fixes: 281091008
Test: m inputflinger_tests && $ANDROID_HOST_OUT/nativetest64/inputflinger_tests/inputflinger_tests
Change-Id: Ib065d39ab162188bf2f6e73601e2bb7e2c5d0409
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index f18265f..055fb6f 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -2579,11 +2579,6 @@
if (entry.injectionState != nullptr) {
std::string errs;
for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
- if (touchedWindow.targetFlags.test(InputTarget::Flags::DISPATCH_AS_OUTSIDE)) {
- // Allow ACTION_OUTSIDE events generated by targeted injection to be
- // dispatched to any uid, since the coords will be zeroed out later.
- continue;
- }
const auto err = verifyTargetedInjection(touchedWindow.windowHandle, entry);
if (err) errs += "\n - " + *err;
}
@@ -2636,6 +2631,18 @@
targets);
}
+ // During targeted injection, only allow owned targets to receive events
+ std::erase_if(targets, [&](const InputTarget& target) {
+ LOG_ALWAYS_FATAL_IF(target.windowHandle == nullptr);
+ const auto err = verifyTargetedInjection(target.windowHandle, entry);
+ if (err) {
+ LOG(WARNING) << "Dropping injected event from " << target.windowHandle->getName()
+ << ": " << (*err);
+ return true;
+ }
+ return false;
+ });
+
if (targets.empty()) {
LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription();
outInjectionResult = InputEventInjectionResult::FAILED;
@@ -2838,7 +2845,7 @@
if (displayInfoIt != mDisplayInfos.end()) {
inputTarget.displayTransform = displayInfoIt->second.transform;
} else {
- // DisplayInfo not found for this window on display windowInfo->displayId.
+ // DisplayInfo not found for this window on display windowHandle->getInfo()->displayId.
// TODO(b/198444055): Make this an error message after 'setInputWindows' API is removed.
}
return inputTarget;