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

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

Merge changes from topic "merge-input-config-feature-tm" into tm-dev

* changes:
  Use InputConfig flags in InputWindowHandle API
  WindowInfo: Merge InputConfig and Feature flags
parents 9e1538b8 bdf0cb72
Loading
Loading
Loading
Loading
+68 −33
Original line number Diff line number Diff line
@@ -16,20 +16,57 @@

package android.view;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Matrix;
import android.graphics.Region;
import android.gui.TouchOcclusionMode;
import android.os.IBinder;
import android.os.InputConfig;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
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.
 * Functions as a handle for a window that can receive input, and allows for the behavior of the
 * input window to be configured.
 * @hide
 */
public final class InputWindowHandle {

    /**
     * An internal annotation for all the {@link android.os.InputConfig} flags that can be
     * specified to {@link #inputConfig} to control the behavior of an input window. Only the
     * flags listed here are valid for use in Java.
     *
     * The default flag value is 0, which is what we expect for a normal application window. Adding
     * a flag indicates that the window's behavior deviates from that of a normal application
     * window.
     *
     * The flags are defined as an AIDL enum to keep it in sync with native code.
     * {@link android.os.InputConfig} flags that are not listed here should not be used in Java, and
     * are only meant to be used in native code.
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, value = {
            InputConfig.DEFAULT,
            InputConfig.NO_INPUT_CHANNEL,
            InputConfig.NOT_FOCUSABLE,
            InputConfig.NOT_TOUCHABLE,
            InputConfig.PREVENT_SPLITTING,
            InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER,
            InputConfig.IS_WALLPAPER,
            InputConfig.PAUSE_DISPATCHING,
            InputConfig.TRUSTED_OVERLAY,
            InputConfig.WATCH_OUTSIDE_TOUCH,
            InputConfig.SLIPPERY,
            InputConfig.DISABLE_USER_ACTIVITY,
            InputConfig.SPY,
            InputConfig.INTERCEPTS_STYLUS,
    })
    public @interface InputConfigFlags {}

    // Pointer to the native input window handle.
    // This field is lazily initialized via JNI.
    @SuppressWarnings("unused")
@@ -57,6 +94,7 @@ public final class InputWindowHandle {
    public String name;

    // Window layout params attributes. (WindowManager.LayoutParams)
    // These values do not affect any input configurations. Use {@link #inputConfig} instead.
    public int layoutParamsFlags;
    public int layoutParamsType;

@@ -78,20 +116,9 @@ public final class InputWindowHandle {
    // Window touchable region.
    public final Region touchableRegion = new Region();

    // Window is visible.
    public boolean visible;

    // Window can be focused.
    public boolean focusable;

    // Window has wallpaper.  (window is the current wallpaper target)
    public boolean hasWallpaper;

    // Input event dispatching is paused.
    public boolean paused;

    // Window is trusted overlay.
    public boolean trustedOverlay;
    // Flags that specify the behavior of this input window. See {@link #InputConfigFlags}.
    @InputConfigFlags
    public int inputConfig;

    // What effect this window has on touch occlusion if it lets touches pass through
    // By default windows will block touches if they are untrusted and from a different UID due to
@@ -105,25 +132,21 @@ public final class InputWindowHandle {
    // Owner package of the window
    public String packageName;

    // Window input features.
    public int inputFeatures;

    // Display this input is on.
    // Display this input window is on.
    public int displayId;

    /**
     * Crops the touchable region to the bounds of the surface provided.
     * Crops the {@link #touchableRegion} 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.
     * This can be used in cases where the window should be constrained to the bounds of a parent
     * window. That is, the window should receive touch events outside its window frame, but be
     * limited to its stack bounds, such as in the case of split screen.
     */
    public WeakReference<SurfaceControl> touchableRegionSurfaceControl = new WeakReference<>(null);

