From 1693a3132fb6d1533388f3a286031f70b108a0a7 Mon Sep 17 00:00:00 2001 From: Prabir Pradhan Date: Fri, 4 Nov 2022 22:28:43 +0000 Subject: [PATCH] InputManager: Expose pilferPointers API We can only migrate existing gesture monitors to spy windows if we allow pilfering from these spy windows. Expose the pilferPointers API so that other processes can pilfer from arbitrary input windows. The pilferPointers API is guarded with the MONITOR_INPUT signature permission. Bug: 257977069 Test: Build Change-Id: Ice43ed420502ce3b5e5d37d9ac9e810a51ed07bc Merged-In: Ice43ed420502ce3b5e5d37d9ac9e810a51ed07bc --- .../android/hardware/input/IInputManager.aidl | 5 ++++ .../android/hardware/input/InputManager.java | 28 +++++++++++++++++++ .../server/input/InputManagerService.java | 9 ++++++ 3 files changed, 42 insertions(+) diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index a645ae4a3964e..3a07bb0d77362 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -160,4 +160,9 @@ interface IInputManager { void registerBatteryListener(int deviceId, IInputDeviceBatteryListener listener); void unregisterBatteryListener(int deviceId, IInputDeviceBatteryListener listener); + + @EnforcePermission("MONITOR_INPUT") + @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + + "android.Manifest.permission.MONITOR_INPUT)") + void pilferPointers(IBinder inputChannelToken); } diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index 97812cea23e18..1cf3bb548a7e8 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -1818,6 +1818,34 @@ public final class InputManager { } } + /** + * Pilfer pointers from an input channel. + * + * Takes all the current pointer event streams that are currently being sent to the given + * input channel and generates appropriate cancellations for all other windows that are + * receiving these pointers. + * + * This API is intended to be used in conjunction with spy windows. When a spy window pilfers + * pointers, the foreground windows and all other spy windows that are receiving any of the + * pointers that are currently being dispatched to the pilfering window will have those pointers + * canceled. Only the pilfering window will continue to receive events for the affected pointers + * until the pointer is lifted. + * + * This method should be used with caution as unexpected pilfering can break fundamental user + * interactions. + * + * @see android.os.InputConfig#SPY + * @hide + */ + @RequiresPermission(Manifest.permission.MONITOR_INPUT) + public void pilferPointers(IBinder inputChannelToken) { + try { + mIm.pilferPointers(inputChannelToken); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Removes a previously registered battery listener for an input device. * @see #addInputDeviceBatteryListener(int, Executor, InputDeviceBatteryListener) diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 91d5698123e8f..89e0d0510cf89 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -18,6 +18,8 @@ package com.android.server.input; import static android.view.KeyEvent.KEYCODE_UNKNOWN; +import android.Manifest; +import android.annotation.EnforcePermission; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManagerInternal; @@ -2678,6 +2680,13 @@ public class InputManagerService extends IInputManager.Stub mNative.cancelCurrentTouch(); } + @EnforcePermission(Manifest.permission.MONITOR_INPUT) + @Override + public void pilferPointers(IBinder inputChannelToken) { + Objects.requireNonNull(inputChannelToken); + mNative.pilferPointers(inputChannelToken); + } + @Override public void registerBatteryListener(int deviceId, IInputDeviceBatteryListener listener) { Objects.requireNonNull(listener);