blob: f058271bda13cd3a5c7fdd29e61905a1963c9dcf [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.
11#define DEBUG_INBOUND_EVENT_DETAILS 1
12
13// Log detailed debug messages about each outbound event processed by the dispatcher.
14#define DEBUG_OUTBOUND_EVENT_DETAILS 1
15
16// Log debug messages about batching.
17#define DEBUG_BATCHING 1
18
19// Log debug messages about the dispatch cycle.
20#define DEBUG_DISPATCH_CYCLE 1
21
Jeff Brown54bc2812010-06-15 01:31:58 -070022// Log debug messages about registrations.
23#define DEBUG_REGISTRATION 1
24
Jeff Browne839a582010-04-22 18:58:52 -070025// Log debug messages about performance statistics.
26#define DEBUG_PERFORMANCE_STATISTICS 1
27
28#include <cutils/log.h>
29#include <ui/InputDispatcher.h>
30
31#include <stddef.h>
32#include <unistd.h>
Jeff Browne839a582010-04-22 18:58:52 -070033#include <errno.h>
34#include <limits.h>
Jeff Browne839a582010-04-22 18:58:52 -070035
36namespace android {
37
38// TODO, this needs to be somewhere else, perhaps in the policy
39static inline bool isMovementKey(int32_t keyCode) {
40 return keyCode == KEYCODE_DPAD_UP
41 || keyCode == KEYCODE_DPAD_DOWN
42 || keyCode == KEYCODE_DPAD_LEFT
43 || keyCode == KEYCODE_DPAD_RIGHT;
44}
45
46// --- InputDispatcher ---
47
Jeff Brown54bc2812010-06-15 01:31:58 -070048InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Browne839a582010-04-22 18:58:52 -070049 mPolicy(policy) {
50 mPollLoop = new PollLoop();
51
52 mInboundQueue.head.refCount = -1;
53 mInboundQueue.head.type = EventEntry::TYPE_SENTINEL;
54 mInboundQueue.head.eventTime = LONG_LONG_MIN;
55
56 mInboundQueue.tail.refCount = -1;
57 mInboundQueue.tail.type = EventEntry::TYPE_SENTINEL;
58 mInboundQueue.tail.eventTime = LONG_LONG_MAX;
59
60 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -070061
62 mCurrentInputTargetsValid = false;
Jeff Browne839a582010-04-22 18:58:52 -070063}
64
65InputDispatcher::~InputDispatcher() {
66 resetKeyRepeatLocked();
67
68 while (mConnectionsByReceiveFd.size() != 0) {
69 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
70 }
71
72 for (EventEntry* entry = mInboundQueue.head.next; entry != & mInboundQueue.tail; ) {
73 EventEntry* next = entry->next;
74 mAllocator.releaseEventEntry(next);
75 entry = next;
76 }
77}
78
79void InputDispatcher::dispatchOnce() {
Jeff Brown54bc2812010-06-15 01:31:58 -070080 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Browne839a582010-04-22 18:58:52 -070081
Jeff Brown54bc2812010-06-15 01:31:58 -070082 bool skipPoll = false;
Jeff Browne839a582010-04-22 18:58:52 -070083 nsecs_t currentTime;
84 nsecs_t nextWakeupTime = LONG_LONG_MAX;
85 { // acquire lock
86 AutoMutex _l(mLock);
87 currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
88
89 // Reset the key repeat timer whenever we disallow key events, even if the next event
90 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
91 // out of sleep.
92 // XXX we should handle resetting input state coming out of sleep more generally elsewhere
Jeff Brown54bc2812010-06-15 01:31:58 -070093 if (keyRepeatTimeout < 0) {
Jeff Browne839a582010-04-22 18:58:52 -070094 resetKeyRepeatLocked();
95 }
96
97 // Process timeouts for all connections and determine if there are any synchronous
98 // event dispatches pending.
99 bool hasPendingSyncTarget = false;
100 for (size_t i = 0; i < mActiveConnections.size(); ) {
101 Connection* connection = mActiveConnections.itemAt(i);
102
103 nsecs_t connectionTimeoutTime = connection->nextTimeoutTime;
104 if (connectionTimeoutTime <= currentTime) {
105 bool deactivated = timeoutDispatchCycleLocked(currentTime, connection);
106 if (deactivated) {
107 // Don't increment i because the connection has been removed
108 // from mActiveConnections (hence, deactivated).
109 continue;
110 }
111 }
112
113 if (connectionTimeoutTime < nextWakeupTime) {
114 nextWakeupTime = connectionTimeoutTime;
115 }
116
117 if (connection->hasPendingSyncTarget()) {
118 hasPendingSyncTarget = true;
119 }
120
121 i += 1;
122 }
123
124 // If we don't have a pending sync target, then we can begin delivering a new event.
125 // (Otherwise we wait for dispatch to complete for that target.)
126 if (! hasPendingSyncTarget) {
127 if (mInboundQueue.isEmpty()) {
128 if (mKeyRepeatState.lastKeyEntry) {
129 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
Jeff Brown54bc2812010-06-15 01:31:58 -0700130 processKeyRepeatLockedInterruptible(currentTime, keyRepeatTimeout);
131 skipPoll = true;
Jeff Browne839a582010-04-22 18:58:52 -0700132 } else {
133 if (mKeyRepeatState.nextRepeatTime < nextWakeupTime) {
134 nextWakeupTime = mKeyRepeatState.nextRepeatTime;
135 }
136 }
137 }
138 } else {
Jeff Brown54bc2812010-06-15 01:31:58 -0700139 // Inbound queue has at least one entry.
140 // Start processing it but leave it on the queue until later so that the
141 // input reader can keep appending samples onto a motion event between the
142 // time we started processing it and the time we finally enqueue dispatch
143 // entries for it.
144 EventEntry* entry = mInboundQueue.head.next;
Jeff Browne839a582010-04-22 18:58:52 -0700145
146 switch (entry->type) {
147 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
148 ConfigurationChangedEntry* typedEntry =
149 static_cast<ConfigurationChangedEntry*>(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700150 processConfigurationChangedLockedInterruptible(currentTime, typedEntry);
Jeff Browne839a582010-04-22 18:58:52 -0700151 break;
152 }
153
154 case EventEntry::TYPE_KEY: {
155 KeyEntry* typedEntry = static_cast<KeyEntry*>(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700156 processKeyLockedInterruptible(currentTime, typedEntry, keyRepeatTimeout);
Jeff Browne839a582010-04-22 18:58:52 -0700157 break;
158 }
159
160 case EventEntry::TYPE_MOTION: {
161 MotionEntry* typedEntry = static_cast<MotionEntry*>(entry);
Jeff Brown54bc2812010-06-15 01:31:58 -0700162 processMotionLockedInterruptible(currentTime, typedEntry);
Jeff Browne839a582010-04-22 18:58:52 -0700163 break;
164 }
165
166 default:
167 assert(false);
168 break;
169 }
Jeff Brown54bc2812010-06-15 01:31:58 -0700170
171 // Dequeue and release the event entry that we just processed.
172 mInboundQueue.dequeue(entry);
173 mAllocator.releaseEventEntry(entry);
174 skipPoll = true;
Jeff Browne839a582010-04-22 18:58:52 -0700175 }
176 }
Jeff Brown54bc2812010-06-15 01:31:58 -0700177
178 // Run any deferred commands.
179 skipPoll |= runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -0700180 } // release lock
181
Jeff Brown54bc2812010-06-15 01:31:58 -0700182 // If we dispatched anything, don't poll just now. Wait for the next iteration.
183 // Contents may have shifted during flight.
184 if (skipPoll) {
185 return;
186 }
187
Jeff Browne839a582010-04-22 18:58:52 -0700188 // Wait for callback or timeout or wake.
189 nsecs_t timeout = nanoseconds_to_milliseconds(nextWakeupTime - currentTime);
190 int32_t timeoutMillis = timeout > INT_MAX ? -1 : timeout > 0 ? int32_t(timeout) : 0;
191 mPollLoop->pollOnce(timeoutMillis);
192}
193
Jeff Brown54bc2812010-06-15 01:31:58 -0700194bool InputDispatcher::runCommandsLockedInterruptible() {
195 if (mCommandQueue.isEmpty()) {
196 return false;
197 }
Jeff Browne839a582010-04-22 18:58:52 -0700198
Jeff Brown54bc2812010-06-15 01:31:58 -0700199 do {
200 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
201
202 Command command = commandEntry->command;
203 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
204
205 mAllocator.releaseCommandEntry(commandEntry);
206 } while (! mCommandQueue.isEmpty());
207 return true;
Jeff Browne839a582010-04-22 18:58:52 -0700208}
209
Jeff Brown54bc2812010-06-15 01:31:58 -0700210InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
211 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
212 mCommandQueue.enqueueAtTail(commandEntry);
213 return commandEntry;
214}
215
216void InputDispatcher::processConfigurationChangedLockedInterruptible(
217 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
218#if DEBUG_OUTBOUND_EVENT_DETAILS
219 LOGD("processConfigurationChanged - eventTime=%lld", entry->eventTime);
220#endif
221
222 mLock.unlock();
223
224 mPolicy->notifyConfigurationChanged(entry->eventTime);
225
226 mLock.lock();
227}
228
229void InputDispatcher::processKeyLockedInterruptible(
230 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout) {
Jeff Browne839a582010-04-22 18:58:52 -0700231#if DEBUG_OUTBOUND_EVENT_DETAILS
232 LOGD("processKey - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, action=0x%x, "
233 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
234 entry->eventTime, entry->deviceId, entry->nature, entry->policyFlags, entry->action,
235 entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
236 entry->downTime);
237#endif
238
239 // TODO: Poke user activity.
240
241 if (entry->action == KEY_EVENT_ACTION_DOWN) {
242 if (mKeyRepeatState.lastKeyEntry
243 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
244 // We have seen two identical key downs in a row which indicates that the device
245 // driver is automatically generating key repeats itself. We take note of the
246 // repeat here, but we disable our own next key repeat timer since it is clear that
247 // we will not need to synthesize key repeats ourselves.
248 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
249 resetKeyRepeatLocked();
250 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
251 } else {
252 // Not a repeat. Save key down state in case we do see a repeat later.
253 resetKeyRepeatLocked();
Jeff Brown54bc2812010-06-15 01:31:58 -0700254 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
Jeff Browne839a582010-04-22 18:58:52 -0700255 }
256 mKeyRepeatState.lastKeyEntry = entry;
257 entry->refCount += 1;
258 } else {
259 resetKeyRepeatLocked();
260 }
261
Jeff Brown54bc2812010-06-15 01:31:58 -0700262 identifyInputTargetsAndDispatchKeyLockedInterruptible(currentTime, entry);
Jeff Browne839a582010-04-22 18:58:52 -0700263}
264
Jeff Brown54bc2812010-06-15 01:31:58 -0700265void InputDispatcher::processKeyRepeatLockedInterruptible(
266 nsecs_t currentTime, nsecs_t keyRepeatTimeout) {
Jeff Browne839a582010-04-22 18:58:52 -0700267 // TODO Old WindowManagerServer code sniffs the input queue for following key up
268 // events and drops the repeat if one is found. We should do something similar.
269 // One good place to do it is in notifyKey as soon as the key up enters the
270 // inbound event queue.
271
272 // Synthesize a key repeat after the repeat timeout expired.
273 // We reuse the previous key entry if otherwise unreferenced.
274 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
275 if (entry->refCount == 1) {
276 entry->repeatCount += 1;
277 } else {
278 KeyEntry* newEntry = mAllocator.obtainKeyEntry();
279 newEntry->deviceId = entry->deviceId;
280 newEntry->nature = entry->nature;
281 newEntry->policyFlags = entry->policyFlags;
282 newEntry->action = entry->action;
283 newEntry->flags = entry->flags;
284 newEntry->keyCode = entry->keyCode;
285 newEntry->scanCode = entry->scanCode;
286 newEntry->metaState = entry->metaState;
287 newEntry->repeatCount = entry->repeatCount + 1;
288
289 mKeyRepeatState.lastKeyEntry = newEntry;
290 mAllocator.releaseKeyEntry(entry);
291
292 entry = newEntry;
293 }
294 entry->eventTime = currentTime;
295 entry->downTime = currentTime;
296 entry->policyFlags = 0;
297
Jeff Brown54bc2812010-06-15 01:31:58 -0700298 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatTimeout;
Jeff Browne839a582010-04-22 18:58:52 -0700299
300#if DEBUG_OUTBOUND_EVENT_DETAILS
301 LOGD("processKeyRepeat - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, "
302 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
303 "repeatCount=%d, downTime=%lld",
304 entry->eventTime, entry->deviceId, entry->nature, entry->policyFlags,
305 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
306 entry->repeatCount, entry->downTime);
307#endif
308
Jeff Brown54bc2812010-06-15 01:31:58 -0700309 identifyInputTargetsAndDispatchKeyLockedInterruptible(currentTime, entry);
Jeff Browne839a582010-04-22 18:58:52 -0700310}
311
Jeff Brown54bc2812010-06-15 01:31:58 -0700312void InputDispatcher::processMotionLockedInterruptible(
313 nsecs_t currentTime, MotionEntry* entry) {
Jeff Browne839a582010-04-22 18:58:52 -0700314#if DEBUG_OUTBOUND_EVENT_DETAILS
315 LOGD("processMotion - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, action=0x%x, "
316 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
317 entry->eventTime, entry->deviceId, entry->nature, entry->policyFlags, entry->action,
318 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
319 entry->downTime);
320
321 // Print the most recent sample that we have available, this may change due to batching.
322 size_t sampleCount = 1;
323 MotionSample* sample = & entry->firstSample;
324 for (; sample->next != NULL; sample = sample->next) {
325 sampleCount += 1;
326 }
327 for (uint32_t i = 0; i < entry->pointerCount; i++) {
328 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
329 i, entry->pointerIds[i],
330 sample->pointerCoords[i].x,
331 sample->pointerCoords[i].y,
332 sample->pointerCoords[i].pressure,
333 sample->pointerCoords[i].size);
334 }
335
336 // Keep in mind that due to batching, it is possible for the number of samples actually
337 // dispatched to change before the application finally consumed them.
338 if (entry->action == MOTION_EVENT_ACTION_MOVE) {
339 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
340 }
341#endif
342
Jeff Brown54bc2812010-06-15 01:31:58 -0700343 identifyInputTargetsAndDispatchMotionLockedInterruptible(currentTime, entry);
Jeff Browne839a582010-04-22 18:58:52 -0700344}
345
Jeff Brown54bc2812010-06-15 01:31:58 -0700346void InputDispatcher::identifyInputTargetsAndDispatchKeyLockedInterruptible(
Jeff Browne839a582010-04-22 18:58:52 -0700347 nsecs_t currentTime, KeyEntry* entry) {
348#if DEBUG_DISPATCH_CYCLE
349 LOGD("identifyInputTargetsAndDispatchKey");
350#endif
351
Jeff Brown54bc2812010-06-15 01:31:58 -0700352 entry->dispatchInProgress = true;
353 mCurrentInputTargetsValid = false;
354 mLock.unlock();
355
Jeff Browne839a582010-04-22 18:58:52 -0700356 mReusableKeyEvent.initialize(entry->deviceId, entry->nature, entry->action, entry->flags,
357 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
358 entry->downTime, entry->eventTime);
359
360 mCurrentInputTargets.clear();
361 mPolicy->getKeyEventTargets(& mReusableKeyEvent, entry->policyFlags,
362 mCurrentInputTargets);
363
Jeff Brown54bc2812010-06-15 01:31:58 -0700364 mLock.lock();
365 mCurrentInputTargetsValid = true;
366
Jeff Browne839a582010-04-22 18:58:52 -0700367 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
368}
369
Jeff Brown54bc2812010-06-15 01:31:58 -0700370void InputDispatcher::identifyInputTargetsAndDispatchMotionLockedInterruptible(
Jeff Browne839a582010-04-22 18:58:52 -0700371 nsecs_t currentTime, MotionEntry* entry) {
372#if DEBUG_DISPATCH_CYCLE
373 LOGD("identifyInputTargetsAndDispatchMotion");
374#endif
375
Jeff Brown54bc2812010-06-15 01:31:58 -0700376 entry->dispatchInProgress = true;
377 mCurrentInputTargetsValid = false;
378 mLock.unlock();
379
Jeff Browne839a582010-04-22 18:58:52 -0700380 mReusableMotionEvent.initialize(entry->deviceId, entry->nature, entry->action,
381 entry->edgeFlags, entry->metaState,
382 entry->firstSample.pointerCoords[0].x, entry->firstSample.pointerCoords[0].y,
383 entry->xPrecision, entry->yPrecision,
384 entry->downTime, entry->eventTime, entry->pointerCount, entry->pointerIds,
385 entry->firstSample.pointerCoords);
386
387 mCurrentInputTargets.clear();
388 mPolicy->getMotionEventTargets(& mReusableMotionEvent, entry->policyFlags,
389 mCurrentInputTargets);
390
Jeff Brown54bc2812010-06-15 01:31:58 -0700391 mLock.lock();
392 mCurrentInputTargetsValid = true;
393
Jeff Browne839a582010-04-22 18:58:52 -0700394 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
395}
396
397void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
398 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
399#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700400 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700401 "resumeWithAppendedMotionSample=%s",
402 resumeWithAppendedMotionSample ? "true" : "false");
403#endif
404
Jeff Brown54bc2812010-06-15 01:31:58 -0700405 assert(eventEntry->dispatchInProgress); // should already have been set to true
406
Jeff Browne839a582010-04-22 18:58:52 -0700407 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
408 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
409
410 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(
411 inputTarget.inputChannel->getReceivePipeFd());
412 if (connectionIndex >= 0) {
413 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
414 prepareDispatchCycleLocked(currentTime, connection.get(), eventEntry, & inputTarget,
415 resumeWithAppendedMotionSample);
416 } else {
417 LOGW("Framework requested delivery of an input event to channel '%s' but it "
418 "is not registered with the input dispatcher.",
419 inputTarget.inputChannel->getName().string());
420 }
421 }
422}
423
424void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime, Connection* connection,
425 EventEntry* eventEntry, const InputTarget* inputTarget,
426 bool resumeWithAppendedMotionSample) {
427#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700428 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, timeout=%lldns, "
Jeff Browne839a582010-04-22 18:58:52 -0700429 "xOffset=%f, yOffset=%f, resumeWithAppendedMotionSample=%s",
430 connection->getInputChannelName(), inputTarget->flags, inputTarget->timeout,
431 inputTarget->xOffset, inputTarget->yOffset,
432 resumeWithAppendedMotionSample ? "true" : "false");
433#endif
434
435 // Skip this event if the connection status is not normal.
436 // We don't want to queue outbound events at all if the connection is broken or
437 // not responding.
438 if (connection->status != Connection::STATUS_NORMAL) {
439 LOGV("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brown54bc2812010-06-15 01:31:58 -0700440 connection->getStatusLabel());
Jeff Browne839a582010-04-22 18:58:52 -0700441 return;
442 }
443
444 // Resume the dispatch cycle with a freshly appended motion sample.
445 // First we check that the last dispatch entry in the outbound queue is for the same
446 // motion event to which we appended the motion sample. If we find such a dispatch
447 // entry, and if it is currently in progress then we try to stream the new sample.
448 bool wasEmpty = connection->outboundQueue.isEmpty();
449
450 if (! wasEmpty && resumeWithAppendedMotionSample) {
451 DispatchEntry* motionEventDispatchEntry =
452 connection->findQueuedDispatchEntryForEvent(eventEntry);
453 if (motionEventDispatchEntry) {
454 // If the dispatch entry is not in progress, then we must be busy dispatching an
455 // earlier event. Not a problem, the motion event is on the outbound queue and will
456 // be dispatched later.
457 if (! motionEventDispatchEntry->inProgress) {
458#if DEBUG_BATCHING
459 LOGD("channel '%s' ~ Not streaming because the motion event has "
460 "not yet been dispatched. "
461 "(Waiting for earlier events to be consumed.)",
462 connection->getInputChannelName());
463#endif
464 return;
465 }
466
467 // If the dispatch entry is in progress but it already has a tail of pending
468 // motion samples, then it must mean that the shared memory buffer filled up.
469 // Not a problem, when this dispatch cycle is finished, we will eventually start
470 // a new dispatch cycle to process the tail and that tail includes the newly
471 // appended motion sample.
472 if (motionEventDispatchEntry->tailMotionSample) {
473#if DEBUG_BATCHING
474 LOGD("channel '%s' ~ Not streaming because no new samples can "
475 "be appended to the motion event in this dispatch cycle. "
476 "(Waiting for next dispatch cycle to start.)",
477 connection->getInputChannelName());
478#endif
479 return;
480 }
481
482 // The dispatch entry is in progress and is still potentially open for streaming.
483 // Try to stream the new motion sample. This might fail if the consumer has already
484 // consumed the motion event (or if the channel is broken).
485 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
486 status_t status = connection->inputPublisher.appendMotionSample(
487 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
488 if (status == OK) {
489#if DEBUG_BATCHING
490 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
491 connection->getInputChannelName());
492#endif
493 return;
494 }
495
496#if DEBUG_BATCHING
497 if (status == NO_MEMORY) {
498 LOGD("channel '%s' ~ Could not append motion sample to currently "
499 "dispatched move event because the shared memory buffer is full. "
500 "(Waiting for next dispatch cycle to start.)",
501 connection->getInputChannelName());
502 } else if (status == status_t(FAILED_TRANSACTION)) {
503 LOGD("channel '%s' ~ Could not append motion sample to currently "
504 "dispatchedmove event because the event has already been consumed. "
505 "(Waiting for next dispatch cycle to start.)",
506 connection->getInputChannelName());
507 } else {
508 LOGD("channel '%s' ~ Could not append motion sample to currently "
509 "dispatched move event due to an error, status=%d. "
510 "(Waiting for next dispatch cycle to start.)",
511 connection->getInputChannelName(), status);
512 }
513#endif
514 // Failed to stream. Start a new tail of pending motion samples to dispatch
515 // in the next cycle.
516 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
517 return;
518 }
519 }
520
521 // This is a new event.
522 // Enqueue a new dispatch entry onto the outbound queue for this connection.
523 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry); // increments ref
524 dispatchEntry->targetFlags = inputTarget->flags;
525 dispatchEntry->xOffset = inputTarget->xOffset;
526 dispatchEntry->yOffset = inputTarget->yOffset;
527 dispatchEntry->timeout = inputTarget->timeout;
528 dispatchEntry->inProgress = false;
529 dispatchEntry->headMotionSample = NULL;
530 dispatchEntry->tailMotionSample = NULL;
531
532 // Handle the case where we could not stream a new motion sample because the consumer has
533 // already consumed the motion event (otherwise the corresponding dispatch entry would
534 // still be in the outbound queue for this connection). We set the head motion sample
535 // to the list starting with the newly appended motion sample.
536 if (resumeWithAppendedMotionSample) {
537#if DEBUG_BATCHING
538 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
539 "that cannot be streamed because the motion event has already been consumed.",
540 connection->getInputChannelName());
541#endif
542 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
543 dispatchEntry->headMotionSample = appendedMotionSample;
544 }
545
546 // Enqueue the dispatch entry.
547 connection->outboundQueue.enqueueAtTail(dispatchEntry);
548
549 // If the outbound queue was previously empty, start the dispatch cycle going.
550 if (wasEmpty) {
551 activateConnectionLocked(connection);
552 startDispatchCycleLocked(currentTime, connection);
553 }
554}
555
556void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, Connection* connection) {
557#if DEBUG_DISPATCH_CYCLE
558 LOGD("channel '%s' ~ startDispatchCycle",
559 connection->getInputChannelName());
560#endif
561
562 assert(connection->status == Connection::STATUS_NORMAL);
563 assert(! connection->outboundQueue.isEmpty());
564
565 DispatchEntry* dispatchEntry = connection->outboundQueue.head.next;
566 assert(! dispatchEntry->inProgress);
567
568 // TODO throttle successive ACTION_MOVE motion events for the same device
569 // possible implementation could set a brief poll timeout here and resume starting the
570 // dispatch cycle when elapsed
571
572 // Publish the event.
573 status_t status;
574 switch (dispatchEntry->eventEntry->type) {
575 case EventEntry::TYPE_KEY: {
576 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
577
578 // Apply target flags.
579 int32_t action = keyEntry->action;
580 int32_t flags = keyEntry->flags;
581 if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
582 flags |= KEY_EVENT_FLAG_CANCELED;
583 }
584
585 // Publish the key event.
586 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->nature,
587 action, flags, keyEntry->keyCode, keyEntry->scanCode,
588 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
589 keyEntry->eventTime);
590
591 if (status) {
592 LOGE("channel '%s' ~ Could not publish key event, "
593 "status=%d", connection->getInputChannelName(), status);
594 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
595 return;
596 }
597 break;
598 }
599
600 case EventEntry::TYPE_MOTION: {
601 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
602
603 // Apply target flags.
604 int32_t action = motionEntry->action;
605 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
606 action = MOTION_EVENT_ACTION_OUTSIDE;
607 }
608 if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
609 action = MOTION_EVENT_ACTION_CANCEL;
610 }
611
612 // If headMotionSample is non-NULL, then it points to the first new sample that we
613 // were unable to dispatch during the previous cycle so we resume dispatching from
614 // that point in the list of motion samples.
615 // Otherwise, we just start from the first sample of the motion event.
616 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
617 if (! firstMotionSample) {
618 firstMotionSample = & motionEntry->firstSample;
619 }
620
621 // Publish the motion event and the first motion sample.
622 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
623 motionEntry->nature, action, motionEntry->edgeFlags, motionEntry->metaState,
624 dispatchEntry->xOffset, dispatchEntry->yOffset,
625 motionEntry->xPrecision, motionEntry->yPrecision,
626 motionEntry->downTime, firstMotionSample->eventTime,
627 motionEntry->pointerCount, motionEntry->pointerIds,
628 firstMotionSample->pointerCoords);
629
630 if (status) {
631 LOGE("channel '%s' ~ Could not publish motion event, "
632 "status=%d", connection->getInputChannelName(), status);
633 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
634 return;
635 }
636
637 // Append additional motion samples.
638 MotionSample* nextMotionSample = firstMotionSample->next;
639 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
640 status = connection->inputPublisher.appendMotionSample(
641 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
642 if (status == NO_MEMORY) {
643#if DEBUG_DISPATCH_CYCLE
644 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
645 "be sent in the next dispatch cycle.",
646 connection->getInputChannelName());
647#endif
648 break;
649 }
650 if (status != OK) {
651 LOGE("channel '%s' ~ Could not append motion sample "
652 "for a reason other than out of memory, status=%d",
653 connection->getInputChannelName(), status);
654 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
655 return;
656 }
657 }
658
659 // Remember the next motion sample that we could not dispatch, in case we ran out
660 // of space in the shared memory buffer.
661 dispatchEntry->tailMotionSample = nextMotionSample;
662 break;
663 }
664
665 default: {
666 assert(false);
667 }
668 }
669
670 // Send the dispatch signal.
671 status = connection->inputPublisher.sendDispatchSignal();
672 if (status) {
673 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
674 connection->getInputChannelName(), status);
675 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
676 return;
677 }
678
679 // Record information about the newly started dispatch cycle.
680 dispatchEntry->inProgress = true;
681
682 connection->lastEventTime = dispatchEntry->eventEntry->eventTime;
683 connection->lastDispatchTime = currentTime;
684
685 nsecs_t timeout = dispatchEntry->timeout;
686 connection->nextTimeoutTime = (timeout >= 0) ? currentTime + timeout : LONG_LONG_MAX;
687
688 // Notify other system components.
689 onDispatchCycleStartedLocked(currentTime, connection);
690}
691
692void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, Connection* connection) {
693#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700694 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -0700695 "%01.1fms since dispatch",
696 connection->getInputChannelName(),
697 connection->getEventLatencyMillis(currentTime),
698 connection->getDispatchLatencyMillis(currentTime));
699#endif
700
Jeff Brown54bc2812010-06-15 01:31:58 -0700701 if (connection->status == Connection::STATUS_BROKEN
702 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -0700703 return;
704 }
705
706 // Clear the pending timeout.
707 connection->nextTimeoutTime = LONG_LONG_MAX;
708
709 if (connection->status == Connection::STATUS_NOT_RESPONDING) {
710 // Recovering from an ANR.
711 connection->status = Connection::STATUS_NORMAL;
712
713 // Notify other system components.
714 onDispatchCycleFinishedLocked(currentTime, connection, true /*recoveredFromANR*/);
715 } else {
716 // Normal finish. Not much to do here.
717
718 // Notify other system components.
719 onDispatchCycleFinishedLocked(currentTime, connection, false /*recoveredFromANR*/);
720 }
721
722 // Reset the publisher since the event has been consumed.
723 // We do this now so that the publisher can release some of its internal resources
724 // while waiting for the next dispatch cycle to begin.
725 status_t status = connection->inputPublisher.reset();
726 if (status) {
727 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
728 connection->getInputChannelName(), status);
729 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
730 return;
731 }
732
733 // Start the next dispatch cycle for this connection.
734 while (! connection->outboundQueue.isEmpty()) {
735 DispatchEntry* dispatchEntry = connection->outboundQueue.head.next;
736 if (dispatchEntry->inProgress) {
737 // Finish or resume current event in progress.
738 if (dispatchEntry->tailMotionSample) {
739 // We have a tail of undispatched motion samples.
740 // Reuse the same DispatchEntry and start a new cycle.
741 dispatchEntry->inProgress = false;
742 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
743 dispatchEntry->tailMotionSample = NULL;
744 startDispatchCycleLocked(currentTime, connection);
745 return;
746 }
747 // Finished.
748 connection->outboundQueue.dequeueAtHead();
749 mAllocator.releaseDispatchEntry(dispatchEntry);
750 } else {
751 // If the head is not in progress, then we must have already dequeued the in
752 // progress event, which means we actually aborted it (due to ANR).
753 // So just start the next event for this connection.
754 startDispatchCycleLocked(currentTime, connection);
755 return;
756 }
757 }
758
759 // Outbound queue is empty, deactivate the connection.
760 deactivateConnectionLocked(connection);
761}
762
763bool InputDispatcher::timeoutDispatchCycleLocked(nsecs_t currentTime, Connection* connection) {
764#if DEBUG_DISPATCH_CYCLE
765 LOGD("channel '%s' ~ timeoutDispatchCycle",
766 connection->getInputChannelName());
767#endif
768
769 if (connection->status != Connection::STATUS_NORMAL) {
770 return false;
771 }
772
773 // Enter the not responding state.
774 connection->status = Connection::STATUS_NOT_RESPONDING;
775 connection->lastANRTime = currentTime;
776 bool deactivated = abortDispatchCycleLocked(currentTime, connection, false /*(not) broken*/);
777
778 // Notify other system components.
779 onDispatchCycleANRLocked(currentTime, connection);
780 return deactivated;
781}
782
783bool InputDispatcher::abortDispatchCycleLocked(nsecs_t currentTime, Connection* connection,
784 bool broken) {
785#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700786 LOGD("channel '%s' ~ abortDispatchCycle - broken=%s",
Jeff Browne839a582010-04-22 18:58:52 -0700787 connection->getInputChannelName(), broken ? "true" : "false");
788#endif
789
Jeff Browne839a582010-04-22 18:58:52 -0700790 // Clear the pending timeout.
791 connection->nextTimeoutTime = LONG_LONG_MAX;
792
793 // Clear the outbound queue.
Jeff Brown54bc2812010-06-15 01:31:58 -0700794 bool deactivated = ! connection->outboundQueue.isEmpty();
795 if (deactivated) {
796 do {
797 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
798 mAllocator.releaseDispatchEntry(dispatchEntry);
799 } while (! connection->outboundQueue.isEmpty());
Jeff Browne839a582010-04-22 18:58:52 -0700800
Jeff Brown54bc2812010-06-15 01:31:58 -0700801 deactivateConnectionLocked(connection);
802 }
Jeff Browne839a582010-04-22 18:58:52 -0700803
804 // Handle the case where the connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -0700805 // Ignore already broken or zombie connections.
Jeff Browne839a582010-04-22 18:58:52 -0700806 if (broken) {
Jeff Brown54bc2812010-06-15 01:31:58 -0700807 if (connection->status == Connection::STATUS_NORMAL
808 || connection->status == Connection::STATUS_NOT_RESPONDING) {
809 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -0700810
Jeff Brown54bc2812010-06-15 01:31:58 -0700811 // Notify other system components.
812 onDispatchCycleBrokenLocked(currentTime, connection);
813 }
Jeff Browne839a582010-04-22 18:58:52 -0700814 }
Jeff Brown54bc2812010-06-15 01:31:58 -0700815
816 return deactivated;
Jeff Browne839a582010-04-22 18:58:52 -0700817}
818
819bool InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
820 InputDispatcher* d = static_cast<InputDispatcher*>(data);
821
822 { // acquire lock
823 AutoMutex _l(d->mLock);
824
825 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
826 if (connectionIndex < 0) {
827 LOGE("Received spurious receive callback for unknown input channel. "
828 "fd=%d, events=0x%x", receiveFd, events);
829 return false; // remove the callback
830 }
831
832 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
833
834 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
835 if (events & (POLLERR | POLLHUP | POLLNVAL)) {
836 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
837 "events=0x%x", connection->getInputChannelName(), events);
838 d->abortDispatchCycleLocked(currentTime, connection.get(), true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -0700839 d->runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -0700840 return false; // remove the callback
841 }
842
843 if (! (events & POLLIN)) {
844 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
845 "events=0x%x", connection->getInputChannelName(), events);
846 return true;
847 }
848
849 status_t status = connection->inputPublisher.receiveFinishedSignal();
850 if (status) {
851 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
852 connection->getInputChannelName(), status);
853 d->abortDispatchCycleLocked(currentTime, connection.get(), true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -0700854 d->runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -0700855 return false; // remove the callback
856 }
857
858 d->finishDispatchCycleLocked(currentTime, connection.get());
Jeff Brown54bc2812010-06-15 01:31:58 -0700859 d->runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -0700860 return true;
861 } // release lock
862}
863
Jeff Brown54bc2812010-06-15 01:31:58 -0700864void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -0700865#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -0700866 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700867#endif
868
869 bool wasEmpty;
870 { // acquire lock
871 AutoMutex _l(mLock);
872
873 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry();
874 newEntry->eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -0700875
876 wasEmpty = mInboundQueue.isEmpty();
877 mInboundQueue.enqueueAtTail(newEntry);
878 } // release lock
879
880 if (wasEmpty) {
881 mPollLoop->wake();
882 }
883}
884
Jeff Browne839a582010-04-22 18:58:52 -0700885void InputDispatcher::notifyAppSwitchComing(nsecs_t eventTime) {
886#if DEBUG_INBOUND_EVENT_DETAILS
887 LOGD("notifyAppSwitchComing - eventTime=%lld", eventTime);
888#endif
889
890 // Remove movement keys from the queue from most recent to least recent, stopping at the
891 // first non-movement key.
892 // TODO: Include a detailed description of why we do this...
893
894 { // acquire lock
895 AutoMutex _l(mLock);
896
897 for (EventEntry* entry = mInboundQueue.tail.prev; entry != & mInboundQueue.head; ) {
898 EventEntry* prev = entry->prev;
899
900 if (entry->type == EventEntry::TYPE_KEY) {
901 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
902 if (isMovementKey(keyEntry->keyCode)) {
903 LOGV("Dropping movement key during app switch: keyCode=%d, action=%d",
904 keyEntry->keyCode, keyEntry->action);
905 mInboundQueue.dequeue(keyEntry);
906 mAllocator.releaseKeyEntry(keyEntry);
907 } else {
908 // stop at last non-movement key
909 break;
910 }
911 }
912
913 entry = prev;
914 }
915 } // release lock
916}
917
918void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nature,
919 uint32_t policyFlags, int32_t action, int32_t flags,
920 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
921#if DEBUG_INBOUND_EVENT_DETAILS
922 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, action=0x%x, "
923 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
924 eventTime, deviceId, nature, policyFlags, action, flags,
925 keyCode, scanCode, metaState, downTime);
926#endif
927
928 bool wasEmpty;
929 { // acquire lock
930 AutoMutex _l(mLock);
931
932 KeyEntry* newEntry = mAllocator.obtainKeyEntry();
933 newEntry->eventTime = eventTime;
934 newEntry->deviceId = deviceId;
935 newEntry->nature = nature;
936 newEntry->policyFlags = policyFlags;
937 newEntry->action = action;
938 newEntry->flags = flags;
939 newEntry->keyCode = keyCode;
940 newEntry->scanCode = scanCode;
941 newEntry->metaState = metaState;
942 newEntry->repeatCount = 0;
943 newEntry->downTime = downTime;
944
945 wasEmpty = mInboundQueue.isEmpty();
946 mInboundQueue.enqueueAtTail(newEntry);
947 } // release lock
948
949 if (wasEmpty) {
950 mPollLoop->wake();
951 }
952}
953
954void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t nature,
955 uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
956 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
957 float xPrecision, float yPrecision, nsecs_t downTime) {
958#if DEBUG_INBOUND_EVENT_DETAILS
959 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, "
960 "action=0x%x, metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, "
961 "downTime=%lld",
962 eventTime, deviceId, nature, policyFlags, action, metaState, edgeFlags,
963 xPrecision, yPrecision, downTime);
964 for (uint32_t i = 0; i < pointerCount; i++) {
965 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
966 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
967 pointerCoords[i].pressure, pointerCoords[i].size);
968 }
969#endif
970
971 bool wasEmpty;
972 { // acquire lock
973 AutoMutex _l(mLock);
974
975 // Attempt batching and streaming of move events.
976 if (action == MOTION_EVENT_ACTION_MOVE) {
977 // BATCHING CASE
978 //
979 // Try to append a move sample to the tail of the inbound queue for this device.
980 // Give up if we encounter a non-move motion event for this device since that
981 // means we cannot append any new samples until a new motion event has started.
982 for (EventEntry* entry = mInboundQueue.tail.prev;
983 entry != & mInboundQueue.head; entry = entry->prev) {
984 if (entry->type != EventEntry::TYPE_MOTION) {
985 // Keep looking for motion events.
986 continue;
987 }
988
989 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
990 if (motionEntry->deviceId != deviceId) {
991 // Keep looking for this device.
992 continue;
993 }
994
995 if (motionEntry->action != MOTION_EVENT_ACTION_MOVE
996 || motionEntry->pointerCount != pointerCount) {
997 // Last motion event in the queue for this device is not compatible for
998 // appending new samples. Stop here.
999 goto NoBatchingOrStreaming;
1000 }
1001
1002 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07001003 // Do the batching magic.
Jeff Browne839a582010-04-22 18:58:52 -07001004 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCount, pointerCoords);
1005#if DEBUG_BATCHING
1006 LOGD("Appended motion sample onto batch for most recent "
1007 "motion event for this device in the inbound queue.");
1008#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07001009
1010 // Sanity check for special case because dispatch is interruptible.
1011 // The dispatch logic is partially interruptible and releases its lock while
1012 // identifying targets. However, as soon as the targets have been identified,
1013 // the dispatcher proceeds to write a dispatch entry into all relevant outbound
1014 // queues and then promptly removes the motion entry from the queue.
1015 //
1016 // Consequently, we should never observe the case where the inbound queue contains
1017 // an in-progress motion entry unless the current input targets are invalid
1018 // (currently being computed). Check for this!
1019 assert(! (motionEntry->dispatchInProgress && mCurrentInputTargetsValid));
1020
1021 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07001022 }
1023
1024 // STREAMING CASE
1025 //
1026 // There is no pending motion event (of any kind) for this device in the inbound queue.
1027 // Search the outbound queues for a synchronously dispatched motion event for this
1028 // device. If found, then we append the new sample to that event and then try to
1029 // push it out to all current targets. It is possible that some targets will already
1030 // have consumed the motion event. This case is automatically handled by the
1031 // logic in prepareDispatchCycleLocked by tracking where resumption takes place.
1032 //
1033 // The reason we look for a synchronously dispatched motion event is because we
1034 // want to be sure that no other motion events have been dispatched since the move.
1035 // It's also convenient because it means that the input targets are still valid.
1036 // This code could be improved to support streaming of asynchronously dispatched
1037 // motion events (which might be significantly more efficient) but it may become
1038 // a little more complicated as a result.
1039 //
1040 // Note: This code crucially depends on the invariant that an outbound queue always
1041 // contains at most one synchronous event and it is always last (but it might
1042 // not be first!).
Jeff Brown54bc2812010-06-15 01:31:58 -07001043 if (mCurrentInputTargetsValid) {
1044 for (size_t i = 0; i < mActiveConnections.size(); i++) {
1045 Connection* connection = mActiveConnections.itemAt(i);
1046 if (! connection->outboundQueue.isEmpty()) {
1047 DispatchEntry* dispatchEntry = connection->outboundQueue.tail.prev;
1048 if (dispatchEntry->targetFlags & InputTarget::FLAG_SYNC) {
1049 if (dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION) {
1050 goto NoBatchingOrStreaming;
1051 }
Jeff Browne839a582010-04-22 18:58:52 -07001052
Jeff Brown54bc2812010-06-15 01:31:58 -07001053 MotionEntry* syncedMotionEntry = static_cast<MotionEntry*>(
1054 dispatchEntry->eventEntry);
1055 if (syncedMotionEntry->action != MOTION_EVENT_ACTION_MOVE
1056 || syncedMotionEntry->deviceId != deviceId
1057 || syncedMotionEntry->pointerCount != pointerCount) {
1058 goto NoBatchingOrStreaming;
1059 }
Jeff Browne839a582010-04-22 18:58:52 -07001060
Jeff Brown54bc2812010-06-15 01:31:58 -07001061 // Found synced move entry. Append sample and resume dispatch.
1062 mAllocator.appendMotionSample(syncedMotionEntry, eventTime,
1063 pointerCount, pointerCoords);
1064 #if DEBUG_BATCHING
1065 LOGD("Appended motion sample onto batch for most recent synchronously "
1066 "dispatched motion event for this device in the outbound queues.");
1067 #endif
1068 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1069 dispatchEventToCurrentInputTargetsLocked(currentTime, syncedMotionEntry,
1070 true /*resumeWithAppendedMotionSample*/);
1071
1072 runCommandsLockedInterruptible();
1073 return; // done!
1074 }
Jeff Browne839a582010-04-22 18:58:52 -07001075 }
1076 }
1077 }
1078
1079NoBatchingOrStreaming:;
1080 }
1081
1082 // Just enqueue a new motion event.
1083 MotionEntry* newEntry = mAllocator.obtainMotionEntry();
1084 newEntry->eventTime = eventTime;
1085 newEntry->deviceId = deviceId;
1086 newEntry->nature = nature;
1087 newEntry->policyFlags = policyFlags;
1088 newEntry->action = action;
1089 newEntry->metaState = metaState;
1090 newEntry->edgeFlags = edgeFlags;
1091 newEntry->xPrecision = xPrecision;
1092 newEntry->yPrecision = yPrecision;
1093 newEntry->downTime = downTime;
1094 newEntry->pointerCount = pointerCount;
1095 newEntry->firstSample.eventTime = eventTime;
1096 newEntry->lastSample = & newEntry->firstSample;
1097 for (uint32_t i = 0; i < pointerCount; i++) {
1098 newEntry->pointerIds[i] = pointerIds[i];
1099 newEntry->firstSample.pointerCoords[i] = pointerCoords[i];
1100 }
1101
1102 wasEmpty = mInboundQueue.isEmpty();
1103 mInboundQueue.enqueueAtTail(newEntry);
1104 } // release lock
1105
1106 if (wasEmpty) {
1107 mPollLoop->wake();
1108 }
1109}
1110
1111void InputDispatcher::resetKeyRepeatLocked() {
1112 if (mKeyRepeatState.lastKeyEntry) {
1113 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
1114 mKeyRepeatState.lastKeyEntry = NULL;
1115 }
1116}
1117
1118status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001119#if DEBUG_REGISTRATION
1120 LOGD("channel '%s' - Registered", inputChannel->getName().string());
1121#endif
1122
Jeff Browne839a582010-04-22 18:58:52 -07001123 int receiveFd;
1124 { // acquire lock
1125 AutoMutex _l(mLock);
1126
1127 receiveFd = inputChannel->getReceivePipeFd();
1128 if (mConnectionsByReceiveFd.indexOfKey(receiveFd) >= 0) {
1129 LOGW("Attempted to register already registered input channel '%s'",
1130 inputChannel->getName().string());
1131 return BAD_VALUE;
1132 }
1133
1134 sp<Connection> connection = new Connection(inputChannel);
1135 status_t status = connection->initialize();
1136 if (status) {
1137 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
1138 inputChannel->getName().string(), status);
1139 return status;
1140 }
1141
1142 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001143
1144 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07001145 } // release lock
1146
1147 mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this);
1148 return OK;
1149}
1150
1151status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001152#if DEBUG_REGISTRATION
1153 LOGD("channel '%s' - Unregistered", inputChannel->getName().string());
1154#endif
1155
Jeff Browne839a582010-04-22 18:58:52 -07001156 int32_t receiveFd;
1157 { // acquire lock
1158 AutoMutex _l(mLock);
1159
1160 receiveFd = inputChannel->getReceivePipeFd();
1161 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd);
1162 if (connectionIndex < 0) {
1163 LOGW("Attempted to unregister already unregistered input channel '%s'",
1164 inputChannel->getName().string());
1165 return BAD_VALUE;
1166 }
1167
1168 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1169 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
1170
1171 connection->status = Connection::STATUS_ZOMBIE;
1172
1173 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1174 abortDispatchCycleLocked(currentTime, connection.get(), true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -07001175
1176 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07001177 } // release lock
1178
1179 mPollLoop->removeCallback(receiveFd);
1180
1181 // Wake the poll loop because removing the connection may have changed the current
1182 // synchronization state.
1183 mPollLoop->wake();
1184 return OK;
1185}
1186
1187void InputDispatcher::activateConnectionLocked(Connection* connection) {
1188 for (size_t i = 0; i < mActiveConnections.size(); i++) {
1189 if (mActiveConnections.itemAt(i) == connection) {
1190 return;
1191 }
1192 }
1193 mActiveConnections.add(connection);
1194}
1195
1196void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
1197 for (size_t i = 0; i < mActiveConnections.size(); i++) {
1198 if (mActiveConnections.itemAt(i) == connection) {
1199 mActiveConnections.removeAt(i);
1200 return;
1201 }
1202 }
1203}
1204
Jeff Brown54bc2812010-06-15 01:31:58 -07001205void InputDispatcher::onDispatchCycleStartedLocked(
1206 nsecs_t currentTime, Connection* connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001207}
1208
Jeff Brown54bc2812010-06-15 01:31:58 -07001209void InputDispatcher::onDispatchCycleFinishedLocked(
1210 nsecs_t currentTime, Connection* connection, bool recoveredFromANR) {
Jeff Browne839a582010-04-22 18:58:52 -07001211 if (recoveredFromANR) {
1212 LOGI("channel '%s' ~ Recovered from ANR. %01.1fms since event, "
1213 "%01.1fms since dispatch, %01.1fms since ANR",
1214 connection->getInputChannelName(),
1215 connection->getEventLatencyMillis(currentTime),
1216 connection->getDispatchLatencyMillis(currentTime),
1217 connection->getANRLatencyMillis(currentTime));
1218
Jeff Brown54bc2812010-06-15 01:31:58 -07001219 CommandEntry* commandEntry = postCommandLocked(
1220 & InputDispatcher::doNotifyInputChannelRecoveredFromANRLockedInterruptible);
1221 commandEntry->inputChannel = connection->inputChannel;
Jeff Browne839a582010-04-22 18:58:52 -07001222 }
1223}
1224
Jeff Brown54bc2812010-06-15 01:31:58 -07001225void InputDispatcher::onDispatchCycleANRLocked(
1226 nsecs_t currentTime, Connection* connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001227 LOGI("channel '%s' ~ Not responding! %01.1fms since event, %01.1fms since dispatch",
1228 connection->getInputChannelName(),
1229 connection->getEventLatencyMillis(currentTime),
1230 connection->getDispatchLatencyMillis(currentTime));
1231
Jeff Brown54bc2812010-06-15 01:31:58 -07001232 CommandEntry* commandEntry = postCommandLocked(
1233 & InputDispatcher::doNotifyInputChannelANRLockedInterruptible);
1234 commandEntry->inputChannel = connection->inputChannel;
Jeff Browne839a582010-04-22 18:58:52 -07001235}
1236
Jeff Brown54bc2812010-06-15 01:31:58 -07001237void InputDispatcher::onDispatchCycleBrokenLocked(
1238 nsecs_t currentTime, Connection* connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001239 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
1240 connection->getInputChannelName());
1241
Jeff Brown54bc2812010-06-15 01:31:58 -07001242 CommandEntry* commandEntry = postCommandLocked(
1243 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
1244 commandEntry->inputChannel = connection->inputChannel;
Jeff Browne839a582010-04-22 18:58:52 -07001245}
1246
Jeff Brown54bc2812010-06-15 01:31:58 -07001247void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
1248 CommandEntry* commandEntry) {
1249 mLock.unlock();
1250
1251 mPolicy->notifyInputChannelBroken(commandEntry->inputChannel);
1252 commandEntry->inputChannel.clear();
1253
1254 mLock.lock();
1255}
1256
1257void InputDispatcher::doNotifyInputChannelANRLockedInterruptible(
1258 CommandEntry* commandEntry) {
1259 mLock.unlock();
1260
1261 mPolicy->notifyInputChannelANR(commandEntry->inputChannel);
1262 commandEntry->inputChannel.clear();
1263
1264 mLock.lock();
1265}
1266
1267void InputDispatcher::doNotifyInputChannelRecoveredFromANRLockedInterruptible(
1268 CommandEntry* commandEntry) {
1269 mLock.unlock();
1270
1271 mPolicy->notifyInputChannelRecoveredFromANR(commandEntry->inputChannel);
1272 commandEntry->inputChannel.clear();
1273
1274 mLock.lock();
1275}
1276
1277
Jeff Browne839a582010-04-22 18:58:52 -07001278// --- InputDispatcher::Allocator ---
1279
1280InputDispatcher::Allocator::Allocator() {
1281}
1282
1283InputDispatcher::ConfigurationChangedEntry*
1284InputDispatcher::Allocator::obtainConfigurationChangedEntry() {
1285 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
1286 entry->refCount = 1;
1287 entry->type = EventEntry::TYPE_CONFIGURATION_CHANGED;
Jeff Brown54bc2812010-06-15 01:31:58 -07001288 entry->dispatchInProgress = false;
Jeff Browne839a582010-04-22 18:58:52 -07001289 return entry;
1290}
1291
1292InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry() {
1293 KeyEntry* entry = mKeyEntryPool.alloc();
1294 entry->refCount = 1;
1295 entry->type = EventEntry::TYPE_KEY;
Jeff Brown54bc2812010-06-15 01:31:58 -07001296 entry->dispatchInProgress = false;
Jeff Browne839a582010-04-22 18:58:52 -07001297 return entry;
1298}
1299
1300InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry() {
1301 MotionEntry* entry = mMotionEntryPool.alloc();
1302 entry->refCount = 1;
1303 entry->type = EventEntry::TYPE_MOTION;
1304 entry->firstSample.next = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -07001305 entry->dispatchInProgress = false;
Jeff Browne839a582010-04-22 18:58:52 -07001306 return entry;
1307}
1308
1309InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
1310 EventEntry* eventEntry) {
1311 DispatchEntry* entry = mDispatchEntryPool.alloc();
1312 entry->eventEntry = eventEntry;
1313 eventEntry->refCount += 1;
1314 return entry;
1315}
1316
Jeff Brown54bc2812010-06-15 01:31:58 -07001317InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
1318 CommandEntry* entry = mCommandEntryPool.alloc();
1319 entry->command = command;
1320 return entry;
1321}
1322
Jeff Browne839a582010-04-22 18:58:52 -07001323void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
1324 switch (entry->type) {
1325 case EventEntry::TYPE_CONFIGURATION_CHANGED:
1326 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
1327 break;
1328 case EventEntry::TYPE_KEY:
1329 releaseKeyEntry(static_cast<KeyEntry*>(entry));
1330 break;
1331 case EventEntry::TYPE_MOTION:
1332 releaseMotionEntry(static_cast<MotionEntry*>(entry));
1333 break;
1334 default:
1335 assert(false);
1336 break;
1337 }
1338}
1339
1340void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
1341 ConfigurationChangedEntry* entry) {
1342 entry->refCount -= 1;
1343 if (entry->refCount == 0) {
1344 mConfigurationChangeEntryPool.free(entry);
1345 } else {
1346 assert(entry->refCount > 0);
1347 }
1348}
1349
1350void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
1351 entry->refCount -= 1;
1352 if (entry->refCount == 0) {
1353 mKeyEntryPool.free(entry);
1354 } else {
1355 assert(entry->refCount > 0);
1356 }
1357}
1358
1359void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
1360 entry->refCount -= 1;
1361 if (entry->refCount == 0) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001362 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
1363 MotionSample* next = sample->next;
1364 mMotionSamplePool.free(sample);
1365 sample = next;
1366 }
Jeff Browne839a582010-04-22 18:58:52 -07001367 mMotionEntryPool.free(entry);
1368 } else {
1369 assert(entry->refCount > 0);
1370 }
1371}
1372
1373void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
1374 releaseEventEntry(entry->eventEntry);
1375 mDispatchEntryPool.free(entry);
1376}
1377
Jeff Brown54bc2812010-06-15 01:31:58 -07001378void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
1379 mCommandEntryPool.free(entry);
1380}
1381
Jeff Browne839a582010-04-22 18:58:52 -07001382void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
1383 nsecs_t eventTime, int32_t pointerCount, const PointerCoords* pointerCoords) {
1384 MotionSample* sample = mMotionSamplePool.alloc();
1385 sample->eventTime = eventTime;
1386 for (int32_t i = 0; i < pointerCount; i++) {
1387 sample->pointerCoords[i] = pointerCoords[i];
1388 }
1389
1390 sample->next = NULL;
1391 motionEntry->lastSample->next = sample;
1392 motionEntry->lastSample = sample;
1393}
1394
Jeff Browne839a582010-04-22 18:58:52 -07001395// --- InputDispatcher::Connection ---
1396
1397InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
1398 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
1399 nextTimeoutTime(LONG_LONG_MAX),
1400 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX),
1401 lastANRTime(LONG_LONG_MAX) {
1402}
1403
1404InputDispatcher::Connection::~Connection() {
1405}
1406
1407status_t InputDispatcher::Connection::initialize() {
1408 return inputPublisher.initialize();
1409}
1410
Jeff Brown54bc2812010-06-15 01:31:58 -07001411const char* InputDispatcher::Connection::getStatusLabel() const {
1412 switch (status) {
1413 case STATUS_NORMAL:
1414 return "NORMAL";
1415
1416 case STATUS_BROKEN:
1417 return "BROKEN";
1418
1419 case STATUS_NOT_RESPONDING:
1420 return "NOT_RESPONDING";
1421
1422 case STATUS_ZOMBIE:
1423 return "ZOMBIE";
1424
1425 default:
1426 return "UNKNOWN";
1427 }
1428}
1429
Jeff Browne839a582010-04-22 18:58:52 -07001430InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
1431 const EventEntry* eventEntry) const {
1432 for (DispatchEntry* dispatchEntry = outboundQueue.tail.prev;
1433 dispatchEntry != & outboundQueue.head; dispatchEntry = dispatchEntry->prev) {
1434 if (dispatchEntry->eventEntry == eventEntry) {
1435 return dispatchEntry;
1436 }
1437 }
1438 return NULL;
1439}
1440
Jeff Brown54bc2812010-06-15 01:31:58 -07001441// --- InputDispatcher::CommandEntry ---
1442
1443InputDispatcher::CommandEntry::CommandEntry() {
1444}
1445
1446InputDispatcher::CommandEntry::~CommandEntry() {
1447}
1448
Jeff Browne839a582010-04-22 18:58:52 -07001449
1450// --- InputDispatcherThread ---
1451
1452InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
1453 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
1454}
1455
1456InputDispatcherThread::~InputDispatcherThread() {
1457}
1458
1459bool InputDispatcherThread::threadLoop() {
1460 mDispatcher->dispatchOnce();
1461 return true;
1462}
1463
1464} // namespace android