    /**
     * Replace {@link touchableRegion} with the bounds of {@link touchableRegionSurfaceControl}. If
     * the handle is {@code null}, the bounds of the surface associated with this window is used
     * Replace {@link #touchableRegion} with the bounds of {@link #touchableRegionSurfaceControl}.
     * If the handle is {@code null}, the bounds of the surface associated with this window is used
     * as the touchable region.
     */
    public boolean replaceTouchableRegionWithCrop;
@@ -147,7 +170,6 @@ public final class InputWindowHandle {
                .append(", frame=[").append(frameLeft).append(",").append(frameTop).append(",")
                        .append(frameRight).append(",").append(frameBottom).append("]")
                .append(", touchableRegion=").append(touchableRegion)
                .append(", visible=").append(visible)
                .append(", scaleFactor=").append(scaleFactor)
                .append(", transform=").append(transform)
                .append(", windowToken=").append(windowToken)
@@ -165,11 +187,11 @@ public final class InputWindowHandle {
    }

    /**
     * Set the window touchable region to the bounds of {@link touchableRegionBounds} ignoring any
     * touchable region provided.
     * Set the window's touchable region to the bounds of {@link #touchableRegionSurfaceControl}
     * and ignore the value of {@link #touchableRegion}.
     *
     * @param bounds surface to set the touchable region to. Set to {@code null} to set the bounds
     * to the current surface.
     * @param bounds surface to set the touchable region to. Set to {@code null} to set the
     *               touchable region as the current surface bounds.
     */
    public void replaceTouchableRegionWithCrop(@Nullable SurfaceControl bounds) {
        setTouchableRegionCrop(bounds);
@@ -195,4 +217,17 @@ public final class InputWindowHandle {
        window = IWindow.Stub.asInterface(windowToken);
        return window;
    }

    /**
     * Set the provided inputConfig flag values.
     * @param inputConfig the flag values to change
     * @param value the provided flag values are set when true, and cleared when false
     */
    public void setInputConfig(@InputConfigFlags int inputConfig, boolean value) {
        if (value) {
            this.inputConfig |= inputConfig;
            return;
        }
        this.inputConfig &= ~inputConfig;
    }
}
+18 −39
Original line number Diff line number Diff line
@@ -106,7 +106,6 @@ import android.graphics.Region;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IInputConstants;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -3360,8 +3359,7 @@ public interface WindowManager extends ViewManager {
         *
         * @hide
         */
        public static final int INPUT_FEATURE_NO_INPUT_CHANNEL =
                IInputConstants.InputFeature.NO_INPUT_CHANNEL;
        public static final int INPUT_FEATURE_NO_INPUT_CHANNEL = 1 << 0;

        /**
         * When this window has focus, does not call user activity for all input events so
@@ -3374,39 +3372,24 @@ public interface WindowManager extends ViewManager {
         * @hide
         */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY =
                IInputConstants.InputFeature.DISABLE_USER_ACTIVITY;
        public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY = 1 << 1;

        /**
         * An input spy window. This window will receive all pointer events within its touchable
         * area, but will will not stop events from being sent to other windows below it in z-order.
         * area, but will not stop events from being sent to other windows below it in z-order.
         * An input event will be dispatched to all spy windows above the top non-spy window at the
         * event's coordinates.
         * @hide
         */
        public static final int INPUT_FEATURE_SPY =
                IInputConstants.InputFeature.SPY;

        /**
         * When used with the window flag {@link #FLAG_NOT_TOUCHABLE}, this window will continue
         * to receive events from a stylus device within its touchable region. All other pointer
         * events, such as from a mouse or touchscreen, will be dispatched to the windows behind it.
         *
         * This input feature has no effect when the window flag {@link #FLAG_NOT_TOUCHABLE} is
         * not set.
         *
         * The window must be a trusted overlay to use this input feature.
         *
         * @see #FLAG_NOT_TOUCHABLE
         *
         * @hide
         */
        public static final int INPUT_FEATURE_INTERCEPTS_STYLUS =
                IInputConstants.InputFeature.INTERCEPTS_STYLUS;
        @RequiresPermission(permission.MONITOR_INPUT)
        public static final int INPUT_FEATURE_SPY = 1 << 2;

        /**
         * An internal annotation for flags that can be specified to {@link #inputFeatures}.
         *
         * NOTE: These are not the same as {@link android.os.InputConfig} flags.
         *
         * @hide
         */
        @Retention(RetentionPolicy.SOURCE)
@@ -3414,18 +3397,18 @@ public interface WindowManager extends ViewManager {
                INPUT_FEATURE_NO_INPUT_CHANNEL,
                INPUT_FEATURE_DISABLE_USER_ACTIVITY,
                INPUT_FEATURE_SPY,
            INPUT_FEATURE_INTERCEPTS_STYLUS,
        })
        public @interface InputFeatureFlags {}
        public @interface InputFeatureFlags {
        }

        /**
         * Control special features of the input subsystem.
         * Control a set of features of the input subsystem that are exposed to the app process.
         *
         * WARNING: Do NOT use {@link android.os.InputConfig} flags! This must be set to flag values
         * included in {@link InputFeatureFlags}.
         *
         * @see #INPUT_FEATURE_NO_INPUT_CHANNEL
         * @see #INPUT_FEATURE_DISABLE_USER_ACTIVITY
         * @see #INPUT_FEATURE_SPY
         * @see #INPUT_FEATURE_INTERCEPTS_STYLUS
         * @hide
         * @see InputFeatureFlags
         */
        @InputFeatureFlags
        @UnsupportedAppUsage
@@ -4845,10 +4828,6 @@ public interface WindowManager extends ViewManager {
                inputFeatures &= ~INPUT_FEATURE_SPY;
                features.add("INPUT_FEATURE_SPY");
            }
            if ((inputFeatures & INPUT_FEATURE_INTERCEPTS_STYLUS) != 0) {
                inputFeatures &= ~INPUT_FEATURE_INTERCEPTS_STYLUS;
                features.add("INPUT_FEATURE_INTERCEPTS_STYLUS");
            }
            if (inputFeatures != 0) {
                features.add(Integer.toHexString(inputFeatures));
            }
+10 −94
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
#include <binder/IPCThreadState.h>
#include <ftl/cast.h>
#include <gui/SurfaceControl.h>
#include <gui/WindowInfo.h>
#include <nativehelper/JNIHelp.h>
@@ -63,16 +64,11 @@ static struct {
    jfieldID surfaceInset;
    jfieldID scaleFactor;
    jfieldID touchableRegion;
    jfieldID visible;
    jfieldID focusable;
    jfieldID hasWallpaper;
    jfieldID paused;
    jfieldID trustedOverlay;
    jfieldID touchOcclusionMode;
    jfieldID ownerPid;
    jfieldID ownerUid;
    jfieldID packageName;
    jfieldID inputFeatures;
    jfieldID inputConfig;
    jfieldID displayId;
    jfieldID replaceTouchableRegionWithCrop;
    WeakRefHandleField touchableRegionSurfaceControl;
@@ -162,64 +158,8 @@ bool NativeInputWindowHandle::updateInfo() {
    mInfo.layoutParamsFlags = flags;
    mInfo.layoutParamsType = type;

    using InputConfig = gui::WindowInfo::InputConfig;
    // Determine the value for each of the InputConfig flags. We rely on a switch statement and
    // -Wswitch-enum to give us a build error if we forget to explicitly handle an InputConfig flag.
    mInfo.inputConfig = InputConfig::NONE;
    InputConfig enumerationStart = InputConfig::NONE;
    switch (enumerationStart) {
        case InputConfig::NONE:
            FALLTHROUGH_INTENDED;
        case InputConfig::NOT_VISIBLE:
            if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.visible) == JNI_FALSE) {
                mInfo.inputConfig |= InputConfig::NOT_VISIBLE;
            }
            FALLTHROUGH_INTENDED;
        case InputConfig::NOT_FOCUSABLE:
            if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.focusable) == JNI_FALSE) {
                mInfo.inputConfig |= InputConfig::NOT_FOCUSABLE;
            }
            FALLTHROUGH_INTENDED;
        case InputConfig::NOT_TOUCHABLE:
            if (flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
                mInfo.inputConfig |= InputConfig::NOT_TOUCHABLE;
            }
            FALLTHROUGH_INTENDED;
        case InputConfig::PREVENT_SPLITTING:
            if (!flags.test(WindowInfo::Flag::SPLIT_TOUCH)) {
                mInfo.inputConfig |= InputConfig::PREVENT_SPLITTING;
            }
            FALLTHROUGH_INTENDED;
        case InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER:
            if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.hasWallpaper) == JNI_TRUE) {
                mInfo.inputConfig |= InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER;
            }
            FALLTHROUGH_INTENDED;
        case InputConfig::IS_WALLPAPER:
            if (type == WindowInfo::Type::WALLPAPER) {
                mInfo.inputConfig |= InputConfig::IS_WALLPAPER;
            }
            FALLTHROUGH_INTENDED;
        case InputConfig::PAUSE_DISPATCHING:
            if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.paused) == JNI_TRUE) {
                mInfo.inputConfig |= InputConfig::PAUSE_DISPATCHING;
            }
            FALLTHROUGH_INTENDED;
        case InputConfig::TRUSTED_OVERLAY:
            if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.trustedOverlay) == JNI_TRUE) {
                mInfo.inputConfig |= InputConfig::TRUSTED_OVERLAY;
            }
            FALLTHROUGH_INTENDED;
        case InputConfig::WATCH_OUTSIDE_TOUCH:
            if (flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
                mInfo.inputConfig |= InputConfig::WATCH_OUTSIDE_TOUCH;
            }
            FALLTHROUGH_INTENDED;
        case InputConfig::SLIPPERY:
            if (flags.test(WindowInfo::Flag::SLIPPERY)) {
                mInfo.inputConfig |= InputConfig::SLIPPERY;
            }
    }
    mInfo.inputConfig = static_cast<gui::WindowInfo::InputConfig>(
            env->GetIntField(obj, gInputWindowHandleClassInfo.inputConfig));

    mInfo.touchOcclusionMode = static_cast<TouchOcclusionMode>(
            env->GetIntField(obj, gInputWindowHandleClassInfo.touchOcclusionMode));
