summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/utils/Pool.h71
-rw-r--r--libs/utils/Android.mk1
-rw-r--r--libs/utils/Pool.cpp37
-rw-r--r--services/input/InputDispatcher.cpp385
-rw-r--r--services/input/InputDispatcher.h164
5 files changed, 239 insertions, 419 deletions
diff --git a/include/utils/Pool.h b/include/utils/Pool.h
deleted file mode 100644
index 2ee768e..0000000
--- a/include/utils/Pool.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef UTILS_POOL_H
-#define UTILS_POOL_H
-
-#include <utils/TypeHelpers.h>
-
-namespace android {
-
-class PoolImpl {
-public:
- PoolImpl(size_t objSize);
- ~PoolImpl();
-
- void* allocImpl();
- void freeImpl(void* obj);
-
-private:
- size_t mObjSize;
-};
-
-/*
- * A homogeneous typed memory pool for fixed size objects.
- * Not intended to be thread-safe.
- */
-template<typename T>
-class Pool : private PoolImpl {
-public:
- /* Creates an initially empty pool. */
- Pool() : PoolImpl(sizeof(T)) { }
-
- /* Destroys the pool.
- * Assumes that the pool is empty. */
- ~Pool() { }
-
- /* Allocates an object from the pool, growing the pool if needed. */
- inline T* alloc() {
- void* mem = allocImpl();
- if (! traits<T>::has_trivial_ctor) {
- return new (mem) T();
- } else {
- return static_cast<T*>(mem);
- }
- }
-
- /* Frees an object from the pool. */
- inline void free(T* obj) {
- if (! traits<T>::has_trivial_dtor) {
- obj->~T();
- }
- freeImpl(obj);
- }
-};
-
-} // namespace android
-
-#endif // UTILS_POOL_H
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index f633357..e4eadbd 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -29,7 +29,6 @@ commonSources:= \
Flattenable.cpp \
LinearTransform.cpp \
ObbFile.cpp \
- Pool.cpp \
PropertyMap.cpp \
RefBase.cpp \
ResourceTypes.cpp \
diff --git a/libs/utils/Pool.cpp b/libs/utils/Pool.cpp
deleted file mode 100644
index 8f18cb9..0000000
--- a/libs/utils/Pool.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// A simple memory pool.
-//
-#define LOG_TAG "Pool"
-
-//#define LOG_NDEBUG 0
-
-#include <cutils/log.h>
-#include <utils/Pool.h>
-
-#include <stdlib.h>
-
-namespace android {
-
-// TODO Provide a real implementation of a pool. This is just a stub for initial development.
-
-PoolImpl::PoolImpl(size_t objSize) :
- mObjSize(objSize) {
-}
-
-PoolImpl::~PoolImpl() {
-}
-
-void* PoolImpl::allocImpl() {
- void* ptr = malloc(mObjSize);
- LOG_ALWAYS_FATAL_IF(ptr == NULL, "Cannot allocate new pool object.");
- return ptr;
-}
-
-void PoolImpl::freeImpl(void* obj) {
- LOG_ALWAYS_FATAL_IF(obj == NULL, "Caller attempted to free NULL pool object.");
- return free(obj);
-}
-
-} // namespace android
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 1cac502..039b003 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -215,14 +215,6 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic
mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
mLooper = new Looper(false);
- mInboundQueue.headSentinel.refCount = -1;
- mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
- mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
-
- mInboundQueue.tailSentinel.refCount = -1;
- mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
- mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
-
mKeyRepeatState.lastKeyEntry = NULL;
policy->getDispatcherConfiguration(&mConfig);
@@ -319,7 +311,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
}
} else {
// Inbound queue has at least one entry.
- EventEntry* entry = mInboundQueue.headSentinel.next;
+ EventEntry* entry = mInboundQueue.head;
// Throttle the entry if it is a move event and there are no
// other events behind it in the queue. Due to movement batching, additional
@@ -335,7 +327,7 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
int32_t deviceId = motionEntry->deviceId;
uint32_t source = motionEntry->source;
if (! isAppSwitchDue
- && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
+ && !motionEntry->next // exactly one event, no successors
&& (motionEntry->action == AMOTION_EVENT_ACTION_MOVE
|| motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE)
&& deviceId == mThrottleState.lastDeviceId
@@ -641,13 +633,13 @@ bool InputDispatcher::runCommandsLockedInterruptible() {
(this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
commandEntry->connection.clear();
- mAllocator.releaseCommandEntry(commandEntry);
+ delete commandEntry;
} while (! mCommandQueue.isEmpty());
return true;
}
InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
- CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
+ CommandEntry* commandEntry = new CommandEntry(command);
mCommandQueue.enqueueAtTail(commandEntry);
return commandEntry;
}
@@ -674,12 +666,12 @@ void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
#endif
setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
}
- mAllocator.releaseEventEntry(entry);
+ entry->release();
}
void InputDispatcher::resetKeyRepeatLocked() {
if (mKeyRepeatState.lastKeyEntry) {
- mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
+ mKeyRepeatState.lastKeyEntry->release();
mKeyRepeatState.lastKeyEntry = NULL;
}
}
@@ -691,18 +683,18 @@ InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t cu
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->recycle();
entry->eventTime = currentTime;
entry->policyFlags = policyFlags;
entry->repeatCount += 1;
} else {
- KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
+ KeyEntry* newEntry = new KeyEntry(currentTime,
entry->deviceId, entry->source, policyFlags,
entry->action, entry->flags, entry->keyCode, entry->scanCode,
entry->metaState, entry->repeatCount + 1, entry->downTime);
mKeyRepeatState.lastKeyEntry = newEntry;
- mAllocator.releaseKeyEntry(entry);
+ entry->release();
entry = newEntry;
}
@@ -887,7 +879,7 @@ bool InputDispatcher::dispatchMotionLocked(
uint32_t originalSampleCount = entry->countSamples();
#endif
MotionSample* nextSample = splitBatchAfterSample->next;
- MotionEntry* nextEntry = mAllocator.obtainMotionEntry(nextSample->eventTime,
+ MotionEntry* nextEntry = new MotionEntry(nextSample->eventTime,
entry->deviceId, entry->source, entry->policyFlags,
entry->action, entry->flags,
entry->metaState, entry->buttonState, entry->edgeFlags,
@@ -897,7 +889,7 @@ bool InputDispatcher::dispatchMotionLocked(
nextEntry->firstSample.next = nextSample->next;
nextEntry->lastSample = entry->lastSample;
}
- mAllocator.freeMotionSample(nextSample);
+ delete nextSample;
entry->lastSample = const_cast<MotionSample*>(splitBatchAfterSample);
entry->lastSample->next = NULL;
@@ -1992,7 +1984,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(
// This is a new event.
// Enqueue a new dispatch entry onto the outbound queue for this connection.
- DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
+ DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
inputTarget->scaleFactor);
if (dispatchEntry->hasForegroundTarget()) {
@@ -2087,7 +2079,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
LOG_ASSERT(connection->status == Connection::STATUS_NORMAL);
LOG_ASSERT(! connection->outboundQueue.isEmpty());
- DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
+ DispatchEntry* dispatchEntry = connection->outboundQueue.head;
LOG_ASSERT(! dispatchEntry->inProgress);
// Mark the dispatch entry as in progress.
@@ -2276,7 +2268,7 @@ void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection) {
// Start the next dispatch cycle for this connection.
while (! connection->outboundQueue.isEmpty()) {
- DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
+ DispatchEntry* dispatchEntry = connection->outboundQueue.head;
if (dispatchEntry->inProgress) {
// Finish or resume current event in progress.
if (dispatchEntry->tailMotionSample) {
@@ -2293,7 +2285,7 @@ void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
if (dispatchEntry->hasForegroundTarget()) {
decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
}
- mAllocator.releaseDispatchEntry(dispatchEntry);
+ delete dispatchEntry;
} else {
// If the head is not in progress, then we must have already dequeued the in
// progress event, which means we actually aborted it.
@@ -2333,7 +2325,7 @@ void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
if (dispatchEntry->hasForegroundTarget()) {
decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
}
- mAllocator.releaseDispatchEntry(dispatchEntry);
+ delete dispatchEntry;
}
deactivateConnectionLocked(connection);
@@ -2407,7 +2399,7 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
nsecs_t currentTime = now();
mTempCancelationEvents.clear();
- connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
+ connection->inputState.synthesizeCancelationEvents(currentTime,
mTempCancelationEvents, options);
if (! mTempCancelationEvents.isEmpty()
@@ -2448,10 +2440,10 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
&target, false, InputTarget::FLAG_DISPATCH_AS_IS);
- mAllocator.releaseEventEntry(cancelationEventEntry);
+ cancelationEventEntry->release();
}
- if (!connection->outboundQueue.headSentinel.next->inProgress) {
+ if (!connection->outboundQueue.head->inProgress) {
startDispatchCycleLocked(currentTime, connection);
}
}
@@ -2523,7 +2515,7 @@ InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet
}
}
- MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
+ MotionEntry* splitMotionEntry = new MotionEntry(
originalMotionEntry->eventTime,
originalMotionEntry->deviceId,
originalMotionEntry->source,
@@ -2547,8 +2539,7 @@ InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet
originalMotionSample->pointerCoords[originalPointerIndex]);
}
- mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
- splitPointerCoords);
+ splitMotionEntry->appendSample(originalMotionSample->eventTime, splitPointerCoords);
}
if (originalMotionEntry->injectionState) {
@@ -2568,7 +2559,7 @@ void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
{ // acquire lock
AutoMutex _l(mLock);
- ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
+ ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(eventTime);
needWake = enqueueInboundEventLocked(newEntry);
} // release lock
@@ -2638,7 +2629,7 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t so
}
int32_t repeatCount = 0;
- KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
+ KeyEntry* newEntry = new KeyEntry(eventTime,
deviceId, source, policyFlags, action, flags, keyCode, scanCode,
metaState, repeatCount, downTime);
@@ -2718,8 +2709,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
// Try to append a move sample to the tail of the inbound queue for this device.
// Give up if we encounter a non-move motion event for this device since that
// means we cannot append any new samples until a new motion event has started.
- for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
- entry != & mInboundQueue.headSentinel; entry = entry->prev) {
+ for (EventEntry* entry = mInboundQueue.tail; entry; entry = entry->prev) {
if (entry->type != EventEntry::TYPE_MOTION) {
// Keep looking for motion events.
continue;
@@ -2798,7 +2788,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
continue;
}
- DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
+ DispatchEntry* dispatchEntry = connection->outboundQueue.head;
if (! dispatchEntry->inProgress
|| dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
|| dispatchEntry->isSplit()) {
@@ -2844,7 +2834,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
// Hurray! This foreground target is currently dispatching a move event
// that we can stream onto. Append the motion sample and resume dispatch.
- mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
+ motionEntry->appendSample(eventTime, pointerCoords);
#if DEBUG_BATCHING
LOGD("Appended motion sample onto batch for most recently dispatched "
"motion event for this device and source in the outbound queues. "
@@ -2864,7 +2854,7 @@ NoBatchingOrStreaming:;
}
// Just enqueue a new motion event.
- MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
+ MotionEntry* newEntry = new MotionEntry(eventTime,
deviceId, source, policyFlags, action, flags, metaState, buttonState, edgeFlags,
xPrecision, yPrecision, downTime,
pointerCount, pointerProperties, pointerCoords);
@@ -2901,7 +2891,7 @@ void InputDispatcher::batchMotionLocked(MotionEntry* entry, nsecs_t eventTime,
}
// Append the sample.
- mAllocator.appendMotionSample(entry, eventTime, pointerCoords);
+ entry->appendSample(eventTime, pointerCoords);
#if DEBUG_BATCHING
LOGD("Appended motion sample onto batch for %s, events were %0.3f ms apart",
eventDescription, interval * 0.000001f);
@@ -2958,7 +2948,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
}
mLock.lock();
- injectedEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
+ injectedEntry = new KeyEntry(keyEvent->getEventTime(),
keyEvent->getDeviceId(), keyEvent->getSource(),
policyFlags, action, flags,
keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
@@ -2983,7 +2973,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
mLock.lock();
const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
- MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
+ MotionEntry* motionEntry = new MotionEntry(*sampleEventTimes,
motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
action, motionEvent->getFlags(),
motionEvent->getMetaState(), motionEvent->getButtonState(),
@@ -2994,7 +2984,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
sampleEventTimes += 1;
samplePointerCoords += pointerCount;
- mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
+ motionEntry->appendSample(*sampleEventTimes, samplePointerCoords);
}
injectedEntry = motionEntry;
break;
@@ -3005,7 +2995,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
return INPUT_EVENT_INJECTION_FAILED;
}
- InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
+ InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
injectionState->injectionIsAsync = true;
}
@@ -3068,7 +3058,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
}
}
- mAllocator.releaseInjectionState(injectionState);
+ injectionState->release();
} // release lock
#if DEBUG_INJECTION
@@ -3704,7 +3694,7 @@ void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
entry->interceptKeyResult = consumed
? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
: KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
- mAllocator.releaseKeyEntry(entry);
+ entry->release();
}
void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
@@ -3714,7 +3704,7 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
bool skipNext = false;
if (!connection->outboundQueue.isEmpty()) {
- DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
+ DispatchEntry* dispatchEntry = connection->outboundQueue.head;
if (dispatchEntry->inProgress) {
if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
@@ -3796,7 +3786,7 @@ bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& con
return true; // skip next cycle
}
- LOG_ASSERT(connection->outboundQueue.headSentinel.next == dispatchEntry);
+ LOG_ASSERT(connection->outboundQueue.head == dispatchEntry);
// Latch the fallback keycode for this key on an initial down.
// The fallback keycode cannot change at any other point in the lifecycle.
@@ -3929,230 +3919,137 @@ void InputDispatcher::dump(String8& dump) {
template <typename T>
uint32_t InputDispatcher::Queue<T>::count() const {
uint32_t result = 0;
- for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
+ for (const T* entry = head; entry; entry = entry->next) {
result += 1;
}
return result;
}
-// --- InputDispatcher::Allocator ---
+// --- InputDispatcher::InjectionState ---
-InputDispatcher::Allocator::Allocator() {
+InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
+ refCount(1),
+ injectorPid(injectorPid), injectorUid(injectorUid),
+ injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
+ pendingForegroundDispatches(0) {
}
-InputDispatcher::InjectionState*
-InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
- InjectionState* injectionState = mInjectionStatePool.alloc();
- injectionState->refCount = 1;
- injectionState->injectorPid = injectorPid;
- injectionState->injectorUid = injectorUid;
- injectionState->injectionIsAsync = false;
- injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
- injectionState->pendingForegroundDispatches = 0;
- return injectionState;
+InputDispatcher::InjectionState::~InjectionState() {
}
-void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
- nsecs_t eventTime, uint32_t policyFlags) {
- entry->type = type;
- entry->refCount = 1;
- entry->dispatchInProgress = false;
- entry->eventTime = eventTime;
- entry->policyFlags = policyFlags;
- entry->injectionState = NULL;
-}
-
-void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
- if (entry->injectionState) {
- releaseInjectionState(entry->injectionState);
- entry->injectionState = NULL;
+void InputDispatcher::InjectionState::release() {
+ refCount -= 1;
+ if (refCount == 0) {
+ delete this;
+ } else {
+ LOG_ASSERT(refCount > 0);
}
}
-InputDispatcher::ConfigurationChangedEntry*
-InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
- ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
- initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
- return entry;
-}
-InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
- int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
- int32_t repeatCount, nsecs_t downTime) {
- KeyEntry* entry = mKeyEntryPool.alloc();
- initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime, policyFlags);
-
- entry->deviceId = deviceId;
- entry->source = source;
- entry->action = action;
- entry->flags = flags;
- entry->keyCode = keyCode;
- entry->scanCode = scanCode;
- entry->metaState = metaState;
- entry->repeatCount = repeatCount;
- entry->downTime = downTime;
- entry->syntheticRepeat = false;
- entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
- return entry;
-}
+// --- InputDispatcher::EventEntry ---
-InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState,
- int32_t edgeFlags, float xPrecision, float yPrecision,
- nsecs_t downTime, uint32_t pointerCount,
- const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) {
- MotionEntry* entry = mMotionEntryPool.alloc();
- initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime, policyFlags);
-
- entry->eventTime = eventTime;
- entry->deviceId = deviceId;
- entry->source = source;
- entry->action = action;
- entry->flags = flags;
- entry->metaState = metaState;
- entry->buttonState = buttonState;
- entry->edgeFlags = edgeFlags;
- entry->xPrecision = xPrecision;
- entry->yPrecision = yPrecision;
- entry->downTime = downTime;
- entry->pointerCount = pointerCount;
- entry->firstSample.eventTime = eventTime;
- entry->firstSample.eventTimeBeforeCoalescing = eventTime;
- entry->firstSample.next = NULL;
- entry->lastSample = & entry->firstSample;
- for (uint32_t i = 0; i < pointerCount; i++) {
- entry->pointerProperties[i].copyFrom(pointerProperties[i]);
- entry->firstSample.pointerCoords[i].copyFrom(pointerCoords[i]);
- }
- return entry;
+InputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) :
+ refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags),
+ injectionState(NULL), dispatchInProgress(false) {
}
-InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
- EventEntry* eventEntry,
- int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) {
- DispatchEntry* entry = mDispatchEntryPool.alloc();
- entry->eventEntry = eventEntry;
- eventEntry->refCount += 1;
- entry->targetFlags = targetFlags;
- entry->xOffset = xOffset;
- entry->yOffset = yOffset;
- entry->scaleFactor = scaleFactor;
- entry->inProgress = false;
- entry->headMotionSample = NULL;
- entry->tailMotionSample = NULL;
- return entry;
+InputDispatcher::EventEntry::~EventEntry() {
+ releaseInjectionState();
}
-InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
- CommandEntry* entry = mCommandEntryPool.alloc();
- entry->command = command;
- return entry;
-}
-
-void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
- injectionState->refCount -= 1;
- if (injectionState->refCount == 0) {
- mInjectionStatePool.free(injectionState);
+void InputDispatcher::EventEntry::release() {
+ refCount -= 1;
+ if (refCount == 0) {
+ delete this;
} else {
- LOG_ASSERT(injectionState->refCount > 0);
+ LOG_ASSERT(refCount > 0);
}
}
-void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
- switch (entry->type) {
- case EventEntry::TYPE_CONFIGURATION_CHANGED:
- releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
- break;
- case EventEntry::TYPE_KEY:
- releaseKeyEntry(static_cast<KeyEntry*>(entry));
- break;
- case EventEntry::TYPE_MOTION:
- releaseMotionEntry(static_cast<MotionEntry*>(entry));
- break;
- default:
- LOG_ASSERT(false);
- break;
+void InputDispatcher::EventEntry::releaseInjectionState() {
+ if (injectionState) {
+ injectionState->release();
+ injectionState = NULL;
}
}
-void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
- ConfigurationChangedEntry* entry) {
- entry->refCount -= 1;
- if (entry->refCount == 0) {
- releaseEventEntryInjectionState(entry);
- mConfigurationChangeEntryPool.free(entry);
- } else {
- LOG_ASSERT(entry->refCount > 0);
- }
-}
-void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
- entry->refCount -= 1;
- if (entry->refCount == 0) {
- releaseEventEntryInjectionState(entry);
- mKeyEntryPool.free(entry);
- } else {
- LOG_ASSERT(entry->refCount > 0);
- }
-}
+// --- InputDispatcher::ConfigurationChangedEntry ---
-void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
- entry->refCount -= 1;
- if (entry->refCount == 0) {
- releaseEventEntryInjectionState(entry);
- for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
- MotionSample* next = sample->next;
- mMotionSamplePool.free(sample);
- sample = next;
- }
- mMotionEntryPool.free(entry);
- } else {
- LOG_ASSERT(entry->refCount > 0);
- }
+InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) :
+ EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
}
-void InputDispatcher::Allocator::freeMotionSample(MotionSample* sample) {
- mMotionSamplePool.free(sample);
+InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
}
-void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
- releaseEventEntry(entry->eventEntry);
- mDispatchEntryPool.free(entry);
+
+// --- InputDispatcher::KeyEntry ---
+
+InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
+ int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
+ int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
+ int32_t repeatCount, nsecs_t downTime) :
+ EventEntry(TYPE_KEY, eventTime, policyFlags),
+ deviceId(deviceId), source(source), action(action), flags(flags),
+ keyCode(keyCode), scanCode(scanCode), metaState(metaState),
+ repeatCount(repeatCount), downTime(downTime),
+ syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
}
-void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
- mCommandEntryPool.free(entry);
+InputDispatcher::KeyEntry::~KeyEntry() {
}
-void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
- nsecs_t eventTime, const PointerCoords* pointerCoords) {
- MotionSample* sample = mMotionSamplePool.alloc();
- sample->eventTime = eventTime;
- sample->eventTimeBeforeCoalescing = eventTime;
- uint32_t pointerCount = motionEntry->pointerCount;
- for (uint32_t i = 0; i < pointerCount; i++) {
- sample->pointerCoords[i].copyFrom(pointerCoords[i]);
- }
+void InputDispatcher::KeyEntry::recycle() {
+ releaseInjectionState();
- sample->next = NULL;
- motionEntry->lastSample->next = sample;
- motionEntry->lastSample = sample;
+ dispatchInProgress = false;
+ syntheticRepeat = false;
+ interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
}
-void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
- releaseEventEntryInjectionState(keyEntry);
- keyEntry->dispatchInProgress = false;
- keyEntry->syntheticRepeat = false;
- keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
+// --- InputDispatcher::MotionSample ---
+
+InputDispatcher::MotionSample::MotionSample(nsecs_t eventTime,
+ const PointerCoords* pointerCoords, uint32_t pointerCount) :
+ next(NULL), eventTime(eventTime), eventTimeBeforeCoalescing(eventTime) {
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ this->pointerCoords[i].copyFrom(pointerCoords[i]);
+ }
}
// --- InputDispatcher::MotionEntry ---
+InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
+ int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
+ int32_t metaState, int32_t buttonState,
+ int32_t edgeFlags, float xPrecision, float yPrecision,
+ nsecs_t downTime, uint32_t pointerCount,
+ const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
+ EventEntry(TYPE_MOTION, eventTime, policyFlags),
+ deviceId(deviceId), source(source), action(action), flags(flags),
+ metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
+ xPrecision(xPrecision), yPrecision(yPrecision),
+ downTime(downTime), pointerCount(pointerCount),
+ firstSample(eventTime, pointerCoords, pointerCount),
+ lastSample(&firstSample) {
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ this->pointerProperties[i].copyFrom(pointerProperties[i]);
+ }
+}
+
+InputDispatcher::MotionEntry::~MotionEntry() {
+ for (MotionSample* sample = firstSample.next; sample != NULL; ) {
+ MotionSample* next = sample->next;
+ delete sample;
+ sample = next;
+ }
+}
+
uint32_t InputDispatcher::MotionEntry::countSamples() const {
uint32_t count = 1;
for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
@@ -4176,6 +4073,31 @@ bool InputDispatcher::MotionEntry::canAppendSamples(int32_t action, uint32_t poi
return true;
}
+void InputDispatcher::MotionEntry::appendSample(
+ nsecs_t eventTime, const PointerCoords* pointerCoords) {
+ MotionSample* sample = new MotionSample(eventTime, pointerCoords, pointerCount);
+
+ lastSample->next = sample;
+ lastSample = sample;
+}
+
+
+// --- InputDispatcher::DispatchEntry ---
+
+InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
+ int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) :
+ eventEntry(eventEntry), targetFlags(targetFlags),
+ xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
+ inProgress(false),
+ resolvedAction(0), resolvedFlags(0),
+ headMotionSample(NULL), tailMotionSample(NULL) {
+ eventEntry->refCount += 1;
+}
+
+InputDispatcher::DispatchEntry::~DispatchEntry() {
+ eventEntry->release();
+}
+
// --- InputDispatcher::InputState ---
@@ -4380,12 +4302,11 @@ void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry*
}
void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
- Allocator* allocator, Vector<EventEntry*>& outEvents,
- const CancelationOptions& options) {
+ Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
for (size_t i = 0; i < mKeyMementos.size(); i++) {
const KeyMemento& memento = mKeyMementos.itemAt(i);
if (shouldCancelKey(memento, options)) {
- outEvents.push(allocator->obtainKeyEntry(currentTime,
+ outEvents.push(new KeyEntry(currentTime,
memento.deviceId, memento.source, 0,
AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
@@ -4395,7 +4316,7 @@ void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTim
for (size_t i = 0; i < mMotionMementos.size(); i++) {
const MotionMemento& memento = mMotionMementos.itemAt(i);
if (shouldCancelMotion(memento, options)) {
- outEvents.push(allocator->obtainMotionEntry(currentTime,
+ outEvents.push(new MotionEntry(currentTime,
memento.deviceId, memento.source, 0,
memento.hovering
? AMOTION_EVENT_ACTION_HOVER_EXIT
@@ -4516,8 +4437,8 @@ const char* InputDispatcher::Connection::getStatusLabel() const {
InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
const EventEntry* eventEntry) const {
- for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
- dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
+ for (DispatchEntry* dispatchEntry = outboundQueue.tail; dispatchEntry;
+ dispatchEntry = dispatchEntry->prev) {
if (dispatchEntry->eventEntry == eventEntry) {
return dispatchEntry;
}
@@ -4528,8 +4449,8 @@ InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchE
// --- InputDispatcher::CommandEntry ---
-InputDispatcher::CommandEntry::CommandEntry() :
- keyEntry(NULL) {
+InputDispatcher::CommandEntry::CommandEntry(Command command) :
+ command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0), handled(false) {
}
InputDispatcher::CommandEntry::~CommandEntry() {
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 15fd274..1d39b2e 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -26,7 +26,6 @@
#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/Looper.h>
-#include <utils/Pool.h>
#include <utils/BitSet.h>
#include <stddef.h>
@@ -434,11 +433,16 @@ private:
int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
bool injectionIsAsync; // set to true if injection is not waiting for the result
int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress
+
+ InjectionState(int32_t injectorPid, int32_t injectorUid);
+ void release();
+
+ private:
+ ~InjectionState();
};
struct EventEntry : Link<EventEntry> {
enum {
- TYPE_SENTINEL,
TYPE_CONFIGURATION_CHANGED,
TYPE_KEY,
TYPE_MOTION
@@ -453,9 +457,20 @@ private:
bool dispatchInProgress; // initially false, set to true while dispatching
inline bool isInjected() const { return injectionState != NULL; }
+
+ void release();
+
+ protected:
+ EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags);
+ virtual ~EventEntry();
+ void releaseInjectionState();
};
struct ConfigurationChangedEntry : EventEntry {
+ ConfigurationChangedEntry(nsecs_t eventTime);
+
+ protected:
+ virtual ~ConfigurationChangedEntry();
};
struct KeyEntry : EventEntry {
@@ -477,6 +492,15 @@ private:
INTERCEPT_KEY_RESULT_CONTINUE,
};
InterceptKeyResult interceptKeyResult; // set based on the interception result
+
+ KeyEntry(nsecs_t eventTime,
+ int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
+ int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
+ int32_t repeatCount, nsecs_t downTime);
+ void recycle();
+
+ protected:
+ virtual ~KeyEntry();
};
struct MotionSample {
@@ -485,6 +509,9 @@ private:
nsecs_t eventTime; // may be updated during coalescing
nsecs_t eventTimeBeforeCoalescing; // not updated during coalescing
PointerCoords pointerCoords[MAX_POINTERS];
+
+ MotionSample(nsecs_t eventTime, const PointerCoords* pointerCoords,
+ uint32_t pointerCount);
};
struct MotionEntry : EventEntry {
@@ -505,11 +532,23 @@ private:
MotionSample firstSample;
MotionSample* lastSample;
+ MotionEntry(nsecs_t eventTime,
+ int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
+ int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
+ float xPrecision, float yPrecision,
+ nsecs_t downTime, uint32_t pointerCount,
+ const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
+
uint32_t countSamples() const;
// Checks whether we can append samples, assuming the device id and source are the same.
bool canAppendSamples(int32_t action, uint32_t pointerCount,
const PointerProperties* pointerProperties) const;
+
+ void appendSample(nsecs_t eventTime, const PointerCoords* pointerCoords);
+
+ protected:
+ virtual ~MotionEntry();
};
// Tracks the progress of dispatching a particular event to a particular connection.
@@ -540,6 +579,10 @@ private:
// will be set to NULL.
MotionSample* tailMotionSample;
+ DispatchEntry(EventEntry* eventEntry,
+ int32_t targetFlags, float xOffset, float yOffset, float scaleFactor);
+ ~DispatchEntry();
+
inline bool hasForegroundTarget() const {
return targetFlags & InputTarget::FLAG_FOREGROUND;
}
@@ -570,7 +613,7 @@ private:
class Connection;
struct CommandEntry : Link<CommandEntry> {
- CommandEntry();
+ CommandEntry(Command command);
~CommandEntry();
Command command;
@@ -588,99 +631,65 @@ private:
// Generic queue implementation.
template <typename T>
struct Queue {
- T headSentinel;
- T tailSentinel;
-
- inline Queue() {
- headSentinel.prev = NULL;
- headSentinel.next = & tailSentinel;
- tailSentinel.prev = & headSentinel;
- tailSentinel.next = NULL;
+ T* head;
+ T* tail;
+
+ inline Queue() : head(NULL), tail(NULL) {
}
inline bool isEmpty() const {
- return headSentinel.next == & tailSentinel;
+ return !head;
}
inline void enqueueAtTail(T* entry) {
- T* last = tailSentinel.prev;
- last->next = entry;
- entry->prev = last;
- entry->next = & tailSentinel;
- tailSentinel.prev = entry;
+ entry->prev = tail;
+ if (tail) {
+ tail->next = entry;
+ } else {
+ head = entry;
+ }
+ entry->next = NULL;
+ tail = entry;
}
inline void enqueueAtHead(T* entry) {
- T* first = headSentinel.next;
- headSentinel.next = entry;
- entry->prev = & headSentinel;
- entry->next = first;
- first->prev = entry;
+ entry->next = head;
+ if (head) {
+ head->prev = entry;
+ } else {
+ tail = entry;
+ }
+ entry->prev = NULL;
+ head = entry;
}
inline void dequeue(T* entry) {
- entry->prev->next = entry->next;
- entry->next->prev = entry->prev;
+ if (entry->prev) {
+ entry->prev->next = entry->next;
+ } else {
+ head = entry->next;
+ }
+ if (entry->next) {
+ entry->next->prev = entry->prev;
+ } else {
+ tail = entry->prev;
+ }
}
inline T* dequeueAtHead() {
- T* first = headSentinel.next;
- dequeue(first);
- return first;
+ T* entry = head;
+ head = entry->next;
+ if (head) {
+ head->prev = NULL;
+ } else {
+ tail = NULL;
+ }
+ return entry;
}
uint32_t count() const;
};
- /* Allocates queue entries and performs reference counting as needed. */
- class Allocator {
- public:
- Allocator();
-
- InjectionState* obtainInjectionState(int32_t injectorPid, int32_t injectorUid);
- ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime);
- KeyEntry* obtainKeyEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
- int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
- int32_t repeatCount, nsecs_t downTime);
- MotionEntry* obtainMotionEntry(nsecs_t eventTime,
- int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
- int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- float xPrecision, float yPrecision,
- nsecs_t downTime, uint32_t pointerCount,
- const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
- DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry,
- int32_t targetFlags, float xOffset, float yOffset, float scaleFactor);
- CommandEntry* obtainCommandEntry(Command command);
-
- void releaseInjectionState(InjectionState* injectionState);
- void releaseEventEntry(EventEntry* entry);
- void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
- void releaseKeyEntry(KeyEntry* entry);
- void releaseMotionEntry(MotionEntry* entry);
- void freeMotionSample(MotionSample* sample);
- void releaseDispatchEntry(DispatchEntry* entry);
- void releaseCommandEntry(CommandEntry* entry);
-
- void recycleKeyEntry(KeyEntry* entry);
-
- void appendMotionSample(MotionEntry* motionEntry,
- nsecs_t eventTime, const PointerCoords* pointerCoords);
-
- private:
- Pool<InjectionState> mInjectionStatePool;
- Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
- Pool<KeyEntry> mKeyEntryPool;
- Pool<MotionEntry> mMotionEntryPool;
- Pool<MotionSample> mMotionSamplePool;
- Pool<DispatchEntry> mDispatchEntryPool;
- Pool<CommandEntry> mCommandEntryPool;
-
- void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime,
- uint32_t policyFlags);
- void releaseEventEntryInjectionState(EventEntry* entry);
- };
-
/* Specifies which events are to be canceled and why. */
struct CancelationOptions {
enum Mode {
@@ -728,7 +737,7 @@ private:
bool trackMotion(const MotionEntry* entry, int32_t action, int32_t flags);
// Synthesizes cancelation events for the current state and resets the tracked state.
- void synthesizeCancelationEvents(nsecs_t currentTime, Allocator* allocator,
+ void synthesizeCancelationEvents(nsecs_t currentTime,
Vector<EventEntry*>& outEvents, const CancelationOptions& options);
// Clears the current state.
@@ -856,7 +865,6 @@ private:
Mutex mLock;
- Allocator mAllocator;
sp<Looper> mLooper;
EventEntry* mPendingEvent;