diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl index 49c0f9261c53d..fd3d1ac09e3fe 100644 --- a/core/java/android/hardware/input/IInputManager.aidl +++ b/core/java/android/hardware/input/IInputManager.aidl @@ -168,4 +168,9 @@ interface IInputManager { @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = " + "android.Manifest.permission.BLUETOOTH)") String getInputDeviceBluetoothAddress(int deviceId); + + @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 0cf15f76103e0..702b39b8cdaa5 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -1719,6 +1719,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(); + } + } + /** * Adds a battery listener to be notified about {@link BatteryState} changes for an input * device. The same listener can be registered for multiple input devices. diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 31f63d864f6cd..2e735077d74fa 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -2679,6 +2679,13 @@ public class InputManagerService extends IInputManager.Stub return mNative.getBluetoothAddress(deviceId); } + @EnforcePermission(Manifest.permission.MONITOR_INPUT) + @Override + public void pilferPointers(IBinder inputChannelToken) { + Objects.requireNonNull(inputChannelToken); + mNative.pilferPointers(inputChannelToken); + } + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;