Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c87f3792 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Handle Keyboard long-presses and Talkback shortcut on notifications"

parents 35f0b541 409db276
Loading
Loading
Loading
Loading
+20 −42
Original line number Original line Diff line number Diff line
@@ -83,7 +83,6 @@ public class SwipeHelper implements Gefingerpoken {


    private boolean mMenuRowIntercepting;
    private boolean mMenuRowIntercepting;
    private boolean mLongPressSent;
    private boolean mLongPressSent;
    private LongPressListener mLongPressListener;
    private Runnable mWatchLongPress;
    private Runnable mWatchLongPress;
    private final long mLongPressTimeout;
    private final long mLongPressTimeout;


@@ -115,10 +114,6 @@ public class SwipeHelper implements Gefingerpoken {
        mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f);
        mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f);
    }
    }


    public void setLongPressListener(LongPressListener listener) {
        mLongPressListener = listener;
    }

    public void setDensityScale(float densityScale) {
    public void setDensityScale(float densityScale) {
        mDensityScale = densityScale;
        mDensityScale = densityScale;
    }
    }
@@ -257,7 +252,7 @@ public class SwipeHelper implements Gefingerpoken {
        }
        }
    }
    }


    public void removeLongPressCallback() {
    public void cancelLongPress() {
        if (mWatchLongPress != null) {
        if (mWatchLongPress != null) {
            mHandler.removeCallbacks(mWatchLongPress);
            mHandler.removeCallbacks(mWatchLongPress);
            mWatchLongPress = null;
            mWatchLongPress = null;
@@ -288,26 +283,21 @@ public class SwipeHelper implements Gefingerpoken {
                    mInitialTouchPos = getPos(ev);
                    mInitialTouchPos = getPos(ev);
                    mPerpendicularInitialTouchPos = getPerpendicularPos(ev);
                    mPerpendicularInitialTouchPos = getPerpendicularPos(ev);
                    mTranslation = getTranslation(mCurrView);
                    mTranslation = getTranslation(mCurrView);
                    if (mLongPressListener != null) {
                    if (mWatchLongPress == null) {
                    if (mWatchLongPress == null) {
                        mWatchLongPress = new Runnable() {
                        mWatchLongPress = new Runnable() {
                            @Override
                            @Override
                            public void run() {
                            public void run() {
                                if (mCurrView != null && !mLongPressSent) {
                                if (mCurrView != null && !mLongPressSent) {
                                    mLongPressSent = true;
                                    mLongPressSent = true;
                                        mCurrView.sendAccessibilityEvent(
                                                AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
                                    mCurrView.getLocationOnScreen(mTmpPos);
                                    mCurrView.getLocationOnScreen(mTmpPos);
                                    final int x = (int) ev.getRawX() - mTmpPos[0];
                                    final int x = (int) ev.getRawX() - mTmpPos[0];
                                    final int y = (int) ev.getRawY() - mTmpPos[1];
                                    final int y = (int) ev.getRawY() - mTmpPos[1];
                                        MenuItem menuItem = null;
                                    if (mCurrView instanceof ExpandableNotificationRow) {
                                    if (mCurrView instanceof ExpandableNotificationRow) {
                                            menuItem = ((ExpandableNotificationRow) mCurrView)
                                        mCurrView.sendAccessibilityEvent(
                                                    .getProvider().getLongpressMenuItem(mContext);
                                                AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
                                        }
                                        ExpandableNotificationRow currRow =
                                        if (menuItem != null) {
                                                (ExpandableNotificationRow) mCurrView;
                                            mLongPressListener.onLongPress(mCurrView, x, y,
                                        currRow.doLongClickCallback(x, y);
                                                    menuItem);
                                    }
                                    }
                                }
                                }
                            }
                            }
@@ -315,7 +305,6 @@ public class SwipeHelper implements Gefingerpoken {
                    }
                    }
                    mHandler.postDelayed(mWatchLongPress, mLongPressTimeout);
                    mHandler.postDelayed(mWatchLongPress, mLongPressTimeout);
                }
                }
                }
                break;
                break;


            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_MOVE:
@@ -331,7 +320,7 @@ public class SwipeHelper implements Gefingerpoken {
                        mDragging = true;
                        mDragging = true;
                        mInitialTouchPos = getPos(ev);
                        mInitialTouchPos = getPos(ev);
                        mTranslation = getTranslation(mCurrView);
                        mTranslation = getTranslation(mCurrView);
                        removeLongPressCallback();
                        cancelLongPress();
                    }
                    }
                }
                }
                break;
                break;
@@ -343,7 +332,7 @@ public class SwipeHelper implements Gefingerpoken {
                mCurrView = null;
                mCurrView = null;
                mLongPressSent = false;
                mLongPressSent = false;
                mMenuRowIntercepting = false;
                mMenuRowIntercepting = false;
                removeLongPressCallback();
                cancelLongPress();
                if (captured) return true;
                if (captured) return true;
                break;
                break;
        }
        }
@@ -586,7 +575,7 @@ public class SwipeHelper implements Gefingerpoken {


                // We are not doing anything, make sure the long press callback
                // We are not doing anything, make sure the long press callback
                // is not still ticking like a bomb waiting to go off.
                // is not still ticking like a bomb waiting to go off.
                removeLongPressCallback();
                cancelLongPress();
                return false;
                return false;
            }
            }
        }
        }
@@ -734,15 +723,4 @@ public class SwipeHelper implements Gefingerpoken {
         */
         */
        float getFalsingThresholdFactor();
        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);
    }
}
}
+66 −0
Original line number Original line Diff line number Diff line
@@ -36,6 +36,7 @@ import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.FloatProperty;
import android.util.Property;
import android.util.Property;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.MotionEvent;
import android.view.NotificationHeaderView;
import android.view.NotificationHeaderView;
@@ -174,6 +175,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    private boolean mShowNoBackground;
    private boolean mShowNoBackground;
    private ExpandableNotificationRow mNotificationParent;
    private ExpandableNotificationRow mNotificationParent;
    private OnExpandClickListener mOnExpandClickListener;
    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;
    private boolean mGroupExpansionChanging;


    /**
    /**
@@ -788,6 +794,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        mOnExpandClickListener = onExpandClickListener;
        mOnExpandClickListener = onExpandClickListener;
    }
    }


    public void setLongPressListener(LongPressListener longPressListener) {
        mLongPressListener = longPressListener;
    }

    @Override
    @Override
    public void setOnClickListener(@Nullable OnClickListener l) {
    public void setOnClickListener(@Nullable OnClickListener l) {
        super.setOnClickListener(l);
        super.setOnClickListener(l);
@@ -1338,6 +1348,47 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        }
        }
    }
    }


    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() {
    public void resetTranslation() {
        if (mTranslateAnim != null) {
        if (mTranslateAnim != null) {
            mTranslateAnim.cancel();
            mTranslateAnim.cancel();
@@ -2205,6 +2256,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    @Override
    @Override
    public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
    public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
        super.onInitializeAccessibilityNodeInfoInternal(info);
        super.onInitializeAccessibilityNodeInfoInternal(info);
        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
        if (canViewBeDismissed()) {
        if (canViewBeDismissed()) {
            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
            info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
        }
        }
@@ -2244,6 +2296,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
            case AccessibilityNodeInfo.ACTION_EXPAND:
            case AccessibilityNodeInfo.ACTION_EXPAND:
                mExpandClickListener.onClick(this);
                mExpandClickListener.onClick(this);
                return true;
                return true;
            case AccessibilityNodeInfo.ACTION_LONG_CLICK:
                doLongClickCallback();
                return true;
        }
        }
        return false;
        return false;
    }
    }
@@ -2332,4 +2387,15 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
    protected void setChildrenContainer(NotificationChildrenContainer childrenContainer) {
    protected void setChildrenContainer(NotificationChildrenContainer childrenContainer) {
        mChildrenContainer = 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);
    }
}
}
+5 −3
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
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.NotificationData;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
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
     * Returns the
     * triggered when a notification card is long-pressed.
     * {@link com.android.systemui.statusbar.ExpandableNotificationRow.LongPressListener} that will
     * be triggered when a notification card is long-pressed.
     */
     */
    @Override
    @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
        // 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
        // a notification other than a regular click. As a result, just return null for the
        // long click listener.
        // long click listener.
