diff options
4 files changed, 97 insertions, 55 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<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() { 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..dc0835e4371a 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 @@ -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); } |