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

Commit 802e1316 authored by Arthur Hung's avatar Arthur Hung
Browse files

Count press counter by event time

Use event time to count the press counter that we could prevent panic
press will trigger unexpected gesture.

Bug: 195097897
Test: atest SingleKeyGestureTests
Change-Id: I5cb49288bb72db9d0e0d03aefb1c87ca44b46767
parent a14619e6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -951,7 +951,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior);
        } else if (count == 3) {
            powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
        } else if (interactive && !beganFromNonInteractive) {
        } else if (count == 1 && interactive && !beganFromNonInteractive) {
            if (mSideFpsEventHandler.onSinglePressDetected(eventTime)) {
                Slog.i(TAG, "Suppressing power key because the user is interacting with the "
                        + "fingerprint sensor");
+24 −21
Original line number Diff line number Diff line
@@ -44,7 +44,7 @@ public final class SingleKeyGestureDetector {
    private static final int MSG_KEY_VERY_LONG_PRESS = 1;
    private static final int MSG_KEY_DELAYED_PRESS = 2;

    private volatile int mKeyPressCounter;
    private int mKeyPressCounter;
    private boolean mBeganFromNonInteractive = false;

    private final ArrayList<SingleKeyRule> mRules = new ArrayList();
@@ -53,7 +53,6 @@ public final class SingleKeyGestureDetector {
    // Key code of current key down event, reset when key up.
    private int mDownKeyCode = KeyEvent.KEYCODE_UNKNOWN;
    private volatile boolean mHandledByLongPress = false;
    private volatile boolean mHandledByMultiPress = false;
    private final Handler mHandler;
    private long mLastDownTime = 0;
    private static final long MULTI_PRESS_TIMEOUT = ViewConfiguration.getMultiPressTimeout();
@@ -223,7 +222,6 @@ public final class SingleKeyGestureDetector {
            reset();
        }
        mDownKeyCode = keyCode;
        mLastDownTime = event.getDownTime();

        // Picks a new rule, return if no rule picked.
        if (mActiveRule == null) {
@@ -238,12 +236,21 @@ public final class SingleKeyGestureDetector {
                    break;
                }
            }
            mLastDownTime = 0;
        }
        if (mActiveRule == null) {
            return;
        }

        if (mKeyPressCounter == 0) {
        final long keyDownInterval = event.getDownTime() - mLastDownTime;
        mLastDownTime = event.getDownTime();
        if (keyDownInterval >= MULTI_PRESS_TIMEOUT) {
            mKeyPressCounter = 1;
        } else {
            mKeyPressCounter++;
        }

        if (mKeyPressCounter == 1) {
            if (mActiveRule.supportLongPress()) {
                final Message msg = mHandler.obtainMessage(MSG_KEY_LONG_PRESS, keyCode, 0,
                        mActiveRule);
@@ -263,17 +270,16 @@ public final class SingleKeyGestureDetector {
            mHandler.removeMessages(MSG_KEY_DELAYED_PRESS);

            // Trigger multi press immediately when reach max count.( > 1)
            if (mKeyPressCounter == mActiveRule.getMaxMultiPressCount() - 1) {
            if (mActiveRule.getMaxMultiPressCount() > 1
                    && mKeyPressCounter == mActiveRule.getMaxMultiPressCount()) {
                if (DEBUG) {
                    Log.i(TAG, "Trigger multi press " + mActiveRule.toString() + " for it"
                            + " reached the max count " + (mKeyPressCounter + 1));
                            + " reached the max count " + mKeyPressCounter);
                }
                final Message msg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, keyCode,
                        mKeyPressCounter + 1, mActiveRule);
                        mKeyPressCounter, mActiveRule);
                msg.setAsynchronous(true);
                mHandler.sendMessage(msg);
                mHandledByMultiPress = true;
                mKeyPressCounter = 0;
            }
        }
    }
@@ -286,10 +292,10 @@ public final class SingleKeyGestureDetector {
            return false;
        }

        if (mHandledByLongPress || mHandledByMultiPress) {
        if (mHandledByLongPress) {
            mHandledByLongPress = false;
            mHandledByMultiPress = false;
            mKeyPressCounter = 0;
            mActiveRule = null;
            return true;
        }

@@ -303,16 +309,17 @@ public final class SingleKeyGestureDetector {
                        1, mActiveRule);
                msg.setAsynchronous(true);
                mHandler.sendMessage(msg);
                reset();
                mActiveRule = null;
                return true;
            }

            // This could be a multi-press.  Wait a little bit longer to confirm.
            mKeyPressCounter++;
            if (mKeyPressCounter < mActiveRule.getMaxMultiPressCount()) {
                Message msg = mHandler.obtainMessage(MSG_KEY_DELAYED_PRESS, mActiveRule.mKeyCode,
                        mKeyPressCounter, mActiveRule);
                msg.setAsynchronous(true);
                mHandler.sendMessageDelayed(msg, MULTI_PRESS_TIMEOUT);
            }
            return true;
        }
        reset();
@@ -342,7 +349,6 @@ public final class SingleKeyGestureDetector {
        }

        mHandledByLongPress = false;
        mHandledByMultiPress = false;
        mDownKeyCode = KeyEvent.KEYCODE_UNKNOWN;
    }

@@ -373,9 +379,6 @@ public final class SingleKeyGestureDetector {
                Log.wtf(TAG, "No active rule.");
                return;
            }
            // We count the press count when interceptKeyUp. Reset the counter here to prevent if
            // the multi-press or press happened but the count is less than max multi-press count.
            mKeyPressCounter = 0;

            final int keyCode = msg.arg1;
            final int pressCount = msg.arg2;
+19 −27
Original line number Diff line number Diff line
@@ -150,11 +150,12 @@ public class SingleKeyGestureTests {

    }

    private void pressKey(long eventTime, int keyCode, long pressTime) {
        pressKey(eventTime, keyCode, pressTime, true /* interactive */);
    private void pressKey(int keyCode, long pressTime) {
        pressKey(keyCode, pressTime, true /* interactive */);
    }

    private void pressKey(long eventTime, int keyCode, long pressTime, boolean interactive) {
    private void pressKey(int keyCode, long pressTime, boolean interactive) {
        long eventTime = SystemClock.uptimeMillis();
        final KeyEvent keyDown = new KeyEvent(eventTime, eventTime, ACTION_DOWN,
                keyCode, 0 /* repeat */, 0 /* metaState */);
        mDetector.interceptKey(keyDown, interactive);
@@ -175,54 +176,48 @@ public class SingleKeyGestureTests {

    @Test
    public void testShortPress() throws InterruptedException {
        final long eventTime = SystemClock.uptimeMillis();
        pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */);
        pressKey(KEYCODE_POWER, 0 /* pressTime */);
        assertTrue(mShortPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));
    }

    @Test
    public void testLongPress() throws InterruptedException {
        final long eventTime = SystemClock.uptimeMillis();
        pressKey(eventTime, KEYCODE_POWER, mLongPressTime);
        pressKey(KEYCODE_POWER, mLongPressTime);
        assertTrue(mLongPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));
    }

    @Test
    public void testVeryLongPress() throws InterruptedException {
        final long eventTime = SystemClock.uptimeMillis();
        pressKey(eventTime, KEYCODE_POWER, mVeryLongPressTime);
        pressKey(KEYCODE_POWER, mVeryLongPressTime);
        assertTrue(mVeryLongPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));
    }

    @Test
    public void testMultiPress() throws InterruptedException {
        final long eventTime = SystemClock.uptimeMillis();
        // Double presses.
        mExpectedMultiPressCount = 2;
        pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */);
        pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */);
        pressKey(KEYCODE_POWER, 0 /* pressTime */);
        pressKey(KEYCODE_POWER, 0 /* pressTime */);
        assertTrue(mMultiPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));

        // Triple presses.
        mExpectedMultiPressCount = 3;
        mMultiPressed = new CountDownLatch(1);
        pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */);
        pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */);
        pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */);
        pressKey(KEYCODE_POWER, 0 /* pressTime */);
        pressKey(KEYCODE_POWER, 0 /* pressTime */);
        pressKey(KEYCODE_POWER, 0 /* pressTime */);
        assertTrue(mMultiPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));
    }

    @Test
    public void testNonInteractive() throws InterruptedException {
        long eventTime = SystemClock.uptimeMillis();
        // Disallow short press behavior from non interactive.
        mAllowNonInteractiveForPress = false;
        pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */, false /* interactive */);
        pressKey(KEYCODE_POWER, 0 /* pressTime */, false /* interactive */);
        assertFalse(mShortPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));

        // Allow long press behavior from non interactive.
        eventTime = SystemClock.uptimeMillis();
        pressKey(eventTime, KEYCODE_POWER, mLongPressTime, false /* interactive */);
        pressKey(KEYCODE_POWER, mLongPressTime, false /* interactive */);
        assertTrue(mLongPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));
    }

