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

Commit 59d50089 authored by Phil Tunstall's avatar Phil Tunstall
Browse files

PhoneWindowManager: Hardware key handling fixes and cleanup

-   Call cancelPreloadRecentApps for long presses and double taps of the home
    key at the right time based on the assigned actions.
    (Reverted Ibd16ff07b9910605c95180b54040f3e2b78939cb as the issue is fixed)
-   Do not allow any menu key events through to apps if
    mPressOnMenuBehavior is not KEY_ACTION_MENU.
-   Don't cancelPreloadRecentApps when menu key is released after a long press.
    (Reverted Idf1d27aa725547e0ddc44905e27da6c1b4540fab as the issue is fixed)
-   For the menu, app switch and assist keys don't cancelPreloadRecentApps on
    long press if the long press has no action assigned to it.

Patch Set 2: -  Fixed not cancelling preload on long press of home when double
                tap is bound to recent apps.
             -  Reduced delta against AOSP.
Patch Set 3: -  Do not perform long press action when key continues to be held
                down after a double tap on home.

Change-Id: I3cc8f9528e5dbd3e0b78308b03440abd9d9351f6
parent 87640167
Loading
Loading
Loading
Loading
+93 −97
Original line number Diff line number Diff line
@@ -456,9 +456,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    boolean mShowingLockscreen;
    boolean mShowingDream;
    boolean mDreamingLockscreen;
    boolean mHomeLongPressed;
    boolean mHomePressed;
    boolean mHomeConsumed;
    boolean mMenuPressed;
    boolean mAppSwitchLongPressed;
    boolean mHomeDoubleTapPending;
    Intent mHomeIntent;
@@ -468,9 +468,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    boolean mConsumeSearchKeyUp;
    boolean mAssistKeyLongPressed;

    // Used when key is pressed and performing non-default action
    boolean mMenuDoCustomAction;

    // Tracks user-customisable behavior for certain key events
    private int mLongPressOnHomeBehavior = -1;
    private int mPressOnMenuBehavior = -1;
@@ -480,9 +477,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    private int mPressOnAppSwitchBehavior = -1;
    private int mLongPressOnAppSwitchBehavior = -1;

    // Tracks preloading of the recent apps screen
    private boolean mRecentAppsPreloaded;

    // support for activating the lock screen while the screen is on
    boolean mAllowLockscreenWhenOn;
    int mLockScreenTimeout;
@@ -966,18 +960,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                triggerVirtualKeypress(KeyEvent.KEYCODE_MENU);
                break;
            case KEY_ACTION_APP_SWITCH:
                sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
                try {
                    IStatusBarService statusbar = getStatusBarService();
                    if (statusbar != null) {
                        statusbar.toggleRecentApps();
                        mRecentAppsPreloaded = false;
                    }
                } catch (RemoteException e) {
                    Slog.e(TAG, "RemoteException when showing recent apps", e);
                    // re-acquire status bar service next time it is needed.
                    mStatusBarService = null;
                }
                toggleRecentApps();
                break;
            case KEY_ACTION_SEARCH:
                launchAssistAction();