@@ -228,8 +168,6 @@ bool NativeInputWindowHandle::updateInfo() {
    mInfo.ownerUid = env->GetIntField(obj,
            gInputWindowHandleClassInfo.ownerUid);
    mInfo.packageName = getStringField(env, obj, gInputWindowHandleClassInfo.packageName, "<null>");
    mInfo.inputFeatures = static_cast<WindowInfo::Feature>(
            env->GetIntField(obj, gInputWindowHandleClassInfo.inputFeatures));
    mInfo.displayId = env->GetIntField(obj,
            gInputWindowHandleClassInfo.displayId);

@@ -359,17 +297,6 @@ jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowIn
    env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.touchableRegion,
                        regionObj.get());

    using InputConfig = gui::WindowInfo::InputConfig;
    env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.visible,
                         !windowInfo.inputConfig.test(InputConfig::NOT_VISIBLE));
    env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.focusable,
                         !windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::NOT_FOCUSABLE));
    env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.hasWallpaper,
                         windowInfo.inputConfig.test(InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER));
    env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.paused,
                         windowInfo.inputConfig.test(InputConfig::PAUSE_DISPATCHING));
    env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.trustedOverlay,
                         windowInfo.inputConfig.test(InputConfig::TRUSTED_OVERLAY));
    env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.touchOcclusionMode,
                     static_cast<int32_t>(windowInfo.touchOcclusionMode));
    env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.ownerPid, windowInfo.ownerPid);
