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

Commit 73ccb72d authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge changes I718d3e64,Idd015077

* changes:
  Fix issue with quickswitch happening after recents animation starting
  Handle both touch flows to start quickscrub
parents 250dfda1 49658847
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -21,9 +21,40 @@ import com.android.systemui.shared.recents.ISystemUiProxy;

oneway interface IOverviewProxy {
    void onBind(in ISystemUiProxy sysUiProxy);

    /**
     * Proxies motion events from the nav bar in SystemUI to the OverviewProxyService. The sender
     * guarantees the following order of events:
     *
     * Normal gesture: DOWN, (MOVE/POINTER_DOWN/POINTER_UP)*, UP
     * Quick switch: DOWN, (MOVE/POINTER_DOWN/POINTER_UP)*, SWITCH
     * Quick scrub: DOWN, (MOVE/POINTER_DOWN/POINTER_UP)*, SCRUB_START, SCRUB_PROGRESS*, SCRUB_END
     *
     * Once quick switch/scrub is sent, then no further motion events will be provided.
     */
    void onMotionEvent(in MotionEvent event);

    /**
     * Sent when a user has quickly flinged on the nav bar to switch tasks. Once this event is sent
     * the caller will stop sending any motion events.
     */
    void onQuickSwitch();

    /**
     * Sent when the user starts to actively scrub the nav bar to switch tasks. Once this event is
     * sent the caller will stop sending any motion events.
     */
    void onQuickScrubStart();

    /**
     * Sent when the user stops actively scrubbing the nav bar to switch tasks. Once this event is
     * sent the caller will stop sending any motion events.
     */
    void onQuickScrubEnd();

    /**
     * Sent for each movement over the nav bar while the user is scrubbing it to switch tasks. Once
     * this event is sent the caller will stop sending any motion events.
     */
    void onQuickScrubProgress(float progress);
}
+37 −14
Original line number Diff line number Diff line
@@ -16,37 +16,37 @@

package com.android.systemui.statusbar.phone;

import static android.view.WindowManager.DOCKED_INVALID;
import static android.view.WindowManager.DOCKED_LEFT;
import static android.view.WindowManager.DOCKED_TOP;
import static com.android.systemui.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
import static com.android.systemui.OverviewProxyService.TAG_OPS;

import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
import com.android.systemui.Dependency;
import com.android.systemui.OverviewProxyService;
import com.android.systemui.OverviewProxyService.OverviewProxyListener;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.tuner.TunerService;

import static android.view.WindowManager.DOCKED_INVALID;
import static android.view.WindowManager.DOCKED_LEFT;
import static android.view.WindowManager.DOCKED_TOP;
import static com.android.systemui.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
import static com.android.systemui.OverviewProxyService.TAG_OPS;

/**
 * Class to detect gestures on the navigation bar.
 */
@@ -84,8 +84,16 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
    private int mTouchDownY;
    private boolean mDownOnRecents;
    private VelocityTracker mVelocityTracker;
    private OverviewProxyService mOverviewEventSender = Dependency.get(OverviewProxyService.class);
    private OverviewProxyService mOverviewProxyService = Dependency.get(OverviewProxyService.class);
    private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() {
        @Override
        public void onRecentsAnimationStarted() {
            mRecentsAnimationStarted = true;
            mQuickScrubController.cancelQuickSwitch();
        }
    };

    private boolean mRecentsAnimationStarted;
    private boolean mDockWindowEnabled;
    private boolean mDockWindowTouchSlopExceeded;
    private int mDragMode;
