From a1da2da8e61b52135059bad22c47525321398279 Mon Sep 17 00:00:00 2001 From: Prabir Pradhan Date: Tue, 1 Jun 2021 17:41:08 -0700 Subject: [PATCH] InputManagerService: Use default display for input injection if not specified When the MotionEvent's displayId is not specified when injecting input events with pointer sources, use the default Context's display. Key, touchpad, and joystick events don't need any transformations, so do not rotate them. This also fixes the improper re-use of getContextForDisplay() in two different scenarios. Bug: 179274888 Test: atest InputShellCommandTest Change-Id: I8221cadbe334f0d0d3ba215b0f54e8decfed508a --- .../server/input/InputManagerService.java | 78 +++++++++++++------ 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 9fcc9a1b79941..2ac21106d9fa8 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -189,7 +189,7 @@ public class InputManagerService extends IInputManager.Stub private final InputManagerHandler mHandler; // Context cache used for loading pointer resources. - private Context mDisplayContext; + private Context mPointerIconDisplayContext; private final File mDoubleTouchGestureEnableFile; @@ -839,21 +839,31 @@ public class InputManagerService extends IInputManager.Stub throw new IllegalArgumentException("mode is invalid"); } if (ENABLE_PER_WINDOW_INPUT_ROTATION) { - if (event instanceof MotionEvent) { - final Context dispCtx = getContextForDisplay(event.getDisplayId()); - final Display display = dispCtx.getDisplay(); + // Motion events that are pointer events or relative mouse events will need to have the + // inverse display rotation applied to them. + if (event instanceof MotionEvent + && (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER) + || event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE))) { + Context displayContext = getContextForDisplay(event.getDisplayId()); + if (displayContext == null) { + displayContext = Objects.requireNonNull( + getContextForDisplay(Display.DEFAULT_DISPLAY)); + } + final Display display = displayContext.getDisplay(); final int rotation = display.getRotation(); if (rotation != ROTATION_0) { final MotionEvent motion = (MotionEvent) event; // Injections are currently expected to be in the space of the injector (ie. - // usually assumed to be post-rotated). Thus we need to unrotate into raw + // usually assumed to be post-rotated). Thus we need to un-rotate into raw // input coordinates for dispatch. final Point sz = new Point(); - display.getRealSize(sz); - if ((rotation % 2) != 0) { - final int tmpX = sz.x; - sz.x = sz.y; - sz.y = tmpX; + if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { + display.getRealSize(sz); + if ((rotation % 2) != 0) { + final int tmpX = sz.x; + sz.x = sz.y; + sz.y = tmpX; + } } motion.applyTransform(MotionEvent.createRotateMatrix( (4 - rotation), sz.x, sz.y)); @@ -1742,6 +1752,11 @@ public class InputManagerService extends IInputManager.Stub /** Clean up input window handles of the given display. */ public void onDisplayRemoved(int displayId) { + if (mPointerIconDisplayContext != null + && mPointerIconDisplayContext.getDisplay().getDisplayId() == displayId) { + mPointerIconDisplayContext = null; + } + nativeDisplayRemoved(mPtr, displayId); } @@ -2971,24 +2986,43 @@ public class InputManagerService extends IInputManager.Stub // Native callback. private PointerIcon getPointerIcon(int displayId) { - return PointerIcon.getDefaultIcon(getContextForDisplay(displayId)); + return PointerIcon.getDefaultIcon(getContextForPointerIcon(displayId)); } - private Context getContextForDisplay(int displayId) { - if (mDisplayContext != null && mDisplayContext.getDisplay().getDisplayId() == displayId) { - return mDisplayContext; - } - - if (mContext.getDisplay().getDisplayId() == displayId) { - mDisplayContext = mContext; - return mDisplayContext; + @NonNull + private Context getContextForPointerIcon(int displayId) { + if (mPointerIconDisplayContext != null + && mPointerIconDisplayContext.getDisplay().getDisplayId() == displayId) { + return mPointerIconDisplayContext; } // Create and cache context for non-default display. - final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); + mPointerIconDisplayContext = getContextForDisplay(displayId); + + // Fall back to default display if the requested displayId does not exist. + if (mPointerIconDisplayContext == null) { + mPointerIconDisplayContext = getContextForDisplay(Display.DEFAULT_DISPLAY); + } + return mPointerIconDisplayContext; + } + + @Nullable + private Context getContextForDisplay(int displayId) { + if (displayId == Display.INVALID_DISPLAY) { + return null; + } + if (mContext.getDisplay().getDisplayId() == displayId) { + return mContext; + } + + final DisplayManager displayManager = Objects.requireNonNull( + mContext.getSystemService(DisplayManager.class)); final Display display = displayManager.getDisplay(displayId); - mDisplayContext = mContext.createDisplayContext(display); - return mDisplayContext; + if (display == null) { + return null; + } + + return mContext.createDisplayContext(display); } // Native callback.