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

Commit f1782de8 authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

Add an input feature for a spy window

Sanitize the input feature flags coming from apps' processes so that
apps cannot add spy windows.

Bug: 162194035
Test: manual
Change-Id: Ib540c5cf4d307f6bac2b417a6e438d6a4c29bedc
parent ca3f2772
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -3354,6 +3354,15 @@ public interface WindowManager extends ViewManager {
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004;

        /**
         * 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.
         * 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 = 0x00000020;

        /**
         * An internal annotation for flags that can be specified to {@link #inputFeatures}.
         *
+23 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY;
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
@@ -1653,6 +1654,8 @@ public class WindowManagerService extends IWindowManager.Stub
            final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
            displayPolicy.adjustWindowParamsLw(win, win.mAttrs);
            attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), callingUid, callingPid);
            attrs.inputFeatures = sanitizeSpyWindow(attrs.inputFeatures, win.getName(), callingUid,
                    callingPid);
            win.setRequestedVisibilities(requestedVisibilities);

            res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid);
@@ -2209,6 +2212,8 @@ public class WindowManagerService extends IWindowManager.Stub
                displayPolicy.adjustWindowParamsLw(win, attrs);
                win.mToken.adjustWindowParams(win, attrs);
                attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), uid, pid);
                attrs.inputFeatures = sanitizeSpyWindow(attrs.inputFeatures, win.getName(), uid,
                        pid);
                int disableFlags =
                        (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility) & DISABLE_MASK;
                if (disableFlags != 0 && !hasStatusBarPermission(pid, uid)) {
@@ -8238,6 +8243,23 @@ public class WindowManagerService extends IWindowManager.Stub
        return flags;
    }

    /**
     * You need MONITOR_INPUT permission to be able to set INPUT_FEATURE_SPY.
     */
    private int sanitizeSpyWindow(int inputFeatures, String windowName, int callingUid,
            int callingPid) {
        if ((inputFeatures & INPUT_FEATURE_SPY) == 0) {
            return inputFeatures;
        }
        final int permissionResult = mContext.checkPermission(
                permission.MONITOR_INPUT, callingPid, callingUid);
        if (permissionResult != PackageManager.PERMISSION_GRANTED) {
            throw new IllegalArgumentException("Cannot use INPUT_FEATURE_SPY from '" + windowName
                    + "' because it doesn't the have MONITOR_INPUT permission");
        }
        return inputFeatures;
    }

    /**
     * Assigns an InputChannel to a SurfaceControl and configures it to receive
     * touch input according to it's on-screen geometry.
@@ -8291,6 +8313,7 @@ public class WindowManagerService extends IWindowManager.Stub
        h.ownerUid = callingUid;
        h.ownerPid = callingPid;

        // Do not allow any input features to be set without sanitizing them first.
        h.inputFeatures = 0;

        if (region == null) {