am 03aa28fb: Merge "Improve the input policy handling a bit." into gingerbread

Merge commit '03aa28fb36589a3d601be08e75c08a24c4344d6f' into gingerbread-plus-aosp

* commit '03aa28fb36589a3d601be08e75c08a24c4344d6f':
  Improve the input policy handling a bit.
This commit is contained in:
Jeff Brown
2010-10-12 01:04:16 -07:00
committed by Android Git Automerger
3 changed files with 84 additions and 64 deletions

View File

@ -432,10 +432,9 @@ void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropR
switch (dropReason) { switch (dropReason) {
case DROP_REASON_POLICY: case DROP_REASON_POLICY:
#if DEBUG_INBOUND_EVENT_DETAILS #if DEBUG_INBOUND_EVENT_DETAILS
LOGD("Dropped event because policy requested that it not be delivered to the application."); LOGD("Dropped event because policy consumed it.");
#endif #endif
reason = "inbound event was dropped because the policy requested that it not be " reason = "inbound event was dropped because the policy consumed it";
"delivered to the application";
break; break;
case DROP_REASON_DISABLED: case DROP_REASON_DISABLED:
LOGI("Dropped event because input dispatch is disabled."); LOGI("Dropped event because input dispatch is disabled.");
@ -625,15 +624,13 @@ bool InputDispatcher::dispatchKeyLocked(
if (*dropReason == DROP_REASON_NOT_DROPPED) { if (*dropReason == DROP_REASON_NOT_DROPPED) {
*dropReason = DROP_REASON_POLICY; *dropReason = DROP_REASON_POLICY;
} }
resetTargetsLocked();
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
return true;
} }
// Clean up if dropping the event. // Clean up if dropping the event.
if (*dropReason != DROP_REASON_NOT_DROPPED) { if (*dropReason != DROP_REASON_NOT_DROPPED) {
resetTargetsLocked(); resetTargetsLocked();
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED); setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
return true; return true;
} }
@ -713,7 +710,8 @@ bool InputDispatcher::dispatchMotionLocked(
// Clean up if dropping the event. // Clean up if dropping the event.
if (*dropReason != DROP_REASON_NOT_DROPPED) { if (*dropReason != DROP_REASON_NOT_DROPPED) {
resetTargetsLocked(); resetTargetsLocked();
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED); setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
return true; return true;
} }

View File

