am e9bb9be9: Simplify input target handling in the dispatcher.

* commit 'e9bb9be9e46523ed901e38cfa83f4630f6496418':
  Simplify input target handling in the dispatcher.
This commit is contained in:
Jeff Brown
2012-02-13 10:31:08 -08:00
committed by Android Git Automerger
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),
mNextUnblockedEvent(NULL),
mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
mCurrentInputTargetsValid(false),
mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
mLooper = new Looper(false);
@@ -269,22 +268,21 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
}
// Nothing to do if there is no pending event.
if (! mPendingEvent) {
if (mActiveConnections.isEmpty()) {
dispatchIdleLocked();
}
if (!mPendingEvent) {
return;
}
} else {
// Inbound queue has at least one entry.
EventEntry* entry = mInboundQueue.dequeueAtHead();
mPendingEvent = entry;
mPendingEvent = mInboundQueue.dequeueAtHead();
}
// Poke user activity for this event.
if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
pokeUserActivityLocked(mPendingEvent);
}
// Get ready to dispatch the event.
resetANRTimeoutsLocked();
}
// 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 needWake = mInboundQueue.isEmpty();
mInboundQueue.enqueueAtTail(entry);
@@ -582,6 +570,7 @@ void InputDispatcher::drainInboundQueueLocked() {
void InputDispatcher::releasePendingEventLocked() {
if (mPendingEvent) {
resetANRTimeoutsLocked();
releaseInboundEventLocked(mPendingEvent);
mPendingEvent = NULL;
}
@@ -704,7 +693,6 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
}
entry->dispatchInProgress = true;
resetTargetsLocked();
logOutboundKeyDetailsLocked("dispatchKey - ", entry);
}
@@ -743,31 +731,28 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
// Clean up if dropping the event.
if (*dropReason != DROP_REASON_NOT_DROPPED) {
resetTargetsLocked();
setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
return true;
}
// Identify targets.
if (! mCurrentInputTargetsValid) {
int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
entry, nextWakeupTime);
if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
return false;
}
setInjectionResultLocked(entry, injectionResult);
if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
return true;
}
addMonitoringTargetsLocked();
commitTargetsLocked();
Vector<InputTarget> inputTargets;
int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
entry, inputTargets, nextWakeupTime);
if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
return false;
}
setInjectionResultLocked(entry, injectionResult);
if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
return true;
}
addMonitoringTargetsLocked(inputTargets);
// Dispatch the key.
dispatchEventToCurrentInputTargetsLocked(currentTime, entry);
dispatchEventLocked(currentTime, entry, inputTargets);
return true;
}
@@ -788,14 +773,12 @@ bool InputDispatcher::dispatchMotionLocked(
// Preprocessing.
if (! entry->dispatchInProgress) {
entry->dispatchInProgress = true;
resetTargetsLocked();
logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
}
// Clean up if dropping the event.
if (*dropReason != DROP_REASON_NOT_DROPPED) {
resetTargetsLocked();
setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
return true;
@@ -804,30 +787,29 @@ bool InputDispatcher::dispatchMotionLocked(
bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
// Identify targets.
Vector<InputTarget> inputTargets;
bool conflictingPointerActions = false;
if (! mCurrentInputTargetsValid) {
int32_t injectionResult;
if (isPointerEvent) {
// Pointer event. (eg. touchscreen)
injectionResult = findTouchedWindowTargetsLocked(currentTime,
entry, nextWakeupTime, &conflictingPointerActions);
} else {
// Non touch event. (eg. trackball)
injectionResult = findFocusedWindowTargetsLocked(currentTime,
entry, nextWakeupTime);
}
if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
return false;
}
setInjectionResultLocked(entry, injectionResult);
if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
return true;
}
addMonitoringTargetsLocked();
commitTargetsLocked();
int32_t injectionResult;
if (isPointerEvent) {
// Pointer event. (eg. touchscreen)
injectionResult = findTouchedWindowTargetsLocked(currentTime,
entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
} else {
// Non touch event. (eg. trackball)
injectionResult = findFocusedWindowTargetsLocked(currentTime,
entry, inputTargets, nextWakeupTime);
}
if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
return false;
}
setInjectionResultLocked(entry, injectionResult);
if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
return true;
}
addMonitoringTargetsLocked(inputTargets);
// Dispatch the motion.
if (conflictingPointerActions) {
@@ -835,7 +817,7 @@ bool InputDispatcher::dispatchMotionLocked(
"conflicting pointer actions");
synthesizeCancelationEventsForAllConnectionsLocked(options);
}
dispatchEventToCurrentInputTargetsLocked(currentTime, entry);
dispatchEventLocked(currentTime, entry, inputTargets);
return true;
}
@@ -873,8 +855,8 @@ void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const M
#endif
}
void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
EventEntry* eventEntry) {
void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
#if DEBUG_DISPATCH_CYCLE
ALOGD("dispatchEventToCurrentInputTargets");
#endif
@@ -883,8 +865,8 @@ void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTi
pokeUserActivityLocked(eventEntry);
for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
for (size_t i = 0; i < inputTargets.size(); i++) {
const InputTarget& inputTarget = inputTargets.itemAt(i);
ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
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,
const EventEntry* entry,
const sp<InputApplicationHandle>& applicationHandle,
@@ -1024,9 +996,7 @@ void InputDispatcher::resetANRTimeoutsLocked() {
}
int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
const EventEntry* entry, nsecs_t* nextWakeupTime) {
mCurrentInputTargets.clear();
const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
int32_t injectionResult;
// 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.
injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
addWindowTargetLocked(mFocusedWindowHandle,
InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0));
InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
inputTargets);
// Done.
Failed:
@@ -1094,15 +1065,14 @@ Unresponsive:
}
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 {
INJECTION_PERMISSION_UNKNOWN,
INJECTION_PERMISSION_GRANTED,
INJECTION_PERMISSION_DENIED
};
mCurrentInputTargets.clear();
nsecs_t startTime = now();
// 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++) {
const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
touchedWindow.pointerIds);
touchedWindow.pointerIds, inputTargets);
}
// 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,
int32_t targetFlags, BitSet32 pointerIds) {
mCurrentInputTargets.push();
int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
inputTargets.push();
const InputWindowInfo* windowInfo = windowHandle->getInfo();
InputTarget& target = mCurrentInputTargets.editTop();
InputTarget& target = inputTargets.editTop();
target.inputChannel = windowInfo->inputChannel;
target.flags = targetFlags;
target.xOffset = - windowInfo->frameLeft;
@@ -1586,11 +1556,11 @@ void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowH
target.pointerIds = pointerIds;
}
void InputDispatcher::addMonitoringTargetsLocked() {
void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets) {
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.flags = InputTarget::FLAG_DISPATCH_AS_IS;
target.xOffset = 0;
@@ -2819,13 +2789,13 @@ void InputDispatcher::setFocusedApplication(
if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) {
if (mFocusedApplicationHandle != inputApplicationHandle) {
if (mFocusedApplicationHandle != NULL) {
resetTargetsLocked();
resetANRTimeoutsLocked();
mFocusedApplicationHandle->releaseInfo();
}
mFocusedApplicationHandle = inputApplicationHandle;
}
} else if (mFocusedApplicationHandle != NULL) {
resetTargetsLocked();
resetANRTimeoutsLocked();
mFocusedApplicationHandle->releaseInfo();
mFocusedApplicationHandle.clear();
}
@@ -2978,7 +2948,7 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
resetKeyRepeatLocked();
releasePendingEventLocked();
drainInboundQueueLocked();
resetTargetsLocked();
resetANRTimeoutsLocked();
mTouchState.reset();
mLastHoverWindowHandle.clear();

View File

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