diff options
| -rw-r--r-- | services/core/java/com/android/server/wm/InputMonitor.java | 59 |
1 files changed, 44 insertions, 15 deletions
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java index 8734b5efa45d..3e88566449fe 100644 --- a/services/core/java/com/android/server/wm/InputMonitor.java +++ b/services/core/java/com/android/server/wm/InputMonitor.java @@ -19,10 +19,13 @@ package com.android.server.wm; import static android.os.Process.myPid; import static android.os.Process.myUid; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; +import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION; import static android.view.WindowManager.INPUT_CONSUMER_PIP; import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION; import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER; +import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; +import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS; @@ -477,12 +480,11 @@ final class InputMonitor { mService.getRecentsAnimationController(); final boolean shouldApplyRecentsInputConsumer = recentsAnimationController != null && recentsAnimationController.shouldApplyInputConsumer(w.mActivityRecord); - if (inputChannel == null || inputWindowHandle == null || w.mRemoved - || (w.cantReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) { + if (inputWindowHandle == null || w.mRemoved) { if (w.mWinAnimator.hasSurface()) { mInputTransaction.setInputWindowInfo( - w.mWinAnimator.mSurfaceController.getClientViewRootSurface(), - mInvalidInputWindow); + w.mWinAnimator.mSurfaceController.getClientViewRootSurface(), + mInvalidInputWindow); } // Skip this window because it cannot possibly receive input. return; @@ -491,9 +493,23 @@ final class InputMonitor { final int flags = w.mAttrs.flags; final int privateFlags = w.mAttrs.privateFlags; final int type = w.mAttrs.type; - final boolean hasFocus = w.isFocused(); final boolean isVisible = w.isVisibleLw(); + // Assign an InputInfo with type to the overlay window which can't receive input event. + // This is used to omit Surfaces from occlusion detection. + if (inputChannel == null + || (w.cantReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) { + if (!w.mWinAnimator.hasSurface()) { + return; + } + populateOverlayInputInfo(inputWindowHandle, w.getName(), type, isVisible); + mInputTransaction.setInputWindowInfo( + w.mWinAnimator.mSurfaceController.getClientViewRootSurface(), + inputWindowHandle); + return; + } + + final boolean hasFocus = w.isFocused(); if (mAddRecentsAnimationInputConsumerHandle && shouldApplyRecentsInputConsumer) { if (recentsAnimationController.updateInputConsumerForApp( mRecentsAnimationInputConsumer.mWindowHandle, hasFocus)) { @@ -555,6 +571,28 @@ final class InputMonitor { } } + // This would reset InputWindowHandle fields to prevent it could be found by input event. + // We need to check if any new field of InputWindowHandle could impact the result. + private static void populateOverlayInputInfo(final InputWindowHandle inputWindowHandle, + final String name, final int type, final boolean isVisible) { + inputWindowHandle.name = name; + inputWindowHandle.layoutParamsType = type; + inputWindowHandle.dispatchingTimeoutNanos = + WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS; + inputWindowHandle.visible = isVisible; + inputWindowHandle.canReceiveKeys = false; + inputWindowHandle.hasFocus = false; + inputWindowHandle.ownerPid = myPid(); + inputWindowHandle.ownerUid = myUid(); + inputWindowHandle.inputFeatures = INPUT_FEATURE_NO_INPUT_CHANNEL; + inputWindowHandle.scaleFactor = 1; + inputWindowHandle.layoutParamsFlags = + FLAG_NOT_TOUCH_MODAL | FLAG_NOT_TOUCHABLE | FLAG_NOT_FOCUSABLE; + inputWindowHandle.portalToDisplayId = INVALID_DISPLAY; + inputWindowHandle.touchableRegion.setEmpty(); + inputWindowHandle.setTouchableRegionCrop(null); + } + /** * Helper function to generate an InputInfo with type SECURE_SYSTEM_OVERLAY. This input * info will not have an input channel or be touchable, but is used to omit Surfaces @@ -564,16 +602,7 @@ final class InputMonitor { static void setTrustedOverlayInputInfo(SurfaceControl sc, SurfaceControl.Transaction t, int displayId, String name) { InputWindowHandle inputWindowHandle = new InputWindowHandle(null, displayId); - inputWindowHandle.name = name; - inputWindowHandle.layoutParamsType = TYPE_SECURE_SYSTEM_OVERLAY; - inputWindowHandle.dispatchingTimeoutNanos = -1; - inputWindowHandle.visible = true; - inputWindowHandle.canReceiveKeys = false; - inputWindowHandle.hasFocus = false; - inputWindowHandle.ownerPid = myPid(); - inputWindowHandle.ownerUid = myUid(); - inputWindowHandle.inputFeatures = INPUT_FEATURE_NO_INPUT_CHANNEL; - inputWindowHandle.scaleFactor = 1; + populateOverlayInputInfo(inputWindowHandle, name, TYPE_SECURE_SYSTEM_OVERLAY, true); t.setInputWindowInfo(sc, inputWindowHandle); } } |