Fix "Allow/Deny" popup window no respond when enable pointer location
Currently, all buffered layers are included in input occlusion calculations, the overlay window which can't receive input event should also need to explicitly opt out by setting window type. Bug: 158717144 Test: enable pointer location, launch app which would popup grant permission dialog Test: atest WindowInputTests Change-Id: Ic5cc5495d38fe88ee2bee46625bf7d4d4a00a044
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user