Loading core/java/android/view/InputWindowHandle.java +42 −1 Original line number Diff line number Diff line Loading @@ -18,9 +18,12 @@ package android.view; import static android.view.Display.INVALID_DISPLAY; import android.annotation.Nullable; import android.graphics.Region; import android.os.IBinder; import java.lang.ref.WeakReference; /** * Functions as a handle for a window that can receive input. * Enables the native input dispatcher to refer indirectly to the window manager's window state. Loading @@ -38,7 +41,7 @@ public final class InputWindowHandle { // The client window. public final IWindow clientWindow; // The token assosciated with the window. // The token associated with the window. public IBinder token; // The window name. Loading Loading @@ -98,6 +101,23 @@ public final class InputWindowHandle { // transports the touch of this window to the display indicated by portalToDisplayId. public int portalToDisplayId = INVALID_DISPLAY; /** * Crops the touchable region to the bounds of the surface provided. * * This can be used in cases where the window is not * {@link android.view.WindowManager#FLAG_NOT_TOUCH_MODAL} but should be constrained to the * bounds of a parent window. That is the window should receive touch events outside its * window but be limited to its stack bounds, such as in the case of split screen. */ public WeakReference<IBinder> touchableRegionCropHandle = new WeakReference<>(null); /** * Replace {@link touchableRegion} with the bounds of {@link touchableRegionCropHandle}. If * the handle is {@code null}, the bounds of the surface associated with this window is used * as the touchable region. */ public boolean replaceTouchableRegionWithCrop; private native void nativeDispose(); public InputWindowHandle(InputApplicationHandle inputApplicationHandle, Loading Loading @@ -127,4 +147,25 @@ public final class InputWindowHandle { super.finalize(); } } /** * Set the window touchable region to the bounds of {@link touchableRegionBounds} ignoring any * touchable region provided. * * @param bounds surface to set the touchable region to. Set to {@code null} to set the bounds * to the current surface. */ public void replaceTouchableRegionWithCrop(@Nullable SurfaceControl bounds) { setTouchableRegionCrop(bounds); replaceTouchableRegionWithCrop = true; } /** * Crop the window touchable region to the bounds of the surface provided. */ public void setTouchableRegionCrop(@Nullable SurfaceControl bounds) { if (bounds != null) { touchableRegionCropHandle = new WeakReference<>(bounds.getHandle()); } } } core/jni/android_hardware_input_InputWindowHandle.cpp +42 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,11 @@ namespace android { struct WeakRefHandleField { jfieldID handle; jmethodID get; }; static struct { jfieldID ptr; jfieldID inputApplicationHandle; Loading @@ -57,6 +62,8 @@ static struct { jfieldID inputFeatures; jfieldID displayId; jfieldID portalToDisplayId; jfieldID replaceTouchableRegionWithCrop; WeakRefHandleField touchableRegionCropHandle; } gInputWindowHandleClassInfo; static Mutex gHandleMutex; Loading Loading @@ -90,6 +97,7 @@ bool NativeInputWindowHandle::updateInfo() { jobject tokenObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.token); if (tokenObj) { mInfo.token = ibinderForJavaObject(env, tokenObj); env->DeleteLocalRef(tokenObj); } else { mInfo.token.clear(); } Loading Loading @@ -161,6 +169,24 @@ bool NativeInputWindowHandle::updateInfo() { env->DeleteLocalRef(inputApplicationHandleObj); } mInfo.replaceTouchableRegionWithCrop = env->GetBooleanField(obj, gInputWindowHandleClassInfo.replaceTouchableRegionWithCrop); jobject handleObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.touchableRegionCropHandle.handle); if (handleObj) { // Promote java weak reference. jobject strongHandleObj = env->CallObjectMethod(handleObj, gInputWindowHandleClassInfo.touchableRegionCropHandle.get); if (strongHandleObj) { mInfo.touchableRegionCropHandle = ibinderForJavaObject(env, strongHandleObj); env->DeleteLocalRef(strongHandleObj); } else { mInfo.touchableRegionCropHandle.clear(); } env->DeleteLocalRef(handleObj); } env->DeleteLocalRef(obj); return true; } Loading Loading @@ -220,6 +246,10 @@ static const JNINativeMethod gInputWindowHandleMethods[] = { var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ LOG_FATAL_IF(! (var), "Unable to find field " fieldName); #define GET_METHOD_ID(var, clazz, methodName, methodSignature) \ var = env->GetMethodID(clazz, methodName, methodSignature); \ LOG_FATAL_IF(! (var), "Unable to find method " methodName); int register_android_view_InputWindowHandle(JNIEnv* env) { int res = jniRegisterNativeMethods(env, "android/view/InputWindowHandle", gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods)); Loading Loading @@ -303,6 +333,18 @@ int register_android_view_InputWindowHandle(JNIEnv* env) { GET_FIELD_ID(gInputWindowHandleClassInfo.portalToDisplayId, clazz, "portalToDisplayId", "I"); GET_FIELD_ID(gInputWindowHandleClassInfo.replaceTouchableRegionWithCrop, clazz, "replaceTouchableRegionWithCrop", "Z"); jclass weakRefClazz; FIND_CLASS(weakRefClazz, "java/lang/ref/Reference"); GET_METHOD_ID(gInputWindowHandleClassInfo.touchableRegionCropHandle.get, weakRefClazz, "get", "()Ljava/lang/Object;") GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegionCropHandle.handle, clazz, "touchableRegionCropHandle", "Ljava/lang/ref/WeakReference;"); return 0; } Loading Loading
core/java/android/view/InputWindowHandle.java +42 −1 Original line number Diff line number Diff line Loading @@ -18,9 +18,12 @@ package android.view; import static android.view.Display.INVALID_DISPLAY; import android.annotation.Nullable; import android.graphics.Region; import android.os.IBinder; import java.lang.ref.WeakReference; /** * Functions as a handle for a window that can receive input. * Enables the native input dispatcher to refer indirectly to the window manager's window state. Loading @@ -38,7 +41,7 @@ public final class InputWindowHandle { // The client window. public final IWindow clientWindow; // The token assosciated with the window. // The token associated with the window. public IBinder token; // The window name. Loading Loading @@ -98,6 +101,23 @@ public final class InputWindowHandle { // transports the touch of this window to the display indicated by portalToDisplayId. public int portalToDisplayId = INVALID_DISPLAY; /** * Crops the touchable region to the bounds of the surface provided. * * This can be used in cases where the window is not * {@link android.view.WindowManager#FLAG_NOT_TOUCH_MODAL} but should be constrained to the * bounds of a parent window. That is the window should receive touch events outside its * window but be limited to its stack bounds, such as in the case of split screen. */ public WeakReference<IBinder> touchableRegionCropHandle = new WeakReference<>(null); /** * Replace {@link touchableRegion} with the bounds of {@link touchableRegionCropHandle}. If * the handle is {@code null}, the bounds of the surface associated with this window is used * as the touchable region. */ public boolean replaceTouchableRegionWithCrop; private native void nativeDispose(); public InputWindowHandle(InputApplicationHandle inputApplicationHandle, Loading Loading @@ -127,4 +147,25 @@ public final class InputWindowHandle { super.finalize(); } } /** * Set the window touchable region to the bounds of {@link touchableRegionBounds} ignoring any * touchable region provided. * * @param bounds surface to set the touchable region to. Set to {@code null} to set the bounds * to the current surface. */ public void replaceTouchableRegionWithCrop(@Nullable SurfaceControl bounds) { setTouchableRegionCrop(bounds); replaceTouchableRegionWithCrop = true; } /** * Crop the window touchable region to the bounds of the surface provided. */ public void setTouchableRegionCrop(@Nullable SurfaceControl bounds) { if (bounds != null) { touchableRegionCropHandle = new WeakReference<>(bounds.getHandle()); } } }
core/jni/android_hardware_input_InputWindowHandle.cpp +42 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,11 @@ namespace android { struct WeakRefHandleField { jfieldID handle; jmethodID get; }; static struct { jfieldID ptr; jfieldID inputApplicationHandle; Loading @@ -57,6 +62,8 @@ static struct { jfieldID inputFeatures; jfieldID displayId; jfieldID portalToDisplayId; jfieldID replaceTouchableRegionWithCrop; WeakRefHandleField touchableRegionCropHandle; } gInputWindowHandleClassInfo; static Mutex gHandleMutex; Loading Loading @@ -90,6 +97,7 @@ bool NativeInputWindowHandle::updateInfo() { jobject tokenObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.token); if (tokenObj) { mInfo.token = ibinderForJavaObject(env, tokenObj); env->DeleteLocalRef(tokenObj); } else { mInfo.token.clear(); } Loading Loading @@ -161,6 +169,24 @@ bool NativeInputWindowHandle::updateInfo() { env->DeleteLocalRef(inputApplicationHandleObj); } mInfo.replaceTouchableRegionWithCrop = env->GetBooleanField(obj, gInputWindowHandleClassInfo.replaceTouchableRegionWithCrop); jobject handleObj = env->GetObjectField(obj, gInputWindowHandleClassInfo.touchableRegionCropHandle.handle); if (handleObj) { // Promote java weak reference. jobject strongHandleObj = env->CallObjectMethod(handleObj, gInputWindowHandleClassInfo.touchableRegionCropHandle.get); if (strongHandleObj) { mInfo.touchableRegionCropHandle = ibinderForJavaObject(env, strongHandleObj); env->DeleteLocalRef(strongHandleObj); } else { mInfo.touchableRegionCropHandle.clear(); } env->DeleteLocalRef(handleObj); } env->DeleteLocalRef(obj); return true; } Loading Loading @@ -220,6 +246,10 @@ static const JNINativeMethod gInputWindowHandleMethods[] = { var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ LOG_FATAL_IF(! (var), "Unable to find field " fieldName); #define GET_METHOD_ID(var, clazz, methodName, methodSignature) \ var = env->GetMethodID(clazz, methodName, methodSignature); \ LOG_FATAL_IF(! (var), "Unable to find method " methodName); int register_android_view_InputWindowHandle(JNIEnv* env) { int res = jniRegisterNativeMethods(env, "android/view/InputWindowHandle", gInputWindowHandleMethods, NELEM(gInputWindowHandleMethods)); Loading Loading @@ -303,6 +333,18 @@ int register_android_view_InputWindowHandle(JNIEnv* env) { GET_FIELD_ID(gInputWindowHandleClassInfo.portalToDisplayId, clazz, "portalToDisplayId", "I"); GET_FIELD_ID(gInputWindowHandleClassInfo.replaceTouchableRegionWithCrop, clazz, "replaceTouchableRegionWithCrop", "Z"); jclass weakRefClazz; FIND_CLASS(weakRefClazz, "java/lang/ref/Reference"); GET_METHOD_ID(gInputWindowHandleClassInfo.touchableRegionCropHandle.get, weakRefClazz, "get", "()Ljava/lang/Object;") GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegionCropHandle.handle, clazz, "touchableRegionCropHandle", "Ljava/lang/ref/WeakReference;"); return 0; } Loading