@@ -238,9 +233,8 @@ public class SingleKeyGestureTests {
            for (int i = 0; i < 100; i++) {
                mShortPressed = new CountDownLatch(2);
                newHandler.runWithScissors(() -> {
                    final long eventTime = SystemClock.uptimeMillis();
                    pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */);
                    pressKey(eventTime, KEYCODE_BACK, 0 /* pressTime */);
                    pressKey(KEYCODE_POWER, 0 /* pressTime */);
                    pressKey(KEYCODE_BACK, 0 /* pressTime */);
                }, mWaitTimeout);
                assertTrue(mShortPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));
            }
@@ -261,15 +255,13 @@ public class SingleKeyGestureTests {
                mMultiPressed = new CountDownLatch(1);
                mShortPressed = new CountDownLatch(1);
                newHandler.runWithScissors(() -> {
                    final long eventTime = SystemClock.uptimeMillis();
                    pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */);
                    pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */);
                    pressKey(KEYCODE_POWER, 0 /* pressTime */);
                    pressKey(KEYCODE_POWER, 0 /* pressTime */);
                }, mWaitTimeout);
                assertTrue(mMultiPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));

                newHandler.runWithScissors(() -> {
                    final long eventTime = SystemClock.uptimeMillis();
                    pressKey(eventTime, KEYCODE_POWER, 0 /* pressTime */);
                    pressKey(KEYCODE_POWER, 0 /* pressTime */);
                }, mWaitTimeout);
                assertTrue(mShortPressed.await(mWaitTimeout, TimeUnit.MILLISECONDS));
            }