Add support for fallback keycodes.
This change enables the framework to synthesize key events to implement
default behavior when an application does not handle a key.
For example, this change enables numeric keypad keys to perform
their associated special function when numlock is off.
The application is informed that it is processing a fallback keypress
so it can choose to ignore it.
Added a new keycode for switching applications.
Added ALT key deadkeys.
New default key mappings:
- ESC -> BACK
- Meta+ESC -> HOME
- Alt+ESC -> MENU
- Meta+Space -> SEARCH
- Meta+Tab -> APP_SWITCH
Fixed some comments.
Fixed some tests.
Change-Id: Id7f3b6645f3a350275e624547822f72652f3defe
diff --git a/libs/ui/KeyCharacterMap.cpp b/libs/ui/KeyCharacterMap.cpp
index e689c4b..9bfa8f6 100644
--- a/libs/ui/KeyCharacterMap.cpp
+++ b/libs/ui/KeyCharacterMap.cpp
@@ -141,9 +141,8 @@
char16_t KeyCharacterMap::getDisplayLabel(int32_t keyCode) const {
char16_t result = 0;
- ssize_t index = mKeys.indexOfKey(keyCode);
- if (index >= 0) {
- const Key* key = mKeys.valueAt(index);
+ const Key* key;
+ if (getKey(keyCode, &key)) {
result = key->label;
}
#if DEBUG_MAPPING
@@ -154,9 +153,8 @@
char16_t KeyCharacterMap::getNumber(int32_t keyCode) const {
char16_t result = 0;
- ssize_t index = mKeys.indexOfKey(keyCode);
- if (index >= 0) {
- const Key* key = mKeys.valueAt(index);
+ const Key* key;
+ if (getKey(keyCode, &key)) {
result = key->number;
}
#if DEBUG_MAPPING
@@ -167,15 +165,10 @@
char16_t KeyCharacterMap::getCharacter(int32_t keyCode, int32_t metaState) const {
char16_t result = 0;
- ssize_t index = mKeys.indexOfKey(keyCode);
- if (index >= 0) {
- const Key* key = mKeys.valueAt(index);
- for (const Behavior* behavior = key->firstBehavior; behavior; behavior = behavior->next) {
- if ((behavior->metaState & metaState) == behavior->metaState) {
- result = behavior->character;
- break;
- }
- }
+ const Key* key;
+ const Behavior* behavior;
+ if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
+ result = behavior->character;
}
#if DEBUG_MAPPING
LOGD("getCharacter: keyCode=%d, metaState=0x%08x ~ Result %d.", keyCode, metaState, result);
@@ -183,13 +176,33 @@
return result;
}
+bool KeyCharacterMap::getFallbackAction(int32_t keyCode, int32_t metaState,
+ FallbackAction* outFallbackAction) const {
+ outFallbackAction->keyCode = 0;
+ outFallbackAction->metaState = 0;
+
+ bool result = false;
+ const Key* key;
+ const Behavior* behavior;
+ if (getKeyBehavior(keyCode, metaState, &key, &behavior)) {
+ outFallbackAction->keyCode = behavior->fallbackKeyCode;
+ outFallbackAction->metaState = metaState & ~behavior->metaState;
+ result = true;
+ }
+#if DEBUG_MAPPING
+ LOGD("getFallbackKeyCode: keyCode=%d, metaState=0x%08x ~ Result %s, "
+ "fallback keyCode=%d, fallback metaState=0x%08x.",
+ keyCode, metaState, result ? "true" : "false",
+ outFallbackAction->keyCode, outFallbackAction->metaState);
+#endif
+ return result;
+}
+
char16_t KeyCharacterMap::getMatch(int32_t keyCode, const char16_t* chars, size_t numChars,
int32_t metaState) const {
char16_t result = 0;
- ssize_t index = mKeys.indexOfKey(keyCode);
- if (index >= 0) {
- const Key* key = mKeys.valueAt(index);
-
+ const Key* key;
+ if (getKey(keyCode, &key)) {
// Try to find the most general behavior that maps to this character.
// For example, the base key behavior will usually be last in the list.
// However, if we find a perfect meta state match for one behavior then use that one.
@@ -238,7 +251,7 @@
}
#if DEBUG_MAPPING
LOGD("getEvents: deviceId=%d, chars=[%s] ~ Generated %d events.",
- deviceId, toString(chars, numChars).string(), outEvents.size());
+ deviceId, toString(chars, numChars).string(), int32_t(outEvents.size()));
for (size_t i = 0; i < outEvents.size(); i++) {
LOGD(" Key: keyCode=%d, metaState=0x%08x, %s.",
outEvents[i].getKeyCode(), outEvents[i].getMetaState(),
@@ -248,6 +261,32 @@
return true;
}
+bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const {
+ ssize_t index = mKeys.indexOfKey(keyCode);
+ if (index >= 0) {
+ *outKey = mKeys.valueAt(index);
+ return true;
+ }
+ return false;
+}
+
+bool KeyCharacterMap::getKeyBehavior(int32_t keyCode, int32_t metaState,
+ const Key** outKey, const Behavior** outBehavior) const {
+ const Key* key;
+ if (getKey(keyCode, &key)) {
+ const Behavior* behavior = key->firstBehavior;
+ while (behavior) {
+ if ((behavior->metaState & metaState) == behavior->metaState) {
+ *outKey = key;
+ *outBehavior = behavior;
+ return true;
+ }
+ behavior = behavior->next;
+ }
+ }
+ return false;
+}
+
bool KeyCharacterMap::findKey(char16_t ch, int32_t* outKeyCode, int32_t* outMetaState) const {
if (!ch) {
return false;