Let InputReader set mouse cursor's display.
InputReader was already responsible to bind device/event and display. It
makes sense to further extend it to control the display where mouse
cursor is shown.
Bug: 146385350
Test: Mouse cursor shows up at expected display.
Test: atest inputflinger_tests
Change-Id: Ie7a9546550b70c8834462b06de929472196fe713
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index f69138e..69a75ba 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -189,12 +189,32 @@
// Update the PointerController if viewports changed.
if (mParameters.mode == Parameters::MODE_POINTER) {
- getPolicy()->obtainPointerController(getDeviceId());
+ updatePointerControllerDisplayViewport(*config);
}
bumpGeneration();
}
}
+void CursorInputMapper::updatePointerControllerDisplayViewport(
+ const InputReaderConfiguration& config) {
+ std::optional<DisplayViewport> viewport =
+ config.getDisplayViewportById(config.defaultPointerDisplayId);
+ if (!viewport) {
+ ALOGW("Can't find the designated viewport with ID %" PRId32 " to update cursor input "
+ "mapper. Fall back to default display",
+ config.defaultPointerDisplayId);
+ viewport = config.getDisplayViewportById(ADISPLAY_ID_DEFAULT);
+ }
+
+ if (!viewport) {
+ ALOGE("Still can't find a viable viewport to update cursor input mapper. Skip setting it to"
+ " PointerController.");
+ return;
+ }
+
+ mPointerController->setDisplayViewport(*viewport);
+}
+
void CursorInputMapper::configureParameters() {
mParameters.mode = Parameters::MODE_POINTER;
String8 cursorModeString;
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h
index 77d122a..d56f9be 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.h
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.h
@@ -117,8 +117,9 @@
void dumpParameters(std::string& dump);
void sync(nsecs_t when);
+ void updatePointerControllerDisplayViewport(const InputReaderConfiguration& config);
};
} // namespace android
-#endif // _UI_INPUTREADER_CURSOR_INPUT_MAPPER_H
\ No newline at end of file
+#endif // _UI_INPUTREADER_CURSOR_INPUT_MAPPER_H
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index c80a2dc..b66caca 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -552,9 +552,10 @@
* Determine which DisplayViewport to use.
* 1. If display port is specified, return the matching viewport. If matching viewport not
* found, then return.
- * 2. If a device has associated display, get the matching viewport by either unique id or by
+ * 2. Always use the suggested viewport from WindowManagerService for pointers.
+ * 3. If a device has associated display, get the matching viewport by either unique id or by
* the display type (internal or external).
- * 3. Otherwise, use a non-display viewport.
+ * 4. Otherwise, use a non-display viewport.
*/
std::optional<DisplayViewport> TouchInputMapper::findViewport() {
if (mParameters.hasAssociatedDisplay) {
@@ -564,6 +565,17 @@
return mDevice->getAssociatedViewport();
}
+ if (mDeviceMode == DEVICE_MODE_POINTER) {
+ std::optional<DisplayViewport> viewport =
+ mConfig.getDisplayViewportById(mConfig.defaultPointerDisplayId);
+ if (viewport) {
+ return viewport;
+ } else {
+ ALOGW("Can't find designated display viewport with ID %" PRId32 " for pointers.",
+ mConfig.defaultPointerDisplayId);
+ }
+ }
+
// Check if uniqueDisplayId is specified in idc file.
if (!mParameters.uniqueDisplayId.empty()) {
return mConfig.getDisplayViewportByUniqueId(mParameters.uniqueDisplayId);
@@ -749,6 +761,7 @@
(mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
if (mPointerController == nullptr || viewportChanged) {
mPointerController = getPolicy()->obtainPointerController(getDeviceId());
+ mPointerController->setDisplayViewport(mViewport);
}
} else {
mPointerController.clear();