Merge "Fix an event injection bug when the policy is bypassed." into gingerbread

This commit is contained in:
Jeff Brown
2010-10-11 16:27:36 -07:00
committed by Android (Google) Code Review
8 changed files with 150 additions and 202 deletions

View File

@@ -77,6 +77,7 @@ public interface WindowManagerPolicy {
public final static int FLAG_VIRTUAL = 0x00000100;
public final static int FLAG_INJECTED = 0x01000000;
public final static int FLAG_TRUSTED = 0x02000000;
public final static int FLAG_WOKE_HERE = 0x10000000;
public final static int FLAG_BRIGHT_HERE = 0x20000000;

View File

@@ -95,6 +95,10 @@ enum {
// Indicates that the input event was injected.
POLICY_FLAG_INJECTED = 0x01000000,
// Indicates that the input event is from a trusted source such as a directly attached
// input device or an application with system-wide event injection permission.
POLICY_FLAG_TRUSTED = 0x02000000,
/* These flags are set by the input reader policy as it intercepts each event. */
// Indicates that the screen was off when the event was received and the event

View File

@@ -913,7 +913,6 @@ private:
void drainInboundQueueLocked();
void releasePendingEventLocked();
void releaseInboundEventLocked(EventEntry* entry);
bool isEventFromTrustedSourceLocked(EventEntry* entry);
// Dispatch state.
bool mDispatchEnabled;
@@ -960,10 +959,10 @@ private:
nsecs_t currentTime, ConfigurationChangedEntry* entry);
bool dispatchKeyLocked(
nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
bool dropEvent, nsecs_t* nextWakeupTime);
DropReason* dropReason, nsecs_t* nextWakeupTime);
bool dispatchMotionLocked(
nsecs_t currentTime, MotionEntry* entry,
bool dropEvent, nsecs_t* nextWakeupTime);
DropReason* dropReason, nsecs_t* nextWakeupTime);
void dispatchEventToCurrentInputTargetsLocked(
nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);

View File