@ -1057,10 +1057,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override @Override
public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags, public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
int keyCode, int metaState, int repeatCount, int policyFlags) { int keyCode, int metaState, int repeatCount, int policyFlags) {
if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
return false;
}
final boolean keyguardOn = keyguardOn(); final boolean keyguardOn = keyguardOn();
final boolean down = (action == KeyEvent.ACTION_DOWN); final boolean down = (action == KeyEvent.ACTION_DOWN);
final boolean canceled = ((flags & KeyEvent.FLAG_CANCELED) != 0); final boolean canceled = ((flags & KeyEvent.FLAG_CANCELED) != 0);
@ -1739,9 +1735,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down, public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
int policyFlags, boolean isScreenOn) { int policyFlags, boolean isScreenOn) {
int result = ACTION_PASS_TO_USER; int result = ACTION_PASS_TO_USER;
if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
return result;
}
if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0) { if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0) {
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false); performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
@ -1750,6 +1743,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final boolean isWakeKey = (policyFlags final boolean isWakeKey = (policyFlags
& (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0; & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
// If the key is injected, pretend that the screen is on and don't let the
// device go to sleep. This feature is mainly used for testing purposes.
final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
if (isInjected) {
isScreenOn = true;
}
// If screen is off then we treat the case where the keyguard is open but hidden // If screen is off then we treat the case where the keyguard is open but hidden
// the same as if it were open and in front. // the same as if it were open and in front.
// This will prevent any keys other than the power button from waking the screen // This will prevent any keys other than the power button from waking the screen
@ -1848,7 +1848,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|| (handled && hungUp && keyCode == KeyEvent.KEYCODE_POWER)) { || (handled && hungUp && keyCode == KeyEvent.KEYCODE_POWER)) {
mShouldTurnOffOnKeyUp = false; mShouldTurnOffOnKeyUp = false;
} else { } else {
// only try to turn off the screen if we didn't already hang up // Only try to turn off the screen if we didn't already hang up.
mShouldTurnOffOnKeyUp = true; mShouldTurnOffOnKeyUp = true;
mHandler.postDelayed(mPowerLongPress, mHandler.postDelayed(mPowerLongPress,
ViewConfiguration.getGlobalActionKeyTimeout()); ViewConfiguration.getGlobalActionKeyTimeout());
@ -1871,12 +1871,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (keyguardActive if (keyguardActive
|| (sleeps && !gohome) || (sleeps && !gohome)
|| (gohome && !goHome() && sleeps)) { || (gohome && !goHome() && sleeps)) {
// they must already be on the keyguad or home screen, // They must already be on the keyguard or home screen,
// go to sleep instead // go to sleep instead unless the event was injected.
Log.d(TAG, "I'm tired mEndcallBehavior=0x" if (!isInjected) {
+ Integer.toHexString(mEndcallBehavior)); Log.d(TAG, "I'm tired mEndcallBehavior=0x"
result &= ~ACTION_POKE_USER_ACTIVITY; + Integer.toHexString(mEndcallBehavior));
result |= ACTION_GO_TO_SLEEP; result &= ~ACTION_POKE_USER_ACTIVITY;
result |= ACTION_GO_TO_SLEEP;
}
} }
result &= ~ACTION_PASS_TO_USER; result &= ~ACTION_PASS_TO_USER;
} }

View File

@ -842,31 +842,35 @@ void NativeInputManager::interceptKeyBeforeQueueing(nsecs_t when,
flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
} }
const int32_t WM_ACTION_PASS_TO_USER = 1; // Policy:
const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2; // - Ignore untrusted events and pass them along.
const int32_t WM_ACTION_GO_TO_SLEEP = 4; // - Ask the window manager what to do with normal events and trusted injected events.
// - For normal events wake and brighten the screen if currently off or dim.
if ((policyFlags & POLICY_FLAG_TRUSTED)) {
const int32_t WM_ACTION_PASS_TO_USER = 1;
const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
const int32_t WM_ACTION_GO_TO_SLEEP = 4;
bool isScreenOn = this->isScreenOn(); bool isScreenOn = this->isScreenOn();
bool isScreenBright = this->isScreenBright(); bool isScreenBright = this->isScreenBright();
JNIEnv* env = jniEnv(); JNIEnv* env = jniEnv();
jint wmActions = env->CallIntMethod(mCallbacksObj, jint wmActions = env->CallIntMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.interceptKeyBeforeQueueing,
when, keyCode, action == AKEY_EVENT_ACTION_DOWN, policyFlags, isScreenOn); when, keyCode, action == AKEY_EVENT_ACTION_DOWN, policyFlags, isScreenOn);
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) { if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
wmActions = 0; wmActions = 0;
}
if (policyFlags & POLICY_FLAG_TRUSTED) {
if (! isScreenOn) {
// Key presses and releases wake the device.
policyFlags |= POLICY_FLAG_WOKE_HERE;
flags |= AKEY_EVENT_FLAG_WOKE_HERE;
} }
if (! isScreenBright) { if (!(flags & POLICY_FLAG_INJECTED)) {
// Key presses and releases brighten the screen if dimmed. if (!isScreenOn) {
policyFlags |= POLICY_FLAG_BRIGHT_HERE; policyFlags |= POLICY_FLAG_WOKE_HERE;
flags |= AKEY_EVENT_FLAG_WOKE_HERE;
}
if (!isScreenBright) {
policyFlags |= POLICY_FLAG_BRIGHT_HERE;
}
} }
if (wmActions & WM_ACTION_GO_TO_SLEEP) { if (wmActions & WM_ACTION_GO_TO_SLEEP) {
@ -876,9 +880,11 @@ void NativeInputManager::interceptKeyBeforeQueueing(nsecs_t when,
if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) { if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT); android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
} }
}
if (wmActions & WM_ACTION_PASS_TO_USER) { if (wmActions & WM_ACTION_PASS_TO_USER) {
policyFlags |= POLICY_FLAG_PASS_TO_USER;
}
} else {
policyFlags |= POLICY_FLAG_PASS_TO_USER; policyFlags |= POLICY_FLAG_PASS_TO_USER;
} }
} }
@ -888,33 +894,47 @@ void NativeInputManager::interceptGenericBeforeQueueing(nsecs_t when, uint32_t&
LOGD("interceptGenericBeforeQueueing - when=%lld, policyFlags=0x%x", when, policyFlags); LOGD("interceptGenericBeforeQueueing - when=%lld, policyFlags=0x%x", when, policyFlags);
#endif #endif
if (isScreenOn()) { // Policy:
// Only dispatch events when the device is awake. // - Ignore untrusted events and pass them along.
// Do not wake the device. // - No special filtering for injected events required at this time.
policyFlags |= POLICY_FLAG_PASS_TO_USER; // - Filter normal events based on screen state.
// - For normal events brighten (but do not wake) the screen if currently dim.
if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
if (isScreenOn()) {
policyFlags |= POLICY_FLAG_PASS_TO_USER;
if ((policyFlags & POLICY_FLAG_TRUSTED) && !isScreenBright()) { if (!isScreenBright()) {
// Brighten the screen if dimmed. policyFlags |= POLICY_FLAG_BRIGHT_HERE;
policyFlags |= POLICY_FLAG_BRIGHT_HERE; }
} }
} else {
policyFlags |= POLICY_FLAG_PASS_TO_USER;
} }
} }
bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel, bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
const KeyEvent* keyEvent, uint32_t policyFlags) { const KeyEvent* keyEvent, uint32_t policyFlags) {
JNIEnv* env = jniEnv(); // Policy:
// - Ignore untrusted events and pass them along.
// - Filter normal events and trusted injected events through the window manager policy to
// handle the HOME key and the like.
if (policyFlags & POLICY_FLAG_TRUSTED) {
JNIEnv* env = jniEnv();
// Note: inputChannel may be null. // Note: inputChannel may be null.
jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel); jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
jboolean consumed = env->CallBooleanMethod(mCallbacksObj, jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.interceptKeyBeforeDispatching,
inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(), inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
keyEvent->getKeyCode(), keyEvent->getMetaState(), keyEvent->getKeyCode(), keyEvent->getMetaState(),
keyEvent->getRepeatCount(), policyFlags); keyEvent->getRepeatCount(), policyFlags);
bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching"); bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
env->DeleteLocalRef(inputChannelObj); env->DeleteLocalRef(inputChannelObj);
return consumed && ! error; return consumed && ! error;
} else {
return false;
}
} }
void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) { void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {