diff options
author | Geoffrey Pitsch <gpitsch@google.com> | 2017-08-18 11:15:12 -0400 |
---|---|---|
committer | Geoffrey Pitsch <gpitsch@google.com> | 2017-08-24 13:22:20 -0400 |
commit | 2ca798932ea2945184df1c5500b5b9f08af9af55 (patch) | |
tree | 3ab796e2fcbca6dc1f7f840f74c4f96a4a1bba71 /packages/SystemUI/src | |
parent | 34eac2c59b3d9323d8519803179d01aad61e8455 (diff) |
Support keyboard long-press on notifications
ExpandableNotificationRow now handles long-clicks for keyboard support.
SwipeHelper calls performLongClick to trigger the listener on the row.
Now that the View listens to long clicks, SwipeHelper cancels
long-presses on the View when it see touch down events, so the event
doesn't get duped in the touch case.
Bug: 34840327
Test: manual
Change-Id: Ibeb93507781443d6b2dac209afd889b1d8d54aeb
Diffstat (limited to 'packages/SystemUI/src')
6 files changed, 100 insertions, 66 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index 4b377153e558..8c1b736d5698 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -83,7 +83,6 @@ public class SwipeHelper implements Gefingerpoken { private boolean mMenuRowIntercepting; private boolean mLongPressSent; - private LongPressListener mLongPressListener; private Runnable mWatchLongPress; private final long mLongPressTimeout; @@ -115,10 +114,6 @@ public class SwipeHelper implements Gefingerpoken { mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f); } - public void setLongPressListener(LongPressListener listener) { - mLongPressListener = listener; - } - public void setDensityScale(float densityScale) { mDensityScale = densityScale; } @@ -257,7 +252,7 @@ public class SwipeHelper implements Gefingerpoken { } } - public void removeLongPressCallback() { + public void cancelLongPress() { if (mWatchLongPress != null) { mHandler.removeCallbacks(mWatchLongPress); mWatchLongPress = null; @@ -281,6 +276,14 @@ public class SwipeHelper implements Gefingerpoken { mVelocityTracker.clear(); mCurrView = mCallback.getChildAtPosition(ev); + // The SwipeHelper sends its own long-press, don't let the view send a dupe. + // Queue up a cancelLongPress on the view a few ms after we see a down event. + mHandler.post(() -> { + if (mCurrView != null) { + mCurrView.cancelLongPress(); + } + }); + if (mCurrView != null) { onDownUpdate(mCurrView, ev); mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView); @@ -288,33 +291,26 @@ public class SwipeHelper implements Gefingerpoken { mInitialTouchPos = getPos(ev); mPerpendicularInitialTouchPos = getPerpendicularPos(ev); mTranslation = getTranslation(mCurrView); - if (mLongPressListener != null) { - if (mWatchLongPress == null) { - mWatchLongPress = new Runnable() { - @Override - public void run() { - if (mCurrView != null && !mLongPressSent) { - mLongPressSent = true; - mCurrView.sendAccessibilityEvent( - AccessibilityEvent.TYPE_VIEW_LONG_CLICKED); - mCurrView.getLocationOnScreen(mTmpPos); - final int x = (int) ev.getRawX() - mTmpPos[0]; - final int y = (int) ev.getRawY() - mTmpPos[1]; - MenuItem menuItem = null; - if (mCurrView instanceof ExpandableNotificationRow) { - menuItem = ((ExpandableNotificationRow) mCurrView) - .getProvider().getLongpressMenuItem(mContext); - } - if (menuItem != null) { - mLongPressListener.onLongPress(mCurrView, x, y, - menuItem); - } + 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) { + ExpandableNotificationRow currRow = + (ExpandableNotificationRow) mCurrView; + currRow.setLongPressPosition(x, y); + currRow.performLongClick(x, y); } } - }; - } - mHandler.postDelayed(mWatchLongPress, mLongPressTimeout); + } + }; } + mHandler.postDelayed(mWatchLongPress, mLongPressTimeout); } break; @@ -331,7 +327,7 @@ public class SwipeHelper implements Gefingerpoken { mDragging = true; mInitialTouchPos = getPos(ev); mTranslation = getTranslation(mCurrView); - removeLongPressCallback(); + cancelLongPress(); } } break; @@ -343,7 +339,7 @@ public class SwipeHelper implements Gefingerpoken { mCurrView = null; mLongPressSent = false; mMenuRowIntercepting = false; - removeLongPressCallback(); + cancelLongPress(); if (captured) return true; break; } @@ -586,7 +582,7 @@ public class SwipeHelper implements Gefingerpoken { // We are not doing anything, make sure the long press callback // is not still ticking like a bomb waiting to go off. - removeLongPressCallback(); + cancelLongPress(); return false; } } @@ -734,15 +730,4 @@ public class SwipeHelper implements Gefingerpoken { */ float getFalsingThresholdFactor(); } - - /** - * Equivalent to View.OnLongClickListener with coordinates - */ - public interface LongPressListener { - /** - * Equivalent to {@link View.OnLongClickListener#onLongClick(View)} with coordinates - * @return whether the longpress was handled - */ - boolean onLongPress(View v, int x, int y, MenuItem item); - } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 7bc1a39dfff5..b43626fa5003 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -172,6 +172,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private boolean mShowNoBackground; private ExpandableNotificationRow mNotificationParent; private OnExpandClickListener mOnExpandClickListener; + + // Listener will be called when receiving a long click event. + // Use #setLongPressPosition to optionally assign positional data with the long press. + private LongPressListener mLongPressListener; + private boolean mLongPressPositionSet = false; + private int mLongPressX = 0; + private int mLongPressY = 0; + private boolean mGroupExpansionChanging; /** @@ -773,6 +781,16 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mOnExpandClickListener = onExpandClickListener; } + public void setLongPressListener(LongPressListener longPressListener) { + mLongPressListener = longPressListener; + } + + public void setLongPressPosition(int x, int y) { + mLongPressPositionSet = true; + mLongPressX = x; + mLongPressY = y; + } + @Override public void setOnClickListener(@Nullable OnClickListener l) { super.setOnClickListener(l); @@ -1321,6 +1339,25 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mTranslateableViews.remove(mChildrenContainerStub); mTranslateableViews.remove(mGutsStub); } + + setOnLongClickListener((View v) -> { + createMenu(); + MenuItem menuItem = getProvider().getLongpressMenuItem(mContext); + if (mLongPressListener != null && menuItem != null) { + int x, y; + if (mLongPressPositionSet) { + x = mLongPressX; + y = mLongPressY; + } else { + // No position assigned - use the center of the View + x = getWidth() / 2; + y = getHeight() / 2; + } + mLongPressPositionSet = false; + return mLongPressListener.onLongPress(this, x, y, menuItem); + } + return false; + }); } public void resetTranslation() { @@ -2304,4 +2341,15 @@ public class ExpandableNotificationRow extends ActivatableNotificationView protected void setChildrenContainer(NotificationChildrenContainer childrenContainer) { mChildrenContainer = childrenContainer; } + + /** + * Equivalent to View.OnLongClickListener with coordinates + */ + public interface LongPressListener { + /** + * Equivalent to {@link View.OnLongClickListener#onLongClick(View)} with coordinates + * @return whether the longpress was handled + */ + boolean onLongPress(View v, int x, int y, MenuItem item); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index 680f693a83f8..2c507363663c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -44,6 +44,7 @@ import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.recents.Recents; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener; +import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment; @@ -247,11 +248,12 @@ public class CarStatusBar extends StatusBar implements } /** - * Returns the {@link com.android.systemui.SwipeHelper.LongPressListener} that will be - * triggered when a notification card is long-pressed. + * Returns the + * {@link com.android.systemui.statusbar.ExpandableNotificationRow.LongPressListener} that will + * be triggered when a notification card is long-pressed. */ @Override - protected SwipeHelper.LongPressListener getNotificationLongClicker() { + protected ExpandableNotificationRow.LongPressListener getNotificationLongClicker() { // For the automative use case, we do not want to the user to be able to interact with // a notification other than a regular click. As a result, just return null for the // long click listener. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index 04be35789807..94530352798e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -700,7 +700,7 @@ public class NotificationPanelView extends PanelView implements mInitialHeightOnTouch = mQsExpansionHeight; mQsTracking = true; mIntercepting = false; - mNotificationStackScroller.removeLongPressCallback(); + mNotificationStackScroller.cancelLongPress(); } break; case MotionEvent.ACTION_POINTER_UP: @@ -736,7 +736,7 @@ public class NotificationPanelView extends PanelView implements mInitialTouchY = y; mInitialTouchX = x; mIntercepting = false; - mNotificationStackScroller.removeLongPressCallback(); + mNotificationStackScroller.cancelLongPress(); return true; } break; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index db4ea504c760..ad7453ae99d1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -168,7 +168,6 @@ import com.android.systemui.Interpolators; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.RecentsComponent; -import com.android.systemui.SwipeHelper; import com.android.systemui.SystemUI; import com.android.systemui.SystemUIFactory; import com.android.systemui.UiOffloadThread; @@ -4940,7 +4939,7 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onTouchSlopExceeded() { - mStackScroller.removeLongPressCallback(); + mStackScroller.cancelLongPress(); mStackScroller.checkSnoozeLeavebehind(); } @@ -5576,7 +5575,7 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onDoubleTap(float screenX, float screenY) { - if (screenX > 0 && screenY > 0 && mAmbientIndicationContainer != null + if (screenX > 0 && screenY > 0 && mAmbientIndicationContainer != null && mAmbientIndicationContainer.getVisibility() == View.VISIBLE) { mAmbientIndicationContainer.getLocationOnScreen(mTmpInt2); float viewX = screenX - mTmpInt2[0]; @@ -6422,14 +6421,15 @@ public class StatusBar extends SystemUI implements DemoMode, true /* removeControls */, x, y, true /* resetMenu */); } - protected SwipeHelper.LongPressListener getNotificationLongClicker() { - return new SwipeHelper.LongPressListener() { + protected ExpandableNotificationRow.LongPressListener getNotificationLongClicker() { + return new ExpandableNotificationRow.LongPressListener() { @Override public boolean onLongPress(View v, final int x, final int y, MenuItem item) { if (!(v instanceof ExpandableNotificationRow)) { return false; } + if (v.getWindowToken() == null) { Log.e(TAG, "Trying to show notification guts, but not attached to window"); return false; @@ -6444,7 +6444,7 @@ public class StatusBar extends SystemUI implements DemoMode, closeAndSaveGuts(false /* removeLeavebehind */, false /* force */, true /* removeControls */, -1 /* x */, -1 /* y */, true /* resetMenu */); - return false; + return true; } bindGuts(row, item); NotificationGuts guts = row.getGuts(); @@ -6730,6 +6730,7 @@ public class StatusBar extends SystemUI implements DemoMode, row.setOnExpandClickListener(this); row.setRemoteViewClickHandler(mOnClickHandler); row.setInflationCallback(this); + row.setLongPressListener(getNotificationLongClicker()); // Get the app name. // Note that Notification.Builder#bindHeaderAppName has similar logic diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index c2da72bb666e..dcf7439b4a12 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -241,7 +241,7 @@ public class NotificationStackScrollLayout extends ViewGroup * motion. */ private int mMaxScrollAfterExpand; - private SwipeHelper.LongPressListener mLongPressListener; + private ExpandableNotificationRow.LongPressListener mLongPressListener; private NotificationMenuRowPlugin mCurrMenuRow; private View mTranslatingParentView; @@ -411,7 +411,6 @@ public class NotificationStackScrollLayout extends ViewGroup mExpandHelper.setEventSource(this); mExpandHelper.setScrollAdapter(this); mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, this, getContext()); - mSwipeHelper.setLongPressListener(mLongPressListener); mStackScrollAlgorithm = createStackScrollAlgorithm(context); initView(context); mFalsingManager = FalsingManager.getInstance(context); @@ -885,8 +884,7 @@ public class NotificationStackScrollLayout extends ViewGroup return firstChild != null ? firstChild.getMinHeight() : mCollapsedSize; } - public void setLongPressListener(SwipeHelper.LongPressListener listener) { - mSwipeHelper.setLongPressListener(listener); + public void setLongPressListener(ExpandableNotificationRow.LongPressListener listener) { mLongPressListener = listener; } @@ -1162,7 +1160,7 @@ public class NotificationStackScrollLayout extends ViewGroup if (v instanceof ExpandableNotificationRow) { ((ExpandableNotificationRow) v).setUserLocked(userLocked); } - removeLongPressCallback(); + cancelLongPress(); requestDisallowInterceptTouchEvent(true); } @@ -2568,7 +2566,7 @@ public class NotificationStackScrollLayout extends ViewGroup public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { super.requestDisallowInterceptTouchEvent(disallowIntercept); if (disallowIntercept) { - mSwipeHelper.removeLongPressCallback(); + cancelLongPress(); } } @@ -3289,7 +3287,7 @@ public class NotificationStackScrollLayout extends ViewGroup mIsBeingDragged = isDragged; if (isDragged) { requestDisallowInterceptTouchEvent(true); - removeLongPressCallback(); + cancelLongPress(); } } @@ -3297,7 +3295,7 @@ public class NotificationStackScrollLayout extends ViewGroup public void onWindowFocusChanged(boolean hasWindowFocus) { super.onWindowFocusChanged(hasWindowFocus); if (!hasWindowFocus) { - removeLongPressCallback(); + cancelLongPress(); } } @@ -3311,7 +3309,7 @@ public class NotificationStackScrollLayout extends ViewGroup @Override public void requestDisallowLongPress() { - removeLongPressCallback(); + cancelLongPress(); } @Override @@ -3319,8 +3317,8 @@ public class NotificationStackScrollLayout extends ViewGroup mDisallowDismissInThisMotion = true; } - public void removeLongPressCallback() { - mSwipeHelper.removeLongPressCallback(); + public void cancelLongPress() { + mSwipeHelper.cancelLongPress(); } @Override |