@@ -97,10 +105,12 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
        mScrollTouchSlop = r.getDimensionPixelSize(R.dimen.navigation_bar_min_swipe_distance);
        mQuickScrubController = new QuickScrubController(context);
        Dependency.get(TunerService.class).addTunable(this, KEY_DOCK_WINDOW_GESTURE);
        mOverviewProxyService.addCallback(mOverviewProxyListener);
    }

    public void destroy() {
        Dependency.get(TunerService.class).removeTunable(this);
        mOverviewProxyService.removeCallback(mOverviewProxyListener);
    }

    public void setComponents(RecentsComponent recentsComponent, Divider divider,
@@ -117,7 +127,7 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
    }

    private boolean proxyMotionEvents(MotionEvent event) {
        final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy();
        final IOverviewProxy overviewProxy = mOverviewProxyService.getProxy();
        if (overviewProxy != null) {
            mNavigationBarView.requestUnbufferedDispatch(event);
            event.transform(mTransformGlobalMatrix);
@@ -146,6 +156,19 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
                mTransformLocalMatrix.set(Matrix.IDENTITY_MATRIX);
                mNavigationBarView.transformMatrixToGlobal(mTransformGlobalMatrix);
                mNavigationBarView.transformMatrixToLocal(mTransformLocalMatrix);
                mRecentsAnimationStarted = false;
                break;
            }
            case MotionEvent.ACTION_UP: {
                // If the overview proxy service has not started the recents animation then clean up
                // after it to ensure that the nav bar buttons still work
                if (mOverviewProxyService.getProxy() != null && !mRecentsAnimationStarted) {
                    try {
                        ActivityManager.getService().cancelRecentsAnimation();
                    } catch (RemoteException e) {
                        Log.e(TAG, "Could not cancel recents animation", e);
                    }
                }
                break;
            }
        }
