Account for per-edge cutout for system gestures

- Currently, the start threshold for all edges is determined by the
  status bar size in the current orientation.  On devices with notches,
  the device overlays override the status bar height to include the
  cutout size, which results in a large threshold on all sides which
  causes touch issues with games (especially now that the game
  dashboard overlay shows with the bars).

  Instead, we can use a standard threshold size for all edges and only
  expand to account for cutouts on each edge respectively.

Bug: 195794974
Test: Without cutout, portrait/landscape app use default threshold
      With cutout, only the edge with the cutout has a non-default
          threshold
Change-Id: Iff7fc98b4fcbb9b78fd5b22bcc07357d7171a9f9
This commit is contained in:
Winson Chung
2021-09-29 00:02:39 -07:00
parent 4589b798fd
commit a40863be3a
4 changed files with 56 additions and 20 deletions

View File

@@ -58,6 +58,9 @@
<!-- How much we expand the touchable region of the status bar below the notch to catch touches
that just start below the notch. -->
<dimen name="display_cutout_touchable_region_size">12dp</dimen>
<!-- The default margin used in immersive mode to capture the start of a swipe gesture from the
edge of the screen to show the system bars. -->
<dimen name="system_gestures_start_threshold">24dp</dimen>
<!-- Height of the bottom navigation bar frame; this is different than navigation_bar_height
where that is the height reported to all the other windows to resize themselves around the

View File

@@ -1743,6 +1743,7 @@
<java-symbol type="dimen" name="navigation_bar_width_car_mode" />
<java-symbol type="dimen" name="status_bar_height" />
<java-symbol type="dimen" name="display_cutout_touchable_region_size" />
<java-symbol type="dimen" name="system_gestures_start_threshold" />
<java-symbol type="dimen" name="quick_qs_offset_height" />
<java-symbol type="drawable" name="ic_jog_dial_sound_off" />
<java-symbol type="drawable" name="ic_jog_dial_sound_on" />

View File

@@ -2998,6 +2998,7 @@ public class DisplayPolicy {
pw.print(" mAllowLockscreenWhenOn="); pw.println(mAllowLockscreenWhenOn);
pw.print(prefix); pw.print("mRemoteInsetsControllerControlsSystemBars=");
pw.println(mDisplayContent.getInsetsPolicy().getRemoteInsetsControllerControlsSystemBars());
mSystemGestures.dump(pw, prefix);
pw.print(prefix); pw.println("Looper state:");
mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + " ");

View File

