Support deep press on notifications.
In addition to handling CLASSIFICATION_DEEP_PRESS in SwipeHelper, touch
slop calculations are updated for scroll/flick interactions that may be
performed on notifications or the notification panel.
Fixes: 148172385
Test: notifications expand when deep pressed
Change-Id: I49f71f919d762ce1a5da145a9377c70422a66c87
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index e2b12da..59af458 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -86,7 +86,8 @@
private float mInitialTouchSpan;
private float mLastFocusY;
private float mLastSpanY;
- private int mTouchSlop;
+ private final int mTouchSlop;
+ private final float mSlopMultiplier;
private float mLastMotionY;
private float mPullGestureMinXSpan;
private Callback mCallback;
@@ -177,6 +178,7 @@
final ViewConfiguration configuration = ViewConfiguration.get(mContext);
mTouchSlop = configuration.getScaledTouchSlop();
+ mSlopMultiplier = configuration.getAmbiguousGestureMultiplier();
mSGD = new ScaleGestureDetector(context, mScaleGestureListener);
mFlingAnimationUtils = new FlingAnimationUtils(mContext.getResources().getDisplayMetrics(),
@@ -258,6 +260,13 @@
mScrollAdapter = adapter;
}
+ private float getTouchSlop(MotionEvent event) {
+ // Adjust the touch slop if another gesture may be being performed.
+ return event.getClassification() == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE
+ ? mTouchSlop * mSlopMultiplier
+ : mTouchSlop;
+ }
+
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!isEnabled()) {
@@ -303,7 +312,7 @@
if (mWatchingForPull) {
final float yDiff = ev.getRawY() - mInitialTouchY;
final float xDiff = ev.getRawX() - mInitialTouchX;
- if (yDiff > mTouchSlop && yDiff > Math.abs(xDiff)) {
+ if (yDiff > getTouchSlop(ev) && yDiff > Math.abs(xDiff)) {
if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)");
mWatchingForPull = false;
if (mResizedView != null && !isFullyExpanded(mResizedView)) {
@@ -431,7 +440,7 @@
if (mWatchingForPull) {
final float yDiff = ev.getRawY() - mInitialTouchY;
final float xDiff = ev.getRawX() - mInitialTouchX;
- if (yDiff > mTouchSlop && yDiff > Math.abs(xDiff)) {
+ if (yDiff > getTouchSlop(ev) && yDiff > Math.abs(xDiff)) {
if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)");
mWatchingForPull = false;
if (mResizedView != null && !isFullyExpanded(mResizedView)) {
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 02a4521..d17ca404 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -69,6 +69,7 @@
private final FlingAnimationUtils mFlingAnimationUtils;
private float mPagingTouchSlop;
+ private final float mSlopMultiplier;
private final Callback mCallback;
private final int mSwipeDirection;
private final VelocityTracker mVelocityTracker;
@@ -84,11 +85,28 @@
private float mTranslation = 0;
private boolean mMenuRowIntercepting;
- private boolean mLongPressSent;
- private Runnable mWatchLongPress;
private final long mLongPressTimeout;
+ private boolean mLongPressSent;
+ private final float[] mDownLocation = new float[2];
+ private final Runnable mPerformLongPress = new Runnable() {
- final private int[] mTmpPos = new int[2];
+ private final int[] mViewOffset = new int[2];
+
+ @Override
+ public void run() {
+ if (mCurrView != null && !mLongPressSent) {
+ mLongPressSent = true;
+ if (mCurrView instanceof ExpandableNotificationRow) {
+ mCurrView.getLocationOnScreen(mViewOffset);
+ final int x = (int) mDownLocation[0] - mViewOffset[0];
+ final int y = (int) mDownLocation[1] - mViewOffset[1];
+ mCurrView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+ ((ExpandableNotificationRow) mCurrView).doLongClickCallback(x, y);
+ }
+ }
+ }
+ };
+
private final int mFalsingThreshold;
private boolean mTouchAboveFalsingThreshold;
private boolean mDisableHwLayers;
@@ -102,7 +120,9 @@
mHandler = new Handler();
mSwipeDirection = swipeDirection;
mVelocityTracker = VelocityTracker.obtain();
- mPagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
+ final ViewConfiguration configuration = ViewConfiguration.get(context);
+ mPagingTouchSlop = configuration.getScaledPagingTouchSlop();
+ mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier();
// Extra long-press!
mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f);
@@ -255,10 +275,7 @@
}
public void cancelLongPress() {
- if (mWatchLongPress != null) {
- mHandler.removeCallbacks(mWatchLongPress);
- mWatchLongPress = null;
- }
+ mHandler.removeCallbacks(mPerformLongPress);
}
@Override
@@ -287,27 +304,9 @@
mInitialTouchPos = getPos(ev);
mPerpendicularInitialTouchPos = getPerpendicularPos(ev);
mTranslation = getTranslation(mCurrView);
- if (mWatchLongPress == null) {
- mWatchLongPress = new Runnable() {
- @Override
- public void run() {
- if (mCurrView != null && !mLongPressSent) {
- mLongPressSent = true;
- mCurrView.getLocationOnScreen(mTmpPos);
- final int x = (int) ev.getRawX() - mTmpPos[0];
- final int y = (int) ev.getRawY() - mTmpPos[1];
- if (mCurrView instanceof ExpandableNotificationRow) {
- mCurrView.sendAccessibilityEvent(
- AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
- ExpandableNotificationRow currRow =
- (ExpandableNotificationRow) mCurrView;
- currRow.doLongClickCallback(x, y);
- }
- }
- }
- };
- }
- mHandler.postDelayed(mWatchLongPress, mLongPressTimeout);
+ mDownLocation[0] = ev.getRawX();
+ mDownLocation[1] = ev.getRawY();
+ mHandler.postDelayed(mPerformLongPress, mLongPressTimeout);
}
break;
@@ -318,7 +317,12 @@
float perpendicularPos = getPerpendicularPos(ev);
float delta = pos - mInitialTouchPos;
float deltaPerpendicular = perpendicularPos - mPerpendicularInitialTouchPos;
- if (Math.abs(delta) > mPagingTouchSlop
+ // Adjust the touch slop if another gesture may be being performed.
+ final float pagingTouchSlop =
+ ev.getClassification() == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE
+ ? mPagingTouchSlop * mSlopMultiplier
+ : mPagingTouchSlop;
+ if (Math.abs(delta) > pagingTouchSlop
&& Math.abs(delta) > Math.abs(deltaPerpendicular)) {
if (mCallback.canChildBeDragged(mCurrView)) {
mCallback.onBeginDrag(mCurrView);
@@ -327,6 +331,11 @@
mTranslation = getTranslation(mCurrView);
}
cancelLongPress();
+ } else if (ev.getClassification() == MotionEvent.CLASSIFICATION_DEEP_PRESS
+ && mHandler.hasCallbacks(mPerformLongPress)) {
+ // Accelerate the long press signal.
+ cancelLongPress();
+ mPerformLongPress.run();
}
}
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index 5adee40..4fa7822 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -48,7 +48,8 @@
private float mInitialTouchX;
private float mInitialTouchY;
private boolean mDraggingDown;
- private float mTouchSlop;
+ private final float mTouchSlop;
+ private final float mSlopMultiplier;
private DragDownCallback mDragDownCallback;
private View mHost;
private final int[] mTemp2 = new int[2];
@@ -62,7 +63,9 @@
FalsingManager falsingManager) {
mMinDragDistance = context.getResources().getDimensionPixelSize(
R.dimen.keyguard_drag_down_min_distance);
- mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+ final ViewConfiguration configuration = ViewConfiguration.get(context);
+ mTouchSlop = configuration.getScaledTouchSlop();
+ mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier();
mCallback = callback;
mDragDownCallback = dragDownCallback;
mHost = host;
@@ -85,7 +88,12 @@
case MotionEvent.ACTION_MOVE:
final float h = y - mInitialTouchY;
- if (h > mTouchSlop && h > Math.abs(x - mInitialTouchX)) {
+ // Adjust the touch slop if another gesture may be being performed.
+ final float touchSlop =
+ event.getClassification() == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE
+ ? mTouchSlop * mSlopMultiplier
+ : mTouchSlop;
+ if (h > touchSlop && h > Math.abs(x - mInitialTouchX)) {
mFalsingManager.onNotificatonStartDraggingDown();
mDraggingDown = true;
captureStartingChild(mInitialTouchX, mInitialTouchY);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 4d4a2ded..c63e19e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -222,6 +222,7 @@
private boolean mIsScrollerBoundSet;
private Runnable mFinishScrollingCallback;
private int mTouchSlop;
+ private float mSlopMultiplier;
private int mMinimumVelocity;
private int mMaximumVelocity;
private int mOverflingDistance;
@@ -1022,6 +1023,7 @@
setClipChildren(false);
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = configuration.getScaledTouchSlop();
+ mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier();
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mOverflingDistance = configuration.getScaledOverflingDistance();
@@ -3744,6 +3746,13 @@
mLongPressListener = listener;
}
+ private float getTouchSlop(MotionEvent event) {
+ // Adjust the touch slop if another gesture may be being performed.
+ return event.getClassification() == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE
+ ? mTouchSlop * mSlopMultiplier
+ : mTouchSlop;
+ }
+
@Override
@ShadeViewRefactor(RefactorComponent.INPUT)
public boolean onTouchEvent(MotionEvent ev) {
@@ -3891,12 +3900,13 @@
int deltaY = mLastMotionY - y;
final int xDiff = Math.abs(x - mDownX);
final int yDiff = Math.abs(deltaY);
- if (!mIsBeingDragged && yDiff > mTouchSlop && yDiff > xDiff) {
+ final float touchSlop = getTouchSlop(ev);
+ if (!mIsBeingDragged && yDiff > touchSlop && yDiff > xDiff) {
setIsBeingDragged(true);
if (deltaY > 0) {
- deltaY -= mTouchSlop;
+ deltaY -= touchSlop;
} else {
- deltaY += mTouchSlop;
+ deltaY += touchSlop;
}
}
if (mIsBeingDragged) {
@@ -4083,8 +4093,9 @@
private void handleEmptySpaceClick(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_MOVE:
- if (mTouchIsClick && (Math.abs(ev.getY() - mInitialTouchY) > mTouchSlop
- || Math.abs(ev.getX() - mInitialTouchX) > mTouchSlop)) {
+ final float touchSlop = getTouchSlop(ev);
+ if (mTouchIsClick && (Math.abs(ev.getY() - mInitialTouchY) > touchSlop
+ || Math.abs(ev.getX() - mInitialTouchX) > touchSlop)) {
mTouchIsClick = false;
}
break;
@@ -4168,7 +4179,7 @@
final int x = (int) ev.getX(pointerIndex);
final int yDiff = Math.abs(y - mLastMotionY);
final int xDiff = Math.abs(x - mDownX);
- if (yDiff > mTouchSlop && yDiff > xDiff) {
+ if (yDiff > getTouchSlop(ev) && yDiff > xDiff) {
setIsBeingDragged(true);
mLastMotionY = y;
mDownX = x;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index f9726d2..5588c24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -1021,7 +1021,8 @@
trackMovement(event);
return true;
}
- if (Math.abs(h) > mTouchSlop && Math.abs(h) > Math.abs(x - mInitialTouchX)
+ if (Math.abs(h) > getTouchSlop(event)
+ && Math.abs(h) > Math.abs(x - mInitialTouchX)
&& shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, h)) {
mQsTracking = true;
onQsExpansionStarted();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 2719a32..481401b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -30,8 +30,6 @@
protected StatusBar mStatusBar;
protected HeadsUpManagerPhone mHeadsUpManager;
- protected int mTouchSlop;
-
protected KeyguardBottomAreaView mKeyguardBottomArea;
private OnConfigurationChangedListener mOnConfigurationChangedListener;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 30367ed..83cc4e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -91,7 +91,8 @@
protected boolean mTracking;
private boolean mTouchSlopExceeded;
private int mTrackingPointer;
- protected int mTouchSlop;
+ private int mTouchSlop;
+ private float mSlopMultiplier;
protected boolean mHintAnimationRunning;
private boolean mOverExpandedBeforeFling;
private boolean mTouchAboveFalsingThreshold;
@@ -260,11 +261,19 @@
protected void loadDimens() {
final ViewConfiguration configuration = ViewConfiguration.get(mView.getContext());
mTouchSlop = configuration.getScaledTouchSlop();
+ mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier();
mHintDistance = mResources.getDimension(R.dimen.hint_move_distance);
mUnlockFalsingThreshold = mResources.getDimensionPixelSize(
R.dimen.unlock_falsing_threshold);
}
+ protected float getTouchSlop(MotionEvent event) {
+ // Adjust the touch slop if another gesture may be being performed.
+ return event.getClassification() == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE
+ ? mTouchSlop * mSlopMultiplier
+ : mTouchSlop;
+ }
+
private void addMovement(MotionEvent event) {
// Add movement to velocity tracker using raw screen X and Y coordinates instead
// of window coordinates because the window frame may be moving at the same time.
@@ -1111,7 +1120,8 @@
addMovement(event);
if (scrolledToBottom || mTouchStartedInEmptyArea || mAnimatingOnDown) {
float hAbs = Math.abs(h);
- if ((h < -mTouchSlop || (mAnimatingOnDown && hAbs > mTouchSlop))
+ float touchSlop = getTouchSlop(event);
+ if ((h < -touchSlop || (mAnimatingOnDown && hAbs > touchSlop))
&& hAbs > Math.abs(x - mInitialTouchX)) {
cancelHeightAnimator();
startExpandMotion(x, y, true /* startTracking */, mExpandedHeight);
@@ -1228,7 +1238,8 @@
// If the panel was collapsed when touching, we only need to check for the
// y-component of the gesture, as we have no conflicting horizontal gesture.
- if (Math.abs(h) > mTouchSlop && (Math.abs(h) > Math.abs(x - mInitialTouchX)
+ if (Math.abs(h) > getTouchSlop(event)
+ && (Math.abs(h) > Math.abs(x - mInitialTouchX)
|| mIgnoreXTouchSlop)) {
mTouchSlopExceeded = true;
if (mGestureWaitForTouchSlop && !mTracking && !mCollapsedAndHeadsUpOnDown) {