Merge "WM: Use task bounds for modal window touchable region" into sc-v2-dev am: d57f990567 am: be8227dbe2

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16080856

Change-Id: I3b86e428bda16326cc871adac86c640e201490ad
This commit is contained in:
Vishnu Nair
2021-11-23 22:54:19 +00:00
committed by Automerger Merge Worker
3 changed files with 37 additions and 26 deletions

View File

@@ -4790,6 +4790,16 @@ public interface WindowManager extends ViewManager {
return Integer.toString(inputFeature);
}
}
/**
* True if the window should consume all pointer events itself, regardless of whether they
* are inside of the window. If the window is modal, its touchable region will expand to the
* size of its task.
* @hide
*/
public boolean isModal() {
return (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
}
}
/**

View File

@@ -50,7 +50,6 @@ import static com.android.server.wm.WindowManagerService.LOGTAG_INPUT_FOCUS;
import static java.lang.Integer.MAX_VALUE;
import android.annotation.Nullable;
import android.graphics.Rect;
import android.graphics.Region;
import android.os.Handler;
import android.os.IBinder;
@@ -262,9 +261,6 @@ final class InputMonitor {
&& !mDisableWallpaperTouchEvents;
inputWindowHandle.setHasWallpaper(hasWallpaper);
final Rect frame = w.getFrame();
inputWindowHandle.setFrame(frame.left, frame.top, frame.right, frame.bottom);
// Surface insets are hardcoded to be the same in all directions
// and we could probably deprecate the "left/right/top/bottom" concept.
// we avoid reintroducing this concept by just choosing one of them here.
@@ -274,11 +270,19 @@ final class InputMonitor {
// what is on screen to what is actually being touched in the UI.
inputWindowHandle.setScaleFactor(w.mGlobalScale != 1f ? (1f / w.mGlobalScale) : 1f);
final int flags = w.getSurfaceTouchableRegion(mTmpRegion, w.mAttrs.flags);
inputWindowHandle.setTouchableRegion(mTmpRegion);
// Update layout params flags to force the window to be not touch modal. We do this to
// restrict the window's touchable region to the task even if it request touches outside its
// window bounds. An example is a dialog in primary split should get touches outside its
// window within the primary task but should not get any touches going to the secondary
// task.
int flags = w.mAttrs.flags;
if (w.mAttrs.isModal()) {
flags = flags | FLAG_NOT_TOUCH_MODAL;
}
inputWindowHandle.setLayoutParamsFlags(flags);
boolean useSurfaceCrop = false;
boolean useSurfaceBoundsAsTouchRegion = false;
SurfaceControl touchableRegionCrop = null;
final Task task = w.getTask();
if (task != null) {
// TODO(b/165794636): Remove the special case for freeform window once drag resizing is
@@ -290,20 +294,22 @@ final class InputMonitor {
// we need to make sure that these changes in crop are reflected in the input
// windows, and so ensure this flag is set so that the input crop always reflects
// the surface hierarchy.
// TODO(b/168252846): we have some issues with modal-windows, so we need to cross
// that bridge now that we organize full-screen Tasks.
inputWindowHandle.setTouchableRegionCrop(null /* Use this surfaces crop */);
inputWindowHandle.setReplaceTouchableRegionWithCrop(true);
useSurfaceCrop = true;
useSurfaceBoundsAsTouchRegion = true;
if (w.mAttrs.isModal()) {
TaskFragment parent = w.getTaskFragment();
touchableRegionCrop = parent != null ? parent.getSurfaceControl() : null;
}
} else if (task.cropWindowsToRootTaskBounds() && !w.inFreeformWindowingMode()) {
inputWindowHandle.setTouchableRegionCrop(task.getRootTask().getSurfaceControl());
inputWindowHandle.setReplaceTouchableRegionWithCrop(false);
useSurfaceCrop = true;
touchableRegionCrop = task.getRootTask().getSurfaceControl();
}
}
if (!useSurfaceCrop) {
inputWindowHandle.setReplaceTouchableRegionWithCrop(false);
inputWindowHandle.setTouchableRegionCrop(null);
inputWindowHandle.setReplaceTouchableRegionWithCrop(useSurfaceBoundsAsTouchRegion);
inputWindowHandle.setTouchableRegionCrop(touchableRegionCrop);
if (!useSurfaceBoundsAsTouchRegion) {
w.getSurfaceTouchableRegion(mTmpRegion, w.mAttrs);
inputWindowHandle.setTouchableRegion(mTmpRegion);
}
}

View File

@@ -48,7 +48,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_BLUR_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.FLAG_SCALED;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
@@ -2687,10 +2686,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
}
int getSurfaceTouchableRegion(Region region, int flags) {
final boolean modal = (flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
void getSurfaceTouchableRegion(Region region, WindowManager.LayoutParams attrs) {
final boolean modal = attrs.isModal();
if (modal) {
flags |= FLAG_NOT_TOUCH_MODAL;
if (mActivityRecord != null) {
// Limit the outer touch to the activity root task region.
updateRegionForModalActivityWindow(region);
@@ -2722,8 +2720,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (mInvGlobalScale != 1.f) {
region.scale(mInvGlobalScale);
}
return flags;
}
/**
@@ -3559,10 +3555,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
* {@link WindowManager.LayoutParams#FLAG_NOT_TOUCH_MODAL touch modality.}
*/
void getEffectiveTouchableRegion(Region outRegion) {
final boolean modal = (mAttrs.flags & (FLAG_NOT_TOUCH_MODAL | FLAG_NOT_FOCUSABLE)) == 0;
final DisplayContent dc = getDisplayContent();
if (modal && dc != null) {
if (mAttrs.isModal() && dc != null) {
outRegion.set(dc.getBounds());
cropRegionToRootTaskBoundsIfNeeded(outRegion);
subtractTouchExcludeRegionIfNeeded(outRegion);