diff options
author | Jeff Brown <jeffbrown@google.com> | 2012-05-09 13:34:28 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2012-05-09 13:34:28 -0700 |
commit | fd23e3ed976b22b9a92ddb2cb3a46f9d2a0ce23f (patch) | |
tree | b3d9f4d12fe2d93ba9979e6d66b1d9f4de016178 /services/input | |
parent | af67fc65bf113b028ff33e71cd6a45810018c273 (diff) | |
download | frameworks_base-fd23e3ed976b22b9a92ddb2cb3a46f9d2a0ce23f.zip frameworks_base-fd23e3ed976b22b9a92ddb2cb3a46f9d2a0ce23f.tar.gz frameworks_base-fd23e3ed976b22b9a92ddb2cb3a46f9d2a0ce23f.tar.bz2 |
Fix bugs in fallback key handling.
If a fallback key is generated using a key plus a modifier,
then it's possible we might get a different fallback key
generated if the modifier has changed. PhoneWindowManager
needs to remember which fallback is last generated for a
given key code so that it can apply the same fallback action.
When generating cancellation events, it's important to have
preserved the policyFlags of the original event. Otherwise
we may not dispatch the cancellation properly. For example,
some actions are not performed if the POLICY_FLAG_TRUSTED
is not specified.
Remember the metaState associated with a key event so we can
include it when canceled.
Tell the policy when a fallback is being cancelled so that it
can clean up its state.
After a SEARCH shortcut is invoked, clear the flag indicating
that a shortcut is pending. This is to prevent SEARCH from
getting stuck down in the case where we might forget to send
the up. (Shouldn't happen anymore after the prior fixes.)
Bug: 5616255
Change-Id: I68f0a9679c7af464eaf31c099f2aa50b53fecf1f
Diffstat (limited to 'services/input')
-rw-r--r-- | services/input/InputDispatcher.cpp | 40 | ||||
-rw-r--r-- | services/input/InputDispatcher.h | 3 |
2 files changed, 35 insertions, 8 deletions
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp index ada9d9e..1062d68 100644 --- a/services/input/InputDispatcher.cpp +++ b/services/input/InputDispatcher.cpp @@ -3354,6 +3354,25 @@ bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& con // generated a fallback or if the window is not a foreground window, // then cancel the associated fallback key, if any. if (fallbackKeyCode != -1) { + // Dispatch the unhandled key to the policy with the cancel flag. +#if DEBUG_OUTBOUND_EVENT_DETAILS + ALOGD("Unhandled key event: Asking policy to cancel fallback action. " + "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x", + keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, + keyEntry->policyFlags); +#endif + KeyEvent event; + initializeKeyEvent(&event, keyEntry); + event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED); + + mLock.unlock(); + + mPolicy->dispatchUnhandledKey(connection->inputWindowHandle, + &event, keyEntry->policyFlags, &event); + + mLock.lock(); + + // Cancel the fallback key. if (fallbackKeyCode != AKEYCODE_UNKNOWN) { CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS, "application handled the original non-fallback key " @@ -3374,8 +3393,9 @@ bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& con #if DEBUG_OUTBOUND_EVENT_DETAILS ALOGD("Unhandled key event: Skipping unhandled key event processing " "since this is not an initial down. " - "keyCode=%d, action=%d, repeatCount=%d", - originalKeyCode, keyEntry->action, keyEntry->repeatCount); + "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x", + originalKeyCode, keyEntry->action, keyEntry->repeatCount, + keyEntry->policyFlags); #endif return false; } @@ -3383,8 +3403,9 @@ bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& con // Dispatch the unhandled key to the policy. #if DEBUG_OUTBOUND_EVENT_DETAILS ALOGD("Unhandled key event: Asking policy to perform fallback action. " - "keyCode=%d, action=%d, repeatCount=%d", - keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount); + "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x", + keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount, + keyEntry->policyFlags); #endif KeyEvent event; initializeKeyEvent(&event, keyEntry); @@ -3426,7 +3447,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& con "to send %d instead. Fallback canceled.", event.getKeyCode(), originalKeyCode, fallbackKeyCode); } else { - ALOGD("Unhandled key event: Policy did not request fallback for %d," + ALOGD("Unhandled key event: Policy did not request fallback for %d, " "but on the DOWN it had requested to send %d. " "Fallback canceled.", originalKeyCode, fallbackKeyCode); @@ -3903,8 +3924,10 @@ void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t f memento.source = entry->source; memento.keyCode = entry->keyCode; memento.scanCode = entry->scanCode; + memento.metaState = entry->metaState; memento.flags = flags; memento.downTime = entry->downTime; + memento.policyFlags = entry->policyFlags; } void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry, @@ -3919,6 +3942,7 @@ void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry, memento.downTime = entry->downTime; memento.setPointers(entry); memento.hovering = hovering; + memento.policyFlags = entry->policyFlags; } void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) { @@ -3935,9 +3959,9 @@ void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTim const KeyMemento& memento = mKeyMementos.itemAt(i); if (shouldCancelKey(memento, options)) { outEvents.push(new KeyEntry(currentTime, - memento.deviceId, memento.source, 0, + memento.deviceId, memento.source, memento.policyFlags, AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED, - memento.keyCode, memento.scanCode, 0, 0, memento.downTime)); + memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime)); } } @@ -3945,7 +3969,7 @@ void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTim const MotionMemento& memento = mMotionMementos.itemAt(i); if (shouldCancelMotion(memento, options)) { outEvents.push(new MotionEntry(currentTime, - memento.deviceId, memento.source, 0, + memento.deviceId, memento.source, memento.policyFlags, memento.hovering ? AMOTION_EVENT_ACTION_HOVER_EXIT : AMOTION_EVENT_ACTION_CANCEL, diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h index 07ca9d5..06b8d64 100644 --- a/services/input/InputDispatcher.h +++ b/services/input/InputDispatcher.h @@ -732,8 +732,10 @@ private: uint32_t source; int32_t keyCode; int32_t scanCode; + int32_t metaState; int32_t flags; nsecs_t downTime; + uint32_t policyFlags; }; struct MotionMemento { @@ -747,6 +749,7 @@ private: PointerProperties pointerProperties[MAX_POINTERS]; PointerCoords pointerCoords[MAX_POINTERS]; bool hovering; + uint32_t policyFlags; void setPointers(const MotionEntry* entry); }; |