summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2011-09-12 18:24:59 -0700
committerJeff Brown <jeffbrown@google.com>2011-09-13 16:52:12 -0700
commit98392efb24d8aac36a4cfa85106812e17d5984f9 (patch)
tree2c48adde5f59b9804b6f2481bcb60d8f3eb5047c
parent6515f50d0c759cfff163aaf7f42a970019d93923 (diff)
downloadframeworks_base-98392efb24d8aac36a4cfa85106812e17d5984f9.zip
frameworks_base-98392efb24d8aac36a4cfa85106812e17d5984f9.tar.gz
frameworks_base-98392efb24d8aac36a4cfa85106812e17d5984f9.tar.bz2
Fix bug in KeyButtonView key injection logic.
Bug: 5299191 Bug: 5300282 Only send keys when mCode != 0. Simplified the logic for repeating / non-repeating keys. Key down / up are always correlated with touch down / up, the only thing that's special is that we detect long press for repeating keys and not for others. Ensure that up or cancel is always sent for every key that is generated. Previously it was possible for keys to get stuck down if touch moved out of the button's active area. Removed the funky HOME long press timer. We don't need it since we can rely on the long-press flag instead. Since the system UI is in direct control of key repeating and long-press behavior for the keys it inject, this eliminates the need for special hacks to circumvent the timer. Ensure that the same haptic feedback is provided for all keys, including the recent apps key. Previously this only worked because the code was injecting a bogus key with code 0. Don't generate repeated haptic feedback for virtual keys even when those keys are injected. This doesn't happen for virtual keys synthesized by the InputReader because it never injects repeats itself (the InputDispatcher synthesizes them), but it is an issue for the KeyButtonView. Change-Id: I8b3615dde738af28e76898d161d6ce9a883b59ec
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java93
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java30
2 files changed, 47 insertions, 76 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 840087c..3a06068 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -16,12 +16,10 @@
package com.android.systemui.statusbar.policy;
-import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
-import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.Canvas;
import android.graphics.RectF;
@@ -29,7 +27,6 @@ import android.os.RemoteException;
import android.os.SystemClock;
import android.os.ServiceManager;
import android.util.AttributeSet;
-import android.util.Slog;
import android.view.accessibility.AccessibilityEvent;
import android.view.HapticFeedbackConstants;
import android.view.IWindowManager;
@@ -40,9 +37,7 @@ import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewConfiguration;
-import android.view.ViewGroup;
import android.widget.ImageView;
-import android.widget.RemoteViews.RemoteView;
import com.android.systemui.R;
@@ -53,9 +48,7 @@ public class KeyButtonView extends ImageView {
IWindowManager mWindowManager;
long mDownTime;
- boolean mSending;
int mCode;
- int mRepeat;
int mTouchSlop;
Drawable mGlowBG;
float mGlowAlpha = 0f, mGlowScale = 1f, mDrawingAlpha = 1f;
@@ -67,12 +60,7 @@ public class KeyButtonView extends ImageView {
if (isPressed()) {
// Slog.d("KeyButtonView", "longpressed: " + this);
if (mCode != 0) {
- mRepeat++;
- sendEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.FLAG_FROM_SYSTEM
- | KeyEvent.FLAG_VIRTUAL_HARD_KEY
- | KeyEvent.FLAG_LONG_PRESS);
-
+ sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
} else {
// Just an old-fashioned ImageView
@@ -217,64 +205,54 @@ public class KeyButtonView extends ImageView {
case MotionEvent.ACTION_DOWN:
//Slog.d("KeyButtonView", "press");
mDownTime = SystemClock.uptimeMillis();
- mRepeat = 0;
- mSending = true;
setPressed(true);
- sendEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, mDownTime);
+ if (mCode != 0) {
+ sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);
+ } else {
+ // Provide the same haptic feedback that the system offers for virtual keys.
+ performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+ }
if (mSupportsLongpress) {
removeCallbacks(mCheckLongPress);
postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
- } else {
- mSending = false;
- sendEvent(KeyEvent.ACTION_UP,
- KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, mDownTime);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
- playSoundEffect(SoundEffectConstants.CLICK);
}
break;
case MotionEvent.ACTION_MOVE:
- if (mSending) {
- x = (int)ev.getX();
- y = (int)ev.getY();
- setPressed(x >= -mTouchSlop
- && x < getWidth() + mTouchSlop
- && y >= -mTouchSlop
- && y < getHeight() + mTouchSlop);
- }
+ x = (int)ev.getX();
+ y = (int)ev.getY();
+ setPressed(x >= -mTouchSlop
+ && x < getWidth() + mTouchSlop
+ && y >= -mTouchSlop
+ && y < getHeight() + mTouchSlop);
break;
case MotionEvent.ACTION_CANCEL:
setPressed(false);
- if (mSending) {
- mSending = false;
- sendEvent(KeyEvent.ACTION_UP,
- KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY
- | KeyEvent.FLAG_CANCELED);
- if (mSupportsLongpress) {
- removeCallbacks(mCheckLongPress);
- }
+ if (mCode != 0) {
+ sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
+ }
+ if (mSupportsLongpress) {
+ removeCallbacks(mCheckLongPress);
}
break;
case MotionEvent.ACTION_UP:
final boolean doIt = isPressed();
setPressed(false);
- if (mSending) {
- mSending = false;
- final int flags = KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY;
- if (mSupportsLongpress) {
- removeCallbacks(mCheckLongPress);
- }
-
- if (mCode != 0) {
- if (doIt) {
- sendEvent(KeyEvent.ACTION_UP, flags);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
- playSoundEffect(SoundEffectConstants.CLICK);
- }
+ if (mCode != 0) {
+ if (doIt) {
+ sendEvent(KeyEvent.ACTION_UP, 0);
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+ playSoundEffect(SoundEffectConstants.CLICK);
} else {
- // no key code, just a regular ImageView
- if (doIt) performClick();
+ sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
}
+ } else {
+ // no key code, just a regular ImageView
+ if (doIt) {
+ performClick();
+ }
+ }
+ if (mSupportsLongpress) {
+ removeCallbacks(mCheckLongPress);
}
break;
}
@@ -287,8 +265,11 @@ public class KeyButtonView extends ImageView {
}
void sendEvent(int action, int flags, long when) {
- final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, mRepeat,
- 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags, InputDevice.SOURCE_KEYBOARD);
+ final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
+ final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount,
+ 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
+ flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
+ InputDevice.SOURCE_KEYBOARD);
try {
//Slog.d(TAG, "injecting event " + ev);
mWindowManager.injectInputEventNoWait(ev);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 86671bd..94fcb44 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -629,15 +629,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mContext.getContentResolver(), Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
}
- /**
- * When a home-key longpress expires, close other system windows and launch the recent apps
- */
- Runnable mHomeLongPress = new Runnable() {
- public void run() {
- handleLongPressOnHome();
- }
- };
-
private void handleLongPressOnHome() {
// We can't initialize this in init() since the configuration hasn't been loaded yet.
if (mLongPressOnHomeBehavior < 0) {
@@ -1418,11 +1409,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// it handle it, because that gives us the correct 5 second
// timeout.
if (keyCode == KeyEvent.KEYCODE_HOME) {
- // Clear a pending HOME longpress if the user releases Home
- if (!down) {
- mHandler.removeCallbacks(mHomeLongPress);
- }
-
// If we have released the home key, and didn't do anything else
// while it was pressed, then it is time to go home!
if (mHomePressed && !down) {
@@ -1470,12 +1456,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
}
-
- if (down && repeatCount == 0) {
- if (!keyguardOn) {
- mHandler.postDelayed(mHomeLongPress, ViewConfiguration.getGlobalActionKeyTimeout());
+
+ if (down) {
+ if (repeatCount == 0) {
+ mHomePressed = true;
+ } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
+ if (!keyguardOn) {
+ handleLongPressOnHome();
+ }
}
- mHomePressed = true;
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_MENU) {
@@ -2518,7 +2507,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive);
}
- if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0) {
+ if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0
+ && event.getRepeatCount() == 0) {
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
}