@@ -154,13 +177,13 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
            proxyMotionEvents(event);
            return false;
        }
        return (mDockWindowEnabled && interceptDockWindowEvent(event));
        return (mDockWindowEnabled && interceptDockWindowEvent(event)) || mRecentsAnimationStarted;
    }

    public boolean onTouchEvent(MotionEvent event) {
        // The same down event was just sent on intercept and therefore can be ignored here
        boolean ignoreProxyDownEvent = event.getAction() == MotionEvent.ACTION_DOWN
                && mOverviewEventSender.getProxy() != null;
                && mOverviewProxyService.getProxy() != null;
        boolean result = mStatusBar.isPresenterFullyCollapsed()
                && (mQuickScrubController.onTouchEvent(event)
                || ignoreProxyDownEvent
@@ -168,11 +191,11 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture
        if (mDockWindowEnabled) {
            result |= handleDockWindowEvent(event);
        }
        return result;
        return result || mRecentsAnimationStarted;
    }

    public void onDraw(Canvas canvas) {
        if (mOverviewEventSender.getProxy() != null) {
        if (mOverviewProxyService.getProxy() != null) {
            mQuickScrubController.onDraw(canvas);
        }
    }
+2 −19
Original line number Diff line number Diff line
@@ -103,7 +103,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
    private DeadZone mDeadZone;
    private final NavigationBarTransitions mBarTransitions;
    private final OverviewProxyService mOverviewProxyService;
    private boolean mRecentsAnimationStarted;

    // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
    final static boolean WORKAROUND_INVALID_LAYOUT = true;
@@ -263,7 +262,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
    }

    public void setRecentsAnimationStarted(boolean started) {
        mRecentsAnimationStarted = started;
        if (mRecentsOnboarding != null) {
            mRecentsOnboarding.onRecentsAnimationStarted();
        }
@@ -277,22 +275,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        int action = event.getActionMasked();
        if (action == MotionEvent.ACTION_DOWN) {
            mRecentsAnimationStarted = false;
        } else if (action == MotionEvent.ACTION_UP) {
            // If the overview proxy service has not started the recents animation then clean up
            // after it to ensure that the nav bar buttons still work
            if (mOverviewProxyService.getProxy() != null && !mRecentsAnimationStarted) {
                try {
                    ActivityManager.getService().cancelRecentsAnimation();
                } catch (RemoteException e) {
                    Log.e(TAG, "Could not cancel recents animation");
                }
            }
        }

        return mGestureHelper.onInterceptTouchEvent(event) || mRecentsAnimationStarted;
        return mGestureHelper.onInterceptTouchEvent(event);
    }

    @Override
@@ -300,7 +283,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav
        if (mGestureHelper.onTouchEvent(event)) {
            return true;
        }
        return mRecentsAnimationStarted || super.onTouchEvent(event);
        return super.onTouchEvent(event);
    }

    public void abortCurrentGesture() {
+27 −22
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
    private static final String TAG = "QuickScrubController";
    private static final int QUICK_SWITCH_FLING_VELOCITY = 0;
    private static final int ANIM_DURATION_MS = 200;
    private static final long LONG_PRESS_DELAY_MS = 150;
    private static final long LONG_PRESS_DELAY_MS = 225;

    /**
     * For quick step, set a damping value to allow the button to stick closer its origin position
@@ -76,6 +76,7 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene

    private boolean mDraggingActive;
    private boolean mQuickScrubActive;
    private boolean mAllowQuickSwitch;
    private float mDownOffset;
    private float mTranslation;
    private int mTouchDownX;
@@ -95,7 +96,6 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
    private final Paint mTrackPaint = new Paint();
    private final int mScrollTouchSlop;
    private final OverviewProxyService mOverviewEventSender;
    private final Display mDisplay;
    private final int mTrackThickness;
    private final int mTrackPadding;
    private final ValueAnimator mTrackAnimator;
@@ -137,7 +137,8 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
        new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velX, float velY) {
                if (!isQuickScrubEnabled() || mQuickScrubActive) {
                if (!isQuickScrubEnabled() || mQuickScrubActive || !mAllowQuickSwitch ||
                        !mHomeButtonRect.contains(mTouchDownX, mTouchDownY)) {
                    return false;
                }
                float velocityX = mIsRTL ? -velX : velX;
@@ -167,8 +168,6 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
    public QuickScrubController(Context context) {
        mContext = context;
        mScrollTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mDisplay = ((WindowManager) context.getSystemService(
                Context.WINDOW_SERVICE)).getDefaultDisplay();
        mOverviewEventSender = Dependency.get(OverviewProxyService.class);
        mGestureDetector = new GestureDetector(mContext, mGestureListener);
        mTrackThickness = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_thickness);
@@ -202,8 +201,24 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
            homeButton.setDelayTouchFeedback(false);
            return false;
        }

        return handleTouchEvent(event);
    }

    /**
     * @return true if we want to handle touch events for quick scrub/switch and prevent proxying
     *         the event to the overview service.
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return handleTouchEvent(event);
    }

    private boolean handleTouchEvent(MotionEvent event) {
        final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy();
        final ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
        if (mGestureDetector.onTouchEvent(event)) {
            // If the fling has been handled, then skip proxying the UP
            // If the fling has been handled on UP, then skip proxying the UP
            return true;
        }
        int action = event.getAction();
@@ -220,6 +235,7 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
                    homeButton.setDelayTouchFeedback(false);
                    mTouchDownX = mTouchDownY = -1;
                }
                mAllowQuickSwitch = true;
                break;
            }
            case MotionEvent.ACTION_MOVE: {
@@ -304,22 +320,6 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
        return mDraggingActive || mQuickScrubActive;
    }

    /**
     * @return true if we want to handle touch events for quick scrub/switch and prevent proxying
     *         the event to the overview service.
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mGestureDetector.onTouchEvent(event)) {
            // If the fling has been handled, then skip proxying the UP
            return true;
        }
        if (event.getAction() == MotionEvent.ACTION_UP) {
            endQuickScrub();
        }
        return mDraggingActive || mQuickScrubActive;
    }

    @Override
    public void onDraw(Canvas canvas) {
        int color = (int) mTrackColorEvaluator.evaluate(mDarkIntensity, mLightTrackColor,
@@ -420,6 +420,11 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene
        mDraggingActive = false;
    }

    public void cancelQuickSwitch() {
        mAllowQuickSwitch = false;
        mHandler.removeCallbacks(mLongPressRunnable);
    }

    private int getDimensionPixelSize(Context context, @DimenRes int resId) {
        return context.getResources().getDimensionPixelSize(resId);
    }