+2 −2
Original line number Original line Diff line number Diff line
@@ -704,7 +704,7 @@ public class NotificationPanelView extends PanelView implements
                    mInitialHeightOnTouch = mQsExpansionHeight;
                    mInitialHeightOnTouch = mQsExpansionHeight;
                    mQsTracking = true;
                    mQsTracking = true;
                    mIntercepting = false;
                    mIntercepting = false;
                    mNotificationStackScroller.removeLongPressCallback();
                    mNotificationStackScroller.cancelLongPress();
                }
                }
                break;
                break;
            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_POINTER_UP:
@@ -740,7 +740,7 @@ public class NotificationPanelView extends PanelView implements
                    mInitialTouchY = y;
                    mInitialTouchY = y;
                    mInitialTouchX = x;
                    mInitialTouchX = x;
                    mIntercepting = false;
                    mIntercepting = false;
                    mNotificationStackScroller.removeLongPressCallback();
                    mNotificationStackScroller.cancelLongPress();
                    return true;
                    return true;
                }
                }
                break;
                break;
+7 −6
Original line number Original line Diff line number Diff line
@@ -160,7 +160,6 @@ import com.android.systemui.Interpolators;
import com.android.systemui.Prefs;
import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SwipeHelper;
import com.android.systemui.SystemUI;
import com.android.systemui.SystemUI;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.UiOffloadThread;
@@ -4838,7 +4837,7 @@ public class StatusBar extends SystemUI implements DemoMode,


    @Override
    @Override
    public void onTouchSlopExceeded() {
    public void onTouchSlopExceeded() {
        mStackScroller.removeLongPressCallback();
        mStackScroller.cancelLongPress();
        mStackScroller.checkSnoozeLeavebehind();
        mStackScroller.checkSnoozeLeavebehind();
    }
    }


