Simplify input target handling in the dispatcher.

Since we no longer stream events to the application, we don't need to
keep the current list of input targets around longer than it takes
to begin the dispatch cycle.

This is part of a series of changes to improve input system pipelining.

Bug: 5963420

Change-Id: I5824b04e564c8a4dec991598292441e46c331905
This commit is contained in:
Jeff Brown
2012-02-06 15:47:55 -08:00
parent cbee6d6ede
commit e9bb9be9e4
2 changed files with 69 additions and 102 deletions

View File

@@ -178,7 +178,6 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic
mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX), mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
mNextUnblockedEvent(NULL), mNextUnblockedEvent(NULL),
mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false), mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
mCurrentInputTargetsValid(false),
mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) { mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
mLooper = new Looper(false); mLooper = new Looper(false);
@@ -269,22 +268,21 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
} }
// Nothing to do if there is no pending event. // Nothing to do if there is no pending event.
if (! mPendingEvent) { if (!mPendingEvent) {
if (mActiveConnections.isEmpty()) {
dispatchIdleLocked();
}
return; return;
} }
} else { } else {
// Inbound queue has at least one entry. // Inbound queue has at least one entry.
EventEntry* entry = mInboundQueue.dequeueAtHead(); mPendingEvent = mInboundQueue.dequeueAtHead();
mPendingEvent = entry;
} }
// Poke user activity for this event. // Poke user activity for this event.
if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) { if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
pokeUserActivityLocked(mPendingEvent); pokeUserActivityLocked(mPendingEvent);
} }
// Get ready to dispatch the event.
resetANRTimeoutsLocked();
} }
// Now we have an event to dispatch. // Now we have an event to dispatch.
@@ -372,16 +370,6 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
} }
} }
void InputDispatcher::dispatchIdleLocked() {
#if DEBUG_FOCUS
ALOGD("Dispatcher idle. There are no pending events or active connections.");
#endif
// Reset targets when idle, to release input channels and other resources
// they are holding onto.
resetTargetsLocked();
}
bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) { bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
bool needWake = mInboundQueue.isEmpty(); bool needWake = mInboundQueue.isEmpty();
mInboundQueue.enqueueAtTail(entry); mInboundQueue.enqueueAtTail(entry);
@@ -582,6 +570,7 @@ void InputDispatcher::drainInboundQueueLocked() {
void InputDispatcher::releasePendingEventLocked() { void InputDispatcher::releasePendingEventLocked() {
if (mPendingEvent) { if (mPendingEvent) {
resetANRTimeoutsLocked();
releaseInboundEventLocked(mPendingEvent); releaseInboundEventLocked(mPendingEvent);
mPendingEvent = NULL; mPendingEvent = NULL;
} }
@@ -704,7 +693,6 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
} }
entry->dispatchInProgress = true; entry->dispatchInProgress = true;
resetTargetsLocked();
logOutboundKeyDetailsLocked("dispatchKey - ", entry); logOutboundKeyDetailsLocked("dispatchKey - ", entry);
} }
@@ -743,31 +731,28 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
// 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();
setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED); ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
return true; return true;
} }
// Identify targets. // Identify targets.
if (! mCurrentInputTargetsValid) { Vector<InputTarget> inputTargets;
int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime, int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
entry, nextWakeupTime); entry, inputTargets, nextWakeupTime);
if (injectionResult == INPUT_EVENT_INJECTION_PENDING) { if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
return false; return false;
}
setInjectionResultLocked(entry, injectionResult);
if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
return true;
}
addMonitoringTargetsLocked();
commitTargetsLocked();
} }
setInjectionResultLocked(entry, injectionResult);
if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
return true;
}
addMonitoringTargetsLocked(inputTargets);
// Dispatch the key. // Dispatch the key.
dispatchEventToCurrentInputTargetsLocked(currentTime, entry); dispatchEventLocked(currentTime, entry, inputTargets);
return true; return true;
} }
@@ -788,14 +773,12 @@ bool InputDispatcher::dispatchMotionLocked(
// Preprocessing. // Preprocessing.
if (! entry->dispatchInProgress) { if (! entry->dispatchInProgress) {
entry->dispatchInProgress = true; entry->dispatchInProgress = true;
resetTargetsLocked();
logOutboundMotionDetailsLocked("dispatchMotion - ", entry); logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
} }
// 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();
setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED); ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
return true; return true;
@@ -804,30 +787,29 @@ bool InputDispatcher::dispatchMotionLocked(
bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER; bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
// Identify targets. // Identify targets.
Vector<InputTarget> inputTargets;
bool conflictingPointerActions = false; bool conflictingPointerActions = false;
if (! mCurrentInputTargetsValid) { int32_t injectionResult;
int32_t injectionResult; if (isPointerEvent) {
if (isPointerEvent) { // Pointer event. (eg. touchscreen)
// Pointer event. (eg. touchscreen) injectionResult = findTouchedWindowTargetsLocked(currentTime,
injectionResult = findTouchedWindowTargetsLocked(currentTime, entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
entry, nextWakeupTime, &conflictingPointerActions); } else {
} else { // Non touch event. (eg. trackball)
// Non touch event. (eg. trackball) injectionResult = findFocusedWindowTargetsLocked(currentTime,
injectionResult = findFocusedWindowTargetsLocked(currentTime, entry, inputTargets, nextWakeupTime);
entry, nextWakeupTime);
}
if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
return false;
}
setInjectionResultLocked(entry, injectionResult);
if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
return true;
}
addMonitoringTargetsLocked();
commitTargetsLocked();
} }
if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
return false;
}
setInjectionResultLocked(entry, injectionResult);
if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
return true;
}
addMonitoringTargetsLocked(inputTargets);
// Dispatch the motion. // Dispatch the motion.
if (conflictingPointerActions) { if (conflictingPointerActions) {
@@ -835,7 +817,7 @@ bool InputDispatcher::dispatchMotionLocked(
"conflicting pointer actions"); "conflicting pointer actions");
synthesizeCancelationEventsForAllConnectionsLocked(options); synthesizeCancelationEventsForAllConnectionsLocked(options);
} }
dispatchEventToCurrentInputTargetsLocked(currentTime, entry); dispatchEventLocked(currentTime, entry, inputTargets);
return true; return true;
} }
@@ -873,8 +855,8 @@ void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const M
#endif #endif
} }
void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime, void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
EventEntry* eventEntry) { EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
#if DEBUG_DISPATCH_CYCLE #if DEBUG_DISPATCH_CYCLE
ALOGD("dispatchEventToCurrentInputTargets"); ALOGD("dispatchEventToCurrentInputTargets");
#endif #endif
@@ -883,8 +865,8 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi
pokeUserActivityLocked(eventEntry); pokeUserActivityLocked(eventEntry);
for (size_t i = 0; i < mCurrentInputTargets.size(); i++) { for (size_t i = 0; i < inputTargets.size(); i++) {
const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i); const InputTarget& inputTarget = inputTargets.itemAt(i);
ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel); ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
if (connectionIndex >= 0) { if (connectionIndex >= 0) {
@@ -900,16 +882,6 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi
} }
} }
void InputDispatcher::resetTargetsLocked() {
mCurrentInputTargetsValid = false;
mCurrentInputTargets.clear();
resetANRTimeoutsLocked();
}
void InputDispatcher::commitTargetsLocked() {
mCurrentInputTargetsValid = true;
}
int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime, int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
const EventEntry* entry, const EventEntry* entry,
const sp<InputApplicationHandle>& applicationHandle, const sp<InputApplicationHandle>& applicationHandle,
@@ -1024,9 +996,7 @@ void InputDispatcher::resetANRTimeoutsLocked() {
} }
int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime, int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
const EventEntry* entry, nsecs_t* nextWakeupTime) { const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
mCurrentInputTargets.clear();
int32_t injectionResult; int32_t injectionResult;
// If there is no currently focused window and no focused application // If there is no currently focused window and no focused application
@@ -1077,7 +1047,8 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
// Success! Output targets. // Success! Output targets.
injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED; injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
addWindowTargetLocked(mFocusedWindowHandle, addWindowTargetLocked(mFocusedWindowHandle,
InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0)); InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
inputTargets);
// Done. // Done.
Failed: Failed:
@@ -1094,15 +1065,14 @@ Unresponsive:
} }
int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
const MotionEntry* entry, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) { const MotionEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
bool* outConflictingPointerActions) {
enum InjectionPermission { enum InjectionPermission {
INJECTION_PERMISSION_UNKNOWN, INJECTION_PERMISSION_UNKNOWN,
INJECTION_PERMISSION_GRANTED, INJECTION_PERMISSION_GRANTED,
INJECTION_PERMISSION_DENIED INJECTION_PERMISSION_DENIED
}; };
mCurrentInputTargets.clear();
nsecs_t startTime = now(); nsecs_t startTime = now();
// For security reasons, we defer updating the touch state until we are sure that // For security reasons, we defer updating the touch state until we are sure that
@@ -1468,7 +1438,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
for (size_t i = 0; i < mTempTouchState.windows.size(); i++) { for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i); const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags, addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
touchedWindow.pointerIds); touchedWindow.pointerIds, inputTargets);
} }
// Drop the outside or hover touch windows since we will not care about them // Drop the outside or hover touch windows since we will not care about them
@@ -1573,11 +1543,11 @@ Unresponsive:
} }
void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle, void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
int32_t targetFlags, BitSet32 pointerIds) { int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
mCurrentInputTargets.push(); inputTargets.push();
const InputWindowInfo* windowInfo = windowHandle->getInfo(); const InputWindowInfo* windowInfo = windowHandle->getInfo();
InputTarget& target = mCurrentInputTargets.editTop(); InputTarget& target = inputTargets.editTop();
target.inputChannel = windowInfo->inputChannel; target.inputChannel = windowInfo->inputChannel;
target.flags = targetFlags; target.flags = targetFlags;
target.xOffset = - windowInfo->frameLeft; target.xOffset = - windowInfo->frameLeft;
@@ -1586,11 +1556,11 @@ void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowH
target.pointerIds = pointerIds; target.pointerIds = pointerIds;
} }
void InputDispatcher::addMonitoringTargetsLocked() { void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets) {
for (size_t i = 0; i < mMonitoringChannels.size(); i++) { for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
mCurrentInputTargets.push(); inputTargets.push();
InputTarget& target = mCurrentInputTargets.editTop(); InputTarget& target = inputTargets.editTop();
target.inputChannel = mMonitoringChannels[i]; target.inputChannel = mMonitoringChannels[i];
target.flags = InputTarget::FLAG_DISPATCH_AS_IS; target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
target.xOffset = 0; target.xOffset = 0;
@@ -2819,13 +2789,13 @@ void InputDispatcher::setFocusedApplication(
if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) { if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) {
if (mFocusedApplicationHandle != inputApplicationHandle) { if (mFocusedApplicationHandle != inputApplicationHandle) {
if (mFocusedApplicationHandle != NULL) { if (mFocusedApplicationHandle != NULL) {
resetTargetsLocked(); resetANRTimeoutsLocked();
mFocusedApplicationHandle->releaseInfo(); mFocusedApplicationHandle->releaseInfo();
} }
mFocusedApplicationHandle = inputApplicationHandle; mFocusedApplicationHandle = inputApplicationHandle;
} }
} else if (mFocusedApplicationHandle != NULL) { } else if (mFocusedApplicationHandle != NULL) {
resetTargetsLocked(); resetANRTimeoutsLocked();
mFocusedApplicationHandle->releaseInfo(); mFocusedApplicationHandle->releaseInfo();
mFocusedApplicationHandle.clear(); mFocusedApplicationHandle.clear();
} }
@@ -2978,7 +2948,7 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
resetKeyRepeatLocked(); resetKeyRepeatLocked();
releasePendingEventLocked(); releasePendingEventLocked();
drainInboundQueueLocked(); drainInboundQueueLocked();
resetTargetsLocked(); resetANRTimeoutsLocked();
mTouchState.reset(); mTouchState.reset();
mLastHoverWindowHandle.clear(); mLastHoverWindowHandle.clear();

View File

@@ -834,7 +834,6 @@ private:
Vector<EventEntry*> mTempCancelationEvents; Vector<EventEntry*> mTempCancelationEvents;
void dispatchOnceInnerLocked(nsecs_t* nextWakeupTime); void dispatchOnceInnerLocked(nsecs_t* nextWakeupTime);
void dispatchIdleLocked();
// Enqueues an inbound event. Returns true if mLooper->wake() should be called. // Enqueues an inbound event. Returns true if mLooper->wake() should be called.
bool enqueueInboundEventLocked(EventEntry* entry); bool enqueueInboundEventLocked(EventEntry* entry);
@@ -955,15 +954,13 @@ private:
bool dispatchMotionLocked( bool dispatchMotionLocked(
nsecs_t currentTime, MotionEntry* entry, nsecs_t currentTime, MotionEntry* entry,
DropReason* dropReason, nsecs_t* nextWakeupTime); DropReason* dropReason, nsecs_t* nextWakeupTime);
void dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime, EventEntry* entry); void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry,
const Vector<InputTarget>& inputTargets);
void logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry); void logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry);
void logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry); void logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry);
// The input targets that were most recently identified for dispatch. // Keeping track of ANR timeouts.
bool mCurrentInputTargetsValid; // false while targets are being recomputed
Vector<InputTarget> mCurrentInputTargets;
enum InputTargetWaitCause { enum InputTargetWaitCause {
INPUT_TARGET_WAIT_CAUSE_NONE, INPUT_TARGET_WAIT_CAUSE_NONE,
INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY, INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY,
@@ -980,8 +977,6 @@ private:
sp<InputWindowHandle> mLastHoverWindowHandle; sp<InputWindowHandle> mLastHoverWindowHandle;
// Finding targets for input events. // Finding targets for input events.
void resetTargetsLocked();
void commitTargetsLocked();
int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry, int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
const sp<InputApplicationHandle>& applicationHandle, const sp<InputApplicationHandle>& applicationHandle,
const sp<InputWindowHandle>& windowHandle, const sp<InputWindowHandle>& windowHandle,
@@ -992,13 +987,15 @@ private:
void resetANRTimeoutsLocked(); void resetANRTimeoutsLocked();
int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry, int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry,
nsecs_t* nextWakeupTime); Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime);
int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry, int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
nsecs_t* nextWakeupTime, bool* outConflictingPointerActions); Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
bool* outConflictingPointerActions);
void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle, void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
int32_t targetFlags, BitSet32 pointerIds); int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets);
void addMonitoringTargetsLocked(); void addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets);
void pokeUserActivityLocked(const EventEntry* eventEntry); void pokeUserActivityLocked(const EventEntry* eventEntry);
bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle, bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
const InjectionState* injectionState); const InjectionState* injectionState);