diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index 1c27c6539b17b..61107b2efc931 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -313,6 +313,7 @@ public class InputManagerService extends IInputManager.Stub private static native void nativeSetFocusedDisplay(long ptr, int displayId); private static native boolean nativeTransferTouchFocus(long ptr, IBinder fromChannelToken, IBinder toChannelToken, boolean isDragDrop); + private static native boolean nativeTransferTouch(long ptr, IBinder destChannelToken); private static native void nativeSetPointerSpeed(long ptr, int speed); private static native void nativeSetShowTouches(long ptr, boolean enabled); private static native void nativeSetInteractive(long ptr, boolean interactive); @@ -675,6 +676,19 @@ public class InputManagerService extends IInputManager.Stub return nativeHasKeys(mPtr, deviceId, sourceMask, keyCodes, keyExists); } + /** + * Transfer the current touch gesture to the provided window. + * + * @param destChannelToken The token of the window or input channel that should receive the + * gesture + * @return True if the transfer succeeded, false if there was no active touch gesture happening + */ + public boolean transferTouch(IBinder destChannelToken) { + // TODO(b/162194035): Replace this with a SPY window + Objects.requireNonNull(destChannelToken, "destChannelToken must not be null."); + return nativeTransferTouch(mPtr, destChannelToken); + } + /** * Creates an input channel that will receive all input from the input dispatcher. * @param inputChannelName The input channel name. diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index b40223f6eed79..a120a42edbfa1 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2682,6 +2682,13 @@ class WindowState extends WindowContainer implements WindowManagerP } } + /** + * Move the touch gesture from the currently touched window on this display to this window. + */ + public boolean transferTouch() { + return mWmService.mInputManager.transferTouch(mInputChannelToken); + } + void disposeInputChannel() { if (mDeadWindowEventReceiver != null) { mDeadWindowEventReceiver.dispose(); diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index cca62b9a7274e..eb9c8dbc7e6b6 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -1834,8 +1834,19 @@ static jboolean nativeTransferTouchFocus(JNIEnv* env, jclass /* clazz */, jlong } } -static void nativeSetPointerSpeed(JNIEnv* /* env */, - jclass /* clazz */, jlong ptr, jint speed) { +static jboolean nativeTransferTouch(JNIEnv* env, jclass /* clazz */, jlong ptr, + jobject destChannelTokenObj) { + sp destChannelToken = ibinderForJavaObject(env, destChannelTokenObj); + + NativeInputManager* im = reinterpret_cast(ptr); + if (im->getInputManager()->getDispatcher()->transferTouch(destChannelToken)) { + return JNI_TRUE; + } else { + return JNI_FALSE; + } +} + +static void nativeSetPointerSpeed(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint speed) { NativeInputManager* im = reinterpret_cast(ptr); im->setPointerSpeed(speed); @@ -2308,6 +2319,7 @@ static const JNINativeMethod gInputManagerMethods[] = { {"nativeSetSystemUiLightsOut", "(JZ)V", (void*)nativeSetSystemUiLightsOut}, {"nativeTransferTouchFocus", "(JLandroid/os/IBinder;Landroid/os/IBinder;Z)Z", (void*)nativeTransferTouchFocus}, + {"nativeTransferTouch", "(JLandroid/os/IBinder;)Z", (void*)nativeTransferTouch}, {"nativeSetPointerSpeed", "(JI)V", (void*)nativeSetPointerSpeed}, {"nativeSetShowTouches", "(JZ)V", (void*)nativeSetShowTouches}, {"nativeSetInteractive", "(JZ)V", (void*)nativeSetInteractive},