No position information for outside touches
When a window registers to listen for outside touches, it doesn't need
the position information for touches that land outside of its activity
for normal use cases.
This patch uses the foreground window's UID as a filter to determine
whether to pass the position information. This will allow applications
to continue to rely on touch information for inputs that were directed
at one of its other windows.
Bug: 4541250
Change-Id: If16eb1ec8404b797d991859eef55ac0a20a355a3
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 4c6098d..eff65c2 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -1464,6 +1464,23 @@
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) {
+ const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
+ const int32_t foregroundWindowUid = foregroundWindow->ownerUid;
+ for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
+ const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
+ if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
+ const InputWindow* inputWindow = touchedWindow.window;
+ if (inputWindow->ownerUid != foregroundWindowUid) {
+ mTempTouchState.addOrUpdateWindow(inputWindow,
+ InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
+ }
+ }
+ }
+ }
+
// Ensure all touched foreground windows are ready for new input.
for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
@@ -1987,7 +2004,8 @@
// Set the X and Y offset depending on the input source.
float xOffset, yOffset, scaleFactor;
- if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
+ if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER
+ && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
scaleFactor = dispatchEntry->scaleFactor;
xOffset = dispatchEntry->xOffset * scaleFactor;
yOffset = dispatchEntry->yOffset * scaleFactor;
@@ -2002,6 +2020,14 @@
xOffset = 0.0f;
yOffset = 0.0f;
scaleFactor = 1.0f;
+
+ // We don't want the dispatch target to know.
+ if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
+ for (size_t i = 0; i < motionEntry->pointerCount; i++) {
+ scaledCoords[i].clear();
+ }
+ usingCoords = scaledCoords;
+ }
}
// Update the connection's input state.
@@ -2030,9 +2056,11 @@
MotionSample* nextMotionSample = firstMotionSample->next;
for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
if (usingCoords == scaledCoords) {
- for (size_t i = 0; i < motionEntry->pointerCount; i++) {
- scaledCoords[i] = nextMotionSample->pointerCoords[i];
- scaledCoords[i].scale(scaleFactor);
+ if (!(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
+ for (size_t i = 0; i < motionEntry->pointerCount; i++) {
+ scaledCoords[i] = nextMotionSample->pointerCoords[i];
+ scaledCoords[i].scale(scaleFactor);
+ }
}
} else {
usingCoords = nextMotionSample->pointerCoords;
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 37cef90..39d4aeb 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -96,6 +96,12 @@
/* This flag indicates that a motion event is being split across multiple windows. */
FLAG_SPLIT = 1 << 2,
+ /* This flag indicates that the pointer coordinates dispatched to the application
+ * will be zeroed out to avoid revealing information to an application. This is
+ * used in conjunction with FLAG_DISPATCH_AS_OUTSIDE to prevent apps not sharing
+ * the same UID from watching all touches. */
+ FLAG_ZERO_COORDS = 1 << 3,
+
/* This flag indicates that the event should be sent as is.
* Should always be set unless the event is to be transmuted. */
FLAG_DISPATCH_AS_IS = 1 << 8,