Merge "Fix bug in KeyButtonView key injection logic. Bug: 5299191 Bug: 5300282"
This commit is contained in:
@@ -16,12 +16,10 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.policy;
|
package com.android.systemui.statusbar.policy;
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.AnimatorSet;
|
import android.animation.AnimatorSet;
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.drawable.AnimationDrawable;
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
@@ -29,7 +27,6 @@ import android.os.RemoteException;
|
|||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Slog;
|
|
||||||
import android.view.accessibility.AccessibilityEvent;
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
import android.view.HapticFeedbackConstants;
|
import android.view.HapticFeedbackConstants;
|
||||||
import android.view.IWindowManager;
|
import android.view.IWindowManager;
|
||||||
@@ -40,9 +37,7 @@ import android.view.MotionEvent;
|
|||||||
import android.view.SoundEffectConstants;
|
import android.view.SoundEffectConstants;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewConfiguration;
|
import android.view.ViewConfiguration;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.RemoteViews.RemoteView;
|
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
|
||||||
@@ -53,9 +48,7 @@ public class KeyButtonView extends ImageView {
|
|||||||
|
|
||||||
IWindowManager mWindowManager;
|
IWindowManager mWindowManager;
|
||||||
long mDownTime;
|
long mDownTime;
|
||||||
boolean mSending;
|
|
||||||
int mCode;
|
int mCode;
|
||||||
int mRepeat;
|
|
||||||
int mTouchSlop;
|
int mTouchSlop;
|
||||||
Drawable mGlowBG;
|
Drawable mGlowBG;
|
||||||
float mGlowAlpha = 0f, mGlowScale = 1f, mDrawingAlpha = 1f;
|
float mGlowAlpha = 0f, mGlowScale = 1f, mDrawingAlpha = 1f;
|
||||||
@@ -67,12 +60,7 @@ public class KeyButtonView extends ImageView {
|
|||||||
if (isPressed()) {
|
if (isPressed()) {
|
||||||
// Slog.d("KeyButtonView", "longpressed: " + this);
|
// Slog.d("KeyButtonView", "longpressed: " + this);
|
||||||
if (mCode != 0) {
|
if (mCode != 0) {
|
||||||
mRepeat++;
|
sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
|
||||||
sendEvent(KeyEvent.ACTION_DOWN,
|
|
||||||
KeyEvent.FLAG_FROM_SYSTEM
|
|
||||||
| KeyEvent.FLAG_VIRTUAL_HARD_KEY
|
|
||||||
| KeyEvent.FLAG_LONG_PRESS);
|
|
||||||
|
|
||||||
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
|
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
|
||||||
} else {
|
} else {
|
||||||
// Just an old-fashioned ImageView
|
// Just an old-fashioned ImageView
|
||||||
@@ -217,64 +205,54 @@ public class KeyButtonView extends ImageView {
|
|||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
//Slog.d("KeyButtonView", "press");
|
//Slog.d("KeyButtonView", "press");
|
||||||
mDownTime = SystemClock.uptimeMillis();
|
mDownTime = SystemClock.uptimeMillis();
|
||||||
mRepeat = 0;
|
|
||||||
mSending = true;
|
|
||||||
setPressed(true);
|
setPressed(true);
|
||||||
sendEvent(KeyEvent.ACTION_DOWN,
|
if (mCode != 0) {
|
||||||
KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, mDownTime);
|
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) {
|
if (mSupportsLongpress) {
|
||||||
removeCallbacks(mCheckLongPress);
|
removeCallbacks(mCheckLongPress);
|
||||||
postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
|
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;
|
break;
|
||||||
case MotionEvent.ACTION_MOVE:
|
case MotionEvent.ACTION_MOVE:
|
||||||
if (mSending) {
|
x = (int)ev.getX();
|
||||||
x = (int)ev.getX();
|
y = (int)ev.getY();
|
||||||
y = (int)ev.getY();
|
setPressed(x >= -mTouchSlop
|
||||||
setPressed(x >= -mTouchSlop
|
&& x < getWidth() + mTouchSlop
|
||||||
&& x < getWidth() + mTouchSlop
|
&& y >= -mTouchSlop
|
||||||
&& y >= -mTouchSlop
|
&& y < getHeight() + mTouchSlop);
|
||||||
&& y < getHeight() + mTouchSlop);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_CANCEL:
|
case MotionEvent.ACTION_CANCEL:
|
||||||
setPressed(false);
|
setPressed(false);
|
||||||
if (mSending) {
|
if (mCode != 0) {
|
||||||
mSending = false;
|
sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
|
||||||
sendEvent(KeyEvent.ACTION_UP,
|
}
|
||||||
KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY
|
if (mSupportsLongpress) {
|
||||||
| KeyEvent.FLAG_CANCELED);
|
removeCallbacks(mCheckLongPress);
|
||||||
if (mSupportsLongpress) {
|
|
||||||
removeCallbacks(mCheckLongPress);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP:
|
||||||
final boolean doIt = isPressed();
|
final boolean doIt = isPressed();
|
||||||
setPressed(false);
|
setPressed(false);
|
||||||
if (mSending) {
|
if (mCode != 0) {
|
||||||
mSending = false;
|
if (doIt) {
|
||||||
final int flags = KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY;
|
sendEvent(KeyEvent.ACTION_UP, 0);
|
||||||
if (mSupportsLongpress) {
|
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
|
||||||
removeCallbacks(mCheckLongPress);
|
playSoundEffect(SoundEffectConstants.CLICK);
|
||||||
}
|
|
||||||
|
|
||||||
if (mCode != 0) {
|
|
||||||
if (doIt) {
|
|
||||||
sendEvent(KeyEvent.ACTION_UP, flags);
|
|
||||||
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
|
|
||||||
playSoundEffect(SoundEffectConstants.CLICK);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// no key code, just a regular ImageView
|
sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
|
||||||
if (doIt) performClick();
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// no key code, just a regular ImageView
|
||||||
|
if (doIt) {
|
||||||
|
performClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mSupportsLongpress) {
|
||||||
|
removeCallbacks(mCheckLongPress);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -287,8 +265,11 @@ public class KeyButtonView extends ImageView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sendEvent(int action, int flags, long when) {
|
void sendEvent(int action, int flags, long when) {
|
||||||
final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, mRepeat,
|
final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
|
||||||
0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0, flags, InputDevice.SOURCE_KEYBOARD);
|
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 {
|
try {
|
||||||
//Slog.d(TAG, "injecting event " + ev);
|
//Slog.d(TAG, "injecting event " + ev);
|
||||||
mWindowManager.injectInputEventNoWait(ev);
|
mWindowManager.injectInputEventNoWait(ev);
|
||||||
|
|||||||
@@ -629,15 +629,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
mContext.getContentResolver(), Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
|
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() {
|
private void handleLongPressOnHome() {
|
||||||
// We can't initialize this in init() since the configuration hasn't been loaded yet.
|
// We can't initialize this in init() since the configuration hasn't been loaded yet.
|
||||||
if (mLongPressOnHomeBehavior < 0) {
|
if (mLongPressOnHomeBehavior < 0) {
|
||||||
@@ -1418,11 +1409,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
// it handle it, because that gives us the correct 5 second
|
// it handle it, because that gives us the correct 5 second
|
||||||
// timeout.
|
// timeout.
|
||||||
if (keyCode == KeyEvent.KEYCODE_HOME) {
|
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
|
// If we have released the home key, and didn't do anything else
|
||||||
// while it was pressed, then it is time to go home!
|
// while it was pressed, then it is time to go home!
|
||||||
if (mHomePressed && !down) {
|
if (mHomePressed && !down) {
|
||||||
@@ -1470,12 +1456,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (down && repeatCount == 0) {
|
if (down) {
|
||||||
if (!keyguardOn) {
|
if (repeatCount == 0) {
|
||||||
mHandler.postDelayed(mHomeLongPress, ViewConfiguration.getGlobalActionKeyTimeout());
|
mHomePressed = true;
|
||||||
|
} else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
|
||||||
|
if (!keyguardOn) {
|
||||||
|
handleLongPressOnHome();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mHomePressed = true;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (keyCode == KeyEvent.KEYCODE_MENU) {
|
} else if (keyCode == KeyEvent.KEYCODE_MENU) {
|
||||||
@@ -2518,7 +2507,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
|||||||
+ " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive);
|
+ " 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);
|
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user