Merge "Consuming common key combinations in app priority"

This commit is contained in:
Arthur Hung
2022-01-05 01:29:14 +00:00
committed by Android (Google) Code Review
5 changed files with 59 additions and 24 deletions

View File

@@ -15272,7 +15272,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param event the KeyEvent object that defines the button action
*/
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (KeyEvent.isConfirmKey(keyCode)) {
if (event.hasNoModifiers() && KeyEvent.isConfirmKey(keyCode)) {
if ((mViewFlags & ENABLED_MASK) == DISABLED) {
return true;
}
@@ -15329,7 +15329,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param event The KeyEvent object that defines the button action.
*/
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (KeyEvent.isConfirmKey(keyCode)) {
if (event.hasNoModifiers() && KeyEvent.isConfirmKey(keyCode)) {
if ((mViewFlags & ENABLED_MASK) == DISABLED) {
return true;
}

View File

@@ -7596,7 +7596,7 @@ public final class ViewRootImpl implements ViewParent,
// When a new focused view is selected, we consume the navigation key because
// navigation doesn't make much sense unless a view already has focus so
// the key's purpose is to set focus.
if (isNavigationKey(event)) {
if (event.hasNoModifiers() && isNavigationKey(event)) {
return ensureTouchMode(false);
}

View File

@@ -560,7 +560,12 @@ public class InputShellCommand extends ShellCommand {
sleep(duration);
for (KeyEvent event: events) {
injectKeyEventAsync(KeyEvent.changeAction(event, KeyEvent.ACTION_UP));
final int keyCode = event.getKeyCode();
final KeyEvent upEvent = new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode,
0, metaState, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /*scancode*/, 0 /*flags*/,
inputSource);
injectKeyEventAsync(upEvent);
metaState &= ~MODIFIER.getOrDefault(keyCode, 0);
}
}

View File

@@ -112,10 +112,15 @@ class ModifierShortcutManager {
* @return The intent that matches the shortcut, or null if not found.
*/
private Intent getIntent(KeyCharacterMap kcm, int keyCode, int metaState) {
// If a modifier key other than shift is also pressed, skip it.
final boolean isShiftOn = KeyEvent.metaStateHasModifiers(metaState, KeyEvent.META_SHIFT_ON);
if (!isShiftOn && !KeyEvent.metaStateHasNoModifiers(metaState)) {
return null;
}
ShortcutInfo shortcut = null;
// If the Shift key is pressed, then search for the shift shortcuts.
boolean isShiftOn = (metaState & KeyEvent.META_SHIFT_ON) == KeyEvent.META_SHIFT_ON;
SparseArray<ShortcutInfo> shortcutMap = isShiftOn ? mShiftShortcuts : mIntentShortcuts;
// First try the exact keycode (with modifiers).

View File

@@ -2696,6 +2696,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final boolean canceled = event.isCanceled();
final int displayId = event.getDisplayId();
final long key_consumed = -1;
final long key_not_consumed = 0;
if (DEBUG_INPUT) {
Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
@@ -2885,7 +2886,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case KeyEvent.KEYCODE_TAB:
if (event.isMetaPressed()) {
// Pass through keyboard navigation keys.
return 0;
return key_not_consumed;
}
// Display task switcher for ALT-TAB.
if (down && repeatCount == 0) {
@@ -2916,9 +2917,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return key_consumed;
case KeyEvent.KEYCODE_SPACE:
// Handle keyboard layout switching.
if ((metaState & (KeyEvent.META_CTRL_MASK | KeyEvent.META_META_MASK)) == 0) {
return 0;
// Handle keyboard layout switching. (META + SPACE)
if ((metaState & KeyEvent.META_META_MASK) == 0) {
return key_not_consumed;
}
// Share the same behavior with KEYCODE_LANGUAGE_SWITCH.
case KeyEvent.KEYCODE_LANGUAGE_SWITCH:
@@ -2992,7 +2993,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
// Let the application handle the key.
return 0;
return key_not_consumed;
}
/**
@@ -3058,6 +3059,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ ", policyFlags=" + policyFlags);
}
if (interceptUnhandledKey(event)) {
return null;
}
KeyEvent fallbackEvent = null;
if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
final KeyCharacterMap kcm = event.getKeyCharacterMap();
@@ -3112,13 +3117,46 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return fallbackEvent;
}
private boolean interceptUnhandledKey(KeyEvent event) {
final int keyCode = event.getKeyCode();
final int repeatCount = event.getRepeatCount();
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final int metaState = event.getModifiers();
switch(keyCode) {
case KeyEvent.KEYCODE_SPACE:
if (down && repeatCount == 0) {
// Handle keyboard layout switching. (CTRL + SPACE)
if (KeyEvent.metaStateHasModifiers(metaState, KeyEvent.META_CTRL_ON)) {
int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
mWindowManagerFuncs.switchKeyboardLayout(event.getDeviceId(), direction);
return true;
}
}
break;
case KeyEvent.KEYCODE_Z:
if (down && KeyEvent.metaStateHasModifiers(metaState,
KeyEvent.META_CTRL_ON | KeyEvent.META_ALT_ON)) {
// Intercept the Accessibility keychord (CTRL + ALT + Z) for keyboard users.
if (mAccessibilityShortcutController
.isAccessibilityShortcutAvailable(isKeyguardLocked())) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT));
return true;
}
}
break;
}
return false;
}
private boolean interceptFallback(IBinder focusedToken, KeyEvent fallbackEvent,
int policyFlags) {
int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags);
if ((actions & ACTION_PASS_TO_USER) != 0) {
long delayMillis = interceptKeyBeforeDispatching(
focusedToken, fallbackEvent, policyFlags);
if (delayMillis == 0) {
if (delayMillis == 0 && !interceptUnhandledKey(fallbackEvent)) {
return true;
}
}
@@ -3989,19 +4027,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
// Intercept the Accessibility keychord (CTRL + ALT + Z) for keyboard users.
if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(isKeyguardLocked())) {
switch (keyCode) {
case KeyEvent.KEYCODE_Z: {
if (down && event.isCtrlPressed() && event.isAltPressed()) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT));
result &= ~ACTION_PASS_TO_USER;
}
break;
}
}
}
if (useHapticFeedback) {
performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, false,
"Virtual Key - Press");