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
This commit is contained in:
Prabir Pradhan
2021-11-19 06:47:32 -08:00
parent ca3f277231
commit f1782de84a
2 changed files with 32 additions and 0 deletions

View File

@@ -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}.
*

View File

@@ -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) {