Add system accelerators for BACK and HOME.
Meta+Backspace -> BACK
Meta+Enter -> HOME
Bug: 14066931
Change-Id: Iff1d027300fa9911626785944a6d8efe4f62235e
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index a750a3d..8c16fad 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -2366,9 +2366,36 @@
policyFlags |= POLICY_FLAG_TRUSTED;
+ int32_t keyCode = args->keyCode;
+ if (metaState & AMETA_META_ON && args->action == AKEY_EVENT_ACTION_DOWN) {
+ int32_t newKeyCode = AKEYCODE_UNKNOWN;
+ if (keyCode == AKEYCODE_DEL) {
+ newKeyCode = AKEYCODE_BACK;
+ } else if (keyCode == AKEYCODE_ENTER) {
+ newKeyCode = AKEYCODE_HOME;
+ }
+ if (newKeyCode != AKEYCODE_UNKNOWN) {
+ AutoMutex _l(mLock);
+ struct KeyReplacement replacement = {keyCode, args->deviceId};
+ mReplacedKeys.add(replacement, newKeyCode);
+ keyCode = newKeyCode;
+ metaState &= ~AMETA_META_ON;
+ }
+ } else if (args->action == AKEY_EVENT_ACTION_UP) {
+ // In order to maintain a consistent stream of up and down events, check to see if the key
+ // going up is one we've replaced in a down event and haven't yet replaced in an up event,
+ // even if the modifier was released between the down and the up events.
+ AutoMutex _l(mLock);
+ struct KeyReplacement replacement = {keyCode, args->deviceId};
+ ssize_t index = mReplacedKeys.indexOfKey(replacement);
+ keyCode = mReplacedKeys.valueAt(index);
+ mReplacedKeys.removeItemsAt(index);
+ metaState &= ~AMETA_META_ON;
+ }
+
KeyEvent event;
event.initialize(args->deviceId, args->source, args->action,
- flags, args->keyCode, args->scanCode, metaState, 0,
+ flags, keyCode, args->scanCode, metaState, 0,
args->downTime, args->eventTime);
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
@@ -2391,7 +2418,7 @@
int32_t repeatCount = 0;
KeyEntry* newEntry = new KeyEntry(args->eventTime,
args->deviceId, args->source, policyFlags,
- args->action, flags, args->keyCode, args->scanCode,
+ args->action, flags, keyCode, args->scanCode,
metaState, repeatCount, args->downTime);
needWake = enqueueInboundEventLocked(newEntry);
@@ -3050,6 +3077,7 @@
mTouchStatesByDisplay.clear();
mLastHoverWindowHandle.clear();
+ mReplacedKeys.clear();
}
void InputDispatcher::logDispatchStateLocked() {
@@ -3188,6 +3216,18 @@
dump.append(INDENT "InboundQueue: <empty>\n");
}
+ if (!mReplacedKeys.isEmpty()) {
+ dump.append(INDENT "ReplacedKeys:\n");
+ for (size_t i = 0; i < mReplacedKeys.size(); i++) {
+ const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
+ int32_t newKeyCode = mReplacedKeys.valueAt(i);
+ dump.appendFormat(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n",
+ i, replacement.keyCode, replacement.deviceId, newKeyCode);
+ }
+ } else {
+ dump.append(INDENT "ReplacedKeys: <empty>\n");
+ }
+
if (!mConnectionsByFd.isEmpty()) {
dump.append(INDENT "Connections:\n");
for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 9439124..0d15d7b 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -904,6 +904,20 @@
void resetKeyRepeatLocked();
KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime);
+ // Key replacement tracking
+ struct KeyReplacement {
+ int32_t keyCode;
+ int32_t deviceId;
+ bool operator==(const KeyReplacement& rhs) const {
+ return keyCode == rhs.keyCode && deviceId == rhs.deviceId;
+ }
+ bool operator<(const KeyReplacement& rhs) const {
+ return keyCode != rhs.keyCode ? keyCode < rhs.keyCode : deviceId < rhs.deviceId;
+ }
+ };
+ // Maps the key code replaced, device id tuple to the key code it was replaced with
+ KeyedVector<KeyReplacement, int32_t> mReplacedKeys;
+
// Deferred command processing.
bool haveCommandsLocked() const;
bool runCommandsLockedInterruptible();