summaryrefslogtreecommitdiff
path: root/core/java/android/view/KeyCharacterMap.java
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2012-05-09 13:34:28 -0700
committerJeff Brown <jeffbrown@google.com>2012-05-09 13:34:28 -0700
commitfd23e3ed976b22b9a92ddb2cb3a46f9d2a0ce23f (patch)
treeb3d9f4d12fe2d93ba9979e6d66b1d9f4de016178 /core/java/android/view/KeyCharacterMap.java
parentaf67fc65bf113b028ff33e71cd6a45810018c273 (diff)
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 'core/java/android/view/KeyCharacterMap.java')
-rw-r--r--core/java/android/view/KeyCharacterMap.java55
1 files changed, 46 insertions, 9 deletions
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 5b371ebf31cd..2cb724f31b13 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -386,19 +386,19 @@ public class KeyCharacterMap implements Parcelable {
*
* @param keyCode The key code.
* @param metaState The meta key modifier state.
- * @param outFallbackAction The fallback action object to populate.
- * @return True if a fallback action was found, false otherwise.
+ * @return The fallback action, or null if none. Remember to recycle the fallback action.
*
* @hide
*/
- public boolean getFallbackAction(int keyCode, int metaState,
- FallbackAction outFallbackAction) {
- if (outFallbackAction == null) {
- throw new IllegalArgumentException("fallbackAction must not be null");
- }
-
+ public FallbackAction getFallbackAction(int keyCode, int metaState) {
+ FallbackAction action = FallbackAction.obtain();
metaState = KeyEvent.normalizeMetaState(metaState);
- return nativeGetFallbackAction(mPtr, keyCode, metaState, outFallbackAction);
+ if (nativeGetFallbackAction(mPtr, keyCode, metaState, action)) {
+ action.metaState = KeyEvent.normalizeMetaState(action.metaState);
+ return action;
+ }
+ action.recycle();
+ return null;
}
/**
@@ -727,7 +727,44 @@ public class KeyCharacterMap implements Parcelable {
* @hide
*/
public static final class FallbackAction {
+ private static final int MAX_RECYCLED = 10;
+ private static final Object sRecycleLock = new Object();
+ private static FallbackAction sRecycleBin;
+ private static int sRecycledCount;
+
+ private FallbackAction next;
+
public int keyCode;
public int metaState;
+
+ private FallbackAction() {
+ }
+
+ public static FallbackAction obtain() {
+ final FallbackAction target;
+ synchronized (sRecycleLock) {
+ if (sRecycleBin == null) {
+ target = new FallbackAction();
+ } else {
+ target = sRecycleBin;
+ sRecycleBin = target.next;
+ sRecycledCount--;
+ target.next = null;
+ }
+ }
+ return target;
+ }
+
+ public void recycle() {
+ synchronized (sRecycleLock) {
+ if (sRecycledCount < MAX_RECYCLED) {
+ next = sRecycleBin;
+ sRecycleBin = this;
+ sRecycledCount += 1;
+ } else {
+ next = null;
+ }
+ }
+ }
}
}