@@ -993,38 +976,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }
    }

    private void preloadRecentApps() {
        try {
            IStatusBarService statusbar = getStatusBarService();
            if (statusbar != null) {
                statusbar.preloadRecentApps();
                mRecentAppsPreloaded = true;
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "RemoteException when preloading recent apps", e);
            // re-acquire status bar service next time it is needed.
            mStatusBarService = null;
        }
    }

    private void cancelPreloadRecentApps() {
        try {
            IStatusBarService statusbar = getStatusBarService();
            if (statusbar != null) {
                statusbar.cancelPreloadRecentApps();
                mRecentAppsPreloaded = false;
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "RemoteException when showing recent apps", e);
            // re-acquire status bar service next time it is needed.
            mStatusBarService = null;
        }
    }

    private final Runnable mHomeDoubleTapTimeoutRunnable = new Runnable() {
        @Override
        public void run() {
            if (mHomeDoubleTapPending) {
                cancelPreloadRecentApps();
                mHomeDoubleTapPending = false;
                launchHomeFromHotKey();
            }
@@ -2331,14 +2287,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            // If we have released the home key, and didn't do anything else
            // while it was pressed, then it is time to go home!
            if (!down && mHomePressed) {
                if (mRecentAppsPreloaded) {
                    cancelPreloadRecentApps();
                }
                mHomePressed = false;
                if (mHomeConsumed) {
                    mHomeConsumed = false;
                    return -1;
                }
                if (mDoubleTapOnHomeBehavior != KEY_ACTION_APP_SWITCH) {
                    cancelPreloadRecentApps();
                }

                if (canceled) {
                    Log.i(TAG, "Ignoring HOME; event canceled.");
@@ -2397,31 +2353,35 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    }
                }
            }

            if (!down) {
                return -1;
            }

            // Remember that home is pressed and handle special actions.
            if (repeatCount == 0) {
                if (down) {
                mHomePressed = true;
                }
                if (mHomeDoubleTapPending) {
                    mHomeDoubleTapPending = false;
                    mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable);
                    mHomeConsumed = true;
                    performKeyAction(mDoubleTapOnHomeBehavior);
                } else if (!mRecentAppsPreloaded &&
                        (mLongPressOnHomeBehavior == KEY_ACTION_APP_SWITCH
                         || mDoubleTapOnHomeBehavior == KEY_ACTION_APP_SWITCH)) {
                    // Eat the key up event so it won't take us home
                    mHomeConsumed = true;
                } else if (!mPreloadedRecentApps &&
                        (mLongPressOnHomeBehavior == KEY_ACTION_APP_SWITCH ||
                        mDoubleTapOnHomeBehavior == KEY_ACTION_APP_SWITCH)) {
                    preloadRecentApps();
                }
            } else if (longPress) {
                if (!mRecentAppsPreloaded && mLongPressOnHomeBehavior == KEY_ACTION_APP_SWITCH) {
                    preloadRecentApps();
                if (!keyguardOn && !mHomeConsumed &&
                        mLongPressOnHomeBehavior != KEY_ACTION_NOTHING) {
                    if (mLongPressOnHomeBehavior != KEY_ACTION_APP_SWITCH) {
                        cancelPreloadRecentApps();
                    }
                if (!keyguardOn && mLongPressOnHomeBehavior != KEY_ACTION_NOTHING) {
                    performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
                    mHomeConsumed = true;
                    performKeyAction(mLongPressOnHomeBehavior);
                    // Eat the long-press so it won't take us home when the key is released
                    mHomeLongPressed = true;
                    // Eat the key up event so it won't take us home when the key is released
                    mHomeConsumed = true;
                }
            }
            return -1;
@@ -2429,12 +2389,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            // Hijack modified menu keys for debugging features
            final int chordBug = KeyEvent.META_SHIFT_ON;

            if (virtualKey) {
                // Let the app handle the key
                return 0;
            }

            if (down) {
                if (!mRecentAppsPreloaded && (mPressOnMenuBehavior == KEY_ACTION_APP_SWITCH ||
                if (!mPreloadedRecentApps && (mPressOnMenuBehavior == KEY_ACTION_APP_SWITCH ||
                        mLongPressOnMenuBehavior == KEY_ACTION_APP_SWITCH)) {
                    preloadRecentApps();
                }
                if (repeatCount == 0) {
                    mMenuPressed = true;
                    if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
                        Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
                        mContext.sendOrderedBroadcast(intent, null);
@@ -2454,32 +2420,37 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                        Settings.System.putInt(
                                res, Settings.System.SHOW_PROCESSES, shown ? 0 : 1);
                        return -1;
                    } else if (mPressOnMenuBehavior != KEY_ACTION_MENU && !virtualKey) {
                        mMenuDoCustomAction = true;
                        return -1;
                    }
                } else if (longPress) {
                    if (mRecentAppsPreloaded &&
                            mLongPressOnMenuBehavior != KEY_ACTION_APP_SWITCH) {
                    if (!keyguardOn && mLongPressOnMenuBehavior != KEY_ACTION_NOTHING) {
                        if (mLongPressOnMenuBehavior != KEY_ACTION_APP_SWITCH) {
                            cancelPreloadRecentApps();
                        }
                    if (!keyguardOn && mLongPressOnMenuBehavior != KEY_ACTION_NOTHING) {
                        performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
                        performKeyAction(mLongPressOnMenuBehavior);
                        // Do not perform action when key is released
                        mMenuDoCustomAction = false;
                        mMenuPressed = false;
                        return -1;
                    }
                }
            } else {
                if (mRecentAppsPreloaded && mPressOnMenuBehavior != KEY_ACTION_APP_SWITCH &&
                        mLongPressOnMenuBehavior != KEY_ACTION_APP_SWITCH) {
            }
            if (mPressOnMenuBehavior != KEY_ACTION_MENU) {
                if (!down && mMenuPressed) {
                    mMenuPressed = false;
                    if (mPressOnMenuBehavior != KEY_ACTION_APP_SWITCH) {
                        cancelPreloadRecentApps();
                    }
                if (mMenuDoCustomAction) {
                    mMenuDoCustomAction = false;
                    if (!canceled && !keyguardOn) {
                        performKeyAction(mPressOnMenuBehavior);
                    }
                }
                return -1;
            } else {
                if (!down) {
                    if (mMenuPressed) {
                        mMenuPressed = false;
                        cancelPreloadRecentApps();
                    } else if (mLongPressOnMenuBehavior != KEY_ACTION_NOTHING) {
                        return -1;
                    }
                }
@@ -2500,18 +2471,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            return 0;
        } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
            if (down) {
                if (!mRecentAppsPreloaded && (mPressOnAppSwitchBehavior == KEY_ACTION_APP_SWITCH ||
                if (!mPreloadedRecentApps && (mPressOnAppSwitchBehavior == KEY_ACTION_APP_SWITCH ||
                        mLongPressOnAppSwitchBehavior == KEY_ACTION_APP_SWITCH)) {
                    preloadRecentApps();
                }
                if (repeatCount == 0) {
                    mAppSwitchLongPressed = false;
                } else if (longPress) {
                    if (mRecentAppsPreloaded &&
                            mLongPressOnAppSwitchBehavior != KEY_ACTION_APP_SWITCH) {
                    if (!keyguardOn && mLongPressOnAppSwitchBehavior != KEY_ACTION_NOTHING) {
                        if (mLongPressOnAppSwitchBehavior != KEY_ACTION_APP_SWITCH) {
                            cancelPreloadRecentApps();
                        }
                    if (!keyguardOn && mLongPressOnAppSwitchBehavior != KEY_ACTION_NOTHING) {
                        performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
                        performKeyAction(mLongPressOnAppSwitchBehavior);
                        mAppSwitchLongPressed = true;
@@ -2521,31 +2491,28 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                if (mAppSwitchLongPressed) {
                    mAppSwitchLongPressed = false;
                } else {
                    if (mRecentAppsPreloaded &&
                            mPressOnAppSwitchBehavior != KEY_ACTION_APP_SWITCH) {
                    if (mPressOnAppSwitchBehavior != KEY_ACTION_APP_SWITCH) {
                        cancelPreloadRecentApps();
                    }
                    if (!canceled && !keyguardOn) {
                        performKeyAction(mPressOnAppSwitchBehavior);
                    }
                    return -1;
                }
            }
            return -1;
        } else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
            if (down) {
                if (!mRecentAppsPreloaded && (mPressOnAssistBehavior == KEY_ACTION_APP_SWITCH ||
                if (!mPreloadedRecentApps && (mPressOnAssistBehavior == KEY_ACTION_APP_SWITCH ||
                        mLongPressOnAssistBehavior == KEY_ACTION_APP_SWITCH)) {
                    preloadRecentApps();
                }
                if (repeatCount == 0) {
                    mAssistKeyLongPressed = false;
                } else if (longPress) {
                    if (mRecentAppsPreloaded &&
                            mLongPressOnAssistBehavior != KEY_ACTION_APP_SWITCH) {
                    if (!keyguardOn && mLongPressOnAssistBehavior != KEY_ACTION_NOTHING) {
                        if (mLongPressOnAssistBehavior != KEY_ACTION_APP_SWITCH) {
                            cancelPreloadRecentApps();
                        }
                    if (!keyguardOn && mLongPressOnAssistBehavior != KEY_ACTION_NOTHING) {
                        performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
                        performKeyAction(mLongPressOnAssistBehavior);
                        mAssistKeyLongPressed = true;
@@ -2555,11 +2522,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                if (mAssistKeyLongPressed) {
                    mAssistKeyLongPressed = false;
                } else {
                    if (mRecentAppsPreloaded &&
                            mPressOnAssistBehavior != KEY_ACTION_APP_SWITCH) {
                    if (mPressOnAssistBehavior != KEY_ACTION_APP_SWITCH) {
                        cancelPreloadRecentApps();
                    }
                    if (!keyguardOn) {
                    if (!canceled && !keyguardOn) {
                        performKeyAction(mPressOnAssistBehavior);
                    }
                }
@@ -2813,6 +2779,36 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        return mSearchManager;
    }

    private void preloadRecentApps() {
        mPreloadedRecentApps = true;
        try {
            IStatusBarService statusbar = getStatusBarService();
            if (statusbar != null) {
                statusbar.preloadRecentApps();
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "RemoteException when preloading recent apps", e);
            // re-acquire status bar service next time it is needed.
            mStatusBarService = null;
        }
    }

    private void cancelPreloadRecentApps() {
        if (mPreloadedRecentApps) {
            mPreloadedRecentApps = false;
            try {
                IStatusBarService statusbar = getStatusBarService();
                if (statusbar != null) {
                    statusbar.cancelPreloadRecentApps();
                }
            } catch (RemoteException e) {
                Slog.e(TAG, "RemoteException when showing recent apps", e);
                // re-acquire status bar service next time it is needed.
                mStatusBarService = null;
            }
        }
    }

    private void toggleRecentApps() {
        mPreloadedRecentApps = false; // preloading no longer needs to be canceled
        sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);