@@ -377,8 +304,11 @@ jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowIn
    ScopedLocalRef<jstring> packageName(env, env->NewStringUTF(windowInfo.packageName.data()));
    env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.packageName,
                        packageName.get());
    env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.inputFeatures,
                     static_cast<int32_t>(windowInfo.inputFeatures.get()));

    const auto inputConfig = windowInfo.inputConfig.get();
    static_assert(sizeof(inputConfig) == sizeof(int32_t));
    env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.inputConfig,
                     static_cast<int32_t>(inputConfig));

    float transformVals[9];
    for (int i = 0; i < 9; i++) {
@@ -481,19 +411,6 @@ int register_android_view_InputWindowHandle(JNIEnv* env) {
    GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegion, clazz,
            "touchableRegion", "Landroid/graphics/Region;");

    GET_FIELD_ID(gInputWindowHandleClassInfo.visible, clazz,
            "visible", "Z");

    GET_FIELD_ID(gInputWindowHandleClassInfo.focusable, clazz, "focusable", "Z");

    GET_FIELD_ID(gInputWindowHandleClassInfo.hasWallpaper, clazz,
            "hasWallpaper", "Z");

    GET_FIELD_ID(gInputWindowHandleClassInfo.paused, clazz,
            "paused", "Z");

    GET_FIELD_ID(gInputWindowHandleClassInfo.trustedOverlay, clazz, "trustedOverlay", "Z");

    GET_FIELD_ID(gInputWindowHandleClassInfo.touchOcclusionMode, clazz, "touchOcclusionMode", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz,
@@ -505,8 +422,7 @@ int register_android_view_InputWindowHandle(JNIEnv* env) {
    GET_FIELD_ID(gInputWindowHandleClassInfo.packageName, clazz, "packageName",
                 "Ljava/lang/String;");

    GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
            "inputFeatures", "I");
    GET_FIELD_ID(gInputWindowHandleClassInfo.inputConfig, clazz, "inputConfig", "I");

    GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz,
            "displayId", "I");
+3 −7
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.input;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;

import android.os.IBinder;
import android.os.InputConfig;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
import android.view.InputMonitor;
@@ -56,18 +57,13 @@ class GestureMonitorSpyWindow {
        mWindowHandle.name = name;
        mWindowHandle.token = mClientChannel.getToken();
        mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
        mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
        mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
        mWindowHandle.visible = true;
        mWindowHandle.focusable = false;
        mWindowHandle.hasWallpaper = false;
        mWindowHandle.paused = false;
        mWindowHandle.ownerPid = pid;
        mWindowHandle.ownerUid = uid;
        mWindowHandle.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY;
        mWindowHandle.scaleFactor = 1.0f;
        mWindowHandle.trustedOverlay = true;
        mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
        mWindowHandle.inputConfig =
                InputConfig.NOT_FOCUSABLE | InputConfig.SPY | InputConfig.TRUSTED_OVERLAY;

        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
        t.setInputWindowInfo(mInputSurface, mWindowHandle);
+8 −10
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.inputmethod;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;

import android.annotation.NonNull;
import android.os.InputConfig;
import android.os.Process;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
@@ -56,20 +57,17 @@ final class HandwritingEventReceiverSurface {
        mWindowHandle.name = name;
        mWindowHandle.token = mClientChannel.getToken();
        mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
        mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
        mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
        mWindowHandle.visible = true;
        mWindowHandle.focusable = false;
        mWindowHandle.hasWallpaper = false;
        mWindowHandle.paused = false;
        mWindowHandle.ownerPid = Process.myPid();
        mWindowHandle.ownerUid = Process.myUid();
        mWindowHandle.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
                | WindowManager.LayoutParams.INPUT_FEATURE_INTERCEPTS_STYLUS;
        mWindowHandle.scaleFactor = 1.0f;
        mWindowHandle.trustedOverlay = true;
        mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
        mWindowHandle.inputConfig =
                InputConfig.NOT_FOCUSABLE
                        | InputConfig.NOT_TOUCHABLE
                        | InputConfig.SPY
                        | InputConfig.INTERCEPTS_STYLUS
                        | InputConfig.TRUSTED_OVERLAY;

        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
        t.setInputWindowInfo(mInputSurface, mWindowHandle);
@@ -85,7 +83,7 @@ final class HandwritingEventReceiverSurface {
    void startIntercepting(int imePid, int imeUid) {
        mWindowHandle.ownerPid = imePid;
        mWindowHandle.ownerUid = imeUid;
        mWindowHandle.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY;
        mWindowHandle.inputConfig &= ~InputConfig.SPY;

        new SurfaceControl.Transaction()
                .setInputWindowInfo(mInputSurface, mWindowHandle)
Loading