Merge "Refactor key handling in interceptKeyBeforeDispatching" into sc-dev

This commit is contained in:
Arthur Hung
2021-02-26 04:06:49 +00:00
committed by Android (Google) Code Review

View File

@@ -520,8 +520,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mConsumeSearchKeyUp; boolean mConsumeSearchKeyUp;
boolean mPendingMetaAction; boolean mPendingMetaAction;
boolean mPendingCapsLockToggle; boolean mPendingCapsLockToggle;
int mMetaState;
int mInitialMetaState;
// support for activating the lock screen while the screen is on // support for activating the lock screen while the screen is on
private HashSet<Integer> mAllowLockscreenWhenOnDisplays = new HashSet<>(); private HashSet<Integer> mAllowLockscreenWhenOnDisplays = new HashSet<>();
@@ -2498,6 +2496,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled(); final boolean canceled = event.isCanceled();
final int displayId = event.getDisplayId(); final int displayId = event.getDisplayId();
final long key_consumed = -1;
if (DEBUG_INPUT) { if (DEBUG_INPUT) {
Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount=" Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
@@ -2505,7 +2504,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} }
if (mKeyCombinationManager.isKeyConsumed(event)) { if (mKeyCombinationManager.isKeyConsumed(event)) {
return -1; return key_consumed;
} }
if ((flags & KeyEvent.FLAG_FALLBACK) == 0) { if ((flags & KeyEvent.FLAG_FALLBACK) == 0) {
@@ -2526,205 +2525,250 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mPendingCapsLockToggle = false; mPendingCapsLockToggle = false;
} }
// First we always handle the home key here, so applications switch(keyCode) {
// can never break it, although if keyguard is on, we do let case KeyEvent.KEYCODE_HOME:
// it handle it, because that gives us the correct 5 second // First we always handle the home key here, so applications
// timeout. // can never break it, although if keyguard is on, we do let
if (keyCode == KEYCODE_HOME) { // it handle it, because that gives us the correct 5 second
DisplayHomeButtonHandler handler = mDisplayHomeButtonHandlers.get(displayId); // timeout.
if (handler == null) { DisplayHomeButtonHandler handler = mDisplayHomeButtonHandlers.get(displayId);
handler = new DisplayHomeButtonHandler(displayId); if (handler == null) {
mDisplayHomeButtonHandlers.put(displayId, handler); handler = new DisplayHomeButtonHandler(displayId);
} mDisplayHomeButtonHandlers.put(displayId, handler);
return handler.handleHomeButton(focusedToken, event); }
} else if (keyCode == KeyEvent.KEYCODE_MENU) { return handler.handleHomeButton(focusedToken, event);
// Hijack modified menu keys for debugging features case KeyEvent.KEYCODE_MENU:
final int chordBug = KeyEvent.META_SHIFT_ON; // Hijack modified menu keys for debugging features
final int chordBug = KeyEvent.META_SHIFT_ON;
if (down && repeatCount == 0) {
if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT,
null, null, null, 0, null, null);
return -1;
}
}
} else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
if (down) {
if (repeatCount == 0) {
mSearchKeyShortcutPending = true;
mConsumeSearchKeyUp = false;
}
} else {
mSearchKeyShortcutPending = false;
if (mConsumeSearchKeyUp) {
mConsumeSearchKeyUp = false;
return -1;
}
}
return 0;
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
if (!keyguardOn) {
if (down && repeatCount == 0) { if (down && repeatCount == 0) {
preloadRecentApps(); if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
} else if (!down) { Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
toggleRecentApps(); mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT,
} null, null, null, 0, null, null);
} return key_consumed;
return -1;
} else if (keyCode == KeyEvent.KEYCODE_N && event.isMetaPressed()) {
if (down) {
IStatusBarService service = getStatusBarService();
if (service != null) {
try {
service.expandNotificationsPanel();
} catch (RemoteException e) {
// do nothing.
} }
} }
} break;
} else if (keyCode == KeyEvent.KEYCODE_S && event.isMetaPressed() case KeyEvent.KEYCODE_SEARCH:
&& event.isCtrlPressed()) { if (down) {
if (down && repeatCount == 0) { if (repeatCount == 0) {
int type = event.isShiftPressed() ? TAKE_SCREENSHOT_SELECTED_REGION mSearchKeyShortcutPending = true;
: TAKE_SCREENSHOT_FULLSCREEN; mConsumeSearchKeyUp = false;
mScreenshotRunnable.setScreenshotType(type); }
mScreenshotRunnable.setScreenshotSource(SCREENSHOT_KEY_OTHER); } else {
mHandler.post(mScreenshotRunnable); mSearchKeyShortcutPending = false;
return -1; if (mConsumeSearchKeyUp) {
} mConsumeSearchKeyUp = false;
} else if (keyCode == KeyEvent.KEYCODE_SLASH && event.isMetaPressed()) { return key_consumed;
if (down && repeatCount == 0 && !isKeyguardLocked()) { }
toggleKeyboardShortcutsMenu(event.getDeviceId()); }
} return 0;
} else if (keyCode == KeyEvent.KEYCODE_ASSIST) { case KeyEvent.KEYCODE_APP_SWITCH:
Slog.wtf(TAG, "KEYCODE_ASSIST should be handled in interceptKeyBeforeQueueing"); if (!keyguardOn) {
return -1; if (down && repeatCount == 0) {
} else if (keyCode == KeyEvent.KEYCODE_VOICE_ASSIST) { preloadRecentApps();
Slog.wtf(TAG, "KEYCODE_VOICE_ASSIST should be handled in interceptKeyBeforeQueueing"); } else if (!down) {
return -1; toggleRecentApps();
} else if (keyCode == KeyEvent.KEYCODE_SYSRQ) { }
if (down && repeatCount == 0) { }
mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN); return key_consumed;
mScreenshotRunnable.setScreenshotSource(SCREENSHOT_KEY_OTHER); case KeyEvent.KEYCODE_N:
mHandler.post(mScreenshotRunnable); if (down && event.isMetaPressed()) {
} IStatusBarService service = getStatusBarService();
return -1; if (service != null) {
} else if (keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP try {
|| keyCode == KeyEvent.KEYCODE_BRIGHTNESS_DOWN) { service.expandNotificationsPanel();
if (down) { } catch (RemoteException e) {
int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1; // do nothing.
}
return key_consumed;
}
}
break;
case KeyEvent.KEYCODE_S:
if (down && event.isMetaPressed() && event.isCtrlPressed() && repeatCount == 0) {
int type = event.isShiftPressed() ? TAKE_SCREENSHOT_SELECTED_REGION
: TAKE_SCREENSHOT_FULLSCREEN;
mScreenshotRunnable.setScreenshotType(type);
mScreenshotRunnable.setScreenshotSource(SCREENSHOT_KEY_OTHER);
mHandler.post(mScreenshotRunnable);
return key_consumed;
}
break;
case KeyEvent.KEYCODE_SLASH:
if (down && repeatCount == 0 && event.isMetaPressed() && !keyguardOn) {
toggleKeyboardShortcutsMenu(event.getDeviceId());
return key_consumed;
}
break;
case KeyEvent.KEYCODE_ASSIST:
Slog.wtf(TAG, "KEYCODE_ASSIST should be handled in interceptKeyBeforeQueueing");
return key_consumed;
case KeyEvent.KEYCODE_VOICE_ASSIST:
Slog.wtf(TAG, "KEYCODE_VOICE_ASSIST should be handled in"
+ " interceptKeyBeforeQueueing");
return key_consumed;
case KeyEvent.KEYCODE_SYSRQ:
if (down && repeatCount == 0) {
mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN);
mScreenshotRunnable.setScreenshotSource(SCREENSHOT_KEY_OTHER);
mHandler.post(mScreenshotRunnable);
}
return key_consumed;
case KeyEvent.KEYCODE_BRIGHTNESS_UP:
case KeyEvent.KEYCODE_BRIGHTNESS_DOWN:
if (down) {
int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1;
// Disable autobrightness if it's on // Disable autobrightness if it's on
int auto = Settings.System.getIntForUser( int auto = Settings.System.getIntForUser(
mContext.getContentResolver(), mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
UserHandle.USER_CURRENT_OR_SELF);
if (auto != 0) {
Settings.System.putIntForUser(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
UserHandle.USER_CURRENT_OR_SELF); UserHandle.USER_CURRENT_OR_SELF);
if (auto != 0) {
Settings.System.putIntForUser(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
UserHandle.USER_CURRENT_OR_SELF);
}
float minFloat = mPowerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM);
float maxFloat = mPowerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM);
float stepFloat = (maxFloat - minFloat) / BRIGHTNESS_STEPS * direction;
float brightnessFloat = Settings.System.getFloatForUser(
mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_FLOAT,
mContext.getDisplay().getBrightnessDefault(),
UserHandle.USER_CURRENT_OR_SELF);
brightnessFloat += stepFloat;
// Make sure we don't go beyond the limits.
brightnessFloat = Math.min(maxFloat, brightnessFloat);
brightnessFloat = Math.max(minFloat, brightnessFloat);
Settings.System.putFloatForUser(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightnessFloat,
UserHandle.USER_CURRENT_OR_SELF);
startActivityAsUser(new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG),
UserHandle.CURRENT_OR_SELF);
} }
float minFloat = mPowerManager.getBrightnessConstraint( return key_consumed;
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM); case KeyEvent.KEYCODE_VOLUME_UP:
float maxFloat = mPowerManager.getBrightnessConstraint( case KeyEvent.KEYCODE_VOLUME_DOWN:
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM); case KeyEvent.KEYCODE_VOLUME_MUTE:
float stepFloat = (maxFloat - minFloat) / BRIGHTNESS_STEPS * direction; if (mUseTvRouting || mHandleVolumeKeysInWM) {
float brightnessFloat = Settings.System.getFloatForUser( // On TVs or when the configuration is enabled, volume keys never
mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS_FLOAT, // go to the foreground app.
mContext.getDisplay().getBrightnessDefault(), dispatchDirectAudioEvent(event);
UserHandle.USER_CURRENT_OR_SELF); return key_consumed;
brightnessFloat += stepFloat;
// Make sure we don't go beyond the limits.
brightnessFloat = Math.min(maxFloat, brightnessFloat);
brightnessFloat = Math.max(minFloat, brightnessFloat);
Settings.System.putFloatForUser(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_FLOAT, brightnessFloat,
UserHandle.USER_CURRENT_OR_SELF);
startActivityAsUser(new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG),
UserHandle.CURRENT_OR_SELF);
}
return -1;
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP
|| keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
if (mUseTvRouting || mHandleVolumeKeysInWM) {
// On TVs or when the configuration is enabled, volume keys never
// go to the foreground app.
dispatchDirectAudioEvent(event);
return -1;
}
// If the device is in VR mode and keys are "internal" (e.g. on the side of the
// device), then drop the volume keys and don't forward it to the application/dispatch
// the audio event.
if (mDefaultDisplayPolicy.isPersistentVrModeEnabled()) {
final InputDevice d = event.getDevice();
if (d != null && !d.isExternal()) {
return -1;
} }
}
} else if (keyCode == KeyEvent.KEYCODE_TAB && event.isMetaPressed()) {
// Pass through keyboard navigation keys.
return 0;
} else if (keyCode == KeyEvent.KEYCODE_ALL_APPS) {
if (!down) {
mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
msg.setAsynchronous(true);
msg.sendToTarget();
}
return -1;
} else if (keyCode == KeyEvent.KEYCODE_NOTIFICATION) {
if (!down) {
toggleNotificationPanel();
}
return -1;
}
// Toggle Caps Lock on META-ALT. // If the device is in VR mode and keys are "internal" (e.g. on the side of the
boolean actionTriggered = false; // device), then drop the volume keys and don't forward it to the
if (KeyEvent.isModifierKey(keyCode)) { // application/dispatch the audio event.
if (!mPendingCapsLockToggle) { if (mDefaultDisplayPolicy.isPersistentVrModeEnabled()) {
// Start tracking meta state for combo. final InputDevice d = event.getDevice();
mInitialMetaState = mMetaState; if (d != null && !d.isExternal()) {
mPendingCapsLockToggle = true; return key_consumed;
} else if (event.getAction() == KeyEvent.ACTION_UP) {
int altOnMask = mMetaState & KeyEvent.META_ALT_MASK;
int metaOnMask = mMetaState & KeyEvent.META_META_MASK;
// Check for Caps Lock toggle
if ((metaOnMask != 0) && (altOnMask != 0)) {
// Check if nothing else is pressed
if (mInitialMetaState == (mMetaState ^ (altOnMask | metaOnMask))) {
// Handle Caps Lock Toggle
mInputManagerInternal.toggleCapsLock(event.getDeviceId());
actionTriggered = true;
} }
} }
break;
case KeyEvent.KEYCODE_TAB:
if (event.isMetaPressed()) {
// Pass through keyboard navigation keys.
return 0;
}
// Display task switcher for ALT-TAB.
if (down && repeatCount == 0) {
if (mRecentAppsHeldModifiers == 0 && !keyguardOn && isUserSetupComplete()) {
final int shiftlessModifiers =
event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
if (KeyEvent.metaStateHasModifiers(
shiftlessModifiers, KeyEvent.META_ALT_ON)) {
mRecentAppsHeldModifiers = shiftlessModifiers;
showRecentApps(true);
return key_consumed;
}
}
}
break;
case KeyEvent.KEYCODE_ALL_APPS:
if (!down) {
mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
msg.setAsynchronous(true);
msg.sendToTarget();
}
return key_consumed;
case KeyEvent.KEYCODE_NOTIFICATION:
if (!down) {
toggleNotificationPanel();
}
return key_consumed;
// Always stop tracking when key goes up. case KeyEvent.KEYCODE_SPACE:
mPendingCapsLockToggle = false; // Handle keyboard layout switching.
} if ((metaState & (KeyEvent.META_CTRL_MASK | KeyEvent.META_META_MASK)) == 0) {
} return 0;
// Store current meta state to be able to evaluate it later. }
mMetaState = metaState; // Share the same behavior with KEYCODE_LANGUAGE_SWITCH.
case KeyEvent.KEYCODE_LANGUAGE_SWITCH:
if (down && repeatCount == 0) {
int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
mWindowManagerFuncs.switchKeyboardLayout(event.getDeviceId(), direction);
return key_consumed;
}
break;
case KeyEvent.KEYCODE_META_LEFT:
case KeyEvent.KEYCODE_META_RIGHT:
if (down) {
if (event.isAltPressed()) {
mPendingCapsLockToggle = true;
mPendingMetaAction = false;
} else {
mPendingCapsLockToggle = false;
mPendingMetaAction = true;
}
} else {
// Toggle Caps Lock on META-ALT.
if (mPendingCapsLockToggle) {
mInputManagerInternal.toggleCapsLock(event.getDeviceId());
mPendingCapsLockToggle = false;
} else if (mPendingMetaAction) {
launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD,
event.getDeviceId(),
event.getEventTime());
mPendingMetaAction = false;
}
}
return key_consumed;
case KeyEvent.KEYCODE_ALT_LEFT:
case KeyEvent.KEYCODE_ALT_RIGHT:
if (down) {
if (event.isMetaPressed()) {
mPendingCapsLockToggle = true;
mPendingMetaAction = false;
} else {
mPendingCapsLockToggle = false;
}
} else {
// hide recent if triggered by ALT-TAB.
if (mRecentAppsHeldModifiers != 0
&& (metaState & mRecentAppsHeldModifiers) == 0) {
mRecentAppsHeldModifiers = 0;
hideRecentApps(true, false);
return key_consumed;
}
if (actionTriggered) { // Toggle Caps Lock on META-ALT.
return -1; if (mPendingCapsLockToggle) {
} mInputManagerInternal.toggleCapsLock(event.getDeviceId());
mPendingCapsLockToggle = false;
if (KeyEvent.isMetaKey(keyCode)) { return key_consumed;
if (down) { }
mPendingMetaAction = true; }
} else if (mPendingMetaAction) { break;
launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD, event.getDeviceId(),
event.getEventTime());
}
return -1;
} }
// Shortcuts are invoked through Search+key, so intercept those here // Shortcuts are invoked through Search+key, so intercept those here
@@ -2754,7 +2798,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ "SEARCH+" + KeyEvent.keyCodeToString(keyCode)); + "SEARCH+" + KeyEvent.keyCodeToString(keyCode));
} }
} }
return -1; return key_consumed;
} }
} }
@@ -2776,7 +2820,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ "the activity to which it is registered was not found: " + "the activity to which it is registered was not found: "
+ "META+" + KeyEvent.keyCodeToString(keyCode), ex); + "META+" + KeyEvent.keyCodeToString(keyCode), ex);
} }
return -1; return key_consumed;
} }
} }
} }
@@ -2795,39 +2839,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ "the activity to which it is registered was not found: " + "the activity to which it is registered was not found: "
+ "keyCode=" + keyCode + ", category=" + category, ex); + "keyCode=" + keyCode + ", category=" + category, ex);
} }
return -1; return key_consumed;
} }
} }
// Display task switcher for ALT-TAB.
if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) {
if (mRecentAppsHeldModifiers == 0 && !keyguardOn && isUserSetupComplete()) {
final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)) {
mRecentAppsHeldModifiers = shiftlessModifiers;
showRecentApps(true);
return -1;
}
}
} else if (!down && mRecentAppsHeldModifiers != 0
&& (metaState & mRecentAppsHeldModifiers) == 0) {
mRecentAppsHeldModifiers = 0;
hideRecentApps(true, false);
}
// Handle keyboard language switching.
final boolean isCtrlOrMetaSpace = keyCode == KeyEvent.KEYCODE_SPACE
&& (metaState & (KeyEvent.META_CTRL_MASK | KeyEvent.META_META_MASK)) != 0;
if (down && repeatCount == 0
&& (keyCode == KeyEvent.KEYCODE_LANGUAGE_SWITCH || isCtrlOrMetaSpace)) {
int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
mWindowManagerFuncs.switchKeyboardLayout(event.getDeviceId(), direction);
return -1;
}
if (isValidGlobalKey(keyCode) if (isValidGlobalKey(keyCode)
&& mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) { && mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
return -1; return key_consumed;
} }
if (down) { if (down) {
@@ -2857,13 +2875,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} catch (RemoteException e) { } catch (RemoteException e) {
mShortcutKeyServices.delete(shortcutCode); mShortcutKeyServices.delete(shortcutCode);
} }
return -1; return key_consumed;
} }
} }
// Reserve all the META modifier combos for system behavior // Reserve all the META modifier combos for system behavior
if ((metaState & KeyEvent.META_META_ON) != 0) { if ((metaState & KeyEvent.META_META_ON) != 0) {
return -1; return key_consumed;
} }
// Let the application handle the key. // Let the application handle the key.