Loading services/core/java/com/android/server/policy/KeyCombinationManager.java +31 −12 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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; }); Loading @@ -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); } } Loading @@ -181,32 +194,38 @@ public class KeyCombinationManager { * Return the interceptTimeout to tell InputDispatcher when is ready to deliver to window. */ long getKeyInterceptTimeout(int keyCode) { synchronized (mLock) { if (forAllActiveRules((rule) -> rule.shouldInterceptKey(keyCode))) { return mDownTimes.get(keyCode) + COMBINE_KEY_DELAY_MILLIS; } return 0; } } /** * True if the key event had been handled. */ boolean isKeyConsumed(KeyEvent event) { synchronized (mLock) { if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) != 0) { return false; } return mTriggeredRule != null && mTriggeredRule.shouldInterceptKey(event.getKeyCode()); } } /** * True if power key is the candidate. */ boolean isPowerKeyIntercepted() { 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; } } /** * Traverse each item of rules. Loading Loading
services/core/java/com/android/server/policy/KeyCombinationManager.java +31 −12 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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; }); Loading @@ -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); } } Loading @@ -181,32 +194,38 @@ public class KeyCombinationManager { * Return the interceptTimeout to tell InputDispatcher when is ready to deliver to window. */ long getKeyInterceptTimeout(int keyCode) { synchronized (mLock) { if (forAllActiveRules((rule) -> rule.shouldInterceptKey(keyCode))) { return mDownTimes.get(keyCode) + COMBINE_KEY_DELAY_MILLIS; } return 0; } } /** * True if the key event had been handled. */ boolean isKeyConsumed(KeyEvent event) { synchronized (mLock) { if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) != 0) { return false; } return mTriggeredRule != null && mTriggeredRule.shouldInterceptKey(event.getKeyCode()); } } /** * True if power key is the candidate. */ boolean isPowerKeyIntercepted() { 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; } } /** * Traverse each item of rules. Loading