summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff Brown <jeffbrown@google.com> 2011-02-22 15:00:50 -0800
committer Jeff Brown <jeffbrown@google.com> 2011-02-22 15:00:50 -0800
commitbfaf3b91709ef35e0d5901b186edd7c2a9729161 (patch)
tree9ecdcc0702b8314ba836508d39a5c754b9537a28
parentcc0c159e9b3dd4e0f48da0ce3e33d2c68a651413 (diff)
Be more precise about tracking fallback keys.
Only initiate fallback key handling if the first key down was not handled and there is no other fallback key already in progress. This prevents spurious fallbacks from being generated when applications handle the initial down but not repeated downs or the up. Change-Id: I8a513896cf96b16dc502cd72291926d5532aa2ab
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java8
-rw-r--r--services/input/InputDispatcher.cpp58
-rw-r--r--services/input/InputDispatcher.h1
3 files changed, 60 insertions, 7 deletions
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 156391e2aac9..14f4df1a281f 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1448,7 +1448,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
| KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
if (shortcutIntent != null) {
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(shortcutIntent);
+ try {
+ mContext.startActivity(shortcutIntent);
+ } catch (ActivityNotFoundException ex) {
+ Slog.w(TAG, "Dropping shortcut key combination because "
+ + "the activity to which it is registered was not found: "
+ + "META+" + KeyEvent.keyCodeToString(keyCode), ex);
+ }
return null;
}
}
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index ef984d41cf17..2e3f0bdc9ff7 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -3211,14 +3211,52 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
// be used as modifiers) but it will ensure that fallback keys do not
// get stuck. This takes care of the case where the application does not handle
// the original DOWN so we generate a fallback DOWN but it does handle
- // the original UP in which case we would not generate the fallback UP.
+ // the original UP in which case we want to send a fallback CANCEL.
synthesizeCancelationEventsForConnectionLocked(connection,
InputState::CANCEL_FALLBACK_EVENTS,
- "application handled a non-fallback event, canceling all fallback events");
+ "application handled a non-fallback event, "
+ "canceling all fallback events");
+ connection->originalKeyCodeForFallback = -1;
} else {
- // If the application did not handle a non-fallback key, then ask
- // the policy what to do with it. We might generate a fallback key
- // event here.
+ // If the application did not handle a non-fallback key, first check
+ // that we are in a good state to handle the fallback key. Then ask
+ // the policy what to do with it.
+ if (connection->originalKeyCodeForFallback < 0) {
+ if (keyEntry->action != AKEY_EVENT_ACTION_DOWN
+ || keyEntry->repeatCount != 0) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+ LOGD("Unhandled key event: Skipping fallback since this "
+ "is not an initial down. "
+ "keyCode=%d, action=%d, repeatCount=%d",
+ keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
+#endif
+ goto SkipFallback;
+ }
+
+ // Start handling the fallback key on DOWN.
+ connection->originalKeyCodeForFallback = keyEntry->keyCode;
+ } else {
+ if (keyEntry->keyCode != connection->originalKeyCodeForFallback) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+ LOGD("Unhandled key event: Skipping fallback since there is "
+ "already a different fallback in progress. "
+ "keyCode=%d, originalKeyCodeForFallback=%d",
+ keyEntry->keyCode, connection->originalKeyCodeForFallback);
+#endif
+ goto SkipFallback;
+ }
+
+ // Finish handling the fallback key on UP.
+ if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
+ connection->originalKeyCodeForFallback = -1;
+ }
+ }
+
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+ LOGD("Unhandled key event: Asking policy to perform fallback action. "
+ "keyCode=%d, action=%d, repeatCount=%d",
+ keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
+#endif
KeyEvent event;
initializeKeyEvent(&event, keyEntry);
@@ -3248,6 +3286,12 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
keyEntry->downTime = event.getDownTime();
keyEntry->syntheticRepeat = false;
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+ LOGD("Unhandled key event: Dispatching fallback key. "
+ "fallbackKeyCode=%d, fallbackMetaState=%08x",
+ keyEntry->keyCode, keyEntry->metaState);
+#endif
+
dispatchEntry->inProgress = false;
startDispatchCycleLocked(now(), connection);
return;
@@ -3257,6 +3301,7 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
}
}
+SkipFallback:
startNextDispatchCycleLocked(now(), connection);
}
@@ -3715,7 +3760,8 @@ InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
const sp<InputWindowHandle>& inputWindowHandle) :
status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
inputPublisher(inputChannel),
- lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
+ lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX),
+ originalKeyCodeForFallback(-1) {
}
InputDispatcher::Connection::~Connection() {
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 7abe0140f445..304b1bbd92d5 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -682,6 +682,7 @@ private:
nsecs_t lastEventTime; // the time when the event was originally captured
nsecs_t lastDispatchTime; // the time when the last event was dispatched
+ int32_t originalKeyCodeForFallback; // original keycode for fallback in progress, -1 if none
explicit Connection(const sp<InputChannel>& inputChannel,
const sp<InputWindowHandle>& inputWindowHandle);