blob: a55864be1c5ebd6fea13b5f036dd22dcb687b95d [file] [log] [blame]
Jeff Browne839a582010-04-22 18:58:52 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4// The input dispatcher.
5//
6#define LOG_TAG "InputDispatcher"
7
8//#define LOG_NDEBUG 0
9
10// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070011#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070012
13// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown50de30a2010-06-22 01:27:15 -070014#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Browne839a582010-04-22 18:58:52 -070015
16// Log debug messages about batching.
Jeff Brown50de30a2010-06-22 01:27:15 -070017#define DEBUG_BATCHING 0
Jeff Browne839a582010-04-22 18:58:52 -070018
19// Log debug messages about the dispatch cycle.
Jeff Brown50de30a2010-06-22 01:27:15 -070020#define DEBUG_DISPATCH_CYCLE 0
Jeff Browne839a582010-04-22 18:58:52 -070021
Jeff Brown54bc2812010-06-15 01:31:58 -070022// Log debug messages about registrations.
Jeff Brown50de30a2010-06-22 01:27:15 -070023#define DEBUG_REGISTRATION 0
Jeff Brown54bc2812010-06-15 01:31:58 -070024
Jeff Browne839a582010-04-22 18:58:52 -070025// Log debug messages about performance statistics.
Jeff Brown50de30a2010-06-22 01:27:15 -070026#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Browne839a582010-04-22 18:58:52 -070027
Jeff Brown51d45a72010-06-17 20:52:56 -070028// Log debug messages about input event injection.
Jeff Brown50de30a2010-06-22 01:27:15 -070029#define DEBUG_INJECTION 0
Jeff Brown51d45a72010-06-17 20:52:56 -070030
Jeff Browne839a582010-04-22 18:58:52 -070031#include <cutils/log.h>
32#include <ui/InputDispatcher.h>
33
34#include <stddef.h>
35#include <unistd.h>
Jeff Browne839a582010-04-22 18:58:52 -070036#include <errno.h>
37#include <limits.h>
Jeff Browne839a582010-04-22 18:58:52 -070038
39namespace android {
40
41// TODO, this needs to be somewhere else, perhaps in the policy
42static inline bool isMovementKey(int32_t keyCode) {
Jeff Brown8575a872010-06-30 16:10:35 -070043 return keyCode == AKEYCODE_DPAD_UP
44 || keyCode == AKEYCODE_DPAD_DOWN
45 || keyCode == AKEYCODE_DPAD_LEFT
46 || keyCode == AKEYCODE_DPAD_RIGHT;
Jeff Browne839a582010-04-22 18:58:52 -070047}
48
Jeff Brown51d45a72010-06-17 20:52:56 -070049static inline nsecs_t now() {
50 return systemTime(SYSTEM_TIME_MONOTONIC);
51}
52
Jeff Browne839a582010-04-22 18:58:52 -070053// --- InputDispatcher ---
54
Jeff Brown54bc2812010-06-15 01:31:58 -070055InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Browne839a582010-04-22 18:58:52 -070056 mPolicy(policy) {
Dianne Hackborn3c5d1252010-07-07 14:27:31 -070057 mPollLoop = new PollLoop(false);
Jeff Browne839a582010-04-22 18:58:52 -070058
59 mInboundQueue.head.refCount = -1;
60 mInboundQueue.head.type = EventEntry::TYPE_SENTINEL;
61 mInboundQueue.head.eventTime = LONG_LONG_MIN;
62
63 mInboundQueue.tail.refCount = -1;
64 mInboundQueue.tail.type = EventEntry::TYPE_SENTINEL;
65 mInboundQueue.tail.eventTime = LONG_LONG_MAX;
66
67 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -070068
69 mCurrentInputTargetsValid = false;
Jeff Browne839a582010-04-22 18:58:52 -070070}
71
72InputDispatcher::~InputDispatcher() {
73 resetKeyRepeatLocked();
74
75 while (mConnectionsByReceiveFd.size() != 0) {
76 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
77 }
78
79 for (EventEntry* entry = mInboundQueue.head.next; entry != & mInboundQueue.tail; ) {
80 EventEntry* next = entry->next;
81 mAllocator.releaseEventEntry(next);
82 entry = next;
83 }
84}
85
86void InputDispatcher::dispatchOnce() {
Jeff Brown54bc2812010-06-15 01:31:58 -070087 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Browne839a582010-04-22 18:58:52 -070088
Jeff Brown54bc2812010-06-15 01:31:58 -070089 bool skipPoll = false;
Jeff Browne839a582010-04-22 18:58:52 -070090 nsecs_t currentTime;
91 nsecs_t nextWakeupTime = LONG_LONG_MAX;
92 { // acquire lock
93 AutoMutex _l(mLock);
Jeff Brown51d45a72010-06-17 20:52:56 -070094 currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -070095
96 // Reset the key repeat timer whenever we disallow key events, even if the next event
97 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
98 // out of sleep.
99 // XXX we should handle resetting input state coming out of sleep more generally elsewhere
Jeff Brown54bc2812010-06-15 01:31:58 -0700100 if (keyRepeatTimeout < 0) {
Jeff Browne839a582010-04-22 18:58:52 -0700101 resetKeyRepeatLocked();
102 }
103
Jeff Brown51d45a72010-06-17 20:52:56 -0700104 // Detect and process timeouts for all connections and determine if there are any
105 // synchronous event dispatches pending. This step is entirely non-interruptible.
Jeff Browne839a582010-04-22 18:58:52 -0700106 bool hasPendingSyncTarget = false;
Jeff Brown51d45a72010-06-17 20:52:56 -0700107 size_t activeConnectionCount = mActiveConnections.size();
108 for (size_t i = 0; i < activeConnectionCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -0700109 Connection* connection = mActiveConnections.itemAt(i);
110
Jeff Browne839a582010-04-22 18:58:52 -0700111 if (connection->hasPendingSyncTarget()) {
112 hasPendingSyncTarget = true;
113 }
114
Jeff Brown51d45a72010-06-17 20:52:56 -0700115 nsecs_t connectionTimeoutTime = connection->nextTimeoutTime;
116 if (connectionTimeoutTime <= currentTime) {
117 mTimedOutConnections.add(connection);
118 } else if (connectionTimeoutTime < nextWakeupTime) {
119 nextWakeupTime = connectionTimeoutTime;
120 }
Jeff Browne839a582010-04-22 18:58:52 -0700121 }
122
Jeff Brown51d45a72010-06-17 20:52:56 -0700123 size_t timedOutConnectionCount = mTimedOutConnections.size();
124 for (size_t i = 0; i < timedOutConnectionCount; i++) {
125 Connection* connection = mTimedOutConnections.itemAt(i);
126 timeoutDispatchCycleLocked(currentTime, connection);
127 skipPoll = true;
128 }
129 mTimedOutConnections.clear();
130
Jeff Browne839a582010-04-22 18:58:52 -0700131 // If we don't have a pending sync target, then we can begin delivering a new event.
132 // (Otherwise we wait for dispatch to complete for that target.)
133 if (! hasPendingSyncTarget) {
134 if (mInboundQueue.isEmpty()) {
135 if (mKeyRepeatState.lastKeyEntry) {
136 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
Jeff Brown54bc2812010-06-15 01:31:58 -0700137 processKeyRepeatLockedInterruptible(currentTime, keyRepeatTimeout);
138 skipPoll = true;
Jeff Browne839a582010-04-22 18:58:52 -0700139 } else {
140 if (mKeyRepeatState.nextRepeatTime < nextWakeupTime) {
141 nextWakeupTime = mKeyRepeatState.nextRepeatTime;
142 }
143 }
144 }
145 } else {
Jeff Brown54bc2812010-06-15 01:31:58 -0700146 // Inbound queue has at least one entry.
147 // Start processing it but leave it on the queue until later so that the
148 // input reader can keep appending samples onto a motion event between the
149 // time we started processing it and the time we finally enqueue dispatch
150 // entries for it.
151 EventEntry* entry = mInboundQueue.head.next;
Jeff Browne839a582010-04-22 18:58:52 -0700152
153 switch (entry->type) {
154 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
155 ConfigurationChangedEntry* typedEntry =
156 static_cast<ConfigurationChangedEntry*>(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700157 processConfigurationChangedLockedInterruptible(currentTime, typedEntry);
Jeff Browne839a582010-04-22 18:58:52 -0700158 break;
159 }
160
161 case EventEntry::TYPE_KEY: {
162 KeyEntry* typedEntry = static_cast<KeyEntry*>(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700163 processKeyLockedInterruptible(currentTime, typedEntry, keyRepeatTimeout);
Jeff Browne839a582010-04-22 18:58:52 -0700164 break;
165 }
166
167 case EventEntry::TYPE_MOTION: {
168 MotionEntry* typedEntry = static_cast<MotionEntry*>(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700169 processMotionLockedInterruptible(currentTime, typedEntry);
Jeff Browne839a582010-04-22 18:58:52 -0700170 break;
171 }
172
173 default:
174 assert(false);
175 break;
176 }
Jeff Brown54bc2812010-06-15 01:31:58 -0700177
178 // Dequeue and release the event entry that we just processed.
179 mInboundQueue.dequeue(entry);
180 mAllocator.releaseEventEntry(entry);
181 skipPoll = true;
Jeff Browne839a582010-04-22 18:58:52 -0700182 }
183 }
Jeff Brown54bc2812010-06-15 01:31:58 -0700184
185 // Run any deferred commands.
186 skipPoll |= runCommandsLockedInterruptible();
Jeff Brown51d45a72010-06-17 20:52:56 -0700187
188 // Wake up synchronization waiters, if needed.
189 if (isFullySynchronizedLocked()) {
190 mFullySynchronizedCondition.broadcast();
191 }
Jeff Browne839a582010-04-22 18:58:52 -0700192 } // release lock
193
Jeff Brown54bc2812010-06-15 01:31:58 -0700194 // If we dispatched anything, don't poll just now. Wait for the next iteration.
195 // Contents may have shifted during flight.
196 if (skipPoll) {
197 return;
198 }
199
Jeff Browne839a582010-04-22 18:58:52 -0700200 // Wait for callback or timeout or wake.
201 nsecs_t timeout = nanoseconds_to_milliseconds(nextWakeupTime - currentTime);
202 int32_t timeoutMillis = timeout > INT_MAX ? -1 : timeout > 0 ? int32_t(timeout) : 0;
203 mPollLoop->pollOnce(timeoutMillis);
204}
205
Jeff Brown54bc2812010-06-15 01:31:58 -0700206bool InputDispatcher::runCommandsLockedInterruptible() {
207 if (mCommandQueue.isEmpty()) {
208 return false;
209 }
Jeff Browne839a582010-04-22 18:58:52 -0700210
Jeff Brown54bc2812010-06-15 01:31:58 -0700211 do {
212 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
213
214 Command command = commandEntry->command;
215 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
216
Jeff Brown51d45a72010-06-17 20:52:56 -0700217 commandEntry->connection.clear();
Jeff Brown54bc2812010-06-15 01:31:58 -0700218 mAllocator.releaseCommandEntry(commandEntry);
219 } while (! mCommandQueue.isEmpty());
220 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700221}
222
Jeff Brown54bc2812010-06-15 01:31:58 -0700223InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
224 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
225 mCommandQueue.enqueueAtTail(commandEntry);
226 return commandEntry;
227}
228
229void InputDispatcher::processConfigurationChangedLockedInterruptible(
230 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
231#if DEBUG_OUTBOUND_EVENT_DETAILS
232 LOGD("processConfigurationChanged - eventTime=%lld", entry->eventTime);
233#endif
234
Jeff Brown4036f7f2010-06-29 16:52:21 -0700235 // Reset key repeating in case a keyboard device was added or removed or something.
236 resetKeyRepeatLocked();
237
Jeff Brown54bc2812010-06-15 01:31:58 -0700238 mLock.unlock();
239
240 mPolicy->notifyConfigurationChanged(entry->eventTime);
241
242 mLock.lock();
243}
244
245void InputDispatcher::processKeyLockedInterruptible(
246 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout) {
Jeff Browne839a582010-04-22 18:58:52 -0700247#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -0700248 LOGD("processKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700249 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -0700250 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags, entry->action,
Jeff Browne839a582010-04-22 18:58:52 -0700251 entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
252 entry->downTime);
253#endif
254
Jeff Brown5c1ed842010-07-14 18:48:53 -0700255 if (entry->action == AKEY_EVENT_ACTION_DOWN && ! entry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -0700256 if (mKeyRepeatState.lastKeyEntry
257 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
258 // We have seen two identical key downs in a row which indicates that the device
259 // driver is automatically generating key repeats itself. We take note of the
260 // repeat here, but we disable our own next key repeat timer since it is clear that
261 // we will not need to synthesize key repeats ourselves.
262 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
263 resetKeyRepeatLocked();
264 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
265 } else {
266 // Not a repeat. Save key down state in case we do see a repeat later.
267 resetKeyRepeatLocked();
Jeff Brown54bc2812010-06-15 01:31:58 -0700268 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
Jeff Browne839a582010-04-22 18:58:52 -0700269 }
270 mKeyRepeatState.lastKeyEntry = entry;
271 entry->refCount += 1;
272 } else {
273 resetKeyRepeatLocked();
274 }
275
Jeff Brown54bc2812010-06-15 01:31:58 -0700276 identifyInputTargetsAndDispatchKeyLockedInterruptible(currentTime, entry);
Jeff Browne839a582010-04-22 18:58:52 -0700277}
278
Jeff Brown54bc2812010-06-15 01:31:58 -0700279void InputDispatcher::processKeyRepeatLockedInterruptible(
280 nsecs_t currentTime, nsecs_t keyRepeatTimeout) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700281 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
282
283 // Search the inbound queue for a key up corresponding to this device.
284 // It doesn't make sense to generate a key repeat event if the key is already up.
285 for (EventEntry* queuedEntry = mInboundQueue.head.next;
286 queuedEntry != & mInboundQueue.tail; queuedEntry = entry->next) {
287 if (queuedEntry->type == EventEntry::TYPE_KEY) {
288 KeyEntry* queuedKeyEntry = static_cast<KeyEntry*>(queuedEntry);
289 if (queuedKeyEntry->deviceId == entry->deviceId
Jeff Brown5c1ed842010-07-14 18:48:53 -0700290 && entry->action == AKEY_EVENT_ACTION_UP) {
Jeff Brown50de30a2010-06-22 01:27:15 -0700291 resetKeyRepeatLocked();
292 return;
293 }
294 }
295 }
Jeff Browne839a582010-04-22 18:58:52 -0700296
297 // Synthesize a key repeat after the repeat timeout expired.
Jeff Brown50de30a2010-06-22 01:27:15 -0700298 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown51d45a72010-06-17 20:52:56 -0700299 uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
Jeff Browne839a582010-04-22 18:58:52 -0700300 if (entry->refCount == 1) {
Jeff Brown51d45a72010-06-17 20:52:56 -0700301 entry->eventTime = currentTime;
Jeff Brown51d45a72010-06-17 20:52:56 -0700302 entry->policyFlags = policyFlags;
Jeff Browne839a582010-04-22 18:58:52 -0700303 entry->repeatCount += 1;
304 } else {
Jeff Brown51d45a72010-06-17 20:52:56 -0700305 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700306 entry->deviceId, entry->source, policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -0700307 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brownf16c26d2010-07-02 15:37:36 -0700308 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700309
310 mKeyRepeatState.lastKeyEntry = newEntry;
311 mAllocator.releaseKeyEntry(entry);
312
313 entry = newEntry;
314 }
Jeff Browne839a582010-04-22 18:58:52 -0700315
Jeff Brownf16c26d2010-07-02 15:37:36 -0700316 if (entry->repeatCount == 1) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700317 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brownf16c26d2010-07-02 15:37:36 -0700318 }
319
Jeff Brown54bc2812010-06-15 01:31:58 -0700320 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatTimeout;
Jeff Browne839a582010-04-22 18:58:52 -0700321
322#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -0700323 LOGD("processKeyRepeat - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700324 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
325 "repeatCount=%d, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -0700326 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
Jeff Browne839a582010-04-22 18:58:52 -0700327 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
328 entry->repeatCount, entry->downTime);
329#endif
330
Jeff Brown54bc2812010-06-15 01:31:58 -0700331 identifyInputTargetsAndDispatchKeyLockedInterruptible(currentTime, entry);
Jeff Browne839a582010-04-22 18:58:52 -0700332}
333
Jeff Brown54bc2812010-06-15 01:31:58 -0700334void InputDispatcher::processMotionLockedInterruptible(
335 nsecs_t currentTime, MotionEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700336#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -0700337 LOGD("processMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700338 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -0700339 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags, entry->action,
Jeff Browne839a582010-04-22 18:58:52 -0700340 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
341 entry->downTime);
342
343 // Print the most recent sample that we have available, this may change due to batching.
344 size_t sampleCount = 1;
345 MotionSample* sample = & entry->firstSample;
346 for (; sample->next != NULL; sample = sample->next) {
347 sampleCount += 1;
348 }
349 for (uint32_t i = 0; i < entry->pointerCount; i++) {
350 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
351 i, entry->pointerIds[i],
352 sample->pointerCoords[i].x,
353 sample->pointerCoords[i].y,
354 sample->pointerCoords[i].pressure,
355 sample->pointerCoords[i].size);
356 }
357
358 // Keep in mind that due to batching, it is possible for the number of samples actually
359 // dispatched to change before the application finally consumed them.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700360 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -0700361 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
362 }
363#endif
364
Jeff Brown54bc2812010-06-15 01:31:58 -0700365 identifyInputTargetsAndDispatchMotionLockedInterruptible(currentTime, entry);
Jeff Browne839a582010-04-22 18:58:52 -0700366}
367
Jeff Brown54bc2812010-06-15 01:31:58 -0700368void InputDispatcher::identifyInputTargetsAndDispatchKeyLockedInterruptible(
Jeff Browne839a582010-04-22 18:58:52 -0700369 nsecs_t currentTime, KeyEntry* entry) {
370#if DEBUG_DISPATCH_CYCLE
371 LOGD("identifyInputTargetsAndDispatchKey");
372#endif
373
Jeff Brown54bc2812010-06-15 01:31:58 -0700374 entry->dispatchInProgress = true;
375 mCurrentInputTargetsValid = false;
376 mLock.unlock();
377
Jeff Brown5c1ed842010-07-14 18:48:53 -0700378 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
Jeff Browne839a582010-04-22 18:58:52 -0700379 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
380 entry->downTime, entry->eventTime);
381
382 mCurrentInputTargets.clear();
Jeff Brown50de30a2010-06-22 01:27:15 -0700383 int32_t injectionResult = mPolicy->waitForKeyEventTargets(& mReusableKeyEvent,
Jeff Brown51d45a72010-06-17 20:52:56 -0700384 entry->policyFlags, entry->injectorPid, entry->injectorUid,
Jeff Browne839a582010-04-22 18:58:52 -0700385 mCurrentInputTargets);
386
Jeff Brown54bc2812010-06-15 01:31:58 -0700387 mLock.lock();
388 mCurrentInputTargetsValid = true;
389
Jeff Brown51d45a72010-06-17 20:52:56 -0700390 setInjectionResultLocked(entry, injectionResult);
391
Jeff Brown50de30a2010-06-22 01:27:15 -0700392 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED) {
393 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
394 }
Jeff Browne839a582010-04-22 18:58:52 -0700395}
396
Jeff Brown54bc2812010-06-15 01:31:58 -0700397void InputDispatcher::identifyInputTargetsAndDispatchMotionLockedInterruptible(
Jeff Browne839a582010-04-22 18:58:52 -0700398 nsecs_t currentTime, MotionEntry* entry) {
399#if DEBUG_DISPATCH_CYCLE
400 LOGD("identifyInputTargetsAndDispatchMotion");
401#endif
402
Jeff Brown54bc2812010-06-15 01:31:58 -0700403 entry->dispatchInProgress = true;
404 mCurrentInputTargetsValid = false;
405 mLock.unlock();
406
Jeff Brown5c1ed842010-07-14 18:48:53 -0700407 mReusableMotionEvent.initialize(entry->deviceId, entry->source, entry->action,
Jeff Browne839a582010-04-22 18:58:52 -0700408 entry->edgeFlags, entry->metaState,
Jeff Brownf4a4ec22010-06-16 01:53:36 -0700409 0, 0, entry->xPrecision, entry->yPrecision,
Jeff Browne839a582010-04-22 18:58:52 -0700410 entry->downTime, entry->eventTime, entry->pointerCount, entry->pointerIds,
411 entry->firstSample.pointerCoords);
412
413 mCurrentInputTargets.clear();
Jeff Brown50de30a2010-06-22 01:27:15 -0700414 int32_t injectionResult = mPolicy->waitForMotionEventTargets(& mReusableMotionEvent,
Jeff Brown51d45a72010-06-17 20:52:56 -0700415 entry->policyFlags, entry->injectorPid, entry->injectorUid,
Jeff Browne839a582010-04-22 18:58:52 -0700416 mCurrentInputTargets);
417
Jeff Brown54bc2812010-06-15 01:31:58 -0700418 mLock.lock();
419 mCurrentInputTargetsValid = true;
420
Jeff Brown51d45a72010-06-17 20:52:56 -0700421 setInjectionResultLocked(entry, injectionResult);
422
Jeff Brown50de30a2010-06-22 01:27:15 -0700423 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED) {
424 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
425 }
Jeff Browne839a582010-04-22 18:58:52 -0700426}
427
428void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
429 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
430#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700431 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700432 "resumeWithAppendedMotionSample=%s",
433 resumeWithAppendedMotionSample ? "true" : "false");
434#endif
435
Jeff Brown54bc2812010-06-15 01:31:58 -0700436 assert(eventEntry->dispatchInProgress); // should already have been set to true
437
Jeff Browne839a582010-04-22 18:58:52 -0700438 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
439 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
440
441 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(
442 inputTarget.inputChannel->getReceivePipeFd());
443 if (connectionIndex >= 0) {
444 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown51d45a72010-06-17 20:52:56 -0700445 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700446 resumeWithAppendedMotionSample);
447 } else {
448 LOGW("Framework requested delivery of an input event to channel '%s' but it "
449 "is not registered with the input dispatcher.",
450 inputTarget.inputChannel->getName().string());
451 }
452 }
453}
454
Jeff Brown51d45a72010-06-17 20:52:56 -0700455void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
456 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Browne839a582010-04-22 18:58:52 -0700457 bool resumeWithAppendedMotionSample) {
458#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700459 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, timeout=%lldns, "
Jeff Browne839a582010-04-22 18:58:52 -0700460 "xOffset=%f, yOffset=%f, resumeWithAppendedMotionSample=%s",
461 connection->getInputChannelName(), inputTarget->flags, inputTarget->timeout,
462 inputTarget->xOffset, inputTarget->yOffset,
463 resumeWithAppendedMotionSample ? "true" : "false");
464#endif
465
466 // Skip this event if the connection status is not normal.
467 // We don't want to queue outbound events at all if the connection is broken or
468 // not responding.
469 if (connection->status != Connection::STATUS_NORMAL) {
470 LOGV("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brown54bc2812010-06-15 01:31:58 -0700471 connection->getStatusLabel());
Jeff Browne839a582010-04-22 18:58:52 -0700472 return;
473 }
474
475 // Resume the dispatch cycle with a freshly appended motion sample.
476 // First we check that the last dispatch entry in the outbound queue is for the same
477 // motion event to which we appended the motion sample. If we find such a dispatch
478 // entry, and if it is currently in progress then we try to stream the new sample.
479 bool wasEmpty = connection->outboundQueue.isEmpty();
480
481 if (! wasEmpty && resumeWithAppendedMotionSample) {
482 DispatchEntry* motionEventDispatchEntry =
483 connection->findQueuedDispatchEntryForEvent(eventEntry);
484 if (motionEventDispatchEntry) {
485 // If the dispatch entry is not in progress, then we must be busy dispatching an
486 // earlier event. Not a problem, the motion event is on the outbound queue and will
487 // be dispatched later.
488 if (! motionEventDispatchEntry->inProgress) {
489#if DEBUG_BATCHING
490 LOGD("channel '%s' ~ Not streaming because the motion event has "
491 "not yet been dispatched. "
492 "(Waiting for earlier events to be consumed.)",
493 connection->getInputChannelName());
494#endif
495 return;
496 }
497
498 // If the dispatch entry is in progress but it already has a tail of pending
499 // motion samples, then it must mean that the shared memory buffer filled up.
500 // Not a problem, when this dispatch cycle is finished, we will eventually start
501 // a new dispatch cycle to process the tail and that tail includes the newly
502 // appended motion sample.
503 if (motionEventDispatchEntry->tailMotionSample) {
504#if DEBUG_BATCHING
505 LOGD("channel '%s' ~ Not streaming because no new samples can "
506 "be appended to the motion event in this dispatch cycle. "
507 "(Waiting for next dispatch cycle to start.)",
508 connection->getInputChannelName());
509#endif
510 return;
511 }
512
513 // The dispatch entry is in progress and is still potentially open for streaming.
514 // Try to stream the new motion sample. This might fail if the consumer has already
515 // consumed the motion event (or if the channel is broken).
516 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
517 status_t status = connection->inputPublisher.appendMotionSample(
518 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
519 if (status == OK) {
520#if DEBUG_BATCHING
521 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
522 connection->getInputChannelName());
523#endif
524 return;
525 }
526
527#if DEBUG_BATCHING
528 if (status == NO_MEMORY) {
529 LOGD("channel '%s' ~ Could not append motion sample to currently "
530 "dispatched move event because the shared memory buffer is full. "
531 "(Waiting for next dispatch cycle to start.)",
532 connection->getInputChannelName());
533 } else if (status == status_t(FAILED_TRANSACTION)) {
534 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown50de30a2010-06-22 01:27:15 -0700535 "dispatched move event because the event has already been consumed. "
Jeff Browne839a582010-04-22 18:58:52 -0700536 "(Waiting for next dispatch cycle to start.)",
537 connection->getInputChannelName());
538 } else {
539 LOGD("channel '%s' ~ Could not append motion sample to currently "
540 "dispatched move event due to an error, status=%d. "
541 "(Waiting for next dispatch cycle to start.)",
542 connection->getInputChannelName(), status);
543 }
544#endif
545 // Failed to stream. Start a new tail of pending motion samples to dispatch
546 // in the next cycle.
547 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
548 return;
549 }
550 }
551
552 // This is a new event.
553 // Enqueue a new dispatch entry onto the outbound queue for this connection.
554 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry); // increments ref
555 dispatchEntry->targetFlags = inputTarget->flags;
556 dispatchEntry->xOffset = inputTarget->xOffset;
557 dispatchEntry->yOffset = inputTarget->yOffset;
558 dispatchEntry->timeout = inputTarget->timeout;
559 dispatchEntry->inProgress = false;
560 dispatchEntry->headMotionSample = NULL;
561 dispatchEntry->tailMotionSample = NULL;
562
563 // Handle the case where we could not stream a new motion sample because the consumer has
564 // already consumed the motion event (otherwise the corresponding dispatch entry would
565 // still be in the outbound queue for this connection). We set the head motion sample
566 // to the list starting with the newly appended motion sample.
567 if (resumeWithAppendedMotionSample) {
568#if DEBUG_BATCHING
569 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
570 "that cannot be streamed because the motion event has already been consumed.",
571 connection->getInputChannelName());
572#endif
573 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
574 dispatchEntry->headMotionSample = appendedMotionSample;
575 }
576
577 // Enqueue the dispatch entry.
578 connection->outboundQueue.enqueueAtTail(dispatchEntry);
579
580 // If the outbound queue was previously empty, start the dispatch cycle going.
581 if (wasEmpty) {
Jeff Brown51d45a72010-06-17 20:52:56 -0700582 activateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -0700583 startDispatchCycleLocked(currentTime, connection);
584 }
585}
586
Jeff Brown51d45a72010-06-17 20:52:56 -0700587void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
588 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -0700589#if DEBUG_DISPATCH_CYCLE
590 LOGD("channel '%s' ~ startDispatchCycle",
591 connection->getInputChannelName());
592#endif
593
594 assert(connection->status == Connection::STATUS_NORMAL);
595 assert(! connection->outboundQueue.isEmpty());
596
597 DispatchEntry* dispatchEntry = connection->outboundQueue.head.next;
598 assert(! dispatchEntry->inProgress);
599
600 // TODO throttle successive ACTION_MOVE motion events for the same device
601 // possible implementation could set a brief poll timeout here and resume starting the
602 // dispatch cycle when elapsed
603
604 // Publish the event.
605 status_t status;
606 switch (dispatchEntry->eventEntry->type) {
607 case EventEntry::TYPE_KEY: {
608 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
609
610 // Apply target flags.
611 int32_t action = keyEntry->action;
612 int32_t flags = keyEntry->flags;
613 if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700614 flags |= AKEY_EVENT_FLAG_CANCELED;
Jeff Browne839a582010-04-22 18:58:52 -0700615 }
616
617 // Publish the key event.
Jeff Brown5c1ed842010-07-14 18:48:53 -0700618 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Browne839a582010-04-22 18:58:52 -0700619 action, flags, keyEntry->keyCode, keyEntry->scanCode,
620 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
621 keyEntry->eventTime);
622
623 if (status) {
624 LOGE("channel '%s' ~ Could not publish key event, "
625 "status=%d", connection->getInputChannelName(), status);
626 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
627 return;
628 }
629 break;
630 }
631
632 case EventEntry::TYPE_MOTION: {
633 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
634
635 // Apply target flags.
636 int32_t action = motionEntry->action;
637 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700638 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Browne839a582010-04-22 18:58:52 -0700639 }
640 if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
Jeff Brown5c1ed842010-07-14 18:48:53 -0700641 action = AMOTION_EVENT_ACTION_CANCEL;
Jeff Browne839a582010-04-22 18:58:52 -0700642 }
643
644 // If headMotionSample is non-NULL, then it points to the first new sample that we
645 // were unable to dispatch during the previous cycle so we resume dispatching from
646 // that point in the list of motion samples.
647 // Otherwise, we just start from the first sample of the motion event.
648 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
649 if (! firstMotionSample) {
650 firstMotionSample = & motionEntry->firstSample;
651 }
652
Jeff Brownf26db0d2010-07-16 17:21:06 -0700653 // Set the X and Y offset depending on the input source.
654 float xOffset, yOffset;
655 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
656 xOffset = dispatchEntry->xOffset;
657 yOffset = dispatchEntry->yOffset;
658 } else {
659 xOffset = 0.0f;
660 yOffset = 0.0f;
661 }
662
Jeff Browne839a582010-04-22 18:58:52 -0700663 // Publish the motion event and the first motion sample.
664 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700665 motionEntry->source, action, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownf26db0d2010-07-16 17:21:06 -0700666 xOffset, yOffset,
Jeff Browne839a582010-04-22 18:58:52 -0700667 motionEntry->xPrecision, motionEntry->yPrecision,
668 motionEntry->downTime, firstMotionSample->eventTime,
669 motionEntry->pointerCount, motionEntry->pointerIds,
670 firstMotionSample->pointerCoords);
671
672 if (status) {
673 LOGE("channel '%s' ~ Could not publish motion event, "
674 "status=%d", connection->getInputChannelName(), status);
675 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
676 return;
677 }
678
679 // Append additional motion samples.
680 MotionSample* nextMotionSample = firstMotionSample->next;
681 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
682 status = connection->inputPublisher.appendMotionSample(
683 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
684 if (status == NO_MEMORY) {
685#if DEBUG_DISPATCH_CYCLE
686 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
687 "be sent in the next dispatch cycle.",
688 connection->getInputChannelName());
689#endif
690 break;
691 }
692 if (status != OK) {
693 LOGE("channel '%s' ~ Could not append motion sample "
694 "for a reason other than out of memory, status=%d",
695 connection->getInputChannelName(), status);
696 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
697 return;
698 }
699 }
700
701 // Remember the next motion sample that we could not dispatch, in case we ran out
702 // of space in the shared memory buffer.
703 dispatchEntry->tailMotionSample = nextMotionSample;
704 break;
705 }
706
707 default: {
708 assert(false);
709 }
710 }
711
712 // Send the dispatch signal.
713 status = connection->inputPublisher.sendDispatchSignal();
714 if (status) {
715 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
716 connection->getInputChannelName(), status);
717 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
718 return;
719 }
720
721 // Record information about the newly started dispatch cycle.
722 dispatchEntry->inProgress = true;
723
724 connection->lastEventTime = dispatchEntry->eventEntry->eventTime;
725 connection->lastDispatchTime = currentTime;
726
727 nsecs_t timeout = dispatchEntry->timeout;
Jeff Brown51d45a72010-06-17 20:52:56 -0700728 connection->setNextTimeoutTime(currentTime, timeout);
Jeff Browne839a582010-04-22 18:58:52 -0700729
730 // Notify other system components.
731 onDispatchCycleStartedLocked(currentTime, connection);
732}
733
Jeff Brown51d45a72010-06-17 20:52:56 -0700734void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
735 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -0700736#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700737 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -0700738 "%01.1fms since dispatch",
739 connection->getInputChannelName(),
740 connection->getEventLatencyMillis(currentTime),
741 connection->getDispatchLatencyMillis(currentTime));
742#endif
743
Jeff Brown54bc2812010-06-15 01:31:58 -0700744 if (connection->status == Connection::STATUS_BROKEN
745 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -0700746 return;
747 }
748
749 // Clear the pending timeout.
750 connection->nextTimeoutTime = LONG_LONG_MAX;
751
752 if (connection->status == Connection::STATUS_NOT_RESPONDING) {
753 // Recovering from an ANR.
754 connection->status = Connection::STATUS_NORMAL;
755
756 // Notify other system components.
757 onDispatchCycleFinishedLocked(currentTime, connection, true /*recoveredFromANR*/);
758 } else {
759 // Normal finish. Not much to do here.
760
761 // Notify other system components.
762 onDispatchCycleFinishedLocked(currentTime, connection, false /*recoveredFromANR*/);
763 }
764
765 // Reset the publisher since the event has been consumed.
766 // We do this now so that the publisher can release some of its internal resources
767 // while waiting for the next dispatch cycle to begin.
768 status_t status = connection->inputPublisher.reset();
769 if (status) {
770 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
771 connection->getInputChannelName(), status);
772 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
773 return;
774 }
775
776 // Start the next dispatch cycle for this connection.
777 while (! connection->outboundQueue.isEmpty()) {
778 DispatchEntry* dispatchEntry = connection->outboundQueue.head.next;
779 if (dispatchEntry->inProgress) {
780 // Finish or resume current event in progress.
781 if (dispatchEntry->tailMotionSample) {
782 // We have a tail of undispatched motion samples.
783 // Reuse the same DispatchEntry and start a new cycle.
784 dispatchEntry->inProgress = false;
785 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
786 dispatchEntry->tailMotionSample = NULL;
787 startDispatchCycleLocked(currentTime, connection);
788 return;
789 }
790 // Finished.
791 connection->outboundQueue.dequeueAtHead();
792 mAllocator.releaseDispatchEntry(dispatchEntry);
793 } else {
794 // If the head is not in progress, then we must have already dequeued the in
795 // progress event, which means we actually aborted it (due to ANR).
796 // So just start the next event for this connection.
797 startDispatchCycleLocked(currentTime, connection);
798 return;
799 }
800 }
801
802 // Outbound queue is empty, deactivate the connection.
Jeff Brown51d45a72010-06-17 20:52:56 -0700803 deactivateConnectionLocked(connection.get());
Jeff Browne839a582010-04-22 18:58:52 -0700804}
805
Jeff Brown51d45a72010-06-17 20:52:56 -0700806void InputDispatcher::timeoutDispatchCycleLocked(nsecs_t currentTime,
807 const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -0700808#if DEBUG_DISPATCH_CYCLE
809 LOGD("channel '%s' ~ timeoutDispatchCycle",
810 connection->getInputChannelName());
811#endif
812
813 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brown51d45a72010-06-17 20:52:56 -0700814 return;
Jeff Browne839a582010-04-22 18:58:52 -0700815 }
816
817 // Enter the not responding state.
818 connection->status = Connection::STATUS_NOT_RESPONDING;
819 connection->lastANRTime = currentTime;
Jeff Browne839a582010-04-22 18:58:52 -0700820
821 // Notify other system components.
Jeff Brown51d45a72010-06-17 20:52:56 -0700822 // This enqueues a command which will eventually either call
823 // resumeAfterTimeoutDispatchCycleLocked or abortDispatchCycleLocked.
Jeff Browne839a582010-04-22 18:58:52 -0700824 onDispatchCycleANRLocked(currentTime, connection);
Jeff Browne839a582010-04-22 18:58:52 -0700825}
826
Jeff Brown51d45a72010-06-17 20:52:56 -0700827void InputDispatcher::resumeAfterTimeoutDispatchCycleLocked(nsecs_t currentTime,
828 const sp<Connection>& connection, nsecs_t newTimeout) {
829#if DEBUG_DISPATCH_CYCLE
830 LOGD("channel '%s' ~ resumeAfterTimeoutDispatchCycleLocked",
831 connection->getInputChannelName());
832#endif
833
834 if (connection->status != Connection::STATUS_NOT_RESPONDING) {
835 return;
836 }
837
838 // Resume normal dispatch.
839 connection->status = Connection::STATUS_NORMAL;
840 connection->setNextTimeoutTime(currentTime, newTimeout);
841}
842
843void InputDispatcher::abortDispatchCycleLocked(nsecs_t currentTime,
844 const sp<Connection>& connection, bool broken) {
Jeff Browne839a582010-04-22 18:58:52 -0700845#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700846 LOGD("channel '%s' ~ abortDispatchCycle - broken=%s",
Jeff Browne839a582010-04-22 18:58:52 -0700847 connection->getInputChannelName(), broken ? "true" : "false");
848#endif
849
Jeff Browne839a582010-04-22 18:58:52 -0700850 // Clear the pending timeout.
851 connection->nextTimeoutTime = LONG_LONG_MAX;
852
853 // Clear the outbound queue.
Jeff Brown51d45a72010-06-17 20:52:56 -0700854 if (! connection->outboundQueue.isEmpty()) {
Jeff Brown54bc2812010-06-15 01:31:58 -0700855 do {
856 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
857 mAllocator.releaseDispatchEntry(dispatchEntry);
858 } while (! connection->outboundQueue.isEmpty());
Jeff Browne839a582010-04-22 18:58:52 -0700859
Jeff Brown51d45a72010-06-17 20:52:56 -0700860 deactivateConnectionLocked(connection.get());
Jeff Brown54bc2812010-06-15 01:31:58 -0700861 }
Jeff Browne839a582010-04-22 18:58:52 -0700862
863 // Handle the case where the connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -0700864 // Ignore already broken or zombie connections.
Jeff Browne839a582010-04-22 18:58:52 -0700865 if (broken) {
Jeff Brown54bc2812010-06-15 01:31:58 -0700866 if (connection->status == Connection::STATUS_NORMAL
867 || connection->status == Connection::STATUS_NOT_RESPONDING) {
868 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -0700869
Jeff Brown54bc2812010-06-15 01:31:58 -0700870 // Notify other system components.
871 onDispatchCycleBrokenLocked(currentTime, connection);
872 }
Jeff Browne839a582010-04-22 18:58:52 -0700873 }
Jeff Browne839a582010-04-22 18:58:52 -0700874}
875
876bool InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
877 InputDispatcher* d = static_cast<InputDispatcher*>(data);
878
879 { // acquire lock
880 AutoMutex _l(d->mLock);
881
882 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
883 if (connectionIndex < 0) {
884 LOGE("Received spurious receive callback for unknown input channel. "
885 "fd=%d, events=0x%x", receiveFd, events);
886 return false; // remove the callback
887 }
888
Jeff Brown51d45a72010-06-17 20:52:56 -0700889 nsecs_t currentTime = now();
Jeff Browne839a582010-04-22 18:58:52 -0700890
891 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
892 if (events & (POLLERR | POLLHUP | POLLNVAL)) {
893 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
894 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown51d45a72010-06-17 20:52:56 -0700895 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -0700896 d->runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -0700897 return false; // remove the callback
898 }
899
900 if (! (events & POLLIN)) {
901 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
902 "events=0x%x", connection->getInputChannelName(), events);
903 return true;
904 }
905
906 status_t status = connection->inputPublisher.receiveFinishedSignal();
907 if (status) {
908 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
909 connection->getInputChannelName(), status);
Jeff Brown51d45a72010-06-17 20:52:56 -0700910 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -0700911 d->runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -0700912 return false; // remove the callback
913 }
914
Jeff Brown51d45a72010-06-17 20:52:56 -0700915 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -0700916 d->runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -0700917 return true;
918 } // release lock
919}
920
Jeff Brown54bc2812010-06-15 01:31:58 -0700921void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -0700922#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -0700923 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700924#endif
925
926 bool wasEmpty;
927 { // acquire lock
928 AutoMutex _l(mLock);
929
Jeff Brown51d45a72010-06-17 20:52:56 -0700930 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700931
932 wasEmpty = mInboundQueue.isEmpty();
933 mInboundQueue.enqueueAtTail(newEntry);
934 } // release lock
935
936 if (wasEmpty) {
937 mPollLoop->wake();
938 }
939}
940
Jeff Browne839a582010-04-22 18:58:52 -0700941void InputDispatcher::notifyAppSwitchComing(nsecs_t eventTime) {
942#if DEBUG_INBOUND_EVENT_DETAILS
943 LOGD("notifyAppSwitchComing - eventTime=%lld", eventTime);
944#endif
945
946 // Remove movement keys from the queue from most recent to least recent, stopping at the
947 // first non-movement key.
948 // TODO: Include a detailed description of why we do this...
949
950 { // acquire lock
951 AutoMutex _l(mLock);
952
953 for (EventEntry* entry = mInboundQueue.tail.prev; entry != & mInboundQueue.head; ) {
954 EventEntry* prev = entry->prev;
955
956 if (entry->type == EventEntry::TYPE_KEY) {
957 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
958 if (isMovementKey(keyEntry->keyCode)) {
959 LOGV("Dropping movement key during app switch: keyCode=%d, action=%d",
960 keyEntry->keyCode, keyEntry->action);
961 mInboundQueue.dequeue(keyEntry);
Jeff Brown51d45a72010-06-17 20:52:56 -0700962
963 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
964
Jeff Browne839a582010-04-22 18:58:52 -0700965 mAllocator.releaseKeyEntry(keyEntry);
966 } else {
967 // stop at last non-movement key
968 break;
969 }
970 }
971
972 entry = prev;
973 }
974 } // release lock
975}
976
Jeff Brown5c1ed842010-07-14 18:48:53 -0700977void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -0700978 uint32_t policyFlags, int32_t action, int32_t flags,
979 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
980#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -0700981 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -0700982 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -0700983 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Browne839a582010-04-22 18:58:52 -0700984 keyCode, scanCode, metaState, downTime);
985#endif
986
987 bool wasEmpty;
988 { // acquire lock
989 AutoMutex _l(mLock);
990
Jeff Brown51d45a72010-06-17 20:52:56 -0700991 int32_t repeatCount = 0;
992 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -0700993 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown51d45a72010-06-17 20:52:56 -0700994 metaState, repeatCount, downTime);
Jeff Browne839a582010-04-22 18:58:52 -0700995
996 wasEmpty = mInboundQueue.isEmpty();
997 mInboundQueue.enqueueAtTail(newEntry);
998 } // release lock
999
1000 if (wasEmpty) {
1001 mPollLoop->wake();
1002 }
1003}
1004
Jeff Brown5c1ed842010-07-14 18:48:53 -07001005void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Browne839a582010-04-22 18:58:52 -07001006 uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
1007 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
1008 float xPrecision, float yPrecision, nsecs_t downTime) {
1009#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown5c1ed842010-07-14 18:48:53 -07001010 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Browne839a582010-04-22 18:58:52 -07001011 "action=0x%x, metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, "
1012 "downTime=%lld",
Jeff Brown5c1ed842010-07-14 18:48:53 -07001013 eventTime, deviceId, source, policyFlags, action, metaState, edgeFlags,
Jeff Browne839a582010-04-22 18:58:52 -07001014 xPrecision, yPrecision, downTime);
1015 for (uint32_t i = 0; i < pointerCount; i++) {
1016 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
1017 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
1018 pointerCoords[i].pressure, pointerCoords[i].size);
1019 }
1020#endif
1021
1022 bool wasEmpty;
1023 { // acquire lock
1024 AutoMutex _l(mLock);
1025
1026 // Attempt batching and streaming of move events.
Jeff Brown5c1ed842010-07-14 18:48:53 -07001027 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Browne839a582010-04-22 18:58:52 -07001028 // BATCHING CASE
1029 //
1030 // Try to append a move sample to the tail of the inbound queue for this device.
1031 // Give up if we encounter a non-move motion event for this device since that
1032 // means we cannot append any new samples until a new motion event has started.
1033 for (EventEntry* entry = mInboundQueue.tail.prev;
1034 entry != & mInboundQueue.head; entry = entry->prev) {
1035 if (entry->type != EventEntry::TYPE_MOTION) {
1036 // Keep looking for motion events.
1037 continue;
1038 }
1039
1040 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
1041 if (motionEntry->deviceId != deviceId) {
1042 // Keep looking for this device.
1043 continue;
1044 }
1045
Jeff Brown5c1ed842010-07-14 18:48:53 -07001046 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown51d45a72010-06-17 20:52:56 -07001047 || motionEntry->pointerCount != pointerCount
1048 || motionEntry->isInjected()) {
Jeff Browne839a582010-04-22 18:58:52 -07001049 // Last motion event in the queue for this device is not compatible for
1050 // appending new samples. Stop here.
1051 goto NoBatchingOrStreaming;
1052 }
1053
1054 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07001055 // Do the batching magic.
Jeff Brown51d45a72010-06-17 20:52:56 -07001056 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07001057#if DEBUG_BATCHING
1058 LOGD("Appended motion sample onto batch for most recent "
1059 "motion event for this device in the inbound queue.");
1060#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07001061
1062 // Sanity check for special case because dispatch is interruptible.
1063 // The dispatch logic is partially interruptible and releases its lock while
1064 // identifying targets. However, as soon as the targets have been identified,
1065 // the dispatcher proceeds to write a dispatch entry into all relevant outbound
1066 // queues and then promptly removes the motion entry from the queue.
1067 //
1068 // Consequently, we should never observe the case where the inbound queue contains
1069 // an in-progress motion entry unless the current input targets are invalid
1070 // (currently being computed). Check for this!
1071 assert(! (motionEntry->dispatchInProgress && mCurrentInputTargetsValid));
1072
1073 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07001074 }
1075
1076 // STREAMING CASE
1077 //
1078 // There is no pending motion event (of any kind) for this device in the inbound queue.
1079 // Search the outbound queues for a synchronously dispatched motion event for this
1080 // device. If found, then we append the new sample to that event and then try to
1081 // push it out to all current targets. It is possible that some targets will already
1082 // have consumed the motion event. This case is automatically handled by the
1083 // logic in prepareDispatchCycleLocked by tracking where resumption takes place.
1084 //
1085 // The reason we look for a synchronously dispatched motion event is because we
1086 // want to be sure that no other motion events have been dispatched since the move.
1087 // It's also convenient because it means that the input targets are still valid.
1088 // This code could be improved to support streaming of asynchronously dispatched
1089 // motion events (which might be significantly more efficient) but it may become
1090 // a little more complicated as a result.
1091 //
1092 // Note: This code crucially depends on the invariant that an outbound queue always
1093 // contains at most one synchronous event and it is always last (but it might
1094 // not be first!).
Jeff Brown54bc2812010-06-15 01:31:58 -07001095 if (mCurrentInputTargetsValid) {
1096 for (size_t i = 0; i < mActiveConnections.size(); i++) {
1097 Connection* connection = mActiveConnections.itemAt(i);
1098 if (! connection->outboundQueue.isEmpty()) {
1099 DispatchEntry* dispatchEntry = connection->outboundQueue.tail.prev;
1100 if (dispatchEntry->targetFlags & InputTarget::FLAG_SYNC) {
1101 if (dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION) {
1102 goto NoBatchingOrStreaming;
1103 }
Jeff Browne839a582010-04-22 18:58:52 -07001104
Jeff Brown54bc2812010-06-15 01:31:58 -07001105 MotionEntry* syncedMotionEntry = static_cast<MotionEntry*>(
1106 dispatchEntry->eventEntry);
Jeff Brown5c1ed842010-07-14 18:48:53 -07001107 if (syncedMotionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown54bc2812010-06-15 01:31:58 -07001108 || syncedMotionEntry->deviceId != deviceId
Jeff Brown51d45a72010-06-17 20:52:56 -07001109 || syncedMotionEntry->pointerCount != pointerCount
1110 || syncedMotionEntry->isInjected()) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001111 goto NoBatchingOrStreaming;
1112 }
Jeff Browne839a582010-04-22 18:58:52 -07001113
Jeff Brown54bc2812010-06-15 01:31:58 -07001114 // Found synced move entry. Append sample and resume dispatch.
1115 mAllocator.appendMotionSample(syncedMotionEntry, eventTime,
Jeff Brown51d45a72010-06-17 20:52:56 -07001116 pointerCoords);
Jeff Brown54bc2812010-06-15 01:31:58 -07001117 #if DEBUG_BATCHING
1118 LOGD("Appended motion sample onto batch for most recent synchronously "
1119 "dispatched motion event for this device in the outbound queues.");
1120 #endif
Jeff Brown51d45a72010-06-17 20:52:56 -07001121 nsecs_t currentTime = now();
Jeff Brown54bc2812010-06-15 01:31:58 -07001122 dispatchEventToCurrentInputTargetsLocked(currentTime, syncedMotionEntry,
1123 true /*resumeWithAppendedMotionSample*/);
1124
1125 runCommandsLockedInterruptible();
1126 return; // done!
1127 }
Jeff Browne839a582010-04-22 18:58:52 -07001128 }
1129 }
1130 }
1131
1132NoBatchingOrStreaming:;
1133 }
1134
1135 // Just enqueue a new motion event.
Jeff Brown51d45a72010-06-17 20:52:56 -07001136 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07001137 deviceId, source, policyFlags, action, metaState, edgeFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07001138 xPrecision, yPrecision, downTime,
1139 pointerCount, pointerIds, pointerCoords);
Jeff Browne839a582010-04-22 18:58:52 -07001140
1141 wasEmpty = mInboundQueue.isEmpty();
1142 mInboundQueue.enqueueAtTail(newEntry);
1143 } // release lock
1144
1145 if (wasEmpty) {
1146 mPollLoop->wake();
1147 }
1148}
1149
Jeff Brown51d45a72010-06-17 20:52:56 -07001150int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
1151 int32_t injectorPid, int32_t injectorUid, bool sync, int32_t timeoutMillis) {
1152#if DEBUG_INBOUND_EVENT_DETAILS
1153 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
1154 "sync=%d, timeoutMillis=%d",
1155 event->getType(), injectorPid, injectorUid, sync, timeoutMillis);
1156#endif
1157
1158 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
1159
1160 EventEntry* injectedEntry;
1161 bool wasEmpty;
1162 { // acquire lock
1163 AutoMutex _l(mLock);
1164
1165 injectedEntry = createEntryFromInputEventLocked(event);
1166 injectedEntry->refCount += 1;
1167 injectedEntry->injectorPid = injectorPid;
1168 injectedEntry->injectorUid = injectorUid;
1169
1170 wasEmpty = mInboundQueue.isEmpty();
1171 mInboundQueue.enqueueAtTail(injectedEntry);
1172
1173 } // release lock
1174
1175 if (wasEmpty) {
1176 mPollLoop->wake();
1177 }
1178
1179 int32_t injectionResult;
1180 { // acquire lock
1181 AutoMutex _l(mLock);
1182
1183 for (;;) {
1184 injectionResult = injectedEntry->injectionResult;
1185 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
1186 break;
1187 }
1188
1189 nsecs_t remainingTimeout = endTime - now();
1190 if (remainingTimeout <= 0) {
1191 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
1192 sync = false;
1193 break;
1194 }
1195
1196 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
1197 }
1198
1199 if (sync) {
1200 while (! isFullySynchronizedLocked()) {
1201 nsecs_t remainingTimeout = endTime - now();
1202 if (remainingTimeout <= 0) {
1203 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
1204 break;
1205 }
1206
1207 mFullySynchronizedCondition.waitRelative(mLock, remainingTimeout);
1208 }
1209 }
1210
1211 mAllocator.releaseEventEntry(injectedEntry);
1212 } // release lock
1213
1214 return injectionResult;
1215}
1216
1217void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
1218 if (entry->isInjected()) {
1219#if DEBUG_INJECTION
1220 LOGD("Setting input event injection result to %d. "
1221 "injectorPid=%d, injectorUid=%d",
1222 injectionResult, entry->injectorPid, entry->injectorUid);
1223#endif
1224
1225 entry->injectionResult = injectionResult;
1226 mInjectionResultAvailableCondition.broadcast();
1227 }
1228}
1229
1230bool InputDispatcher::isFullySynchronizedLocked() {
1231 return mInboundQueue.isEmpty() && mActiveConnections.isEmpty();
1232}
1233
1234InputDispatcher::EventEntry* InputDispatcher::createEntryFromInputEventLocked(
1235 const InputEvent* event) {
1236 switch (event->getType()) {
Jeff Brown5c1ed842010-07-14 18:48:53 -07001237 case AINPUT_EVENT_TYPE_KEY: {
Jeff Brown51d45a72010-06-17 20:52:56 -07001238 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
1239 uint32_t policyFlags = 0; // XXX consider adding a policy flag to track injected events
1240
1241 KeyEntry* keyEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
Jeff Brown5c1ed842010-07-14 18:48:53 -07001242 keyEvent->getDeviceId(), keyEvent->getSource(), policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07001243 keyEvent->getAction(), keyEvent->getFlags(),
1244 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
1245 keyEvent->getRepeatCount(), keyEvent->getDownTime());
1246 return keyEntry;
1247 }
1248
Jeff Brown5c1ed842010-07-14 18:48:53 -07001249 case AINPUT_EVENT_TYPE_MOTION: {
Jeff Brown51d45a72010-06-17 20:52:56 -07001250 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
1251 uint32_t policyFlags = 0; // XXX consider adding a policy flag to track injected events
1252
1253 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
1254 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
1255 size_t pointerCount = motionEvent->getPointerCount();
1256
1257 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
Jeff Brown5c1ed842010-07-14 18:48:53 -07001258 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
Jeff Brown51d45a72010-06-17 20:52:56 -07001259 motionEvent->getAction(), motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
1260 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
1261 motionEvent->getDownTime(), uint32_t(pointerCount),
1262 motionEvent->getPointerIds(), samplePointerCoords);
1263 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
1264 sampleEventTimes += 1;
1265 samplePointerCoords += pointerCount;
1266 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
1267 }
1268 return motionEntry;
1269 }
1270
1271 default:
1272 assert(false);
1273 return NULL;
1274 }
1275}
1276
Jeff Browne839a582010-04-22 18:58:52 -07001277void InputDispatcher::resetKeyRepeatLocked() {
1278 if (mKeyRepeatState.lastKeyEntry) {
1279 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
1280 mKeyRepeatState.lastKeyEntry = NULL;
1281 }
1282}
1283
Jeff Brown50de30a2010-06-22 01:27:15 -07001284void InputDispatcher::preemptInputDispatch() {
1285#if DEBUG_DISPATCH_CYCLE
1286 LOGD("preemptInputDispatch");
1287#endif
1288
1289 bool preemptedOne = false;
1290 { // acquire lock
1291 AutoMutex _l(mLock);
1292
1293 for (size_t i = 0; i < mActiveConnections.size(); i++) {
1294 Connection* connection = mActiveConnections[i];
1295 if (connection->hasPendingSyncTarget()) {
1296#if DEBUG_DISPATCH_CYCLE
1297 LOGD("channel '%s' ~ Preempted pending synchronous dispatch",
1298 connection->getInputChannelName());
1299#endif
1300 connection->outboundQueue.tail.prev->targetFlags &= ~ InputTarget::FLAG_SYNC;
1301 preemptedOne = true;
1302 }
1303 }
1304 } // release lock
1305
1306 if (preemptedOne) {
1307 // Wake up the poll loop so it can get a head start dispatching the next event.
1308 mPollLoop->wake();
1309 }
1310}
1311
Jeff Browne839a582010-04-22 18:58:52 -07001312status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001313#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07001314 LOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07001315#endif
1316
Jeff Browne839a582010-04-22 18:58:52 -07001317 int receiveFd;
1318 { // acquire lock
1319 AutoMutex _l(mLock);
1320
1321 receiveFd = inputChannel->getReceivePipeFd();
1322 if (mConnectionsByReceiveFd.indexOfKey(receiveFd) >= 0) {
1323 LOGW("Attempted to register already registered input channel '%s'",
1324 inputChannel->getName().string());
1325 return BAD_VALUE;
1326 }
1327
1328 sp<Connection> connection = new Connection(inputChannel);
1329 status_t status = connection->initialize();
1330 if (status) {
1331 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
1332 inputChannel->getName().string(), status);
1333 return status;
1334 }
1335
1336 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001337
1338 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07001339 } // release lock
1340
1341 mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this);
1342 return OK;
1343}
1344
1345status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001346#if DEBUG_REGISTRATION
Jeff Brown50de30a2010-06-22 01:27:15 -07001347 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown54bc2812010-06-15 01:31:58 -07001348#endif
1349
Jeff Browne839a582010-04-22 18:58:52 -07001350 int32_t receiveFd;
1351 { // acquire lock
1352 AutoMutex _l(mLock);
1353
1354 receiveFd = inputChannel->getReceivePipeFd();
1355 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd);
1356 if (connectionIndex < 0) {
1357 LOGW("Attempted to unregister already unregistered input channel '%s'",
1358 inputChannel->getName().string());
1359 return BAD_VALUE;
1360 }
1361
1362 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1363 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
1364
1365 connection->status = Connection::STATUS_ZOMBIE;
1366
Jeff Brown51d45a72010-06-17 20:52:56 -07001367 nsecs_t currentTime = now();
1368 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -07001369
1370 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07001371 } // release lock
1372
1373 mPollLoop->removeCallback(receiveFd);
1374
1375 // Wake the poll loop because removing the connection may have changed the current
1376 // synchronization state.
1377 mPollLoop->wake();
1378 return OK;
1379}
1380
1381void InputDispatcher::activateConnectionLocked(Connection* connection) {
1382 for (size_t i = 0; i < mActiveConnections.size(); i++) {
1383 if (mActiveConnections.itemAt(i) == connection) {
1384 return;
1385 }
1386 }
1387 mActiveConnections.add(connection);
1388}
1389
1390void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
1391 for (size_t i = 0; i < mActiveConnections.size(); i++) {
1392 if (mActiveConnections.itemAt(i) == connection) {
1393 mActiveConnections.removeAt(i);
1394 return;
1395 }
1396 }
1397}
1398
Jeff Brown54bc2812010-06-15 01:31:58 -07001399void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07001400 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001401}
1402
Jeff Brown54bc2812010-06-15 01:31:58 -07001403void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07001404 nsecs_t currentTime, const sp<Connection>& connection, bool recoveredFromANR) {
Jeff Browne839a582010-04-22 18:58:52 -07001405 if (recoveredFromANR) {
1406 LOGI("channel '%s' ~ Recovered from ANR. %01.1fms since event, "
1407 "%01.1fms since dispatch, %01.1fms since ANR",
1408 connection->getInputChannelName(),
1409 connection->getEventLatencyMillis(currentTime),
1410 connection->getDispatchLatencyMillis(currentTime),
1411 connection->getANRLatencyMillis(currentTime));
1412
Jeff Brown54bc2812010-06-15 01:31:58 -07001413 CommandEntry* commandEntry = postCommandLocked(
1414 & InputDispatcher::doNotifyInputChannelRecoveredFromANRLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07001415 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07001416 }
1417}
1418
Jeff Brown54bc2812010-06-15 01:31:58 -07001419void InputDispatcher::onDispatchCycleANRLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07001420 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001421 LOGI("channel '%s' ~ Not responding! %01.1fms since event, %01.1fms since dispatch",
1422 connection->getInputChannelName(),
1423 connection->getEventLatencyMillis(currentTime),
1424 connection->getDispatchLatencyMillis(currentTime));
1425
Jeff Brown54bc2812010-06-15 01:31:58 -07001426 CommandEntry* commandEntry = postCommandLocked(
1427 & InputDispatcher::doNotifyInputChannelANRLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07001428 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07001429}
1430
Jeff Brown54bc2812010-06-15 01:31:58 -07001431void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown51d45a72010-06-17 20:52:56 -07001432 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001433 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
1434 connection->getInputChannelName());
1435
Jeff Brown54bc2812010-06-15 01:31:58 -07001436 CommandEntry* commandEntry = postCommandLocked(
1437 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown51d45a72010-06-17 20:52:56 -07001438 commandEntry->connection = connection;
Jeff Browne839a582010-04-22 18:58:52 -07001439}
1440
Jeff Brown54bc2812010-06-15 01:31:58 -07001441void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
1442 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001443 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07001444
Jeff Brown51d45a72010-06-17 20:52:56 -07001445 if (connection->status != Connection::STATUS_ZOMBIE) {
1446 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07001447
Jeff Brown51d45a72010-06-17 20:52:56 -07001448 mPolicy->notifyInputChannelBroken(connection->inputChannel);
1449
1450 mLock.lock();
1451 }
Jeff Brown54bc2812010-06-15 01:31:58 -07001452}
1453
1454void InputDispatcher::doNotifyInputChannelANRLockedInterruptible(
1455 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001456 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07001457
Jeff Brown51d45a72010-06-17 20:52:56 -07001458 if (connection->status != Connection::STATUS_ZOMBIE) {
1459 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07001460
Jeff Brown51d45a72010-06-17 20:52:56 -07001461 nsecs_t newTimeout;
1462 bool resume = mPolicy->notifyInputChannelANR(connection->inputChannel, newTimeout);
1463
1464 mLock.lock();
1465
1466 nsecs_t currentTime = now();
1467 if (resume) {
1468 resumeAfterTimeoutDispatchCycleLocked(currentTime, connection, newTimeout);
1469 } else {
1470 abortDispatchCycleLocked(currentTime, connection, false /*(not) broken*/);
1471 }
1472 }
Jeff Brown54bc2812010-06-15 01:31:58 -07001473}
1474
1475void InputDispatcher::doNotifyInputChannelRecoveredFromANRLockedInterruptible(
1476 CommandEntry* commandEntry) {
Jeff Brown51d45a72010-06-17 20:52:56 -07001477 sp<Connection> connection = commandEntry->connection;
Jeff Brown54bc2812010-06-15 01:31:58 -07001478
Jeff Brown51d45a72010-06-17 20:52:56 -07001479 if (connection->status != Connection::STATUS_ZOMBIE) {
1480 mLock.unlock();
Jeff Brown54bc2812010-06-15 01:31:58 -07001481
Jeff Brown51d45a72010-06-17 20:52:56 -07001482 mPolicy->notifyInputChannelRecoveredFromANR(connection->inputChannel);
1483
1484 mLock.lock();
1485 }
Jeff Brown54bc2812010-06-15 01:31:58 -07001486}
1487
1488
Jeff Browne839a582010-04-22 18:58:52 -07001489// --- InputDispatcher::Allocator ---
1490
1491InputDispatcher::Allocator::Allocator() {
1492}
1493
Jeff Brown51d45a72010-06-17 20:52:56 -07001494void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
1495 nsecs_t eventTime) {
1496 entry->type = type;
1497 entry->refCount = 1;
1498 entry->dispatchInProgress = false;
Christopher Tated974e002010-06-23 16:50:30 -07001499 entry->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07001500 entry->injectionResult = INPUT_EVENT_INJECTION_PENDING;
1501 entry->injectorPid = -1;
1502 entry->injectorUid = -1;
1503}
1504
Jeff Browne839a582010-04-22 18:58:52 -07001505InputDispatcher::ConfigurationChangedEntry*
Jeff Brown51d45a72010-06-17 20:52:56 -07001506InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -07001507 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown51d45a72010-06-17 20:52:56 -07001508 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime);
Jeff Browne839a582010-04-22 18:58:52 -07001509 return entry;
1510}
1511
Jeff Brown51d45a72010-06-17 20:52:56 -07001512InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07001513 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07001514 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
1515 int32_t repeatCount, nsecs_t downTime) {
Jeff Browne839a582010-04-22 18:58:52 -07001516 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown51d45a72010-06-17 20:52:56 -07001517 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime);
1518
1519 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07001520 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07001521 entry->policyFlags = policyFlags;
1522 entry->action = action;
1523 entry->flags = flags;
1524 entry->keyCode = keyCode;
1525 entry->scanCode = scanCode;
1526 entry->metaState = metaState;
1527 entry->repeatCount = repeatCount;
1528 entry->downTime = downTime;
Jeff Browne839a582010-04-22 18:58:52 -07001529 return entry;
1530}
1531
Jeff Brown51d45a72010-06-17 20:52:56 -07001532InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown5c1ed842010-07-14 18:48:53 -07001533 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown51d45a72010-06-17 20:52:56 -07001534 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
1535 nsecs_t downTime, uint32_t pointerCount,
1536 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07001537 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown51d45a72010-06-17 20:52:56 -07001538 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime);
1539
1540 entry->eventTime = eventTime;
1541 entry->deviceId = deviceId;
Jeff Brown5c1ed842010-07-14 18:48:53 -07001542 entry->source = source;
Jeff Brown51d45a72010-06-17 20:52:56 -07001543 entry->policyFlags = policyFlags;
1544 entry->action = action;
1545 entry->metaState = metaState;
1546 entry->edgeFlags = edgeFlags;
1547 entry->xPrecision = xPrecision;
1548 entry->yPrecision = yPrecision;
1549 entry->downTime = downTime;
1550 entry->pointerCount = pointerCount;
1551 entry->firstSample.eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -07001552 entry->firstSample.next = NULL;
Jeff Brown51d45a72010-06-17 20:52:56 -07001553 entry->lastSample = & entry->firstSample;
1554 for (uint32_t i = 0; i < pointerCount; i++) {
1555 entry->pointerIds[i] = pointerIds[i];
1556 entry->firstSample.pointerCoords[i] = pointerCoords[i];
1557 }
Jeff Browne839a582010-04-22 18:58:52 -07001558 return entry;
1559}
1560
1561InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
1562 EventEntry* eventEntry) {
1563 DispatchEntry* entry = mDispatchEntryPool.alloc();
1564 entry->eventEntry = eventEntry;
1565 eventEntry->refCount += 1;
1566 return entry;
1567}
1568
Jeff Brown54bc2812010-06-15 01:31:58 -07001569InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
1570 CommandEntry* entry = mCommandEntryPool.alloc();
1571 entry->command = command;
1572 return entry;
1573}
1574
Jeff Browne839a582010-04-22 18:58:52 -07001575void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
1576 switch (entry->type) {
1577 case EventEntry::TYPE_CONFIGURATION_CHANGED:
1578 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
1579 break;
1580 case EventEntry::TYPE_KEY:
1581 releaseKeyEntry(static_cast<KeyEntry*>(entry));
1582 break;
1583 case EventEntry::TYPE_MOTION:
1584 releaseMotionEntry(static_cast<MotionEntry*>(entry));
1585 break;
1586 default:
1587 assert(false);
1588 break;
1589 }
1590}
1591
1592void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
1593 ConfigurationChangedEntry* entry) {
1594 entry->refCount -= 1;
1595 if (entry->refCount == 0) {
1596 mConfigurationChangeEntryPool.free(entry);
1597 } else {
1598 assert(entry->refCount > 0);
1599 }
1600}
1601
1602void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
1603 entry->refCount -= 1;
1604 if (entry->refCount == 0) {
1605 mKeyEntryPool.free(entry);
1606 } else {
1607 assert(entry->refCount > 0);
1608 }
1609}
1610
1611void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
1612 entry->refCount -= 1;
1613 if (entry->refCount == 0) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001614 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
1615 MotionSample* next = sample->next;
1616 mMotionSamplePool.free(sample);
1617 sample = next;
1618 }
Jeff Browne839a582010-04-22 18:58:52 -07001619 mMotionEntryPool.free(entry);
1620 } else {
1621 assert(entry->refCount > 0);
1622 }
1623}
1624
1625void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
1626 releaseEventEntry(entry->eventEntry);
1627 mDispatchEntryPool.free(entry);
1628}
1629
Jeff Brown54bc2812010-06-15 01:31:58 -07001630void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
1631 mCommandEntryPool.free(entry);
1632}
1633
Jeff Browne839a582010-04-22 18:58:52 -07001634void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown51d45a72010-06-17 20:52:56 -07001635 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Browne839a582010-04-22 18:58:52 -07001636 MotionSample* sample = mMotionSamplePool.alloc();
1637 sample->eventTime = eventTime;
Jeff Brown51d45a72010-06-17 20:52:56 -07001638 uint32_t pointerCount = motionEntry->pointerCount;
1639 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Browne839a582010-04-22 18:58:52 -07001640 sample->pointerCoords[i] = pointerCoords[i];
1641 }
1642
1643 sample->next = NULL;
1644 motionEntry->lastSample->next = sample;
1645 motionEntry->lastSample = sample;
1646}
1647
Jeff Browne839a582010-04-22 18:58:52 -07001648// --- InputDispatcher::Connection ---
1649
1650InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
1651 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
1652 nextTimeoutTime(LONG_LONG_MAX),
1653 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX),
1654 lastANRTime(LONG_LONG_MAX) {
1655}
1656
1657InputDispatcher::Connection::~Connection() {
1658}
1659
1660status_t InputDispatcher::Connection::initialize() {
1661 return inputPublisher.initialize();
1662}
1663
Jeff Brown51d45a72010-06-17 20:52:56 -07001664void InputDispatcher::Connection::setNextTimeoutTime(nsecs_t currentTime, nsecs_t timeout) {
1665 nextTimeoutTime = (timeout >= 0) ? currentTime + timeout : LONG_LONG_MAX;
1666}
1667
Jeff Brown54bc2812010-06-15 01:31:58 -07001668const char* InputDispatcher::Connection::getStatusLabel() const {
1669 switch (status) {
1670 case STATUS_NORMAL:
1671 return "NORMAL";
1672
1673 case STATUS_BROKEN:
1674 return "BROKEN";
1675
1676 case STATUS_NOT_RESPONDING:
1677 return "NOT_RESPONDING";
1678
1679 case STATUS_ZOMBIE:
1680 return "ZOMBIE";
1681
1682 default:
1683 return "UNKNOWN";
1684 }
1685}
1686
Jeff Browne839a582010-04-22 18:58:52 -07001687InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
1688 const EventEntry* eventEntry) const {
1689 for (DispatchEntry* dispatchEntry = outboundQueue.tail.prev;
1690 dispatchEntry != & outboundQueue.head; dispatchEntry = dispatchEntry->prev) {
1691 if (dispatchEntry->eventEntry == eventEntry) {
1692 return dispatchEntry;
1693 }
1694 }
1695 return NULL;
1696}
1697
Jeff Brown54bc2812010-06-15 01:31:58 -07001698// --- InputDispatcher::CommandEntry ---
1699
1700InputDispatcher::CommandEntry::CommandEntry() {
1701}
1702
1703InputDispatcher::CommandEntry::~CommandEntry() {
1704}
1705
Jeff Browne839a582010-04-22 18:58:52 -07001706
1707// --- InputDispatcherThread ---
1708
1709InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
1710 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
1711}
1712
1713InputDispatcherThread::~InputDispatcherThread() {
1714}
1715
1716bool InputDispatcherThread::threadLoop() {
1717 mDispatcher->dispatchOnce();
1718 return true;
1719}
1720
1721} // namespace android