diff options
| -rw-r--r-- | services/core/java/com/android/server/policy/KeyCombinationManager.java | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/services/core/java/com/android/server/policy/KeyCombinationManager.java b/services/core/java/com/android/server/policy/KeyCombinationManager.java index 268de3e2182b..68e078c519ba 100644 --- a/services/core/java/com/android/server/policy/KeyCombinationManager.java +++ b/services/core/java/com/android/server/policy/KeyCombinationManager.java @@ -17,11 +17,13 @@ package com.android.server.policy; import static android.view.KeyEvent.KEYCODE_POWER; +import android.os.Handler; import android.os.SystemClock; import android.util.Log; import android.util.SparseLongArray; import android.view.KeyEvent; +import com.android.internal.annotations.GuardedBy; import com.android.internal.util.ToBooleanFunction; import java.io.PrintWriter; @@ -35,13 +37,18 @@ public class KeyCombinationManager { private static final String TAG = "KeyCombinationManager"; // Store the received down time of keycode. + @GuardedBy("mLock") private final SparseLongArray mDownTimes = new SparseLongArray(2); private final ArrayList<TwoKeysCombinationRule> mRules = new ArrayList(); // Selected rules according to current key down. + private final Object mLock = new Object(); + @GuardedBy("mLock") private final ArrayList<TwoKeysCombinationRule> mActiveRules = new ArrayList(); // The rule has been triggered by current keys. + @GuardedBy("mLock") private TwoKeysCombinationRule mTriggeredRule; + private final Handler mHandler = new Handler(); // Keys in a key combination must be pressed within this interval of each other. 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. */ 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 int keyCode = event.getKeyCode(); final int count = mActiveRules.size(); @@ -154,7 +167,7 @@ public class KeyCombinationManager { return false; } Log.v(TAG, "Performing combination rule : " + rule); - rule.execute(); + mHandler.post(rule::execute); mTriggeredRule = rule; return true; }); @@ -169,7 +182,7 @@ public class KeyCombinationManager { for (int index = count - 1; index >= 0; index--) { final TwoKeysCombinationRule rule = mActiveRules.get(index); if (rule.shouldInterceptKey(keyCode)) { - rule.cancel(); + mHandler.post(rule::cancel); mActiveRules.remove(index); } } @@ -181,31 +194,37 @@ public class KeyCombinationManager { * Return the interceptTimeout to tell InputDispatcher when is ready to deliver to window. */ long getKeyInterceptTimeout(int keyCode) { - if (forAllActiveRules((rule) -> rule.shouldInterceptKey(keyCode))) { - return mDownTimes.get(keyCode) + COMBINE_KEY_DELAY_MILLIS; + synchronized (mLock) { + 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. */ boolean isKeyConsumed(KeyEvent event) { - if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) != 0) { - return false; + synchronized (mLock) { + 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. */ boolean isPowerKeyIntercepted() { - if (forAllActiveRules((rule) -> rule.shouldInterceptKey(KEYCODE_POWER))) { - // return false if only if power key pressed. - return mDownTimes.size() > 1 || mDownTimes.get(KEYCODE_POWER) == 0; + synchronized (mLock) { + if (forAllActiveRules((rule) -> rule.shouldInterceptKey(KEYCODE_POWER))) { + // return false if only if power key pressed. + return mDownTimes.size() > 1 || mDownTimes.get(KEYCODE_POWER) == 0; + } + return false; } - return false; } /** |