From ef804614e20ec422194704aa7aa8eed15a520954 Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Mon, 29 Nov 2021 09:07:25 -0800 Subject: [PATCH] Add ALLOW_SLIPPERY_TOUCHES permission This permission allows the app to use FLAG_SLIPPERY. This means, windows of the app that has this permission can let touches slip out when the finger moves out of the window bounds. Bug: 157929241 Bug: 206188649 Test: atest FlagSlipperyTest Change-Id: I9ccdfd298f32c36b9c4da68c2e9c355c97dc7593 --- core/res/AndroidManifest.xml | 4 ++++ packages/SystemUI/AndroidManifest.xml | 1 + .../com/android/server/wm/DisplayPolicy.java | 17 --------------- .../server/wm/WindowManagerService.java | 21 ++++++++++++++++++- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 316ea3455c69d..f84623a7691da 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -5845,6 +5845,10 @@ + + + diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 71ab5b617e8e3..4768b27a4f9ec 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -45,7 +45,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCRE import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; -import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; @@ -845,20 +844,6 @@ public class DisplayPolicy { return true; } - /** - * Only trusted overlays are allowed to use FLAG_SLIPPERY. - */ - static int sanitizeFlagSlippery(int flags, int privateFlags, String name) { - if ((flags & FLAG_SLIPPERY) == 0) { - return flags; - } - if ((privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0) { - return flags; - } - Slog.w(TAG, "Removing FLAG_SLIPPERY for non-trusted overlay " + name); - return flags & ~FLAG_SLIPPERY; - } - /** * Sanitize the layout parameters coming from a client. Allows the policy * to do things like ensure that windows of a specific type can't take @@ -942,8 +927,6 @@ public class DisplayPolicy { } else if (mRoundedCornerWindow == win) { mRoundedCornerWindow = null; } - - attrs.flags = sanitizeFlagSlippery(attrs.flags, attrs.privateFlags, win.getName()); } /** diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 23f9c58b9af9f..35ffdf40492cf 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1652,6 +1652,7 @@ 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); win.setRequestedVisibilities(requestedVisibilities); res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid); @@ -2207,6 +2208,7 @@ public class WindowManagerService extends IWindowManager.Stub if (attrs != null) { displayPolicy.adjustWindowParamsLw(win, attrs); win.mToken.adjustWindowParams(win, attrs); + attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), uid, pid); int disableFlags = (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility) & DISABLE_MASK; if (disableFlags != 0 && !hasStatusBarPermission(pid, uid)) { @@ -8219,6 +8221,23 @@ public class WindowManagerService extends IWindowManager.Stub mAtmService.setFocusedTask(task.mTaskId, touchedActivity); } + /** + * You need ALLOW_SLIPPERY_TOUCHES permission to be able to set FLAG_SLIPPERY. + */ + private int sanitizeFlagSlippery(int flags, String windowName, int callingUid, int callingPid) { + if ((flags & FLAG_SLIPPERY) == 0) { + return flags; + } + final int permissionResult = mContext.checkPermission( + android.Manifest.permission.ALLOW_SLIPPERY_TOUCHES, callingPid, callingUid); + if (permissionResult != PackageManager.PERMISSION_GRANTED) { + Slog.w(TAG, "Removing FLAG_SLIPPERY from '" + windowName + + "' because it doesn't have ALLOW_SLIPPERY_TOUCHES permission"); + return flags & ~FLAG_SLIPPERY; + } + return flags; + } + /** * Assigns an InputChannel to a SurfaceControl and configures it to receive * touch input according to it's on-screen geometry. @@ -8258,7 +8277,7 @@ public class WindowManagerService extends IWindowManager.Stub h.setWindowToken(window); h.name = name; - flags = DisplayPolicy.sanitizeFlagSlippery(flags, privateFlags, name); + flags = sanitizeFlagSlippery(flags, name, callingUid, callingPid); final int sanitizedFlags = flags & (LayoutParams.FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE);