From 278b525d25b852554015ec4f92862f9297b502fd Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Mon, 4 Aug 2014 20:26:30 -0700 Subject: [PATCH] Add system accelerators for BACK and HOME. Meta+Backspace -> BACK Meta+Enter -> HOME Bug: 14066931 Change-Id: Iff1d027300fa9911626785944a6d8efe4f62235e --- services/inputflinger/InputDispatcher.cpp | 44 +++++++++++++++++++++-- services/inputflinger/InputDispatcher.h | 14 ++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp index a750a3d53..8c16fade2 100644 --- a/services/inputflinger/InputDispatcher.cpp +++ b/services/inputflinger/InputDispatcher.cpp @@ -2366,9 +2366,36 @@ void InputDispatcher::notifyKey(const NotifyKeyArgs* args) { 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 @@ void InputDispatcher::notifyKey(const NotifyKeyArgs* args) { 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 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) { mTouchStatesByDisplay.clear(); mLastHoverWindowHandle.clear(); + mReplacedKeys.clear(); } void InputDispatcher::logDispatchStateLocked() { @@ -3188,6 +3216,18 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) { dump.append(INDENT "InboundQueue: \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: \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 9439124be..0d15d7b27 100644 --- a/services/inputflinger/InputDispatcher.h +++ b/services/inputflinger/InputDispatcher.h @@ -904,6 +904,20 @@ private: 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 mReplacedKeys; + // Deferred command processing. bool haveCommandsLocked() const; bool runCommandsLockedInterruptible();