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

Commit e3fbfaca authored by Andreas Agvard's avatar Andreas Agvard
Browse files

Synchonizes touch slop across input consumers

This is done so that an outer input consumer isn't inside it's touch slop while an inner consumer has passed it's touch slop. An inner consumer cannot inform the outer consumers that it has intercepted in the current design.

Removes MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE handling from NavHandleLongPressInputConsumer since other input consumers do not use this mechanism leading to misalligned touch slops.

OtherActivityInputConsumer now uses touch slop from the device configuration (it already did so for the squared touch slop).

Flag: LEGACY CUSTOM_LPNH_THRESHOLDS DISABLED
Bug: 305924072
Test: Manual
Change-Id: Idf5e88d75914255923fbbcfb602cf2a53773ff9a
parent 4d59d52d
Loading
Loading
Loading
Loading
+25 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.Display.DEFAULT_DISPLAY;

import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
@@ -60,6 +61,8 @@ import android.view.ViewConfiguration;
import androidx.annotation.BinderThread;
import androidx.annotation.NonNull;

import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
@@ -86,8 +89,8 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
    static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";

    // TODO: Move to quickstep contract
    private static final float QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON = 9;
    private static final float QUICKSTEP_TOUCH_SLOP_RATIO_GESTURAL = 2;
    private static final float QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON = 3f;
    private static final float QUICKSTEP_TOUCH_SLOP_RATIO_GESTURAL = 1.414f;

    private final Context mContext;
    private final DisplayController mDisplayController;
@@ -546,15 +549,31 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {

    /**
     * Returns the touch slop for {@link InputConsumer}s to compare against before pilfering
     * pointers. Note that this is squared because it expects to be compared against
     * {@link com.android.launcher3.Utilities#squaredHypot} (to avoid square root on each event).
     * pointers.
     */
    public float getSquaredTouchSlop() {
    public float getTouchSlop() {
        float slopMultiplier = isFullyGesturalNavMode()
                ? QUICKSTEP_TOUCH_SLOP_RATIO_GESTURAL
                : QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON;
        float touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
        return slopMultiplier * touchSlop * touchSlop;

        if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
            float customSlopMultiplier =
                    LauncherPrefs.get(mContext).get(LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE) / 100f;
            return customSlopMultiplier * slopMultiplier * touchSlop;
        } else {
            return slopMultiplier * touchSlop;
        }
    }

    /**
     * Returns the squared touch slop for {@link InputConsumer}s to compare against before pilfering
     * pointers. Note that this is squared because it expects to be compared against
     * {@link com.android.launcher3.Utilities#squaredHypot} (to avoid square root on each event).
     */
    public float getSquaredTouchSlop() {
        float touchSlop = getTouchSlop();
        return touchSlop * touchSlop;
    }

    public String getSystemUiStateString() {
+2 −1
Original line number Diff line number Diff line
@@ -963,7 +963,8 @@ public class TouchInteractionService extends Service {
                        .append(SUBSTRING_PREFIX)
                        .append("Long press nav handle enabled, ")
                        .append("using NavHandleLongPressInputConsumer");
                base = new NavHandleLongPressInputConsumer(this, base, mInputMonitorCompat);
                base = new NavHandleLongPressInputConsumer(this, base, mInputMonitorCompat,
                        mDeviceState);
            }

            if (mDeviceState.isBubblesExpanded()) {
+7 −15
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
 */
package com.android.quickstep.inputconsumers;

import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE;
import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_TIMEOUT_MS;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;

@@ -28,6 +27,7 @@ import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.InputConsumer;
import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.systemui.shared.system.InputMonitorCompat;

/**
@@ -47,23 +47,18 @@ public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
    private MotionEvent mCurrentDownEvent;

    public NavHandleLongPressInputConsumer(Context context, InputConsumer delegate,
            InputMonitorCompat inputMonitor) {
            InputMonitorCompat inputMonitor, RecentsAnimationDeviceState deviceState) {
        super(delegate, inputMonitor);
        mViewConfiguration = ViewConfiguration.get(context);
        mNavHandleWidth = context.getResources().getDimensionPixelSize(
                R.dimen.navigation_home_handle_width);
        mScreenWidth = DisplayController.INSTANCE.get(context).getInfo().currentSize.x;
        float touchSlop;
        if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
            float customSlopMultiplier =
                    LauncherPrefs.get(context).get(LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE) / 100f;
            touchSlop = mViewConfiguration.getScaledEdgeSlop() * customSlopMultiplier;
            mLongPressTimeout = LauncherPrefs.get(context).get(LONG_PRESS_NAV_HANDLE_TIMEOUT_MS);
        } else {
            touchSlop = mViewConfiguration.getScaledTouchSlop();
            mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
        }
        mTouchSlopSquared = touchSlop * touchSlop;
        mTouchSlopSquared = deviceState.getSquaredTouchSlop();
        mNavHandleLongPressHandler = NavHandleLongPressHandler.newInstance(context);
    }

@@ -87,17 +82,14 @@ public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
                }
            }
            case MotionEvent.ACTION_MOVE -> {
                if (!MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)) {
                    break;
                }

                float touchSlopSquared = mTouchSlopSquared;
                float dx = ev.getX() - mCurrentDownEvent.getX();
                float dy = ev.getY() - mCurrentDownEvent.getY();
                double distanceSquared = (dx * dx) + (dy * dy);
                // If the gesture is ambiguous then require more movement before classifying this
                // as a NON long press gesture.
                if (ev.getClassification() == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE) {
                    float ambiguousGestureMultiplier =
                            mViewConfiguration.getScaledAmbiguousGestureMultiplier();
                    touchSlopSquared *= ambiguousGestureMultiplier * ambiguousGestureMultiplier;
                }
                if (distanceSquared > touchSlopSquared) {
                    cancelLongPress();
                }
+1 −2
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import android.os.Build;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;

import androidx.annotation.UiThread;

@@ -154,7 +153,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
        boolean continuingPreviousGesture = mTaskAnimationManager.isRecentsAnimationRunning();
        mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget;

        mTouchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
        mTouchSlop = mDeviceState.getTouchSlop();
        mSquaredTouchSlop = mDeviceState.getSquaredTouchSlop();

        mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture;