Handle Keyboard long-presses and Talkback shortcut on notifications
An incremental improvement to keyboard support on the status bar.
SwipeHelper calls a method on ExpandableNotificationRow, which it then
manually invokes from keydown/ups and the AccessibilityAction shortcut.
Regular clicks on the lockscreen still do not activate the notification.
Bug: 34840327
Test: manual
Change-Id: I5b59dec26c5e20237c4136820fff902ff8221371
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 966e789..6c5f4b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -36,6 +36,7 @@
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Property;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.NotificationHeaderView;
@@ -174,6 +175,11 @@
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 mGroupExpansionChanging;
/**
@@ -788,6 +794,10 @@
mOnExpandClickListener = onExpandClickListener;
}
+ public void setLongPressListener(LongPressListener longPressListener) {
+ mLongPressListener = longPressListener;
+ }
+
@Override
public void setOnClickListener(@Nullable OnClickListener l) {
super.setOnClickListener(l);
@@ -1338,6 +1348,47 @@
}
}
+ private void doLongClickCallback() {
+ doLongClickCallback(getWidth() / 2, getHeight() / 2);
+ }
+
+ public void doLongClickCallback(int x, int y) {
+ createMenu();
+ MenuItem menuItem = getProvider().getLongpressMenuItem(mContext);
+ if (mLongPressListener != null && menuItem != null) {
+ mLongPressListener.onLongPress(this, x, y, menuItem);
+ }
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (KeyEvent.isConfirmKey(keyCode)) {
+ event.startTracking();
+ return true;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ if (KeyEvent.isConfirmKey(keyCode)) {
+ if (!event.isCanceled()) {
+ performClick();
+ }
+ return true;
+ }
+ return super.onKeyUp(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyLongPress(int keyCode, KeyEvent event) {
+ if (KeyEvent.isConfirmKey(keyCode)) {
+ doLongClickCallback();
+ return true;
+ }
+ return false;
+ }
+
public void resetTranslation() {
if (mTranslateAnim != null) {
mTranslateAnim.cancel();
@@ -2205,6 +2256,7 @@
@Override
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfoInternal(info);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
if (canViewBeDismissed()) {
info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
}
@@ -2244,6 +2296,9 @@
case AccessibilityNodeInfo.ACTION_EXPAND:
mExpandClickListener.onClick(this);
return true;
+ case AccessibilityNodeInfo.ACTION_LONG_CLICK:
+ doLongClickCallback();
+ return true;
}
return false;
}
@@ -2332,4 +2387,15 @@
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);
+ }
}