Loading services/core/java/com/android/server/policy/PhoneWindowManager.java +29 −27 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -1869,7 +1871,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } // Go home! launchHomeFromHotKey(displayId); launchHomeFromHotKey(event.getDisplayId()); } /** Loading Loading @@ -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; } } }; Loading @@ -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(); } Loading @@ -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; Loading @@ -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; } Loading @@ -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 Loading @@ -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; Loading @@ -2103,7 +2102,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } private void handleLongPressOnHome(int deviceId, long eventTime) { private void handleLongPressOnHome(KeyEvent event) { if (mHomeConsumed) { return; } Loading @@ -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: Loading Loading @@ -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; Loading Loading @@ -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: Loading Loading @@ -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); } Loading services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java +27 −8 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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); } Loading services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java +83 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); } Loading services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -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()); } Loading Loading
services/core/java/com/android/server/policy/PhoneWindowManager.java +29 −27 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading @@ -1869,7 +1871,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } // Go home! launchHomeFromHotKey(displayId); launchHomeFromHotKey(event.getDisplayId()); } /** Loading Loading @@ -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; } } }; Loading @@ -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(); } Loading @@ -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; Loading @@ -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; } Loading @@ -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 Loading @@ -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; Loading @@ -2103,7 +2102,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } private void handleLongPressOnHome(int deviceId, long eventTime) { private void handleLongPressOnHome(KeyEvent event) { if (mHomeConsumed) { return; } Loading @@ -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: Loading Loading @@ -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; Loading Loading @@ -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: Loading Loading @@ -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); } Loading
services/tests/wmtests/src/com/android/server/policy/ShortcutKeyTestBase.java +27 −8 Original line number Diff line number Diff line Loading @@ -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); } Loading Loading @@ -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); } Loading
services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java +83 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); } Loading
services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -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()); } Loading