Make sure that touches are within the surface.
Changed TouchInputMapper::isPointInsideSurface should check the
surface range instead of physical frame range.
Test: atest inputflinger_tests
Test: enable emulator, open second display with landscape mode, try
YouTube and changed it to portrait mode.
Bug: 139805619
Change-Id: Id4ad7053acac33f49363442bd5f710f8023d5190
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index 6bd0ea9..34603b9 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -3621,9 +3621,9 @@
const float scaledX = x * mXScale;
const float scaledY = y * mYScale;
return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue &&
- scaledX >= mPhysicalLeft && scaledX <= mPhysicalLeft + mPhysicalWidth &&
+ scaledX >= mSurfaceLeft && scaledX <= mSurfaceLeft + mSurfaceWidth &&
y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue &&
- scaledY >= mPhysicalTop && scaledY <= mPhysicalTop + mPhysicalHeight;
+ scaledY >= mSurfaceTop && scaledY <= mSurfaceTop + mSurfaceHeight;
}
const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(int32_t x, int32_t y) {
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 2153108..31b1652 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -202,6 +202,20 @@
mConfig.setDisplayViewports(mViewports);
}
+ bool updateViewport(const DisplayViewport& viewport) {
+ size_t count = mViewports.size();
+ for (size_t i = 0; i < count; i++) {
+ const DisplayViewport& currentViewport = mViewports[i];
+ if (currentViewport.displayId == viewport.displayId) {
+ mViewports[i] = viewport;
+ mConfig.setDisplayViewports(mViewports);
+ return true;
+ }
+ }
+ // no viewport found.
+ return false;
+ }
+
void addExcludedDeviceName(const std::string& deviceName) {
mConfig.excludedDeviceNames.push_back(deviceName);
}
@@ -6593,4 +6607,30 @@
ASSERT_EQ(SECONDARY_DISPLAY_ID, args.displayId);
}
+/**
+ * Test touch should not work if outside of surface.
+ */
+TEST_F(MultiTouchInputMapperTest, Viewports_SurfaceRange) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ // Let surface be different from physical display.
+ std::optional<DisplayViewport> internalViewport =
+ mFakePolicy->getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL);
+ internalViewport->logicalLeft = internalViewport->physicalTop + 20;
+ internalViewport->logicalTop = internalViewport->physicalRight + 20;
+ internalViewport->logicalRight = internalViewport->physicalRight - 20;
+ internalViewport->logicalBottom = internalViewport->physicalBottom - 20;
+ mFakePolicy->updateViewport(internalViewport.value());
+
+ prepareAxes(POSITION);
+ addMapperAndConfigure(mapper);
+
+ int32_t rawX = 10;
+ int32_t rawY = 10;
+ processPosition(mapper, rawX, rawY);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+}
+
} // namespace android