@@ -16,6 +16,12 @@
package com.android.server.wm;
import static android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM;
import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
import static android.view.DisplayCutout.BOUNDS_POSITION_RIGHT;
import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
@@ -33,6 +39,8 @@ import android.view.MotionEvent;
import android.view.WindowManagerPolicyConstants.PointerEventListener;
import android.widget.OverScroller;
import java.io.PrintWriter;
/**
* Listens for system-wide input gestures, firing callbacks when detected.
* @hide
@@ -54,7 +62,8 @@ class SystemGesturesPointerEventListener implements PointerEventListener {
private final Context mContext;
private final Handler mHandler;
private int mDisplayCutoutTouchableRegionSize;
private int mSwipeStartThreshold;
// The thresholds for each edge of the display
private final Rect mSwipeStartThreshold = new Rect();
private int mSwipeDistanceThreshold;
private final Callbacks mCallbacks;
private final int[] mDownPointerId = new int[MAX_TRACKED_POINTERS];
@@ -66,7 +75,6 @@ class SystemGesturesPointerEventListener implements PointerEventListener {
int screenHeight;
int screenWidth;
private DisplayInfo mTmpDisplayInfo = new DisplayInfo();
private int mDownPointers;
private boolean mSwipeFireable;
private boolean mDebugFireable;
@@ -88,27 +96,41 @@ class SystemGesturesPointerEventListener implements PointerEventListener {
void onConfigurationChanged() {
final Resources r = mContext.getResources();
final int defaultThreshold = r.getDimensionPixelSize(
com.android.internal.R.dimen.system_gestures_start_threshold);
mSwipeStartThreshold.set(defaultThreshold, defaultThreshold, defaultThreshold,
defaultThreshold);
mSwipeDistanceThreshold = defaultThreshold;
final Display display = DisplayManagerGlobal.getInstance()
.getRealDisplay(Display.DEFAULT_DISPLAY);
display.getDisplayInfo(mTmpDisplayInfo);
mSwipeStartThreshold = mTmpDisplayInfo.logicalWidth > mTmpDisplayInfo.logicalHeight
? r.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height_landscape)
: r.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height_portrait);
final DisplayCutout displayCutout = display.getCutout();
if (displayCutout != null) {
final Rect bounds = displayCutout.getBoundingRectTop();
if (!bounds.isEmpty()) {
// Expand swipe start threshold such that we can catch touches that just start below
// the notch area
mDisplayCutoutTouchableRegionSize = r.getDimensionPixelSize(
com.android.internal.R.dimen.display_cutout_touchable_region_size);
mSwipeStartThreshold += mDisplayCutoutTouchableRegionSize;
// Expand swipe start threshold such that we can catch touches that just start beyond
// the notch area
mDisplayCutoutTouchableRegionSize = r.getDimensionPixelSize(
com.android.internal.R.dimen.display_cutout_touchable_region_size);
final Rect[] bounds = displayCutout.getBoundingRectsAll();
if (bounds[BOUNDS_POSITION_LEFT] != null) {
mSwipeStartThreshold.left = Math.max(mSwipeStartThreshold.left,
bounds[BOUNDS_POSITION_LEFT].width() + mDisplayCutoutTouchableRegionSize);
}
if (bounds[BOUNDS_POSITION_TOP] != null) {
mSwipeStartThreshold.top = Math.max(mSwipeStartThreshold.top,
bounds[BOUNDS_POSITION_TOP].height() + mDisplayCutoutTouchableRegionSize);
}
if (bounds[BOUNDS_POSITION_RIGHT] != null) {
mSwipeStartThreshold.right = Math.max(mSwipeStartThreshold.right,
bounds[BOUNDS_POSITION_RIGHT].width() + mDisplayCutoutTouchableRegionSize);
}
if (bounds[BOUNDS_POSITION_BOTTOM] != null) {
mSwipeStartThreshold.bottom = Math.max(mSwipeStartThreshold.bottom,
bounds[BOUNDS_POSITION_BOTTOM].height()
+ mDisplayCutoutTouchableRegionSize);
}
}
mSwipeDistanceThreshold = mSwipeStartThreshold;
if (DEBUG) Slog.d(TAG, "mSwipeStartThreshold=" + mSwipeStartThreshold
+ " mSwipeDistanceThreshold=" + mSwipeDistanceThreshold);
+ " mSwipeDistanceThreshold=" + mSwipeDistanceThreshold);
}
private static <T> T checkNull(String name, T arg) {
@@ -275,22 +297,22 @@ class SystemGesturesPointerEventListener implements PointerEventListener {
final long elapsed = time - mDownTime[i];
if (DEBUG) Slog.d(TAG, "pointer " + mDownPointerId[i]
+ " moved (" + fromX + "->" + x + "," + fromY + "->" + y + ") in " + elapsed);
if (fromY <= mSwipeStartThreshold
if (fromY <= mSwipeStartThreshold.top
&& y > fromY + mSwipeDistanceThreshold
&& elapsed < SWIPE_TIMEOUT_MS) {
return SWIPE_FROM_TOP;
}
if (fromY >= screenHeight - mSwipeStartThreshold
if (fromY >= screenHeight - mSwipeStartThreshold.bottom
&& y < fromY - mSwipeDistanceThreshold
&& elapsed < SWIPE_TIMEOUT_MS) {
return SWIPE_FROM_BOTTOM;
}
if (fromX >= screenWidth - mSwipeStartThreshold
if (fromX >= screenWidth - mSwipeStartThreshold.right
&& x < fromX - mSwipeDistanceThreshold
&& elapsed < SWIPE_TIMEOUT_MS) {
return SWIPE_FROM_RIGHT;
}
if (fromX <= mSwipeStartThreshold
if (fromX <= mSwipeStartThreshold.left
&& x > fromX + mSwipeDistanceThreshold
&& elapsed < SWIPE_TIMEOUT_MS) {
return SWIPE_FROM_LEFT;
@@ -298,6 +320,15 @@ class SystemGesturesPointerEventListener implements PointerEventListener {
return SWIPE_NONE;
}
public void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
final String inner = prefix + " ";
pw.println(prefix + TAG + ":");
pw.print(inner); pw.print("mDisplayCutoutTouchableRegionSize=");
pw.println(mDisplayCutoutTouchableRegionSize);
pw.print(inner); pw.print("mSwipeStartThreshold="); pw.println(mSwipeStartThreshold);
pw.print(inner); pw.print("mSwipeDistanceThreshold="); pw.println(mSwipeDistanceThreshold);
}
private final class FlingGestureDetector extends GestureDetector.SimpleOnGestureListener {
private OverScroller mOverscroller;