diff options
5 files changed, 78 insertions, 17 deletions
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java index 9db1060abad4..de5fc7f3e358 100644 --- a/core/java/android/view/InputWindowHandle.java +++ b/core/java/android/view/InputWindowHandle.java @@ -67,6 +67,7 @@ public final class InputWindowHandle { InputConfig.SPY, InputConfig.INTERCEPTS_STYLUS, InputConfig.CLONE, + InputConfig.SENSITIVE_FOR_TRACING, }) public @interface InputConfigFlags {} diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 56667398265e..0d2aae0d3690 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -4370,6 +4370,22 @@ public interface WindowManager extends ViewManager { public static final int INPUT_FEATURE_SPY = 1 << 2; /** + * Input feature used to indicate that this window is sensitive for tracing. + * <p> + * A window that uses {@link LayoutParams#FLAG_SECURE} will automatically be treated as + * a sensitive for input tracing, but this input feature can be set on windows that don't + * set FLAG_SECURE. The tracing configuration will determine how these sensitive events + * are eventually traced. + * <p> + * This can only be set for trusted system overlays. + * <p> + * Note: Input tracing is only available on userdebug and eng builds. + * + * @hide + */ + public static final int INPUT_FEATURE_SENSITIVE_FOR_TRACING = 1 << 3; + + /** * An internal annotation for flags that can be specified to {@link #inputFeatures}. * * NOTE: These are not the same as {@link android.os.InputConfig} flags. @@ -4381,6 +4397,7 @@ public interface WindowManager extends ViewManager { INPUT_FEATURE_NO_INPUT_CHANNEL, INPUT_FEATURE_DISABLE_USER_ACTIVITY, INPUT_FEATURE_SPY, + INPUT_FEATURE_SENSITIVE_FOR_TRACING, }) public @interface InputFeatureFlags { } diff --git a/services/core/java/com/android/server/wm/InputConfigAdapter.java b/services/core/java/com/android/server/wm/InputConfigAdapter.java index 2dcde4ee2ba8..ef1b02d8accc 100644 --- a/services/core/java/com/android/server/wm/InputConfigAdapter.java +++ b/services/core/java/com/android/server/wm/InputConfigAdapter.java @@ -56,7 +56,10 @@ class InputConfigAdapter { InputConfig.DISABLE_USER_ACTIVITY, false /* inverted */), new FlagMapping( LayoutParams.INPUT_FEATURE_SPY, - InputConfig.SPY, false /* inverted */)); + InputConfig.SPY, false /* inverted */), + new FlagMapping( + LayoutParams.INPUT_FEATURE_SENSITIVE_FOR_TRACING, + InputConfig.SENSITIVE_FOR_TRACING, false /* inverted */)); @InputConfigFlags private static final int INPUT_FEATURE_TO_CONFIG_MASK = diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f09ef9643433..34fcb4d037bc 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -65,6 +65,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_SENSITIVE_FOR_TRACING; 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; @@ -1718,8 +1719,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); + attrs.inputFeatures = sanitizeInputFeatures(attrs.inputFeatures, win.getName(), + callingUid, callingPid, win.isTrustedOverlay()); win.setRequestedVisibleTypes(requestedVisibleTypes); res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid); @@ -2289,8 +2290,8 @@ public class WindowManagerService extends IWindowManager.Stub if (attrs != null) { displayPolicy.adjustWindowParamsLw(win, attrs); attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), uid, pid); - attrs.inputFeatures = sanitizeSpyWindow(attrs.inputFeatures, win.getName(), uid, - pid); + attrs.inputFeatures = sanitizeInputFeatures(attrs.inputFeatures, win.getName(), uid, + pid, win.isTrustedOverlay()); int disableFlags = (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility) & DISABLE_MASK; if (disableFlags != 0 && !hasStatusBarPermission(pid, uid)) { @@ -9105,18 +9106,26 @@ public class WindowManagerService extends IWindowManager.Stub } /** - * You need MONITOR_INPUT permission to be able to set INPUT_FEATURE_SPY. + * Ensure the caller has the right permissions to be able to set the requested input features. */ - private int sanitizeSpyWindow(int inputFeatures, String windowName, int callingUid, - int callingPid) { - if ((inputFeatures & INPUT_FEATURE_SPY) == 0) { - return inputFeatures; + private int sanitizeInputFeatures(int inputFeatures, String windowName, int callingUid, + int callingPid, boolean isTrustedOverlay) { + // You need MONITOR_INPUT permission to be able to set INPUT_FEATURE_SPY. + if ((inputFeatures & INPUT_FEATURE_SPY) != 0) { + 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"); + } } - 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"); + + // You can only use INPUT_FEATURE_SENSITIVE_FOR_TRACING on a trusted overlay. + if ((inputFeatures & INPUT_FEATURE_SENSITIVE_FOR_TRACING) != 0 && !isTrustedOverlay) { + Slog.w(TAG, "Removing INPUT_FEATURE_SENSITIVE_FOR_TRACING from '" + windowName + + "' because it isn't a trusted overlay"); + return inputFeatures & ~INPUT_FEATURE_SENSITIVE_FOR_TRACING; } return inputFeatures; } @@ -9194,8 +9203,10 @@ public class WindowManagerService extends IWindowManager.Stub h.setWindowToken(clientToken); h.name = name; + final boolean isTrustedOverlay = (privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0; flags = sanitizeFlagSlippery(flags, name, callingUid, callingPid); - inputFeatures = sanitizeSpyWindow(inputFeatures, name, callingUid, callingPid); + inputFeatures = sanitizeInputFeatures(inputFeatures, name, callingUid, callingPid, + isTrustedOverlay); final int sanitizedLpFlags = (flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE)) @@ -9232,7 +9243,7 @@ public class WindowManagerService extends IWindowManager.Stub final SurfaceControl.Transaction t = mTransactionFactory.get(); // Check private trusted overlay flag to set trustedOverlay field of input window handle. - h.setTrustedOverlay(t, surface, (privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0); + h.setTrustedOverlay(t, surface, isTrustedOverlay); t.setInputWindowInfo(surface, h); t.apply(); t.close(); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java index e37da2040850..e113547ede3c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -28,6 +28,7 @@ import static android.view.Display.INVALID_DISPLAY; import static android.view.flags.Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; +import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SENSITIVE_FOR_TRACING; import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY; import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; @@ -1115,6 +1116,34 @@ public class WindowManagerServiceTests extends WindowTestsBase { argThat(h -> (h.inputConfig & InputConfig.SPY) == InputConfig.SPY)); } + @Test + public void testUpdateInputChannel_sanitizeInputFeatureSensitive_forUntrustedWindows() { + final Session session = mock(Session.class); + final int callingUid = Process.FIRST_APPLICATION_UID; + final int callingPid = 1234; + final SurfaceControl surfaceControl = mock(SurfaceControl.class); + final IBinder window = new Binder(); + final InputTransferToken inputTransferToken = mock(InputTransferToken.class); + + final InputChannel inputChannel = new InputChannel(); + mWm.grantInputChannel(session, callingUid, callingPid, DEFAULT_DISPLAY, surfaceControl, + window, null /* hostInputToken */, FLAG_NOT_FOCUSABLE, 0 /* privateFlags */, + INPUT_FEATURE_SENSITIVE_FOR_TRACING, TYPE_APPLICATION, null /* windowToken */, + inputTransferToken, + "TestInputChannel", inputChannel); + verify(mTransaction).setInputWindowInfo( + eq(surfaceControl), + argThat(h -> (h.inputConfig & InputConfig.SENSITIVE_FOR_TRACING) == 0)); + + mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl, + FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, + INPUT_FEATURE_SENSITIVE_FOR_TRACING, + null /* region */); + verify(mTransaction).setInputWindowInfo( + eq(surfaceControl), + argThat(h -> (h.inputConfig & InputConfig.SENSITIVE_FOR_TRACING) != 0)); + } + @RequiresFlagsDisabled(Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER) @Test public void testDrawMagnifiedViewport() { |