@@ -6296,14 +6295,15 @@ public class StatusBar extends SystemUI implements DemoMode,
                true /* removeControls */, x, y, true /* resetMenu */);
                true /* removeControls */, x, y, true /* resetMenu */);
    }
    }


    protected SwipeHelper.LongPressListener getNotificationLongClicker() {
    protected ExpandableNotificationRow.LongPressListener getNotificationLongClicker() {
        return new SwipeHelper.LongPressListener() {
        return new ExpandableNotificationRow.LongPressListener() {
            @Override
            @Override
            public boolean onLongPress(View v, final int x, final int y,
            public boolean onLongPress(View v, final int x, final int y,
                    MenuItem item) {
                    MenuItem item) {
                if (!(v instanceof ExpandableNotificationRow)) {
                if (!(v instanceof ExpandableNotificationRow)) {
                    return false;
                    return false;
                }
                }

                if (v.getWindowToken() == null) {
                if (v.getWindowToken() == null) {
                    Log.e(TAG, "Trying to show notification guts, but not attached to window");
                    Log.e(TAG, "Trying to show notification guts, but not attached to window");
                    return false;
                    return false;
@@ -6318,7 +6318,7 @@ public class StatusBar extends SystemUI implements DemoMode,
                    closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
                    closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
                            true /* removeControls */, -1 /* x */, -1 /* y */,
                            true /* removeControls */, -1 /* x */, -1 /* y */,
                            true /* resetMenu */);
                            true /* resetMenu */);
                    return false;
                    return true;
                }
                }
                bindGuts(row, item);
                bindGuts(row, item);
                NotificationGuts guts = row.getGuts();
                NotificationGuts guts = row.getGuts();
@@ -6598,6 +6598,7 @@ public class StatusBar extends SystemUI implements DemoMode,
        row.setRemoteViewClickHandler(mOnClickHandler);
        row.setRemoteViewClickHandler(mOnClickHandler);
        row.setInflationCallback(this);
        row.setInflationCallback(this);
        row.setSecureStateProvider(this::isKeyguardCurrentlySecure);
        row.setSecureStateProvider(this::isKeyguardCurrentlySecure);
        row.setLongPressListener(getNotificationLongClicker());


        // Get the app name.
        // Get the app name.
        // Note that Notification.Builder#bindHeaderAppName has similar logic
        // Note that Notification.Builder#bindHeaderAppName has similar logic
Loading