Skip to content

Commit a76a87a

Browse files
Winson ChungAndroid (Google) Code Review
authored andcommitted
Merge "DO NOT MERGE. Improve screenshot chord debouncing. Bug: 5011907" into ics-mr0
2 parents f838b7c + d5bb82d commit a76a87a

File tree

8 files changed

+241
-161
lines changed

8 files changed

+241
-161
lines changed

core/java/android/view/WindowManagerPolicy.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,23 +104,23 @@ public interface WindowManagerPolicy {
104104
*/
105105
public final static String EXTRA_HDMI_PLUGGED_STATE = "state";
106106

107-
// flags for interceptKeyTq
108107
/**
109-
* Pass this event to the user / app. To be returned from {@link #interceptKeyTq}.
108+
* Pass this event to the user / app. To be returned from
109+
* {@link #interceptKeyBeforeQueueing}.
110110
*/
111111
public final static int ACTION_PASS_TO_USER = 0x00000001;
112112

113113
/**
114114
* This key event should extend the user activity timeout and turn the lights on.
115-
* To be returned from {@link #interceptKeyTq}. Do not return this and
116-
* {@link #ACTION_GO_TO_SLEEP} or {@link #ACTION_PASS_TO_USER}.
115+
* To be returned from {@link #interceptKeyBeforeQueueing}.
116+
* Do not return this and {@link #ACTION_GO_TO_SLEEP} or {@link #ACTION_PASS_TO_USER}.
117117
*/
118118
public final static int ACTION_POKE_USER_ACTIVITY = 0x00000002;
119119

120120
/**
121121
* This key event should put the device to sleep (and engage keyguard if necessary)
122-
* To be returned from {@link #interceptKeyTq}. Do not return this and
123-
* {@link #ACTION_POKE_USER_ACTIVITY} or {@link #ACTION_PASS_TO_USER}.
122+
* To be returned from {@link #interceptKeyBeforeQueueing}.
123+
* Do not return this and {@link #ACTION_POKE_USER_ACTIVITY} or {@link #ACTION_PASS_TO_USER}.
124124
*/
125125
public final static int ACTION_GO_TO_SLEEP = 0x00000004;
126126

@@ -677,10 +677,12 @@ public int prepareAddWindowLw(WindowState win,
677677
* event will normally go.
678678
* @param event The key event.
679679
* @param policyFlags The policy flags associated with the key.
680-
* @return Returns true if the policy consumed the event and it should
681-
* not be further dispatched.
680+
* @return 0 if the key should be dispatched immediately, -1 if the key should
681+
* not be dispatched ever, or a positive value indicating the number of
682+
* milliseconds by which the key dispatch should be delayed before trying
683+
* again.
682684
*/
683-
public boolean interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags);
685+
public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags);
684686

685687
/**
686688
* Called from the input dispatcher thread when an application did not handle

policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

Lines changed: 180 additions & 130 deletions
Large diffs are not rendered by default.

services/input/InputDispatcher.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,18 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
804804
logOutboundKeyDetailsLocked("dispatchKey - ", entry);
805805
}
806806

807+
// Handle case where the policy asked us to try again later last time.
808+
if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
809+
if (currentTime < entry->interceptKeyWakeupTime) {
810+
if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
811+
*nextWakeupTime = entry->interceptKeyWakeupTime;
812+
}
813+
return false; // wait until next wakeup
814+
}
815+
entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
816+
entry->interceptKeyWakeupTime = 0;
817+
}
818+
807819
// Give the policy a chance to intercept the key.
808820
if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
809821
if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
@@ -3827,14 +3839,19 @@ void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
38273839

38283840
mLock.unlock();
38293841

3830-
bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
3842+
nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
38313843
&event, entry->policyFlags);
38323844

38333845
mLock.lock();
38343846

3835-
entry->interceptKeyResult = consumed
3836-
? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
3837-
: KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3847+
if (delay < 0) {
3848+
entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
3849+
} else if (!delay) {
3850+
entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3851+
} else {
3852+
entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
3853+
entry->interceptKeyWakeupTime = now() + delay;
3854+
}
38383855
entry->release();
38393856
}
38403857

@@ -4156,7 +4173,8 @@ InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
41564173
deviceId(deviceId), source(source), action(action), flags(flags),
41574174
keyCode(keyCode), scanCode(scanCode), metaState(metaState),
41584175
repeatCount(repeatCount), downTime(downTime),
4159-
syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
4176+
syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4177+
interceptKeyWakeupTime(0) {
41604178
}
41614179

41624180
InputDispatcher::KeyEntry::~KeyEntry() {
@@ -4168,6 +4186,7 @@ void InputDispatcher::KeyEntry::recycle() {
41684186
dispatchInProgress = false;
41694187
syntheticRepeat = false;
41704188
interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
4189+
interceptKeyWakeupTime = 0;
41714190
}
41724191

41734192

services/input/InputDispatcher.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ class InputDispatcherPolicyInterface : public virtual RefBase {
242242
virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
243243

244244
/* Allows the policy a chance to intercept a key before dispatching. */
245-
virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
245+
virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
246246
const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
247247

