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

Commit 34be9571 authored by Alexandra-Mara Smau's avatar Alexandra-Mara Smau Committed by Android (Google) Code Review
Browse files

Merge "Explicitly log LONG_PRESS_HOME corresponding events." into main

parents 2e44debc d7b7a664
Loading
Loading
Loading
Loading
+29 −27
Original line number Diff line number Diff line
@@ -607,10 +607,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    DisplayPolicy mDefaultDisplayPolicy;

    // What we do when the user long presses on home
    private int mLongPressOnHomeBehavior;
    int mLongPressOnHomeBehavior;

    // What we do when the user double-taps on home
    private int mDoubleTapOnHomeBehavior;
    int mDoubleTapOnHomeBehavior;

    // Must match config_primaryShortPressTargetActivity in config.xml
    ComponentName mPrimaryShortPressTargetActivity;
@@ -1853,7 +1853,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                Settings.Secure.TV_USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
    }

    private void handleShortPressOnHome(int displayId) {
    private void handleShortPressOnHome(KeyEvent event) {
        logKeyboardSystemsEvent(event, KeyboardLogEvent.HOME);

        // Turn on the connected TV and switch HDMI input if we're a HDMI playback device.
        final HdmiControl hdmiControl = getHdmiControl();
        if (hdmiControl != null) {
@@ -1869,7 +1871,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }

        // Go home!
        launchHomeFromHotKey(displayId);
        launchHomeFromHotKey(event.getDisplayId());
    }

    /**
@@ -1974,17 +1976,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    private class DisplayHomeButtonHandler {

        private final int mDisplayId;

        private boolean mHomeDoubleTapPending;
        private boolean mHomePressed;
        private boolean mHomeConsumed;

        private KeyEvent mPendingHomeKeyEvent;
        private final Runnable mHomeDoubleTapTimeoutRunnable = new Runnable() {
            @Override
            public void run() {
                if (mHomeDoubleTapPending) {
                    mHomeDoubleTapPending = false;
                    handleShortPressOnHome(mDisplayId);
                if (mPendingHomeKeyEvent != null) {
                    handleShortPressOnHome(mPendingHomeKeyEvent);
                    mPendingHomeKeyEvent = null;
                }
            }
        };
@@ -2007,7 +2007,6 @@ 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) {
                logKeyboardSystemsEvent(event, KeyboardLogEvent.HOME);
                if (mDisplayId == DEFAULT_DISPLAY) {
                    cancelPreloadRecentApps();
                }
@@ -2029,7 +2028,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_PIP_MENU
                            || mPictureInPictureVisible) {
                        mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case
                        mHomeDoubleTapPending = true;
                        mPendingHomeKeyEvent = event;
                        mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable,
                                ViewConfiguration.getDoubleTapTimeout());
                        return true;
@@ -2037,7 +2036,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                }

                // Post to main thread to avoid blocking input pipeline.
                mHandler.post(() -> handleShortPressOnHome(mDisplayId));
                mHandler.post(() -> handleShortPressOnHome(event));
                return true;
            }

@@ -2063,10 +2062,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            // Remember that home is pressed and handle special actions.
            if (repeatCount == 0) {
                mHomePressed = true;
                if (mHomeDoubleTapPending) {
                    mHomeDoubleTapPending = false;
                if (mPendingHomeKeyEvent != null) {
                    mPendingHomeKeyEvent = null;
                    mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable);
                    mHandler.post(this::handleDoubleTapOnHome);
                    mHandler.post(() -> handleDoubleTapOnHome(event));
                // TODO(multi-display): Remove display id check once we support recents on
                // multi-display
                } else if (mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI
@@ -2076,19 +2075,19 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                if (!keyguardOn) {
                    // Post to main thread to avoid blocking input pipeline.
                    mHandler.post(() -> handleLongPressOnHome(event.getDeviceId(),
                            event.getEventTime()));
                    mHandler.post(() -> handleLongPressOnHome(event));
                }
            }
            return true;
        }

        private void handleDoubleTapOnHome() {
        private void handleDoubleTapOnHome(KeyEvent event) {
            if (mHomeConsumed) {
                return;
            }
            switch (mDoubleTapOnHomeBehavior) {
                case DOUBLE_TAP_HOME_RECENT_SYSTEM_UI:
                    logKeyboardSystemsEvent(event, KeyboardLogEvent.APP_SWITCH);
                    mHomeConsumed = true;
                    toggleRecentApps();
                    break;
@@ -2103,7 +2102,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            }
        }

        private void handleLongPressOnHome(int deviceId, long eventTime) {
        private void handleLongPressOnHome(KeyEvent event) {
            if (mHomeConsumed) {
                return;
            }
@@ -2115,13 +2114,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                    "Home - Long Press");
            switch (mLongPressOnHomeBehavior) {
                case LONG_PRESS_HOME_ALL_APPS:
                    logKeyboardSystemsEvent(event, KeyboardLogEvent.ALL_APPS);
                    launchAllAppsAction();
                    break;
                case LONG_PRESS_HOME_ASSIST:
                    launchAssistAction(null, deviceId, eventTime,
                    logKeyboardSystemsEvent(event, KeyboardLogEvent.LAUNCH_ASSISTANT);
                    launchAssistAction(null, event.getDeviceId(), event.getEventTime(),
                            AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
                    break;
                case LONG_PRESS_HOME_NOTIFICATION_PANEL:
                    logKeyboardSystemsEvent(event, KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL);
                    toggleNotificationPanel();
                    break;
                default:
@@ -3269,7 +3271,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {

        switch (keyCode) {
            case KeyEvent.KEYCODE_HOME:
                return handleHomeShortcuts(displayId, focusedToken, event);
                return handleHomeShortcuts(focusedToken, event);
            case KeyEvent.KEYCODE_MENU:
                // Hijack modified menu keys for debugging features
                final int chordBug = KeyEvent.META_SHIFT_ON;
@@ -3311,7 +3313,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            case KeyEvent.KEYCODE_H:
            case KeyEvent.KEYCODE_ENTER:
                if (event.isMetaPressed()) {
                    return handleHomeShortcuts(displayId, focusedToken, event);
                    return handleHomeShortcuts(focusedToken, event);
                }
                break;
            case KeyEvent.KEYCODE_I:
@@ -3661,15 +3663,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        upEvent.recycle();
    }

    private boolean handleHomeShortcuts(int displayId, IBinder focusedToken, KeyEvent event) {
    private boolean handleHomeShortcuts(IBinder focusedToken, KeyEvent event) {
        // First we always handle the home key here, so applications
        // can never break it, although if keyguard is on, we do let
        // it handle it, because that gives us the correct 5 second
        // timeout.
        DisplayHomeButtonHandler handler = mDisplayHomeButtonHandlers.get(displayId);
        DisplayHomeButtonHandler handler = mDisplayHomeButtonHandlers.get(event.getDisplayId());
        if (handler == null) {
            handler = new DisplayHomeButtonHandler(displayId);
            mDisplayHomeButtonHandlers.put(displayId, handler);
            handler = new DisplayHomeButtonHandler(event.getDisplayId());
            mDisplayHomeButtonHandlers.put(event.getDisplayId(), handler);
        }
        return handler.handleHomeButton(focusedToken, event);
    }
+27 −8
Original line number Diff line number Diff line
@@ -115,43 +115,61 @@ class ShortcutKeyTestBase {
        }
    }

    void sendKeyCombination(int[] keyCodes, long duration) {
    void sendKeyCombination(int[] keyCodes, long duration, boolean longPress) {
        final long downTime = SystemClock.uptimeMillis();
        final int count = keyCodes.length;
        final KeyEvent[] events = new KeyEvent[count];
        int metaState = 0;

        for (int i = 0; i < count; i++) {
            final int keyCode = keyCodes[i];
            final KeyEvent event = new KeyEvent(downTime, downTime, KeyEvent.ACTION_DOWN, keyCode,
                    0 /*repeat*/, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/,
                    0 /*flags*/, InputDevice.SOURCE_KEYBOARD);
            event.setDisplayId(DEFAULT_DISPLAY);
            events[i] = event;
            interceptKey(event);
            // The order is important here, metaState could be updated and applied to the next key.
            metaState |= MODIFIER.getOrDefault(keyCode, 0);
        }

        for (KeyEvent event: events) {
            interceptKey(event);
        }

        try {
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        for (int i = count - 1; i >= 0; i--) {
        if (longPress) {
            final long nextDownTime = SystemClock.uptimeMillis();
            for (int i = 0; i < count; i++) {
                final int keyCode = keyCodes[i];
                final KeyEvent nextDownEvent = new KeyEvent(downTime, nextDownTime,
                        KeyEvent.ACTION_DOWN, keyCode, 1 /*repeat*/, metaState,
                        KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/,
                        KeyEvent.FLAG_LONG_PRESS /*flags*/, InputDevice.SOURCE_KEYBOARD);
                nextDownEvent.setDisplayId(DEFAULT_DISPLAY);
                interceptKey(nextDownEvent);
            }
        }

        final long eventTime = SystemClock.uptimeMillis();
        for (int i = count - 1; i >= 0; i--) {
            final int keyCode = keyCodes[i];
            final KeyEvent upEvent = new KeyEvent(downTime, eventTime, KeyEvent.ACTION_UP, keyCode,
                    0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, 0 /*flags*/,
                    InputDevice.SOURCE_KEYBOARD);
            upEvent.setDisplayId(DEFAULT_DISPLAY);
            interceptKey(upEvent);
            metaState &= ~MODIFIER.getOrDefault(keyCode, 0);
        }
    }

    void sendKeyCombination(int[] keyCodes, long duration) {
        sendKeyCombination(keyCodes, duration, false /* longPress */);
    }

    void sendLongPressKeyCombination(int[] keyCodes) {
        sendKeyCombination(keyCodes, ViewConfiguration.getLongPressTimeout(), true /* longPress */);
    }

    void sendKey(int keyCode) {
        sendKey(keyCode, false);
    }
@@ -179,6 +197,7 @@ class ShortcutKeyTestBase {
        final KeyEvent upEvent = new KeyEvent(downTime, eventTime, KeyEvent.ACTION_UP, keyCode,
                0 /*repeat*/, 0 /*metaState*/, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/,
                0 /*flags*/, InputDevice.SOURCE_KEYBOARD);
        upEvent.setDisplayId(DEFAULT_DISPLAY);
        interceptKey(upEvent);
    }

+83 −1
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@

package com.android.server.policy;

import static com.android.server.policy.PhoneWindowManager.DOUBLE_TAP_HOME_RECENT_SYSTEM_UI;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_ALL_APPS;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_ASSIST;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_NOTIFICATION_PANEL;

import android.platform.test.annotations.Presubmit;
import android.view.KeyEvent;

@@ -226,6 +231,59 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase {
                        KeyboardLogEvent.LAUNCH_DEFAULT_MESSAGING, KeyEvent.KEYCODE_S, META_ON}};
    }

    @Keep
    private static Object[][] longPressOnHomeTestArguments() {
        // testName, testKeys, longPressOnHomeBehavior, expectedLogEvent, expectedKey,
        // expectedModifierState
        return new Object[][]{
                {"Long press HOME key -> Toggle Notification panel",
                        new int[]{KeyEvent.KEYCODE_HOME}, LONG_PRESS_HOME_NOTIFICATION_PANEL,
                        KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL, KeyEvent.KEYCODE_HOME, 0},
                {"Long press META + ENTER -> Toggle Notification panel",
                        new int[]{META_KEY, KeyEvent.KEYCODE_ENTER},
                        LONG_PRESS_HOME_NOTIFICATION_PANEL,
                        KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL, KeyEvent.KEYCODE_ENTER,
                        META_ON},
                {"Long press META + H -> Toggle Notification panel",
                        new int[]{META_KEY, KeyEvent.KEYCODE_H}, LONG_PRESS_HOME_NOTIFICATION_PANEL,
                        KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL, KeyEvent.KEYCODE_H, META_ON},
                {"Long press HOME key -> Launch assistant",
                        new int[]{KeyEvent.KEYCODE_HOME}, LONG_PRESS_HOME_ASSIST,
                        KeyboardLogEvent.LAUNCH_ASSISTANT, KeyEvent.KEYCODE_HOME, 0},
                {"Long press META + ENTER -> Launch assistant",
                        new int[]{META_KEY, KeyEvent.KEYCODE_ENTER}, LONG_PRESS_HOME_ASSIST,
                        KeyboardLogEvent.LAUNCH_ASSISTANT, KeyEvent.KEYCODE_ENTER, META_ON},
                {"Long press META + H -> Launch assistant",
                        new int[]{META_KEY, KeyEvent.KEYCODE_H}, LONG_PRESS_HOME_ASSIST,
                        KeyboardLogEvent.LAUNCH_ASSISTANT, KeyEvent.KEYCODE_H, META_ON},
                {"Long press HOME key -> Open App Drawer",
                        new int[]{KeyEvent.KEYCODE_HOME}, LONG_PRESS_HOME_ALL_APPS,
                        KeyboardLogEvent.ALL_APPS, KeyEvent.KEYCODE_HOME, 0},
                {"Long press META + ENTER -> Open App Drawer",
                        new int[]{META_KEY, KeyEvent.KEYCODE_ENTER}, LONG_PRESS_HOME_ALL_APPS,
                        KeyboardLogEvent.ALL_APPS, KeyEvent.KEYCODE_ENTER, META_ON},
                {"Long press META + H -> Open App Drawer", new int[]{META_KEY, KeyEvent.KEYCODE_H},
                        LONG_PRESS_HOME_ALL_APPS, KeyboardLogEvent.ALL_APPS,
                        KeyEvent.KEYCODE_H, META_ON}};
    }

    @Keep
    private static Object[][] doubleTapOnHomeTestArguments() {
        // testName, testKeys, doubleTapOnHomeBehavior, expectedLogEvent, expectedKey,
        // expectedModifierState
        return new Object[][]{
                {"Double tap HOME -> Open App switcher",
                        new int[]{KeyEvent.KEYCODE_HOME}, DOUBLE_TAP_HOME_RECENT_SYSTEM_UI,
                        KeyboardLogEvent.APP_SWITCH, KeyEvent.KEYCODE_HOME, 0},
                {"Double tap META + ENTER -> Open App switcher",
                        new int[]{META_KEY, KeyEvent.KEYCODE_ENTER},
                        DOUBLE_TAP_HOME_RECENT_SYSTEM_UI, KeyboardLogEvent.APP_SWITCH,
                        KeyEvent.KEYCODE_ENTER, META_ON},
                {"Double tap META + H -> Open App switcher",
                        new int[]{META_KEY, KeyEvent.KEYCODE_H}, DOUBLE_TAP_HOME_RECENT_SYSTEM_UI,
                        KeyboardLogEvent.APP_SWITCH, KeyEvent.KEYCODE_H, META_ON}};
    }

    @Before
    public void setUp() {
        setUpPhoneWindowManager(/*supportSettingsUpdate*/ true);
@@ -237,13 +295,37 @@ public class ShortcutLoggingTests extends ShortcutKeyTestBase {
        mPhoneWindowManager.overrideStatusBarManagerInternal();
        mPhoneWindowManager.overrideStartActivity();
        mPhoneWindowManager.overrideUserSetupComplete();
        mPhoneWindowManager.setupAssistForLaunch();
        mPhoneWindowManager.overrideTogglePanel();
    }

    @Test
    @Parameters(method = "shortcutTestArguments")
    public void testShortcuts(String testName, int[] testKeys, KeyboardLogEvent expectedLogEvent,
            int expectedKey, int expectedModifierState) {
        sendKeyCombination(testKeys, 0);
        sendKeyCombination(testKeys, 0 /* duration */);
        mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
                expectedKey, expectedModifierState, "Failed while executing " + testName);
    }

    @Test
    @Parameters(method = "longPressOnHomeTestArguments")
    public void testLongPressOnHome(String testName, int[] testKeys, int longPressOnHomeBehavior,
            KeyboardLogEvent expectedLogEvent, int expectedKey, int expectedModifierState) {
        mPhoneWindowManager.overrideLongPressOnHomeBehavior(longPressOnHomeBehavior);
        sendLongPressKeyCombination(testKeys);
        mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
                expectedKey, expectedModifierState, "Failed while executing " + testName);
    }

    @Test
    @Parameters(method = "doubleTapOnHomeTestArguments")
    public void testDoubleTapOnHomeBehavior(String testName, int[] testKeys,
            int doubleTapOnHomeBehavior, KeyboardLogEvent expectedLogEvent, int expectedKey,
            int expectedModifierState) {
        mPhoneWindowManager.overriderDoubleTapOnHomeBehavior(doubleTapOnHomeBehavior);
        sendKeyCombination(testKeys, 0 /* duration */);
        sendKeyCombination(testKeys, 0 /* duration */);
        mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
                expectedKey, expectedModifierState, "Failed while executing " + testName);
    }
+8 −0
Original line number Diff line number Diff line
@@ -364,6 +364,14 @@ class TestPhoneWindowManager {
        }
    }

    void overrideLongPressOnHomeBehavior(int behavior) {
        mPhoneWindowManager.mLongPressOnHomeBehavior = behavior;
    }

    void overriderDoubleTapOnHomeBehavior(int behavior) {
        mPhoneWindowManager.mDoubleTapOnHomeBehavior = behavior;
    }

    void overrideCanStartDreaming(boolean canDream) {
        doReturn(canDream).when(mDreamManagerInternal).canStartDreaming(anyBoolean());
    }