Merge "Fix potential exception while pressing volume up and volume down"
This commit is contained in:
@@ -17,11 +17,13 @@ package com.android.server.policy;
|
|||||||
|
|
||||||
import static android.view.KeyEvent.KEYCODE_POWER;
|
import static android.view.KeyEvent.KEYCODE_POWER;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseLongArray;
|
import android.util.SparseLongArray;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.GuardedBy;
|
||||||
import com.android.internal.util.ToBooleanFunction;
|
import com.android.internal.util.ToBooleanFunction;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -35,13 +37,18 @@ public class KeyCombinationManager {
|
|||||||
private static final String TAG = "KeyCombinationManager";
|
private static final String TAG = "KeyCombinationManager";
|
||||||
|
|
||||||
// Store the received down time of keycode.
|
// Store the received down time of keycode.
|
||||||
|
@GuardedBy("mLock")
|
||||||
private final SparseLongArray mDownTimes = new SparseLongArray(2);
|
private final SparseLongArray mDownTimes = new SparseLongArray(2);
|
||||||
private final ArrayList<TwoKeysCombinationRule> mRules = new ArrayList();
|
private final ArrayList<TwoKeysCombinationRule> mRules = new ArrayList();
|
||||||
|
|
||||||
// Selected rules according to current key down.
|
// Selected rules according to current key down.
|
||||||
|
private final Object mLock = new Object();
|
||||||
|
@GuardedBy("mLock")
|
||||||
private final ArrayList<TwoKeysCombinationRule> mActiveRules = new ArrayList();
|
private final ArrayList<TwoKeysCombinationRule> mActiveRules = new ArrayList();
|
||||||
// The rule has been triggered by current keys.
|
// The rule has been triggered by current keys.
|
||||||
|
@GuardedBy("mLock")
|
||||||
private TwoKeysCombinationRule mTriggeredRule;
|
private TwoKeysCombinationRule mTriggeredRule;
|
||||||
|
private final Handler mHandler = new Handler();
|
||||||
|
|
||||||
// Keys in a key combination must be pressed within this interval of each other.
|
// Keys in a key combination must be pressed within this interval of each other.
|
||||||
private static final long COMBINE_KEY_DELAY_MILLIS = 150;
|
private static final long COMBINE_KEY_DELAY_MILLIS = 150;
|
||||||
@@ -109,6 +116,12 @@ public class KeyCombinationManager {
|
|||||||
* Return true if any active rule could be triggered by the key event, otherwise false.
|
* Return true if any active rule could be triggered by the key event, otherwise false.
|
||||||
*/
|
*/
|
||||||
boolean interceptKey(KeyEvent event, boolean interactive) {
|
boolean interceptKey(KeyEvent event, boolean interactive) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
return interceptKeyLocked(event, interactive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean interceptKeyLocked(KeyEvent event, boolean interactive) {
|
||||||
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
|
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
|
||||||
final int keyCode = event.getKeyCode();
|
final int keyCode = event.getKeyCode();
|
||||||
final int count = mActiveRules.size();
|
final int count = mActiveRules.size();
|
||||||
@@ -154,7 +167,7 @@ public class KeyCombinationManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Log.v(TAG, "Performing combination rule : " + rule);
|
Log.v(TAG, "Performing combination rule : " + rule);
|
||||||
rule.execute();
|
mHandler.post(rule::execute);
|
||||||
mTriggeredRule = rule;
|
mTriggeredRule = rule;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@@ -169,7 +182,7 @@ public class KeyCombinationManager {
|
|||||||
for (int index = count - 1; index >= 0; index--) {
|
for (int index = count - 1; index >= 0; index--) {
|
||||||
final TwoKeysCombinationRule rule = mActiveRules.get(index);
|
final TwoKeysCombinationRule rule = mActiveRules.get(index);
|
||||||
if (rule.shouldInterceptKey(keyCode)) {
|
if (rule.shouldInterceptKey(keyCode)) {
|
||||||
rule.cancel();
|
mHandler.post(rule::cancel);
|
||||||
mActiveRules.remove(index);
|
mActiveRules.remove(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,31 +194,37 @@ public class KeyCombinationManager {
|
|||||||
* Return the interceptTimeout to tell InputDispatcher when is ready to deliver to window.
|
* Return the interceptTimeout to tell InputDispatcher when is ready to deliver to window.
|
||||||
*/
|
*/
|
||||||
long getKeyInterceptTimeout(int keyCode) {
|
long getKeyInterceptTimeout(int keyCode) {
|
||||||
if (forAllActiveRules((rule) -> rule.shouldInterceptKey(keyCode))) {
|
synchronized (mLock) {
|
||||||
return mDownTimes.get(keyCode) + COMBINE_KEY_DELAY_MILLIS;
|
if (forAllActiveRules((rule) -> rule.shouldInterceptKey(keyCode))) {
|
||||||
|
return mDownTimes.get(keyCode) + COMBINE_KEY_DELAY_MILLIS;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the key event had been handled.
|
* True if the key event had been handled.
|
||||||
*/
|
*/
|
||||||
boolean isKeyConsumed(KeyEvent event) {
|
boolean isKeyConsumed(KeyEvent event) {
|
||||||
if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) != 0) {
|
synchronized (mLock) {
|
||||||
return false;
|
if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return mTriggeredRule != null && mTriggeredRule.shouldInterceptKey(event.getKeyCode());
|
||||||
}
|
}
|
||||||
return mTriggeredRule != null && mTriggeredRule.shouldInterceptKey(event.getKeyCode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if power key is the candidate.
|
* True if power key is the candidate.
|
||||||
*/
|
*/
|
||||||
boolean isPowerKeyIntercepted() {
|
boolean isPowerKeyIntercepted() {
|
||||||
if (forAllActiveRules((rule) -> rule.shouldInterceptKey(KEYCODE_POWER))) {
|
synchronized (mLock) {
|
||||||
// return false if only if power key pressed.
|
if (forAllActiveRules((rule) -> rule.shouldInterceptKey(KEYCODE_POWER))) {
|
||||||
return mDownTimes.size() > 1 || mDownTimes.get(KEYCODE_POWER) == 0;
|
// return false if only if power key pressed.
|
||||||
|
return mDownTimes.size() > 1 || mDownTimes.get(KEYCODE_POWER) == 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user