248248
/* Allows the policy a chance to perform default processing for an unhandled key.
@@ -481,8 +481,10 @@ class InputDispatcher : public InputDispatcherInterface {
481481
INTERCEPT_KEY_RESULT_UNKNOWN,
482482
INTERCEPT_KEY_RESULT_SKIP,
483483
INTERCEPT_KEY_RESULT_CONTINUE,
484+
INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER,
484485
};
485486
InterceptKeyResult interceptKeyResult; // set based on the interception result
487+
nsecs_t interceptKeyWakeupTime; // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
486488

487489
KeyEntry(nsecs_t eventTime,
488490
int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,

services/input/tests/InputDispatcher_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
7575
virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
7676
}
7777

78-
virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
78+
virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
7979
const KeyEvent* keyEvent, uint32_t policyFlags) {
80-
return false;
80+
return 0;
8181
}
8282

8383
virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,

services/java/com/android/server/wm/InputManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
575575
}
576576

577577
@SuppressWarnings("unused")
578-
public boolean interceptKeyBeforeDispatching(InputWindowHandle focus,
578+
public long interceptKeyBeforeDispatching(InputWindowHandle focus,
579579
KeyEvent event, int policyFlags) {
580580
return mWindowManagerService.mInputMonitor.interceptKeyBeforeDispatching(
581581
focus, event, policyFlags);

services/java/com/android/server/wm/InputMonitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ public int interceptMotionBeforeQueueingWhenScreenOff(int policyFlags) {
288288

289289
/* Provides an opportunity for the window manager policy to process a key before
290290
* ordinary dispatch. */
291-
public boolean interceptKeyBeforeDispatching(
291+
public long interceptKeyBeforeDispatching(
292292
InputWindowHandle focus, KeyEvent event, int policyFlags) {
293293
WindowState windowState = focus != null ? (WindowState) focus.windowState : null;
294294
return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags);

services/jni/com_android_server_InputManager.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t styl
149149
}
150150
}
151151

152+
enum {
153+
WM_ACTION_PASS_TO_USER = 1,
154+
WM_ACTION_POKE_USER_ACTIVITY = 2,
155+
WM_ACTION_GO_TO_SLEEP = 4,
156+
};
157+
152158

153159
// --- NativeInputManager ---
154160

@@ -199,7 +205,8 @@ class NativeInputManager : public virtual RefBase,
199205
virtual bool isKeyRepeatEnabled();
200206
virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
201207
virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
202-
virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
208+
virtual nsecs_t interceptKeyBeforeDispatching(
209+
const sp<InputWindowHandle>& inputWindowHandle,
203210
const KeyEvent* keyEvent, uint32_t policyFlags);
204211
virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
205212
const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
@@ -819,12 +826,6 @@ void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& p
819826

820827
void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
821828
uint32_t& policyFlags) {
822-
enum {
823-
WM_ACTION_PASS_TO_USER = 1,
824-
WM_ACTION_POKE_USER_ACTIVITY = 2,
825-
WM_ACTION_GO_TO_SLEEP = 4,
826-
};
827-
828829
if (wmActions & WM_ACTION_GO_TO_SLEEP) {
829830
#if DEBUG_INPUT_DISPATCHER_POLICY
830831
LOGD("handleInterceptActions: Going to sleep.");
@@ -848,28 +849,34 @@ void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
848849
}
849850
}
850851

851-
bool NativeInputManager::interceptKeyBeforeDispatching(
852+
nsecs_t NativeInputManager::interceptKeyBeforeDispatching(
852853
const sp<InputWindowHandle>& inputWindowHandle,
853854
const KeyEvent* keyEvent, uint32_t policyFlags) {
854855
// Policy:
855856
// - Ignore untrusted events and pass them along.
856857
// - Filter normal events and trusted injected events through the window manager policy to
857858
// handle the HOME key and the like.
858-
bool result = false;
859+
nsecs_t result = 0;
859860
if (policyFlags & POLICY_FLAG_TRUSTED) {
860861
JNIEnv* env = jniEnv();
861862

862863
// Note: inputWindowHandle may be null.
863864
jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
864865
jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
865866
if (keyEventObj) {
866-
jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
867+
jlong delayMillis = env->CallLongMethod(mCallbacksObj,
867868
gCallbacksClassInfo.interceptKeyBeforeDispatching,
868869
inputWindowHandleObj, keyEventObj, policyFlags);
869870
bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
870871
android_view_KeyEvent_recycle(env, keyEventObj);
871872
env->DeleteLocalRef(keyEventObj);
872-
result = consumed && !error;
873+
if (!error) {
874+
if (delayMillis < 0) {
875+
result = -1;
876+
} else if (delayMillis > 0) {
877+
result = milliseconds_to_nanoseconds(delayMillis);
878+
}
879+
}
873880
} else {
874881
LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
875882
}
@@ -1433,7 +1440,7 @@ int register_android_server_InputManager(JNIEnv* env) {
14331440

14341441
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
14351442
"interceptKeyBeforeDispatching",
1436-
"(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
1443+
"(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)J");
14371444

14381445
GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
14391446
"dispatchUnhandledKey",

0 commit comments

Comments
 (0)