From de2a1248280421f3a1640d385250628a9af652c0 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 7 Feb 2018 15:59:43 -0800 Subject: Handle both touch flows to start quickscrub - Ensure that quickswitch can only happen if the user started on the home button Bug: 67957962 Bug: 70180755 Test: Enable quickscrub, start scrubbing and swipe up Change-Id: Idd015077ad72705ee82087c5ff70ec25a238da6a --- .../statusbar/phone/QuickScrubController.java | 42 +++++++++++----------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java index 6bfaaf49b65b..ae276a861243 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java @@ -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 @@ -95,7 +95,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 +136,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 || + !mHomeButtonRect.contains(mTouchDownX, mTouchDownY)) { return false; } float velocityX = mIsRTL ? -velX : velX; @@ -167,8 +167,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 +200,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(); @@ -304,22 +318,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, -- cgit v1.2.3-59-g8ed1b From 4965884784468e42485fbd52335905a56a6d7c5a Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Thu, 8 Feb 2018 12:52:21 -0800 Subject: Fix issue with quickswitch happening after recents animation starting - When the animation starts, prevent quickswitch until the next gesture starts - Refactor recents animation started signal into the gesture helper to simplify the code in the nav bar view Bug: 67957962 Bug: 70180755 Bug: 73080940 Test: Quick scrub on nav bar Change-Id: I718d3e64c14569e5df2e6a0ffc1aecdb0125f54f Signed-off-by: Winson Chung --- .../systemui/shared/recents/IOverviewProxy.aidl | 31 +++++++++++++ .../phone/NavigationBarGestureHelper.java | 51 ++++++++++++++++------ .../statusbar/phone/NavigationBarView.java | 21 +-------- .../statusbar/phone/QuickScrubController.java | 9 +++- 4 files changed, 78 insertions(+), 34 deletions(-) diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl index 64fa9c61280a..cd9e1268f0c7 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/IOverviewProxy.aidl @@ -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); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java index 7db6e2848b2a..8d14db78fe29 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java @@ -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); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index ad5144e941ad..af0afbdd6782 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -103,7 +103,6 @@ public class NavigationBarView extends FrameLayout implements PluginListener