Loading packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl +3 −11 Original line number Diff line number Diff line Loading @@ -35,20 +35,12 @@ oneway interface IOverviewProxy { * 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. * Once quick 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 and will no longer preemptively cancel any * recents animations started as a part of the motion event handling. */ 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 and will no longer preemptively cancel Loading Loading @@ -89,8 +81,8 @@ oneway interface IOverviewProxy { * {@link onMotionEvent}. Since motion events will be sent, motion up or cancel can still be * sent to cancel overview regardless the current state of launcher (eg. if overview is already * visible, this event will still be sent if user swipes up). When this signal is sent, * navigation bar will not handle any gestures such as quick scrub or switch and the home button * will cancel (long) press. * navigation bar will not handle any gestures such as quick scrub and the home button will * cancel (long) press. */ void onQuickStep(in MotionEvent event); } packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java +1 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ public class NavigationBarCompat { public static final int FLAG_DISABLE_SWIPE_UP = 0x1; /** * Interaction type: enable quick scrub and switch interaction on the home button * Interaction type: enable quick scrub interaction on the home button */ public static final int FLAG_DISABLE_QUICK_SCRUB = 0x2; Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java +22 −91 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import android.os.Handler; import android.os.RemoteException; import android.util.Log; import android.util.Slog; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; Loading @@ -54,28 +53,16 @@ import static com.android.systemui.OverviewProxyService.TAG_OPS; import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME; /** * Class to detect gestures on the navigation bar and implement quick scrub and switch. * Class to detect gestures on the navigation bar and implement quick scrub. */ public class QuickStepController extends GestureDetector.SimpleOnGestureListener implements GestureHelper { public class QuickStepController implements GestureHelper { private static final String TAG = "QuickStepController"; 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 = 225; /** * For quick step, set a damping value to allow the button to stick closer its origin position * when dragging before quick scrub is active. */ private static final int SWITCH_STICKINESS = 4; private NavigationBarView mNavigationBarView; private GestureDetector mGestureDetector; private boolean mDraggingActive; private boolean mQuickScrubActive; private boolean mAllowQuickSwitch; private boolean mAllowGestureDetection; private boolean mQuickStepStarted; private float mDownOffset; Loading Loading @@ -134,45 +121,10 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } }; private Runnable mLongPressRunnable = this::startQuickScrub; private final GestureDetector.SimpleOnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velX, float velY) { if (!mNavigationBarView.isQuickScrubEnabled() || mQuickScrubActive || !mAllowQuickSwitch || mNavigationBarView.getDownHitTarget() != HIT_TARGET_HOME) { return false; } float velocityX = mIsRTL ? -velX : velX; float absVelY = Math.abs(velY); final boolean isValidFling = velocityX > QUICK_SWITCH_FLING_VELOCITY && mIsVertical ? (absVelY > velocityX) : (velocityX > absVelY); if (isValidFling) { mDraggingActive = false; animateEnd(); mHandler.removeCallbacks(mLongPressRunnable); try { final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy(); overviewProxy.onQuickSwitch(); if (DEBUG_OVERVIEW_PROXY) { Log.d(TAG_OPS, "Quick Switch"); } } catch (RemoteException e) { Log.e(TAG, "Failed to send start of quick switch.", e); } return true; } return false; } }; public QuickStepController(Context context) { mContext = context; mScrollTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mOverviewEventSender = Dependency.get(OverviewProxyService.class); mGestureDetector = new GestureDetector(mContext, mGestureListener); mTrackThickness = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_thickness); mTrackPadding = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_edge_padding); mTrackPaint.setAlpha(0); Loading @@ -195,8 +147,8 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } /** * @return true if we want to intercept touch events for quick scrub/switch and prevent proxying * the event to the overview service. * @return true if we want to intercept touch events for quick scrub and prevent proxying the * event to the overview service. */ @Override public boolean onInterceptTouchEvent(MotionEvent event) { Loading @@ -204,8 +156,8 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } /** * @return true if we want to handle touch events for quick scrub/switch or if down event (that * will get consumed and ignored). No events will be proxied to the overview service. * @return true if we want to handle touch events for quick scrub or if down event (that will * get consumed and ignored). No events will be proxied to the overview service. */ @Override public boolean onTouchEvent(MotionEvent event) { Loading @@ -224,10 +176,6 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener mNavigationBarView.requestUnbufferedDispatch(event); final ButtonDispatcher homeButton = mNavigationBarView.getHomeButton(); if (mGestureDetector.onTouchEvent(event)) { // If the fling has been handled on UP, then skip proxying the UP return true; } final boolean homePressed = mNavigationBarView.getDownHitTarget() == HIT_TARGET_HOME; int action = event.getAction(); switch (action & MotionEvent.ACTION_MASK) { Loading @@ -242,15 +190,11 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener homeButton.setDelayTouchFeedback(true /* delay */); mTouchDownX = x; mTouchDownY = y; if (homePressed) { mHandler.postDelayed(mLongPressRunnable, LONG_PRESS_DELAY_MS); } mTransformGlobalMatrix.set(Matrix.IDENTITY_MATRIX); mTransformLocalMatrix.set(Matrix.IDENTITY_MATRIX); mNavigationBarView.transformMatrixToGlobal(mTransformGlobalMatrix); mNavigationBarView.transformMatrixToLocal(mTransformLocalMatrix); mQuickStepStarted = false; mAllowQuickSwitch = true; mAllowGestureDetection = true; break; } Loading Loading @@ -284,14 +228,14 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } // 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 (!mDraggingActive && !mQuickScrubActive && exceededPerpendicularTouchSlop) { if (!mQuickScrubActive && exceededPerpendicularTouchSlop) { if (mNavigationBarView.isQuickStepSwipeUpEnabled()) { startQuickStep(event); } break; } // Do not handle quick scrub/switch if disabled or hit target is not home button // Do not handle quick scrub if disabled or hit target is not home button if (!homePressed || !mNavigationBarView.isQuickScrubEnabled()) { break; } Loading @@ -301,22 +245,21 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } // Control the button movement if (!mDraggingActive && exceededTouchSlop) { if (!mQuickScrubActive && exceededTouchSlop) { boolean allowDrag = !mDragPositive ? offset < 0 && pos < touchDown : offset >= 0 && pos > touchDown; if (allowDrag) { mDownOffset = offset; homeButton.abortCurrentGesture(); mDraggingActive = true; startQuickScrub(); } } if (mDraggingActive && (mDragPositive && offset >= 0 if (mQuickScrubActive && (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) { try { mOverviewEventSender.getProxy().onQuickScrubProgress(scrubFraction); if (DEBUG_OVERVIEW_PROXY) { Loading @@ -325,9 +268,6 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } catch (RemoteException e) { Log.e(TAG, "Failed to send progress of quick scrub.", e); } } else { mTranslation /= SWITCH_STICKINESS; } if (mIsVertical) { mHomeButtonView.setTranslationY(mTranslation); } else { Loading @@ -342,12 +282,11 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener break; } // Proxy motion events to launcher if not handled by quick scrub/switch boolean handled = mDraggingActive || mQuickScrubActive; if (!handled && mAllowGestureDetection) { // Proxy motion events to launcher if not handled by quick scrub if (!mQuickScrubActive && mAllowGestureDetection) { proxyMotionEvents(event); } return handled || mQuickStepStarted; return mQuickScrubActive || mQuickStepStarted; } @Override Loading Loading @@ -428,12 +367,11 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } mOverviewEventSender.notifyQuickStepStarted(); mNavigationBarView.getHomeButton().abortCurrentGesture(); cancelQuickSwitch(); mHandler.removeCallbacksAndMessages(null); } private void startQuickScrub() { if (!mQuickScrubActive && mDraggingActive) { if (!mQuickScrubActive) { mQuickScrubActive = true; mLightTrackColor = mContext.getColor(R.color.quick_step_track_background_light); mDarkTrackColor = mContext.getColor(R.color.quick_step_track_background_dark); Loading @@ -451,8 +389,7 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } private void endQuickScrub(boolean animate) { mHandler.removeCallbacks(mLongPressRunnable); if (mDraggingActive || mQuickScrubActive) { if (mQuickScrubActive) { animateEnd(); try { mOverviewEventSender.getProxy().onQuickScrubEnd(); Loading @@ -466,7 +403,6 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener if (mHomeButtonView != null && !animate) { mQuickScrubEndAnimator.end(); } mDraggingActive = false; } private boolean proxyMotionEvents(MotionEvent event) { Loading @@ -489,11 +425,6 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener return false; } public void cancelQuickSwitch() { mAllowQuickSwitch = false; mHandler.removeCallbacks(mLongPressRunnable); } private void animateEnd() { mButtonAnimator.setIntValues((int) mTranslation, 0); mTrackAnimator.setFloatValues(mTrackAlpha, 0); Loading Loading
packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl +3 −11 Original line number Diff line number Diff line Loading @@ -35,20 +35,12 @@ oneway interface IOverviewProxy { * 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. * Once quick 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 and will no longer preemptively cancel any * recents animations started as a part of the motion event handling. */ 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 and will no longer preemptively cancel Loading Loading @@ -89,8 +81,8 @@ oneway interface IOverviewProxy { * {@link onMotionEvent}. Since motion events will be sent, motion up or cancel can still be * sent to cancel overview regardless the current state of launcher (eg. if overview is already * visible, this event will still be sent if user swipes up). When this signal is sent, * navigation bar will not handle any gestures such as quick scrub or switch and the home button * will cancel (long) press. * navigation bar will not handle any gestures such as quick scrub and the home button will * cancel (long) press. */ void onQuickStep(in MotionEvent event); }
packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java +1 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ public class NavigationBarCompat { public static final int FLAG_DISABLE_SWIPE_UP = 0x1; /** * Interaction type: enable quick scrub and switch interaction on the home button * Interaction type: enable quick scrub interaction on the home button */ public static final int FLAG_DISABLE_QUICK_SCRUB = 0x2; Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java +22 −91 Original line number Diff line number Diff line Loading @@ -32,7 +32,6 @@ import android.os.Handler; import android.os.RemoteException; import android.util.Log; import android.util.Slog; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; Loading @@ -54,28 +53,16 @@ import static com.android.systemui.OverviewProxyService.TAG_OPS; import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME; /** * Class to detect gestures on the navigation bar and implement quick scrub and switch. * Class to detect gestures on the navigation bar and implement quick scrub. */ public class QuickStepController extends GestureDetector.SimpleOnGestureListener implements GestureHelper { public class QuickStepController implements GestureHelper { private static final String TAG = "QuickStepController"; 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 = 225; /** * For quick step, set a damping value to allow the button to stick closer its origin position * when dragging before quick scrub is active. */ private static final int SWITCH_STICKINESS = 4; private NavigationBarView mNavigationBarView; private GestureDetector mGestureDetector; private boolean mDraggingActive; private boolean mQuickScrubActive; private boolean mAllowQuickSwitch; private boolean mAllowGestureDetection; private boolean mQuickStepStarted; private float mDownOffset; Loading Loading @@ -134,45 +121,10 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } }; private Runnable mLongPressRunnable = this::startQuickScrub; private final GestureDetector.SimpleOnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velX, float velY) { if (!mNavigationBarView.isQuickScrubEnabled() || mQuickScrubActive || !mAllowQuickSwitch || mNavigationBarView.getDownHitTarget() != HIT_TARGET_HOME) { return false; } float velocityX = mIsRTL ? -velX : velX; float absVelY = Math.abs(velY); final boolean isValidFling = velocityX > QUICK_SWITCH_FLING_VELOCITY && mIsVertical ? (absVelY > velocityX) : (velocityX > absVelY); if (isValidFling) { mDraggingActive = false; animateEnd(); mHandler.removeCallbacks(mLongPressRunnable); try { final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy(); overviewProxy.onQuickSwitch(); if (DEBUG_OVERVIEW_PROXY) { Log.d(TAG_OPS, "Quick Switch"); } } catch (RemoteException e) { Log.e(TAG, "Failed to send start of quick switch.", e); } return true; } return false; } }; public QuickStepController(Context context) { mContext = context; mScrollTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mOverviewEventSender = Dependency.get(OverviewProxyService.class); mGestureDetector = new GestureDetector(mContext, mGestureListener); mTrackThickness = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_thickness); mTrackPadding = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_edge_padding); mTrackPaint.setAlpha(0); Loading @@ -195,8 +147,8 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } /** * @return true if we want to intercept touch events for quick scrub/switch and prevent proxying * the event to the overview service. * @return true if we want to intercept touch events for quick scrub and prevent proxying the * event to the overview service. */ @Override public boolean onInterceptTouchEvent(MotionEvent event) { Loading @@ -204,8 +156,8 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } /** * @return true if we want to handle touch events for quick scrub/switch or if down event (that * will get consumed and ignored). No events will be proxied to the overview service. * @return true if we want to handle touch events for quick scrub or if down event (that will * get consumed and ignored). No events will be proxied to the overview service. */ @Override public boolean onTouchEvent(MotionEvent event) { Loading @@ -224,10 +176,6 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener mNavigationBarView.requestUnbufferedDispatch(event); final ButtonDispatcher homeButton = mNavigationBarView.getHomeButton(); if (mGestureDetector.onTouchEvent(event)) { // If the fling has been handled on UP, then skip proxying the UP return true; } final boolean homePressed = mNavigationBarView.getDownHitTarget() == HIT_TARGET_HOME; int action = event.getAction(); switch (action & MotionEvent.ACTION_MASK) { Loading @@ -242,15 +190,11 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener homeButton.setDelayTouchFeedback(true /* delay */); mTouchDownX = x; mTouchDownY = y; if (homePressed) { mHandler.postDelayed(mLongPressRunnable, LONG_PRESS_DELAY_MS); } mTransformGlobalMatrix.set(Matrix.IDENTITY_MATRIX); mTransformLocalMatrix.set(Matrix.IDENTITY_MATRIX); mNavigationBarView.transformMatrixToGlobal(mTransformGlobalMatrix); mNavigationBarView.transformMatrixToLocal(mTransformLocalMatrix); mQuickStepStarted = false; mAllowQuickSwitch = true; mAllowGestureDetection = true; break; } Loading Loading @@ -284,14 +228,14 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } // 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 (!mDraggingActive && !mQuickScrubActive && exceededPerpendicularTouchSlop) { if (!mQuickScrubActive && exceededPerpendicularTouchSlop) { if (mNavigationBarView.isQuickStepSwipeUpEnabled()) { startQuickStep(event); } break; } // Do not handle quick scrub/switch if disabled or hit target is not home button // Do not handle quick scrub if disabled or hit target is not home button if (!homePressed || !mNavigationBarView.isQuickScrubEnabled()) { break; } Loading @@ -301,22 +245,21 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } // Control the button movement if (!mDraggingActive && exceededTouchSlop) { if (!mQuickScrubActive && exceededTouchSlop) { boolean allowDrag = !mDragPositive ? offset < 0 && pos < touchDown : offset >= 0 && pos > touchDown; if (allowDrag) { mDownOffset = offset; homeButton.abortCurrentGesture(); mDraggingActive = true; startQuickScrub(); } } if (mDraggingActive && (mDragPositive && offset >= 0 if (mQuickScrubActive && (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) { try { mOverviewEventSender.getProxy().onQuickScrubProgress(scrubFraction); if (DEBUG_OVERVIEW_PROXY) { Loading @@ -325,9 +268,6 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } catch (RemoteException e) { Log.e(TAG, "Failed to send progress of quick scrub.", e); } } else { mTranslation /= SWITCH_STICKINESS; } if (mIsVertical) { mHomeButtonView.setTranslationY(mTranslation); } else { Loading @@ -342,12 +282,11 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener break; } // Proxy motion events to launcher if not handled by quick scrub/switch boolean handled = mDraggingActive || mQuickScrubActive; if (!handled && mAllowGestureDetection) { // Proxy motion events to launcher if not handled by quick scrub if (!mQuickScrubActive && mAllowGestureDetection) { proxyMotionEvents(event); } return handled || mQuickStepStarted; return mQuickScrubActive || mQuickStepStarted; } @Override Loading Loading @@ -428,12 +367,11 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } mOverviewEventSender.notifyQuickStepStarted(); mNavigationBarView.getHomeButton().abortCurrentGesture(); cancelQuickSwitch(); mHandler.removeCallbacksAndMessages(null); } private void startQuickScrub() { if (!mQuickScrubActive && mDraggingActive) { if (!mQuickScrubActive) { mQuickScrubActive = true; mLightTrackColor = mContext.getColor(R.color.quick_step_track_background_light); mDarkTrackColor = mContext.getColor(R.color.quick_step_track_background_dark); Loading @@ -451,8 +389,7 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener } private void endQuickScrub(boolean animate) { mHandler.removeCallbacks(mLongPressRunnable); if (mDraggingActive || mQuickScrubActive) { if (mQuickScrubActive) { animateEnd(); try { mOverviewEventSender.getProxy().onQuickScrubEnd(); Loading @@ -466,7 +403,6 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener if (mHomeButtonView != null && !animate) { mQuickScrubEndAnimator.end(); } mDraggingActive = false; } private boolean proxyMotionEvents(MotionEvent event) { Loading @@ -489,11 +425,6 @@ public class QuickStepController extends GestureDetector.SimpleOnGestureListener return false; } public void cancelQuickSwitch() { mAllowQuickSwitch = false; mHandler.removeCallbacks(mLongPressRunnable); } private void animateEnd() { mButtonAnimator.setIntValues((int) mTranslation, 0); mTrackAnimator.setFloatValues(mTrackAlpha, 0); Loading