DisplayViewport should only have actual viewports (1/2)
If input device is external, TouchInputMapper would be associated with
external display. But if external viewport is not present,
it should fallback to the internal viewport.
Bug: 116850516
Test: atest inputflinger_tests
Change-Id: I044a5c66fd28ae1d032e56791478c4c46f13ef25
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 5d0b894..75095cb 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -254,7 +254,6 @@
}
-
// --- InputReader ---
InputReader::InputReader(const sp<EventHubInterface>& eventHub,
@@ -3446,7 +3445,17 @@
} else {
viewportTypeToUse = ViewportType::VIEWPORT_INTERNAL;
}
- return mConfig.getDisplayViewportByType(viewportTypeToUse);
+
+ std::optional<DisplayViewport> viewport =
+ mConfig.getDisplayViewportByType(viewportTypeToUse);
+ if (!viewport && viewportTypeToUse == ViewportType::VIEWPORT_EXTERNAL) {
+ ALOGW("Input device %s should be associated with external display, "
+ "fallback to internal one for the external viewport is not found.",
+ getDeviceName().c_str());
+ viewport = mConfig.getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL);
+ }
+
+ return viewport;
}
DisplayViewport newViewport;
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 167a624..b5d2090 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -6284,4 +6284,34 @@
ASSERT_EQ(DISPLAY_ID, args.displayId);
}
+/**
+ * Expect fallback to internal viewport if device is external and external viewport is not present.
+ */
+TEST_F(MultiTouchInputMapperTest, Viewports_Fallback) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ prepareAxes(POSITION);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ mDevice->setExternal(true);
+ addMapperAndConfigure(mapper);
+
+ ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper->getSources());
+
+ NotifyMotionArgs motionArgs;
+
+ // Expect the event to be sent to the internal viewport,
+ // because an external viewport is not present.
+ processPosition(mapper, 100, 100);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(ADISPLAY_ID_DEFAULT, motionArgs.displayId);
+
+ // Expect the event to be sent to the external viewport if it is present.
+ prepareSecondaryDisplay(ViewportType::VIEWPORT_EXTERNAL);
+ processPosition(mapper, 100, 100);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
+}
+
} // namespace android