Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ddff3f3 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Input: Override touchable region bounds with surface bounds 1/2"

parents 527dde6d 40efb71f
Loading
Loading
Loading
Loading
+42 −1
Original line number Diff line number Diff line
@@ -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.
@@ -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.
@@ -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,
@@ -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());
        }
    }
}
+42 −0
Original line number Diff line number Diff line
@@ -31,6 +31,11 @@

namespace android {

struct WeakRefHandleField {
    jfieldID handle;
    jmethodID get;
};

static struct {
    jfieldID ptr;
    jfieldID inputApplicationHandle;
@@ -57,6 +62,8 @@ static struct {
    jfieldID inputFeatures;
    jfieldID displayId;
    jfieldID portalToDisplayId;
    jfieldID replaceTouchableRegionWithCrop;
    WeakRefHandleField touchableRegionCropHandle;
} gInputWindowHandleClassInfo;

static Mutex gHandleMutex;
@@ -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();
    }
@@ -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;
}
@@ -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));
@@ -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;
}