From 46f0571d47fdf4c55364b641cf0906b88d45edcd Mon Sep 17 00:00:00 2001 From: Linus Tufvesson Date: Tue, 4 Jan 2022 11:25:08 +0000 Subject: [PATCH] Make Splash-screens touch opaque cross uid Attempt 2. First attempt broke automated testing that started sending input as soon as the ActivityWindow was created. Since there are a few frames where both the SpalshScreen and the underlaying activity is visible we let touches pass through the SpalshScreen to the underlaying activity. However if the ActivityWindow doesn't exists the touches will be blocked by the ActivityRecordInputSink. This works thanks to the untrusted touches feature in InputDispatcher that blocks touches that are passing through opaque layers if the layers belong to different UIDs. By moving the ActivityRecordInputSink layer to the framework uid and leaving the AcitvityWindow and the splashscreen belonging to the application uid we achive the separtion we want: SpalshScreen are touch opaque cross uid, but are non-touchable within the same uid. Test: atest CtsInputTestCases:android.input.cts.InputShellCommandTest Test: Manually verified that touches will no longer pass through the StartingSurface to the ActivityRecordInputSink Bug: 194480991 Bug: 208659130 Bug: 211748378 Change-Id: I35ee6b40c108607c17dbf65fcd74656aec9c2a87 --- .../wm/shell/startingsurface/StartingSurfaceDrawer.java | 5 ++--- .../com/android/server/wm/ActivityRecordInputSink.java | 8 ++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java index 73f65b08a7eb6..f8902c6d2cc66 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java @@ -269,6 +269,8 @@ public class StartingSurfaceDrawer { // touchable or focusable by the user. We also add in the ALT_FOCUSABLE_IM // flag because we do know that the next window will take input // focus, so we want to get the IME window up on top of us right away. + // Touches will only pass through to the host activity window and will be blocked from + // passing to any other windows. windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; @@ -276,9 +278,6 @@ public class StartingSurfaceDrawer { params.token = appToken; params.packageName = activityInfo.packageName; params.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; - // Setting as trusted overlay to let touches pass through. This is safe because this - // window is controlled by the system. - params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; if (!context.getResources().getCompatibilityInfo().supportsScreen()) { params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW; diff --git a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java index 9353f6dfdabf6..16813485b988f 100644 --- a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java +++ b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java @@ -26,6 +26,7 @@ import android.compat.annotation.Disabled; import android.os.IBinder; import android.os.InputConstants; import android.os.Looper; +import android.os.Process; import android.util.Slog; import android.view.InputChannel; import android.view.InputEvent; @@ -113,14 +114,13 @@ class ActivityRecordInputSink { } private InputWindowHandle createInputWindowHandle() { - InputWindowHandle inputWindowHandle = new InputWindowHandle( - mActivityRecord.getInputApplicationHandle(false), + InputWindowHandle inputWindowHandle = new InputWindowHandle(null, mActivityRecord.getDisplayId()); inputWindowHandle.replaceTouchableRegionWithCrop( mActivityRecord.getParentSurfaceControl()); inputWindowHandle.name = mName; - inputWindowHandle.ownerUid = mActivityRecord.getUid(); - inputWindowHandle.ownerPid = mActivityRecord.getPid(); + inputWindowHandle.ownerUid = Process.myUid(); + inputWindowHandle.ownerPid = Process.myPid(); inputWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;