Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a40863be authored by Winson Chung's avatar Winson Chung
Browse files

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
parent 4589b798
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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" />
+1 −0
Original line number Diff line number Diff line
@@ -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 + "  ");
+51 −20
Original line number Diff line number Diff line
@@ -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,25 +96,39 @@ 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
            // 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);
                mSwipeStartThreshold += mDisplayCutoutTouchableRegionSize;
            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);
    }
@@ -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;