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

Commit 9a22363a authored by Matthew Ng's avatar Matthew Ng
Browse files

Added two touch slops for easier home press (1/3)

The first slop starts the drag either for quick step or scrub. At this
point either launcher can animate swipe up or the home button moves for
scrub, however the home button is still active and can be pressed or
long pressed. The second slop is for activating quick step or scrub.
Similar to before when an operation has activated, the home button
cannot be pressed or long pressed. This allows the home button to have a
larger area to be clicked.

Change-Id: I0a3dd2b5e0f41748a7ba9ebb6241283291995228
Fixes: 76430825
Test: scrub or swipe up
parent a1fc0255
Loading
Loading
Loading
Loading
+21 −1
Original line number Diff line number Diff line
@@ -17,10 +17,27 @@
package com.android.systemui.shared.system;

import android.annotation.IntDef;
import android.content.Context;
import android.content.res.Resources;
import android.util.DisplayMetrics;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import sun.misc.Resource;

public class NavigationBarCompat {
    /**
     * Touch slopes and thresholds for quick step operations. Drag slop is the point where the
     * home button press/long press over are ignored and will start to drag when exceeded and the
     * touch slop is when the respected operation will occur when exceeded. Touch slop must be
     * larger than the drag slop.
     */
    public static final int QUICK_STEP_DRAG_SLOP_PX = convertDpToPixel(10);
    public static final int QUICK_SCRUB_DRAG_SLOP_PX = convertDpToPixel(20);
    public static final int QUICK_STEP_TOUCH_SLOP_PX = convertDpToPixel(40);
    public static final int QUICK_SCRUB_TOUCH_SLOP_PX = convertDpToPixel(35);

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({HIT_TARGET_NONE, HIT_TARGET_BACK, HIT_TARGET_HOME, HIT_TARGET_OVERVIEW})
    public @interface HitTarget{}
@@ -42,7 +59,6 @@ public class NavigationBarCompat {
     * Interaction type: whether the gesture to swipe up from the navigation bar will trigger
     * launcher to show overview
     */

    public static final int FLAG_DISABLE_SWIPE_UP = 0x1;
    /**
     * Interaction type: enable quick scrub interaction on the home button
@@ -58,4 +74,8 @@ public class NavigationBarCompat {
     * Interaction type: show/hide the back button while this service is connected to launcher
     */
    public static final int FLAG_HIDE_BACK_BUTTON = 0x8;

    private static int convertDpToPixel(float dp){
        return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
    }
}
+58 −36
Original line number Diff line number Diff line
@@ -51,6 +51,10 @@ import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
import static com.android.systemui.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
import static com.android.systemui.OverviewProxyService.TAG_OPS;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_SCRUB_DRAG_SLOP_PX;
import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_SCRUB_TOUCH_SLOP_PX;
import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_STEP_DRAG_SLOP_PX;
import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_STEP_TOUCH_SLOP_PX;

/**
 * Class to detect gestures on the navigation bar and implement quick scrub.
@@ -69,6 +73,7 @@ public class QuickStepController implements GestureHelper {
    private float mTranslation;
    private int mTouchDownX;
    private int mTouchDownY;
    private boolean mDragScrubActive;
    private boolean mDragPositive;
    private boolean mIsVertical;
    private boolean mIsRTL;
@@ -82,7 +87,6 @@ public class QuickStepController implements GestureHelper {
    private final Interpolator mQuickScrubEndInterpolator = new DecelerateInterpolator();
    private final Rect mTrackRect = new Rect();
    private final Paint mTrackPaint = new Paint();
    private final int mScrollTouchSlop;
    private final OverviewProxyService mOverviewEventSender;
    private final int mTrackThickness;
    private final int mTrackPadding;
@@ -115,6 +119,7 @@ public class QuickStepController implements GestureHelper {
        @Override
        public void onAnimationEnd(Animator animation) {
            mQuickScrubActive = false;
            mDragScrubActive = false;
            mTranslation = 0;
            mQuickScrubEndAnimator.setCurrentPlayTime(mQuickScrubEndAnimator.getDuration());
            mHomeButtonView = null;
@@ -123,7 +128,6 @@ public class QuickStepController implements GestureHelper {

    public QuickStepController(Context context) {
        mContext = context;
        mScrollTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mOverviewEventSender = Dependency.get(OverviewProxyService.class);
        mTrackThickness = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_thickness);
        mTrackPadding = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_edge_padding);
@@ -177,8 +181,8 @@ public class QuickStepController implements GestureHelper {

        final ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
        final boolean homePressed = mNavigationBarView.getDownHitTarget() == HIT_TARGET_HOME;
        int action = event.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
        int action = event.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN: {
                int x = (int) event.getX();
                int y = (int) event.getY();
@@ -206,21 +210,22 @@ public class QuickStepController implements GestureHelper {
                int y = (int) event.getY();
                int xDiff = Math.abs(x - mTouchDownX);
                int yDiff = Math.abs(y - mTouchDownY);
                boolean exceededTouchSlopX = xDiff > mScrollTouchSlop && xDiff > yDiff;
                boolean exceededTouchSlopY = yDiff > mScrollTouchSlop && yDiff > xDiff;
                boolean exceededTouchSlop, exceededPerpendicularTouchSlop;

                boolean exceededScrubTouchSlop, exceededSwipeUpTouchSlop, exceededScrubDragSlop;
                int pos, touchDown, offset, trackSize;

                if (mIsVertical) {
                    exceededTouchSlop = exceededTouchSlopY;
                    exceededPerpendicularTouchSlop = exceededTouchSlopX;
                    exceededScrubTouchSlop = yDiff > QUICK_STEP_TOUCH_SLOP_PX && yDiff > xDiff;
                    exceededSwipeUpTouchSlop = xDiff > QUICK_STEP_DRAG_SLOP_PX && xDiff > yDiff;
                    exceededScrubDragSlop = yDiff > QUICK_SCRUB_DRAG_SLOP_PX && yDiff > xDiff;
                    pos = y;
                    touchDown = mTouchDownY;
                    offset = pos - mTrackRect.top;
                    trackSize = mTrackRect.height();
                } else {
                    exceededTouchSlop = exceededTouchSlopX;
                    exceededPerpendicularTouchSlop = exceededTouchSlopY;
                    exceededScrubTouchSlop = xDiff > QUICK_STEP_TOUCH_SLOP_PX && xDiff > yDiff;
                    exceededSwipeUpTouchSlop = yDiff > QUICK_SCRUB_TOUCH_SLOP_PX && yDiff > xDiff;
                    exceededScrubDragSlop = xDiff > QUICK_SCRUB_DRAG_SLOP_PX && xDiff > yDiff;
                    pos = x;
                    touchDown = mTouchDownX;
                    offset = pos - mTrackRect.left;
@@ -228,7 +233,7 @@ public class QuickStepController implements GestureHelper {
                }
                // Decide to start quickstep if dragging away from the navigation bar, otherwise in
                // the parallel direction, decide to start quickscrub. Only one may run.
                if (!mQuickScrubActive && exceededPerpendicularTouchSlop) {
                if (!mQuickScrubActive && exceededSwipeUpTouchSlop) {
                    if (mNavigationBarView.isQuickStepSwipeUpEnabled()) {
                        startQuickStep(event);
                    }
@@ -244,22 +249,30 @@ public class QuickStepController implements GestureHelper {
                    offset -= mIsVertical ? mTrackRect.height() : mTrackRect.width();
                }

                // Control the button movement
                if (!mQuickScrubActive && exceededTouchSlop) {
                    boolean allowDrag = !mDragPositive
                final boolean allowDrag = !mDragPositive
                        ? offset < 0 && pos < touchDown : offset >= 0 && pos > touchDown;
                if (allowDrag) {
                    // Passing the drag slop is for visual feedback and will not initiate anything
                    if (!mDragScrubActive && exceededScrubDragSlop) {
                        mDownOffset = offset;
                        mDragScrubActive = true;
                    }

                    // Passing the drag slop then touch slop will start quick step
                    if (!mQuickScrubActive && exceededScrubTouchSlop) {
                        homeButton.abortCurrentGesture();
                        startQuickScrub();
                    }
                }
                if (mQuickScrubActive && (mDragPositive && offset >= 0

                if ((mQuickScrubActive || mDragScrubActive) && (mDragPositive && offset >= 0
                        || !mDragPositive && offset <= 0)) {
                    float scrubFraction = Utilities.clamp(Math.abs(offset) * 1f / trackSize, 0, 1);
                    mTranslation = !mDragPositive
                            ? Utilities.clamp(offset - mDownOffset, -trackSize, 0)
                            : Utilities.clamp(offset - mDownOffset, 0, trackSize);
                    if (mQuickScrubActive) {
                        float scrubFraction =
                                Utilities.clamp(Math.abs(offset) * 1f / trackSize, 0, 1);
                        try {
                            mOverviewEventSender.getProxy().onQuickScrubProgress(scrubFraction);
                            if (DEBUG_OVERVIEW_PROXY) {
@@ -268,6 +281,7 @@ public class QuickStepController implements GestureHelper {
                        } catch (RemoteException e) {
                            Log.e(TAG, "Failed to send progress of quick scrub.", e);
                        }
                    }
                    if (mIsVertical) {
                        mHomeButtonView.setTranslationY(mTranslation);
                    } else {
@@ -283,7 +297,9 @@ public class QuickStepController implements GestureHelper {
        }

        // Proxy motion events to launcher if not handled by quick scrub
        if (!mQuickScrubActive && mAllowGestureDetection) {
        // Proxy motion events up/cancel that would be sent after long press on any nav button
        if (!mQuickScrubActive && (mAllowGestureDetection || action == MotionEvent.ACTION_CANCEL
                || action == MotionEvent.ACTION_UP)) {
            proxyMotionEvents(event);
        }
        return mQuickScrubActive || mQuickStepStarted;
@@ -370,10 +386,14 @@ public class QuickStepController implements GestureHelper {
        mOverviewEventSender.notifyQuickStepStarted();
        mNavigationBarView.getHomeButton().abortCurrentGesture();
        mHandler.removeCallbacksAndMessages(null);

        if (mDragScrubActive) {
            animateEnd();
        }
    }

    private void startQuickScrub() {
        if (!mQuickScrubActive) {
        if (!mQuickScrubActive && mDragScrubActive) {
            mQuickScrubActive = true;
            mLightTrackColor = mContext.getColor(R.color.quick_step_track_background_light);
            mDarkTrackColor = mContext.getColor(R.color.quick_step_track_background_dark);
@@ -391,8 +411,9 @@ public class QuickStepController implements GestureHelper {
    }

    private void endQuickScrub(boolean animate) {
        if (mQuickScrubActive) {
        if (mQuickScrubActive || mDragScrubActive) {
            animateEnd();
            if (mQuickScrubActive) {
                try {
                    mOverviewEventSender.getProxy().onQuickScrubEnd();
                    if (DEBUG_OVERVIEW_PROXY) {
@@ -402,6 +423,7 @@ public class QuickStepController implements GestureHelper {
                    Log.e(TAG, "Failed to send end of quick scrub.", e);
                }
            }
        }
        if (mHomeButtonView != null && !animate) {
            mQuickScrubEndAnimator.end();
        }
+9 −5
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ import com.android.systemui.statusbar.VibratorHelper;

import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_SCRUB_TOUCH_SLOP_PX;
import static com.android.systemui.shared.system.NavigationBarCompat.QUICK_STEP_TOUCH_SLOP_PX;

public class KeyButtonView extends ImageView implements ButtonInterface {
    private static final String TAG = KeyButtonView.class.getSimpleName();
@@ -62,9 +64,9 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
    private int mContentDescriptionRes;
    private long mDownTime;
    private int mCode;
    private int mTouchSlop;
    private int mTouchDownX;
    private int mTouchDownY;
    private boolean mIsVertical;
    private boolean mSupportsLongpress = true;
    private AudioManager mAudioManager;
    private boolean mGestureAborted;
@@ -115,7 +117,6 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
        a.recycle();

        setClickable(true);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

        mRipple = new KeyButtonRipple(context, this);
@@ -235,8 +236,11 @@ public class KeyButtonView extends ImageView implements ButtonInterface {
            case MotionEvent.ACTION_MOVE:
                x = (int)ev.getRawX();
                y = (int)ev.getRawY();
                boolean exceededTouchSlopX = Math.abs(x - mTouchDownX) > mTouchSlop;
                boolean exceededTouchSlopY = Math.abs(y - mTouchDownY) > mTouchSlop;

                boolean exceededTouchSlopX = Math.abs(x - mTouchDownX) >
                        (mIsVertical ? QUICK_SCRUB_TOUCH_SLOP_PX : QUICK_STEP_TOUCH_SLOP_PX);
                boolean exceededTouchSlopY = Math.abs(y - mTouchDownY) >
                        (mIsVertical ? QUICK_STEP_TOUCH_SLOP_PX : QUICK_SCRUB_TOUCH_SLOP_PX);
                if (exceededTouchSlopX || exceededTouchSlopY) {
                    // When quick step is enabled, prevent animating the ripple triggered by
                    // setPressed and decide to run it on touch up
@@ -342,7 +346,7 @@ public class KeyButtonView extends ImageView implements ButtonInterface {

    @Override
    public void setVertical(boolean vertical) {
        //no op
        mIsVertical = vertical;
    }
}