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

Commit 7d2aed0c authored by Miranda Kephart's avatar Miranda Kephart
Browse files

Allow shallow-angle flings in AssistantTouchConsumer

While any angle above 22 degrees from horizontal is permitted for
drag invocations, the SwipeDetector used to detect flings only
allowed angles within 45 degrees of vertical. This changes to using
GestureListener and permits flings in the 22-45 degree region (as
well as up to vertical).

Test: manual
Bug: 135011207
Change-Id: I8e08650395917341869b27ff381f32268fadcb3c
parent 6aabe679
Loading
Loading
Loading
Loading
+43 −38
Original line number Diff line number Diff line
@@ -34,11 +34,14 @@ import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerTyp
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.gesture.Gesture;
import android.graphics.PointF;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
@@ -56,8 +59,7 @@ import com.android.systemui.shared.system.QuickStepContract;
/**
 * Touch consumer for handling events to launch assistant from launcher
 */
public class AssistantTouchConsumer extends DelegateInputConsumer
    implements SwipeDetector.Listener {
public class AssistantTouchConsumer extends DelegateInputConsumer {

    private static final String TAG = "AssistantTouchConsumer";
    private static final long RETRACT_ANIMATION_DURATION_MS = 300;
@@ -68,7 +70,6 @@ public class AssistantTouchConsumer extends DelegateInputConsumer
    private static final int OPA_BUNDLE_TRIGGER_DIAG_SWIPE_GESTURE = 83;
    private static final String INVOCATION_TYPE_KEY = "invocation_type";
    private static final int INVOCATION_TYPE_GESTURE = 1;
    private static final int INVOCATION_TYPE_FLING = 6;

    private final PointF mDownPos = new PointF();
    private final PointF mLastPos = new PointF();
@@ -90,7 +91,7 @@ public class AssistantTouchConsumer extends DelegateInputConsumer
    private final float mSquaredSlop;
    private final ISystemUiProxy mSysUiProxy;
    private final Context mContext;
    private final SwipeDetector mSwipeDetector;
    private final GestureDetector mGestureDetector;

    public AssistantTouchConsumer(Context context, ISystemUiProxy systemUiProxy,
            ActivityControlHelper activityControlHelper, InputConsumer delegate,
@@ -107,8 +108,8 @@ public class AssistantTouchConsumer extends DelegateInputConsumer

        mSquaredSlop = slop * slop;
        mActivityControlHelper = activityControlHelper;
        mSwipeDetector = new SwipeDetector(mContext, this, SwipeDetector.VERTICAL);
        mSwipeDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_POSITIVE, false);

        mGestureDetector = new GestureDetector(context, new AssistantGestureListener());
    }

    @Override
@@ -119,7 +120,7 @@ public class AssistantTouchConsumer extends DelegateInputConsumer
    @Override
    public void onMotionEvent(MotionEvent ev) {
        // TODO add logging
        mSwipeDetector.onTouchEvent(ev);
        mGestureDetector.onTouchEvent(ev);

        switch (ev.getActionMasked()) {
            case ACTION_DOWN: {
@@ -171,13 +172,8 @@ public class AssistantTouchConsumer extends DelegateInputConsumer
                        mStartDragPos.set(mLastPos.x, mLastPos.y);
                        mDragTime = SystemClock.uptimeMillis();

                        // Determine if angle is larger than threshold for assistant detection
                        float angle = (float) Math.toDegrees(
                            Math.atan2(mDownPos.y - mLastPos.y, mDownPos.x - mLastPos.x));
                        mDirection = angle > 90 ? UPLEFT : UPRIGHT;
                        angle = angle > 90 ? 180 - angle : angle;

                        if (angle > mAngleThreshold && angle < 90) {
                        if (isValidAssistantGestureAngle(
                            mDownPos.x - mLastPos.x, mDownPos.y - mLastPos.y)) {
                            setActive(ev);
                        } else {
                            mState = STATE_DELEGATE_ACTIVE;
@@ -261,6 +257,19 @@ public class AssistantTouchConsumer extends DelegateInputConsumer
        }
    }

    /**
     * Determine if angle is larger than threshold for assistant detection
     */
    private boolean isValidAssistantGestureAngle(float deltaX, float deltaY) {
        float angle = (float) Math.toDegrees(Math.atan2(deltaY, deltaX));
        mDirection = angle > 90 ? UPLEFT : UPRIGHT;

        // normalize so that angle is measured clockwise from horizontal in the bottom right corner
        // and counterclockwise from horizontal in the bottom left corner
        angle = angle > 90 ? 180 - angle : angle;
        return (angle > mAngleThreshold && angle < 90);
    }

    public static boolean withinTouchRegion(Context context, MotionEvent ev) {
        final Resources res = context.getResources();
        final int width = res.getDisplayMetrics().widthPixels;
@@ -269,22 +278,15 @@ public class AssistantTouchConsumer extends DelegateInputConsumer
        return (ev.getX() > width - size || ev.getX() < size) && ev.getY() > height - size;
    }

    private class AssistantGestureListener extends SimpleOnGestureListener {
        @Override
    public void onDragStart(boolean start) {
        // do nothing
    }

    @Override
    public boolean onDrag(float displacement) {
        return false;
    }

    @Override
    public void onDragEnd(float velocity, boolean fling) {
        if (fling && !mLaunchedAssistant && mState != STATE_DELEGATE_ACTIVE) {
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if (isValidAssistantGestureAngle(velocityX, -velocityY)
                && !mLaunchedAssistant && mState != STATE_DELEGATE_ACTIVE) {
                mLastProgress = 1;
                try {
                mSysUiProxy.onAssistantGestureCompletion(velocity);
                    mSysUiProxy.onAssistantGestureCompletion(
                        (float) Math.sqrt(velocityX * velocityX + velocityY * velocityY));
                    startAssistantInternal(FLING);

                    Bundle args = new Bundle();
@@ -292,9 +294,12 @@ public class AssistantTouchConsumer extends DelegateInputConsumer
                    mSysUiProxy.startAssistant(args);
                    mLaunchedAssistant = true;
                } catch (RemoteException e) {
                Log.w(TAG, "Failed to send SysUI start/send assistant progress: " + mLastProgress,
                    Log.w(TAG,
                        "Failed to send SysUI start/send assistant progress: " + mLastProgress,
                        e);
                }
            }
            return true;
        }
    }
}