@@ -370,7 +370,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
}
}
done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
dropReason != DROP_REASON_NOT_DROPPED, nextWakeupTime);
&dropReason, nextWakeupTime);
break;
}
@@ -380,7 +380,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
dropReason = DROP_REASON_APP_SWITCH;
}
done = dispatchMotionLocked(currentTime, typedEntry,
dropReason != DROP_REASON_NOT_DROPPED, nextWakeupTime);
&dropReason, nextWakeupTime);
break;
}
@@ -431,6 +431,9 @@ void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropR
const char* reason;
switch (dropReason) {
case DROP_REASON_POLICY:
#if DEBUG_INBOUND_EVENT_DETAILS
LOGD("Dropped event because policy requested that it not be delivered to the application.");
#endif
reason = "inbound event was dropped because the policy requested that it not be "
"delivered to the application";
break;
@@ -473,7 +476,7 @@ bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
&& isAppSwitchKeyCode(keyEntry->keyCode)
&& isEventFromTrustedSourceLocked(keyEntry)
&& (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
&& (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
}
@@ -541,12 +544,6 @@ void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
mAllocator.releaseEventEntry(entry);
}
bool InputDispatcher::isEventFromTrustedSourceLocked(EventEntry* entry) {
InjectionState* injectionState = entry->injectionState;
return ! injectionState
|| hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid);
}
void InputDispatcher::resetKeyRepeatLocked() {
if (mKeyRepeatState.lastKeyEntry) {
mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
@@ -559,7 +556,8 @@ InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
// Reuse the repeated key entry if it is otherwise unreferenced.
uint32_t policyFlags = entry->policyFlags & (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER);
uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
| POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
if (entry->refCount == 1) {
mAllocator.recycleKeyEntry(entry);
entry->eventTime = currentTime;
@@ -608,19 +606,13 @@ bool InputDispatcher::dispatchConfigurationChangedLocked(
bool InputDispatcher::dispatchKeyLocked(
nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
bool dropEvent, nsecs_t* nextWakeupTime) {
DropReason* dropReason, nsecs_t* nextWakeupTime) {
// Give the policy a chance to intercept the key.
if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
bool trusted;
if (! dropEvent && mFocusedWindow) {
trusted = checkInjectionPermission(mFocusedWindow, entry->injectionState);
} else {
trusted = isEventFromTrustedSourceLocked(entry);
}
if (trusted) {
if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
CommandEntry* commandEntry = postCommandLocked(
& InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
if (! dropEvent && mFocusedWindow) {
if (mFocusedWindow) {
commandEntry->inputChannel = mFocusedWindow->inputChannel;
}
commandEntry->keyEntry = entry;
@@ -630,13 +622,16 @@ bool InputDispatcher::dispatchKeyLocked(
entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
}
} else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
if (*dropReason == DROP_REASON_NOT_DROPPED) {
*dropReason = DROP_REASON_POLICY;
}
resetTargetsLocked();
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
return true;
}
// Clean up if dropping the event.
if (dropEvent) {
if (*dropReason != DROP_REASON_NOT_DROPPED) {
resetTargetsLocked();
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
return true;
@@ -648,7 +643,8 @@ bool InputDispatcher::dispatchKeyLocked(
if (entry->repeatCount == 0
&& entry->action == AKEY_EVENT_ACTION_DOWN
&& ! entry->isInjected()) {
&& (entry->policyFlags & POLICY_FLAG_TRUSTED)
&& !entry->isInjected()) {
if (mKeyRepeatState.lastKeyEntry
&& mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
// We have seen two identical key downs in a row which indicates that the device
@@ -713,9 +709,9 @@ void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyE
}
bool InputDispatcher::dispatchMotionLocked(
nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
// Clean up if dropping the event.
if (dropEvent) {
if (*dropReason != DROP_REASON_NOT_DROPPED) {
resetTargetsLocked();
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
return true;
@@ -2085,6 +2081,7 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t sou
return;
}
policyFlags |= POLICY_FLAG_TRUSTED;
mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
keyCode, scanCode, /*byref*/ policyFlags);
@@ -2130,6 +2127,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t
return;
}
policyFlags |= POLICY_FLAG_TRUSTED;
mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
bool needWake;
@@ -2263,6 +2261,7 @@ void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t swi
switchCode, switchValue, policyFlags);
#endif
policyFlags |= POLICY_FLAG_TRUSTED;
mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
}
@@ -2275,7 +2274,11 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
#endif
nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
bool trusted = hasInjectionPermission(injectorPid, injectorUid);
uint32_t policyFlags = POLICY_FLAG_INJECTED;
if (hasInjectionPermission(injectorPid, injectorUid)) {
policyFlags |= POLICY_FLAG_TRUSTED;
}
EventEntry* injectedEntry;
switch (event->getType()) {
@@ -2291,11 +2294,8 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
int32_t flags = keyEvent->getFlags();
int32_t keyCode = keyEvent->getKeyCode();
int32_t scanCode = keyEvent->getScanCode();
uint32_t policyFlags = POLICY_FLAG_INJECTED;
if (trusted) {
mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
keyCode, scanCode, /*byref*/ policyFlags);
}
mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
keyCode, scanCode, /*byref*/ policyFlags);
mLock.lock();
injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
@@ -2314,10 +2314,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
}
nsecs_t eventTime = motionEvent->getEventTime();
uint32_t policyFlags = POLICY_FLAG_INJECTED;
if (trusted) {
mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
}
mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
mLock.lock();
const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();

View File

@@ -1057,6 +1057,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
int keyCode, int metaState, int repeatCount, int policyFlags) {
if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
return false;
}
final boolean keyguardOn = keyguardOn();
final boolean down = (action == KeyEvent.ACTION_DOWN);
final boolean canceled = ((flags & KeyEvent.FLAG_CANCELED) != 0);
@@ -1083,7 +1087,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (!down) {
mHomePressed = false;
if (! canceled) {
if (!canceled) {
// If an incoming call is ringing, HOME is totally disabled.
// (The user is already on the InCallScreen at this point,
// and his ONLY options are to answer or reject the call.)
@@ -1735,7 +1739,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
int policyFlags, boolean isScreenOn) {
int result = ACTION_PASS_TO_USER;
if ((policyFlags & WindowManagerPolicy.FLAG_TRUSTED) == 0) {
return result;
}
if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0) {
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
}
final boolean isWakeKey = (policyFlags
& (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;

View File

@@ -358,11 +358,6 @@ public class InputManager {
private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
private static final String CALIBRATION_DIR_PATH = "usr/idc/";
@SuppressWarnings("unused")
public void virtualKeyDownFeedback() {
mWindowManagerService.mInputMonitor.virtualKeyDownFeedback();
}
@SuppressWarnings("unused")
public void notifyConfigurationChanged(long whenNanos) {
mWindowManagerService.sendNewConfiguration();

View File

@@ -5243,13 +5243,6 @@ public class WindowManagerService extends IWindowManager.Stub
mTempInputWindows.clear();
}
/* Provides feedback for a virtual key down. */
public void virtualKeyDownFeedback() {
synchronized (mWindowMap) {
mPolicy.performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
}
}
/* Notifies that the lid switch changed state. */
public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
mPolicy.notifyLidSwitchChanged(whenNanos, lidOpen);

View File

@@ -50,7 +50,6 @@ static struct {
jmethodID notifyLidSwitchChanged;
jmethodID notifyInputChannelBroken;
jmethodID notifyANR;
jmethodID virtualKeyDownFeedback;
jmethodID interceptKeyBeforeQueueing;
jmethodID interceptKeyBeforeDispatching;
jmethodID checkInjectEventsPermission;
@@ -192,6 +191,8 @@ public:
/* --- InputDispatcherPolicyInterface implementation --- */
virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
uint32_t policyFlags);
virtual void notifyConfigurationChanged(nsecs_t when);
virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
const sp<InputChannel>& inputChannel);
@@ -205,8 +206,6 @@ public:
virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
const KeyEvent* keyEvent, uint32_t policyFlags);
virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
uint32_t policyFlags);
virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
virtual bool checkInjectEventsPermissionNonReentrant(
int32_t injectorPid, int32_t injectorUid);
@@ -255,7 +254,6 @@ private:
static bool populateWindow(JNIEnv* env, jobject windowObj, InputWindow& outWindow);
static bool isPolicyKey(int32_t keyCode, bool isScreenOn);
static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
static inline JNIEnv* jniEnv() {
@@ -291,37 +289,6 @@ void NativeInputManager::dump(String8& dump) {
dump.append("\n");
}
bool NativeInputManager::isPolicyKey(int32_t keyCode, bool isScreenOn) {
// Special keys that the WindowManagerPolicy might care about.
switch (keyCode) {
case AKEYCODE_VOLUME_UP:
case AKEYCODE_VOLUME_DOWN:
case AKEYCODE_ENDCALL:
case AKEYCODE_POWER:
case AKEYCODE_CALL:
case AKEYCODE_HOME:
case AKEYCODE_MENU:
case AKEYCODE_SEARCH:
// media keys
case AKEYCODE_HEADSETHOOK:
case AKEYCODE_MEDIA_PLAY_PAUSE:
case AKEYCODE_MEDIA_STOP:
case AKEYCODE_MEDIA_NEXT:
case AKEYCODE_MEDIA_PREVIOUS:
case AKEYCODE_MEDIA_REWIND:
case AKEYCODE_MEDIA_FAST_FORWARD:
// The policy always cares about these keys.
return true;
default:
// We need to pass all keys to the policy in the following cases:
// - screen is off
// - keyguard is visible
// - policy is performing key chording
//return ! isScreenOn || keyguardVisible || chording;
return true; // XXX stubbed out for now
}
}
bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
if (env->ExceptionCheck()) {
LOGE("An exception was thrown by callback '%s'.", methodName);
@@ -454,115 +421,6 @@ bool NativeInputManager::getDisplayInfo(int32_t displayId,
return result;
}
bool NativeInputManager::isScreenOn() {
return android_server_PowerManagerService_isScreenOn();
}
bool NativeInputManager::isScreenBright() {
return android_server_PowerManagerService_isScreenBright();
}
void NativeInputManager::interceptKeyBeforeQueueing(nsecs_t when,
int32_t deviceId, int32_t action, int32_t &flags,
int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("interceptKeyBeforeQueueing - when=%lld, deviceId=%d, action=%d, flags=%d, "
"keyCode=%d, scanCode=%d, policyFlags=0x%x",
when, deviceId, action, flags, keyCode, scanCode, policyFlags);
#endif
bool down = action == AKEY_EVENT_ACTION_DOWN;
if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
policyFlags |= POLICY_FLAG_VIRTUAL;
flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
if (down) {
JNIEnv* env = jniEnv();
env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback);
checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback");
}
}
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 isScreenBright = this->isScreenBright();
jint wmActions = 0;
if (isPolicyKey(keyCode, isScreenOn)) {
JNIEnv* env = jniEnv();
wmActions = env->CallIntMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeQueueing,
when, keyCode, down, policyFlags, isScreenOn);
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
wmActions = 0;
}
} else {
wmActions = WM_ACTION_PASS_TO_USER;
}
if (! isScreenOn) {
// Key presses and releases wake the device.
policyFlags |= POLICY_FLAG_WOKE_HERE;
flags |= AKEY_EVENT_FLAG_WOKE_HERE;
}
if (! isScreenBright) {
// Key presses and releases brighten the screen if dimmed.
policyFlags |= POLICY_FLAG_BRIGHT_HERE;
}
if (wmActions & WM_ACTION_GO_TO_SLEEP) {
android_server_PowerManagerService_goToSleep(when);
}
if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
}
if (wmActions & WM_ACTION_PASS_TO_USER) {
policyFlags |= POLICY_FLAG_PASS_TO_USER;
}
}
void NativeInputManager::interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("interceptGenericBeforeQueueing - when=%lld, policyFlags=0x%x", when, policyFlags);
#endif
if (isScreenOn()) {
// Only dispatch events when the device is awake.
// Do not wake the device.
policyFlags |= POLICY_FLAG_PASS_TO_USER;
if (! isScreenBright()) {
// Brighten the screen if dimmed.
policyFlags |= POLICY_FLAG_BRIGHT_HERE;
}
}
}
void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
int32_t switchValue, uint32_t policyFlags) {
#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
when, switchCode, switchValue, policyFlags);
#endif
JNIEnv* env = jniEnv();
switch (switchCode) {
case SW_LID:
env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
when, switchValue == 0);
checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
break;
}
}
bool NativeInputManager::filterTouchEvents() {
if (mFilterTouchEvents < 0) {
JNIEnv* env = jniEnv();
@@ -692,6 +550,24 @@ void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDevi
}
}
void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
int32_t switchValue, uint32_t policyFlags) {
#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
when, switchCode, switchValue, policyFlags);
#endif
JNIEnv* env = jniEnv();
switch (switchCode) {
case SW_LID:
env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
when, switchValue == 0);
checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
break;
}
}
void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("notifyConfigurationChanged - when=%lld", when);
@@ -944,13 +820,88 @@ void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
}
bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
const KeyEvent* keyEvent, uint32_t policyFlags) {
bool isScreenOn = this->isScreenOn();
if (! isPolicyKey(keyEvent->getKeyCode(), isScreenOn)) {
return false;
bool NativeInputManager::isScreenOn() {
return android_server_PowerManagerService_isScreenOn();
}
bool NativeInputManager::isScreenBright() {
return android_server_PowerManagerService_isScreenBright();
}
void NativeInputManager::interceptKeyBeforeQueueing(nsecs_t when,
int32_t deviceId, int32_t action, int32_t &flags,
int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("interceptKeyBeforeQueueing - when=%lld, deviceId=%d, action=%d, flags=%d, "
"keyCode=%d, scanCode=%d, policyFlags=0x%x",
when, deviceId, action, flags, keyCode, scanCode, policyFlags);
#endif
if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
policyFlags |= POLICY_FLAG_VIRTUAL;
flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
}
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 isScreenBright = this->isScreenBright();
JNIEnv* env = jniEnv();
jint wmActions = env->CallIntMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeQueueing,
when, keyCode, action == AKEY_EVENT_ACTION_DOWN, policyFlags, isScreenOn);
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
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) {
// Key presses and releases brighten the screen if dimmed.
policyFlags |= POLICY_FLAG_BRIGHT_HERE;
}
if (wmActions & WM_ACTION_GO_TO_SLEEP) {
android_server_PowerManagerService_goToSleep(when);
}
if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
}
}
if (wmActions & WM_ACTION_PASS_TO_USER) {
policyFlags |= POLICY_FLAG_PASS_TO_USER;
}
}
void NativeInputManager::interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
#if DEBUG_INPUT_DISPATCHER_POLICY
LOGD("interceptGenericBeforeQueueing - when=%lld, policyFlags=0x%x", when, policyFlags);
#endif
if (isScreenOn()) {
// Only dispatch events when the device is awake.
// Do not wake the device.
policyFlags |= POLICY_FLAG_PASS_TO_USER;
if ((policyFlags & POLICY_FLAG_TRUSTED) && !isScreenBright()) {
// Brighten the screen if dimmed.
policyFlags |= POLICY_FLAG_BRIGHT_HERE;
}
}
}
bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
const KeyEvent* keyEvent, uint32_t policyFlags) {
JNIEnv* env = jniEnv();
// Note: inputChannel may be null.
@@ -1365,9 +1316,6 @@ int register_android_server_InputManager(JNIEnv* env) {
GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
"notifyANR", "(Ljava/lang/Object;Landroid/view/InputChannel;)J");
GET_METHOD_ID(gCallbacksClassInfo.virtualKeyDownFeedback, gCallbacksClassInfo.clazz,
"virtualKeyDownFeedback", "()V");
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
"interceptKeyBeforeQueueing", "(JIZIZ)I");