blob: 14dcada3b51897cfcb6d893fc1be41471d49734a [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,
Jeff Brownf4a4ec22010-06-16 01:53:36 -0700382 0, 0, entry->xPrecision, entry->yPrecision,
Jeff Browne839a582010-04-22 18:58:52 -0700383 entry->downTime, entry->eventTime, entry->pointerCount, entry->pointerIds,
384 entry->firstSample.pointerCoords);
385
386 mCurrentInputTargets.clear();
387 mPolicy->getMotionEventTargets(& mReusableMotionEvent, entry->policyFlags,
388 mCurrentInputTargets);
389
Jeff Brown54bc2812010-06-15 01:31:58 -0700390 mLock.lock();
391 mCurrentInputTargetsValid = true;
392
Jeff Browne839a582010-04-22 18:58:52 -0700393 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
394}
395
396void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
397 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
398#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700399 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Browne839a582010-04-22 18:58:52 -0700400 "resumeWithAppendedMotionSample=%s",
401 resumeWithAppendedMotionSample ? "true" : "false");
402#endif
403
Jeff Brown54bc2812010-06-15 01:31:58 -0700404 assert(eventEntry->dispatchInProgress); // should already have been set to true
405
Jeff Browne839a582010-04-22 18:58:52 -0700406 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
407 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
408
409 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(
410 inputTarget.inputChannel->getReceivePipeFd());
411 if (connectionIndex >= 0) {
412 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
413 prepareDispatchCycleLocked(currentTime, connection.get(), eventEntry, & inputTarget,
414 resumeWithAppendedMotionSample);
415 } else {
416 LOGW("Framework requested delivery of an input event to channel '%s' but it "
417 "is not registered with the input dispatcher.",
418 inputTarget.inputChannel->getName().string());
419 }
420 }
421}
422
423void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime, Connection* connection,
424 EventEntry* eventEntry, const InputTarget* inputTarget,
425 bool resumeWithAppendedMotionSample) {
426#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700427 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, timeout=%lldns, "
Jeff Browne839a582010-04-22 18:58:52 -0700428 "xOffset=%f, yOffset=%f, resumeWithAppendedMotionSample=%s",
429 connection->getInputChannelName(), inputTarget->flags, inputTarget->timeout,
430 inputTarget->xOffset, inputTarget->yOffset,
431 resumeWithAppendedMotionSample ? "true" : "false");
432#endif
433
434 // Skip this event if the connection status is not normal.
435 // We don't want to queue outbound events at all if the connection is broken or
436 // not responding.
437 if (connection->status != Connection::STATUS_NORMAL) {
438 LOGV("channel '%s' ~ Dropping event because the channel status is %s",
Jeff Brown54bc2812010-06-15 01:31:58 -0700439 connection->getStatusLabel());
Jeff Browne839a582010-04-22 18:58:52 -0700440 return;
441 }
442
443 // Resume the dispatch cycle with a freshly appended motion sample.
444 // First we check that the last dispatch entry in the outbound queue is for the same
445 // motion event to which we appended the motion sample. If we find such a dispatch
446 // entry, and if it is currently in progress then we try to stream the new sample.
447 bool wasEmpty = connection->outboundQueue.isEmpty();
448
449 if (! wasEmpty && resumeWithAppendedMotionSample) {
450 DispatchEntry* motionEventDispatchEntry =
451 connection->findQueuedDispatchEntryForEvent(eventEntry);
452 if (motionEventDispatchEntry) {
453 // If the dispatch entry is not in progress, then we must be busy dispatching an
454 // earlier event. Not a problem, the motion event is on the outbound queue and will
455 // be dispatched later.
456 if (! motionEventDispatchEntry->inProgress) {
457#if DEBUG_BATCHING
458 LOGD("channel '%s' ~ Not streaming because the motion event has "
459 "not yet been dispatched. "
460 "(Waiting for earlier events to be consumed.)",
461 connection->getInputChannelName());
462#endif
463 return;
464 }
465
466 // If the dispatch entry is in progress but it already has a tail of pending
467 // motion samples, then it must mean that the shared memory buffer filled up.
468 // Not a problem, when this dispatch cycle is finished, we will eventually start
469 // a new dispatch cycle to process the tail and that tail includes the newly
470 // appended motion sample.
471 if (motionEventDispatchEntry->tailMotionSample) {
472#if DEBUG_BATCHING
473 LOGD("channel '%s' ~ Not streaming because no new samples can "
474 "be appended to the motion event in this dispatch cycle. "
475 "(Waiting for next dispatch cycle to start.)",
476 connection->getInputChannelName());
477#endif
478 return;
479 }
480
481 // The dispatch entry is in progress and is still potentially open for streaming.
482 // Try to stream the new motion sample. This might fail if the consumer has already
483 // consumed the motion event (or if the channel is broken).
484 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
485 status_t status = connection->inputPublisher.appendMotionSample(
486 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
487 if (status == OK) {
488#if DEBUG_BATCHING
489 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
490 connection->getInputChannelName());
491#endif
492 return;
493 }
494
495#if DEBUG_BATCHING
496 if (status == NO_MEMORY) {
497 LOGD("channel '%s' ~ Could not append motion sample to currently "
498 "dispatched move event because the shared memory buffer is full. "
499 "(Waiting for next dispatch cycle to start.)",
500 connection->getInputChannelName());
501 } else if (status == status_t(FAILED_TRANSACTION)) {
502 LOGD("channel '%s' ~ Could not append motion sample to currently "
503 "dispatchedmove event because the event has already been consumed. "
504 "(Waiting for next dispatch cycle to start.)",
505 connection->getInputChannelName());
506 } else {
507 LOGD("channel '%s' ~ Could not append motion sample to currently "
508 "dispatched move event due to an error, status=%d. "
509 "(Waiting for next dispatch cycle to start.)",
510 connection->getInputChannelName(), status);
511 }
512#endif
513 // Failed to stream. Start a new tail of pending motion samples to dispatch
514 // in the next cycle.
515 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
516 return;
517 }
518 }
519
520 // This is a new event.
521 // Enqueue a new dispatch entry onto the outbound queue for this connection.
522 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry); // increments ref
523 dispatchEntry->targetFlags = inputTarget->flags;
524 dispatchEntry->xOffset = inputTarget->xOffset;
525 dispatchEntry->yOffset = inputTarget->yOffset;
526 dispatchEntry->timeout = inputTarget->timeout;
527 dispatchEntry->inProgress = false;
528 dispatchEntry->headMotionSample = NULL;
529 dispatchEntry->tailMotionSample = NULL;
530
531 // Handle the case where we could not stream a new motion sample because the consumer has
532 // already consumed the motion event (otherwise the corresponding dispatch entry would
533 // still be in the outbound queue for this connection). We set the head motion sample
534 // to the list starting with the newly appended motion sample.
535 if (resumeWithAppendedMotionSample) {
536#if DEBUG_BATCHING
537 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
538 "that cannot be streamed because the motion event has already been consumed.",
539 connection->getInputChannelName());
540#endif
541 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
542 dispatchEntry->headMotionSample = appendedMotionSample;
543 }
544
545 // Enqueue the dispatch entry.
546 connection->outboundQueue.enqueueAtTail(dispatchEntry);
547
548 // If the outbound queue was previously empty, start the dispatch cycle going.
549 if (wasEmpty) {
550 activateConnectionLocked(connection);
551 startDispatchCycleLocked(currentTime, connection);
552 }
553}
554
555void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, Connection* connection) {
556#if DEBUG_DISPATCH_CYCLE
557 LOGD("channel '%s' ~ startDispatchCycle",
558 connection->getInputChannelName());
559#endif
560
561 assert(connection->status == Connection::STATUS_NORMAL);
562 assert(! connection->outboundQueue.isEmpty());
563
564 DispatchEntry* dispatchEntry = connection->outboundQueue.head.next;
565 assert(! dispatchEntry->inProgress);
566
567 // TODO throttle successive ACTION_MOVE motion events for the same device
568 // possible implementation could set a brief poll timeout here and resume starting the
569 // dispatch cycle when elapsed
570
571 // Publish the event.
572 status_t status;
573 switch (dispatchEntry->eventEntry->type) {
574 case EventEntry::TYPE_KEY: {
575 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
576
577 // Apply target flags.
578 int32_t action = keyEntry->action;
579 int32_t flags = keyEntry->flags;
580 if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
581 flags |= KEY_EVENT_FLAG_CANCELED;
582 }
583
584 // Publish the key event.
585 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->nature,
586 action, flags, keyEntry->keyCode, keyEntry->scanCode,
587 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
588 keyEntry->eventTime);
589
590 if (status) {
591 LOGE("channel '%s' ~ Could not publish key event, "
592 "status=%d", connection->getInputChannelName(), status);
593 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
594 return;
595 }
596 break;
597 }
598
599 case EventEntry::TYPE_MOTION: {
600 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
601
602 // Apply target flags.
603 int32_t action = motionEntry->action;
604 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
605 action = MOTION_EVENT_ACTION_OUTSIDE;
606 }
607 if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
608 action = MOTION_EVENT_ACTION_CANCEL;
609 }
610
611 // If headMotionSample is non-NULL, then it points to the first new sample that we
612 // were unable to dispatch during the previous cycle so we resume dispatching from
613 // that point in the list of motion samples.
614 // Otherwise, we just start from the first sample of the motion event.
615 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
616 if (! firstMotionSample) {
617 firstMotionSample = & motionEntry->firstSample;
618 }
619
620 // Publish the motion event and the first motion sample.
621 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
622 motionEntry->nature, action, motionEntry->edgeFlags, motionEntry->metaState,
623 dispatchEntry->xOffset, dispatchEntry->yOffset,
624 motionEntry->xPrecision, motionEntry->yPrecision,
625 motionEntry->downTime, firstMotionSample->eventTime,
626 motionEntry->pointerCount, motionEntry->pointerIds,
627 firstMotionSample->pointerCoords);
628
629 if (status) {
630 LOGE("channel '%s' ~ Could not publish motion event, "
631 "status=%d", connection->getInputChannelName(), status);
632 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
633 return;
634 }
635
636 // Append additional motion samples.
637 MotionSample* nextMotionSample = firstMotionSample->next;
638 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
639 status = connection->inputPublisher.appendMotionSample(
640 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
641 if (status == NO_MEMORY) {
642#if DEBUG_DISPATCH_CYCLE
643 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
644 "be sent in the next dispatch cycle.",
645 connection->getInputChannelName());
646#endif
647 break;
648 }
649 if (status != OK) {
650 LOGE("channel '%s' ~ Could not append motion sample "
651 "for a reason other than out of memory, status=%d",
652 connection->getInputChannelName(), status);
653 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
654 return;
655 }
656 }
657
658 // Remember the next motion sample that we could not dispatch, in case we ran out
659 // of space in the shared memory buffer.
660 dispatchEntry->tailMotionSample = nextMotionSample;
661 break;
662 }
663
664 default: {
665 assert(false);
666 }
667 }
668
669 // Send the dispatch signal.
670 status = connection->inputPublisher.sendDispatchSignal();
671 if (status) {
672 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
673 connection->getInputChannelName(), status);
674 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
675 return;
676 }
677
678 // Record information about the newly started dispatch cycle.
679 dispatchEntry->inProgress = true;
680
681 connection->lastEventTime = dispatchEntry->eventEntry->eventTime;
682 connection->lastDispatchTime = currentTime;
683
684 nsecs_t timeout = dispatchEntry->timeout;
685 connection->nextTimeoutTime = (timeout >= 0) ? currentTime + timeout : LONG_LONG_MAX;
686
687 // Notify other system components.
688 onDispatchCycleStartedLocked(currentTime, connection);
689}
690
691void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, Connection* connection) {
692#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700693 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Browne839a582010-04-22 18:58:52 -0700694 "%01.1fms since dispatch",
695 connection->getInputChannelName(),
696 connection->getEventLatencyMillis(currentTime),
697 connection->getDispatchLatencyMillis(currentTime));
698#endif
699
Jeff Brown54bc2812010-06-15 01:31:58 -0700700 if (connection->status == Connection::STATUS_BROKEN
701 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Browne839a582010-04-22 18:58:52 -0700702 return;
703 }
704
705 // Clear the pending timeout.
706 connection->nextTimeoutTime = LONG_LONG_MAX;
707
708 if (connection->status == Connection::STATUS_NOT_RESPONDING) {
709 // Recovering from an ANR.
710 connection->status = Connection::STATUS_NORMAL;
711
712 // Notify other system components.
713 onDispatchCycleFinishedLocked(currentTime, connection, true /*recoveredFromANR*/);
714 } else {
715 // Normal finish. Not much to do here.
716
717 // Notify other system components.
718 onDispatchCycleFinishedLocked(currentTime, connection, false /*recoveredFromANR*/);
719 }
720
721 // Reset the publisher since the event has been consumed.
722 // We do this now so that the publisher can release some of its internal resources
723 // while waiting for the next dispatch cycle to begin.
724 status_t status = connection->inputPublisher.reset();
725 if (status) {
726 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
727 connection->getInputChannelName(), status);
728 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
729 return;
730 }
731
732 // Start the next dispatch cycle for this connection.
733 while (! connection->outboundQueue.isEmpty()) {
734 DispatchEntry* dispatchEntry = connection->outboundQueue.head.next;
735 if (dispatchEntry->inProgress) {
736 // Finish or resume current event in progress.
737 if (dispatchEntry->tailMotionSample) {
738 // We have a tail of undispatched motion samples.
739 // Reuse the same DispatchEntry and start a new cycle.
740 dispatchEntry->inProgress = false;
741 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
742 dispatchEntry->tailMotionSample = NULL;
743 startDispatchCycleLocked(currentTime, connection);
744 return;
745 }
746 // Finished.
747 connection->outboundQueue.dequeueAtHead();
748 mAllocator.releaseDispatchEntry(dispatchEntry);
749 } else {
750 // If the head is not in progress, then we must have already dequeued the in
751 // progress event, which means we actually aborted it (due to ANR).
752 // So just start the next event for this connection.
753 startDispatchCycleLocked(currentTime, connection);
754 return;
755 }
756 }
757
758 // Outbound queue is empty, deactivate the connection.
759 deactivateConnectionLocked(connection);
760}
761
762bool InputDispatcher::timeoutDispatchCycleLocked(nsecs_t currentTime, Connection* connection) {
763#if DEBUG_DISPATCH_CYCLE
764 LOGD("channel '%s' ~ timeoutDispatchCycle",
765 connection->getInputChannelName());
766#endif
767
768 if (connection->status != Connection::STATUS_NORMAL) {
769 return false;
770 }
771
772 // Enter the not responding state.
773 connection->status = Connection::STATUS_NOT_RESPONDING;
774 connection->lastANRTime = currentTime;
775 bool deactivated = abortDispatchCycleLocked(currentTime, connection, false /*(not) broken*/);
776
777 // Notify other system components.
778 onDispatchCycleANRLocked(currentTime, connection);
779 return deactivated;
780}
781
782bool InputDispatcher::abortDispatchCycleLocked(nsecs_t currentTime, Connection* connection,
783 bool broken) {
784#if DEBUG_DISPATCH_CYCLE
Jeff Brown54bc2812010-06-15 01:31:58 -0700785 LOGD("channel '%s' ~ abortDispatchCycle - broken=%s",
Jeff Browne839a582010-04-22 18:58:52 -0700786 connection->getInputChannelName(), broken ? "true" : "false");
787#endif
788
Jeff Browne839a582010-04-22 18:58:52 -0700789 // Clear the pending timeout.
790 connection->nextTimeoutTime = LONG_LONG_MAX;
791
792 // Clear the outbound queue.
Jeff Brown54bc2812010-06-15 01:31:58 -0700793 bool deactivated = ! connection->outboundQueue.isEmpty();
794 if (deactivated) {
795 do {
796 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
797 mAllocator.releaseDispatchEntry(dispatchEntry);
798 } while (! connection->outboundQueue.isEmpty());
Jeff Browne839a582010-04-22 18:58:52 -0700799
Jeff Brown54bc2812010-06-15 01:31:58 -0700800 deactivateConnectionLocked(connection);
801 }
Jeff Browne839a582010-04-22 18:58:52 -0700802
803 // Handle the case where the connection appears to be unrecoverably broken.
Jeff Brown54bc2812010-06-15 01:31:58 -0700804 // Ignore already broken or zombie connections.
Jeff Browne839a582010-04-22 18:58:52 -0700805 if (broken) {
Jeff Brown54bc2812010-06-15 01:31:58 -0700806 if (connection->status == Connection::STATUS_NORMAL
807 || connection->status == Connection::STATUS_NOT_RESPONDING) {
808 connection->status = Connection::STATUS_BROKEN;
Jeff Browne839a582010-04-22 18:58:52 -0700809
Jeff Brown54bc2812010-06-15 01:31:58 -0700810 // Notify other system components.
811 onDispatchCycleBrokenLocked(currentTime, connection);
812 }
Jeff Browne839a582010-04-22 18:58:52 -0700813 }
Jeff Brown54bc2812010-06-15 01:31:58 -0700814
815 return deactivated;
Jeff Browne839a582010-04-22 18:58:52 -0700816}
817
818bool InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
819 InputDispatcher* d = static_cast<InputDispatcher*>(data);
820
821 { // acquire lock
822 AutoMutex _l(d->mLock);
823
824 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
825 if (connectionIndex < 0) {
826 LOGE("Received spurious receive callback for unknown input channel. "
827 "fd=%d, events=0x%x", receiveFd, events);
828 return false; // remove the callback
829 }
830
831 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
832
833 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
834 if (events & (POLLERR | POLLHUP | POLLNVAL)) {
835 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
836 "events=0x%x", connection->getInputChannelName(), events);
837 d->abortDispatchCycleLocked(currentTime, connection.get(), true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -0700838 d->runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -0700839 return false; // remove the callback
840 }
841
842 if (! (events & POLLIN)) {
843 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
844 "events=0x%x", connection->getInputChannelName(), events);
845 return true;
846 }
847
848 status_t status = connection->inputPublisher.receiveFinishedSignal();
849 if (status) {
850 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
851 connection->getInputChannelName(), status);
852 d->abortDispatchCycleLocked(currentTime, connection.get(), true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -0700853 d->runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -0700854 return false; // remove the callback
855 }
856
857 d->finishDispatchCycleLocked(currentTime, connection.get());
Jeff Brown54bc2812010-06-15 01:31:58 -0700858 d->runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -0700859 return true;
860 } // release lock
861}
862
Jeff Brown54bc2812010-06-15 01:31:58 -0700863void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Browne839a582010-04-22 18:58:52 -0700864#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown54bc2812010-06-15 01:31:58 -0700865 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Browne839a582010-04-22 18:58:52 -0700866#endif
867
868 bool wasEmpty;
869 { // acquire lock
870 AutoMutex _l(mLock);
871
872 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry();
873 newEntry->eventTime = eventTime;
Jeff Browne839a582010-04-22 18:58:52 -0700874
875 wasEmpty = mInboundQueue.isEmpty();
876 mInboundQueue.enqueueAtTail(newEntry);
877 } // release lock
878
879 if (wasEmpty) {
880 mPollLoop->wake();
881 }
882}
883
Jeff Browne839a582010-04-22 18:58:52 -0700884void InputDispatcher::notifyAppSwitchComing(nsecs_t eventTime) {
885#if DEBUG_INBOUND_EVENT_DETAILS
886 LOGD("notifyAppSwitchComing - eventTime=%lld", eventTime);
887#endif
888
889 // Remove movement keys from the queue from most recent to least recent, stopping at the
890 // first non-movement key.
891 // TODO: Include a detailed description of why we do this...
892
893 { // acquire lock
894 AutoMutex _l(mLock);
895
896 for (EventEntry* entry = mInboundQueue.tail.prev; entry != & mInboundQueue.head; ) {
897 EventEntry* prev = entry->prev;
898
899 if (entry->type == EventEntry::TYPE_KEY) {
900 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
901 if (isMovementKey(keyEntry->keyCode)) {
902 LOGV("Dropping movement key during app switch: keyCode=%d, action=%d",
903 keyEntry->keyCode, keyEntry->action);
904 mInboundQueue.dequeue(keyEntry);
905 mAllocator.releaseKeyEntry(keyEntry);
906 } else {
907 // stop at last non-movement key
908 break;
909 }
910 }
911
912 entry = prev;
913 }
914 } // release lock
915}
916
917void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t nature,
918 uint32_t policyFlags, int32_t action, int32_t flags,
919 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
920#if DEBUG_INBOUND_EVENT_DETAILS
921 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, action=0x%x, "
922 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
923 eventTime, deviceId, nature, policyFlags, action, flags,
924 keyCode, scanCode, metaState, downTime);
925#endif
926
927 bool wasEmpty;
928 { // acquire lock
929 AutoMutex _l(mLock);
930
931 KeyEntry* newEntry = mAllocator.obtainKeyEntry();
932 newEntry->eventTime = eventTime;
933 newEntry->deviceId = deviceId;
934 newEntry->nature = nature;
935 newEntry->policyFlags = policyFlags;
936 newEntry->action = action;
937 newEntry->flags = flags;
938 newEntry->keyCode = keyCode;
939 newEntry->scanCode = scanCode;
940 newEntry->metaState = metaState;
941 newEntry->repeatCount = 0;
942 newEntry->downTime = downTime;
943
944 wasEmpty = mInboundQueue.isEmpty();
945 mInboundQueue.enqueueAtTail(newEntry);
946 } // release lock
947
948 if (wasEmpty) {
949 mPollLoop->wake();
950 }
951}
952
953void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t nature,
954 uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags,
955 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
956 float xPrecision, float yPrecision, nsecs_t downTime) {
957#if DEBUG_INBOUND_EVENT_DETAILS
958 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, nature=0x%x, policyFlags=0x%x, "
959 "action=0x%x, metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, "
960 "downTime=%lld",
961 eventTime, deviceId, nature, policyFlags, action, metaState, edgeFlags,
962 xPrecision, yPrecision, downTime);
963 for (uint32_t i = 0; i < pointerCount; i++) {
964 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f",
965 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
966 pointerCoords[i].pressure, pointerCoords[i].size);
967 }
968#endif
969
970 bool wasEmpty;
971 { // acquire lock
972 AutoMutex _l(mLock);
973
974 // Attempt batching and streaming of move events.
975 if (action == MOTION_EVENT_ACTION_MOVE) {
976 // BATCHING CASE
977 //
978 // Try to append a move sample to the tail of the inbound queue for this device.
979 // Give up if we encounter a non-move motion event for this device since that
980 // means we cannot append any new samples until a new motion event has started.
981 for (EventEntry* entry = mInboundQueue.tail.prev;
982 entry != & mInboundQueue.head; entry = entry->prev) {
983 if (entry->type != EventEntry::TYPE_MOTION) {
984 // Keep looking for motion events.
985 continue;
986 }
987
988 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
989 if (motionEntry->deviceId != deviceId) {
990 // Keep looking for this device.
991 continue;
992 }
993
994 if (motionEntry->action != MOTION_EVENT_ACTION_MOVE
995 || motionEntry->pointerCount != pointerCount) {
996 // Last motion event in the queue for this device is not compatible for
997 // appending new samples. Stop here.
998 goto NoBatchingOrStreaming;
999 }
1000
1001 // The last motion event is a move and is compatible for appending.
Jeff Brown54bc2812010-06-15 01:31:58 -07001002 // Do the batching magic.
Jeff Browne839a582010-04-22 18:58:52 -07001003 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCount, pointerCoords);
1004#if DEBUG_BATCHING
1005 LOGD("Appended motion sample onto batch for most recent "
1006 "motion event for this device in the inbound queue.");
1007#endif
Jeff Brown54bc2812010-06-15 01:31:58 -07001008
1009 // Sanity check for special case because dispatch is interruptible.
1010 // The dispatch logic is partially interruptible and releases its lock while
1011 // identifying targets. However, as soon as the targets have been identified,
1012 // the dispatcher proceeds to write a dispatch entry into all relevant outbound
1013 // queues and then promptly removes the motion entry from the queue.
1014 //
1015 // Consequently, we should never observe the case where the inbound queue contains
1016 // an in-progress motion entry unless the current input targets are invalid
1017 // (currently being computed). Check for this!
1018 assert(! (motionEntry->dispatchInProgress && mCurrentInputTargetsValid));
1019
1020 return; // done!
Jeff Browne839a582010-04-22 18:58:52 -07001021 }
1022
1023 // STREAMING CASE
1024 //
1025 // There is no pending motion event (of any kind) for this device in the inbound queue.
1026 // Search the outbound queues for a synchronously dispatched motion event for this
1027 // device. If found, then we append the new sample to that event and then try to
1028 // push it out to all current targets. It is possible that some targets will already
1029 // have consumed the motion event. This case is automatically handled by the
1030 // logic in prepareDispatchCycleLocked by tracking where resumption takes place.
1031 //
1032 // The reason we look for a synchronously dispatched motion event is because we
1033 // want to be sure that no other motion events have been dispatched since the move.
1034 // It's also convenient because it means that the input targets are still valid.
1035 // This code could be improved to support streaming of asynchronously dispatched
1036 // motion events (which might be significantly more efficient) but it may become
1037 // a little more complicated as a result.
1038 //
1039 // Note: This code crucially depends on the invariant that an outbound queue always
1040 // contains at most one synchronous event and it is always last (but it might
1041 // not be first!).
Jeff Brown54bc2812010-06-15 01:31:58 -07001042 if (mCurrentInputTargetsValid) {
1043 for (size_t i = 0; i < mActiveConnections.size(); i++) {
1044 Connection* connection = mActiveConnections.itemAt(i);
1045 if (! connection->outboundQueue.isEmpty()) {
1046 DispatchEntry* dispatchEntry = connection->outboundQueue.tail.prev;
1047 if (dispatchEntry->targetFlags & InputTarget::FLAG_SYNC) {
1048 if (dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION) {
1049 goto NoBatchingOrStreaming;
1050 }
Jeff Browne839a582010-04-22 18:58:52 -07001051
Jeff Brown54bc2812010-06-15 01:31:58 -07001052 MotionEntry* syncedMotionEntry = static_cast<MotionEntry*>(
1053 dispatchEntry->eventEntry);
1054 if (syncedMotionEntry->action != MOTION_EVENT_ACTION_MOVE
1055 || syncedMotionEntry->deviceId != deviceId
1056 || syncedMotionEntry->pointerCount != pointerCount) {
1057 goto NoBatchingOrStreaming;
1058 }
Jeff Browne839a582010-04-22 18:58:52 -07001059
Jeff Brown54bc2812010-06-15 01:31:58 -07001060 // Found synced move entry. Append sample and resume dispatch.
1061 mAllocator.appendMotionSample(syncedMotionEntry, eventTime,
1062 pointerCount, pointerCoords);
1063 #if DEBUG_BATCHING
1064 LOGD("Appended motion sample onto batch for most recent synchronously "
1065 "dispatched motion event for this device in the outbound queues.");
1066 #endif
1067 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1068 dispatchEventToCurrentInputTargetsLocked(currentTime, syncedMotionEntry,
1069 true /*resumeWithAppendedMotionSample*/);
1070
1071 runCommandsLockedInterruptible();
1072 return; // done!
1073 }
Jeff Browne839a582010-04-22 18:58:52 -07001074 }
1075 }
1076 }
1077
1078NoBatchingOrStreaming:;
1079 }
1080
1081 // Just enqueue a new motion event.
1082 MotionEntry* newEntry = mAllocator.obtainMotionEntry();
1083 newEntry->eventTime = eventTime;
1084 newEntry->deviceId = deviceId;
1085 newEntry->nature = nature;
1086 newEntry->policyFlags = policyFlags;
1087 newEntry->action = action;
1088 newEntry->metaState = metaState;
1089 newEntry->edgeFlags = edgeFlags;
1090 newEntry->xPrecision = xPrecision;
1091 newEntry->yPrecision = yPrecision;
1092 newEntry->downTime = downTime;
1093 newEntry->pointerCount = pointerCount;
1094 newEntry->firstSample.eventTime = eventTime;
1095 newEntry->lastSample = & newEntry->firstSample;
1096 for (uint32_t i = 0; i < pointerCount; i++) {
1097 newEntry->pointerIds[i] = pointerIds[i];
1098 newEntry->firstSample.pointerCoords[i] = pointerCoords[i];
1099 }
1100
1101 wasEmpty = mInboundQueue.isEmpty();
1102 mInboundQueue.enqueueAtTail(newEntry);
1103 } // release lock
1104
1105 if (wasEmpty) {
1106 mPollLoop->wake();
1107 }
1108}
1109
1110void InputDispatcher::resetKeyRepeatLocked() {
1111 if (mKeyRepeatState.lastKeyEntry) {
1112 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
1113 mKeyRepeatState.lastKeyEntry = NULL;
1114 }
1115}
1116
1117status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001118#if DEBUG_REGISTRATION
1119 LOGD("channel '%s' - Registered", inputChannel->getName().string());
1120#endif
1121
Jeff Browne839a582010-04-22 18:58:52 -07001122 int receiveFd;
1123 { // acquire lock
1124 AutoMutex _l(mLock);
1125
1126 receiveFd = inputChannel->getReceivePipeFd();
1127 if (mConnectionsByReceiveFd.indexOfKey(receiveFd) >= 0) {
1128 LOGW("Attempted to register already registered input channel '%s'",
1129 inputChannel->getName().string());
1130 return BAD_VALUE;
1131 }
1132
1133 sp<Connection> connection = new Connection(inputChannel);
1134 status_t status = connection->initialize();
1135 if (status) {
1136 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
1137 inputChannel->getName().string(), status);
1138 return status;
1139 }
1140
1141 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown54bc2812010-06-15 01:31:58 -07001142
1143 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07001144 } // release lock
1145
1146 mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this);
1147 return OK;
1148}
1149
1150status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001151#if DEBUG_REGISTRATION
1152 LOGD("channel '%s' - Unregistered", inputChannel->getName().string());
1153#endif
1154
Jeff Browne839a582010-04-22 18:58:52 -07001155 int32_t receiveFd;
1156 { // acquire lock
1157 AutoMutex _l(mLock);
1158
1159 receiveFd = inputChannel->getReceivePipeFd();
1160 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd);
1161 if (connectionIndex < 0) {
1162 LOGW("Attempted to unregister already unregistered input channel '%s'",
1163 inputChannel->getName().string());
1164 return BAD_VALUE;
1165 }
1166
1167 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1168 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
1169
1170 connection->status = Connection::STATUS_ZOMBIE;
1171
1172 nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
1173 abortDispatchCycleLocked(currentTime, connection.get(), true /*broken*/);
Jeff Brown54bc2812010-06-15 01:31:58 -07001174
1175 runCommandsLockedInterruptible();
Jeff Browne839a582010-04-22 18:58:52 -07001176 } // release lock
1177
1178 mPollLoop->removeCallback(receiveFd);
1179
1180 // Wake the poll loop because removing the connection may have changed the current
1181 // synchronization state.
1182 mPollLoop->wake();
1183 return OK;
1184}
1185
1186void InputDispatcher::activateConnectionLocked(Connection* connection) {
1187 for (size_t i = 0; i < mActiveConnections.size(); i++) {
1188 if (mActiveConnections.itemAt(i) == connection) {
1189 return;
1190 }
1191 }
1192 mActiveConnections.add(connection);
1193}
1194
1195void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
1196 for (size_t i = 0; i < mActiveConnections.size(); i++) {
1197 if (mActiveConnections.itemAt(i) == connection) {
1198 mActiveConnections.removeAt(i);
1199 return;
1200 }
1201 }
1202}
1203
Jeff Brown54bc2812010-06-15 01:31:58 -07001204void InputDispatcher::onDispatchCycleStartedLocked(
1205 nsecs_t currentTime, Connection* connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001206}
1207
Jeff Brown54bc2812010-06-15 01:31:58 -07001208void InputDispatcher::onDispatchCycleFinishedLocked(
1209 nsecs_t currentTime, Connection* connection, bool recoveredFromANR) {
Jeff Browne839a582010-04-22 18:58:52 -07001210 if (recoveredFromANR) {
1211 LOGI("channel '%s' ~ Recovered from ANR. %01.1fms since event, "
1212 "%01.1fms since dispatch, %01.1fms since ANR",
1213 connection->getInputChannelName(),
1214 connection->getEventLatencyMillis(currentTime),
1215 connection->getDispatchLatencyMillis(currentTime),
1216 connection->getANRLatencyMillis(currentTime));
1217
Jeff Brown54bc2812010-06-15 01:31:58 -07001218 CommandEntry* commandEntry = postCommandLocked(
1219 & InputDispatcher::doNotifyInputChannelRecoveredFromANRLockedInterruptible);
1220 commandEntry->inputChannel = connection->inputChannel;
Jeff Browne839a582010-04-22 18:58:52 -07001221 }
1222}
1223
Jeff Brown54bc2812010-06-15 01:31:58 -07001224void InputDispatcher::onDispatchCycleANRLocked(
1225 nsecs_t currentTime, Connection* connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001226 LOGI("channel '%s' ~ Not responding! %01.1fms since event, %01.1fms since dispatch",
1227 connection->getInputChannelName(),
1228 connection->getEventLatencyMillis(currentTime),
1229 connection->getDispatchLatencyMillis(currentTime));
1230
Jeff Brown54bc2812010-06-15 01:31:58 -07001231 CommandEntry* commandEntry = postCommandLocked(
1232 & InputDispatcher::doNotifyInputChannelANRLockedInterruptible);
1233 commandEntry->inputChannel = connection->inputChannel;
Jeff Browne839a582010-04-22 18:58:52 -07001234}
1235
Jeff Brown54bc2812010-06-15 01:31:58 -07001236void InputDispatcher::onDispatchCycleBrokenLocked(
1237 nsecs_t currentTime, Connection* connection) {
Jeff Browne839a582010-04-22 18:58:52 -07001238 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
1239 connection->getInputChannelName());
1240
Jeff Brown54bc2812010-06-15 01:31:58 -07001241 CommandEntry* commandEntry = postCommandLocked(
1242 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
1243 commandEntry->inputChannel = connection->inputChannel;
Jeff Browne839a582010-04-22 18:58:52 -07001244}
1245
Jeff Brown54bc2812010-06-15 01:31:58 -07001246void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
1247 CommandEntry* commandEntry) {
1248 mLock.unlock();
1249
1250 mPolicy->notifyInputChannelBroken(commandEntry->inputChannel);
1251 commandEntry->inputChannel.clear();
1252
1253 mLock.lock();
1254}
1255
1256void InputDispatcher::doNotifyInputChannelANRLockedInterruptible(
1257 CommandEntry* commandEntry) {
1258 mLock.unlock();
1259
1260 mPolicy->notifyInputChannelANR(commandEntry->inputChannel);
1261 commandEntry->inputChannel.clear();
1262
1263 mLock.lock();
1264}
1265
1266void InputDispatcher::doNotifyInputChannelRecoveredFromANRLockedInterruptible(
1267 CommandEntry* commandEntry) {
1268 mLock.unlock();
1269
1270 mPolicy->notifyInputChannelRecoveredFromANR(commandEntry->inputChannel);
1271 commandEntry->inputChannel.clear();
1272
1273 mLock.lock();
1274}
1275
1276
Jeff Browne839a582010-04-22 18:58:52 -07001277// --- InputDispatcher::Allocator ---
1278
1279InputDispatcher::Allocator::Allocator() {
1280}
1281
1282InputDispatcher::ConfigurationChangedEntry*
1283InputDispatcher::Allocator::obtainConfigurationChangedEntry() {
1284 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
1285 entry->refCount = 1;
1286 entry->type = EventEntry::TYPE_CONFIGURATION_CHANGED;
Jeff Brown54bc2812010-06-15 01:31:58 -07001287 entry->dispatchInProgress = false;
Jeff Browne839a582010-04-22 18:58:52 -07001288 return entry;
1289}
1290
1291InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry() {
1292 KeyEntry* entry = mKeyEntryPool.alloc();
1293 entry->refCount = 1;
1294 entry->type = EventEntry::TYPE_KEY;
Jeff Brown54bc2812010-06-15 01:31:58 -07001295 entry->dispatchInProgress = false;
Jeff Browne839a582010-04-22 18:58:52 -07001296 return entry;
1297}
1298
1299InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry() {
1300 MotionEntry* entry = mMotionEntryPool.alloc();
1301 entry->refCount = 1;
1302 entry->type = EventEntry::TYPE_MOTION;
1303 entry->firstSample.next = NULL;
Jeff Brown54bc2812010-06-15 01:31:58 -07001304 entry->dispatchInProgress = false;
Jeff Browne839a582010-04-22 18:58:52 -07001305 return entry;
1306}
1307
1308InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
1309 EventEntry* eventEntry) {
1310 DispatchEntry* entry = mDispatchEntryPool.alloc();
1311 entry->eventEntry = eventEntry;
1312 eventEntry->refCount += 1;
1313 return entry;
1314}
1315
Jeff Brown54bc2812010-06-15 01:31:58 -07001316InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
1317 CommandEntry* entry = mCommandEntryPool.alloc();
1318 entry->command = command;
1319 return entry;
1320}
1321
Jeff Browne839a582010-04-22 18:58:52 -07001322void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
1323 switch (entry->type) {
1324 case EventEntry::TYPE_CONFIGURATION_CHANGED:
1325 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
1326 break;
1327 case EventEntry::TYPE_KEY:
1328 releaseKeyEntry(static_cast<KeyEntry*>(entry));
1329 break;
1330 case EventEntry::TYPE_MOTION:
1331 releaseMotionEntry(static_cast<MotionEntry*>(entry));
1332 break;
1333 default:
1334 assert(false);
1335 break;
1336 }
1337}
1338
1339void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
1340 ConfigurationChangedEntry* entry) {
1341 entry->refCount -= 1;
1342 if (entry->refCount == 0) {
1343 mConfigurationChangeEntryPool.free(entry);
1344 } else {
1345 assert(entry->refCount > 0);
1346 }
1347}
1348
1349void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
1350 entry->refCount -= 1;
1351 if (entry->refCount == 0) {
1352 mKeyEntryPool.free(entry);
1353 } else {
1354 assert(entry->refCount > 0);
1355 }
1356}
1357
1358void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
1359 entry->refCount -= 1;
1360 if (entry->refCount == 0) {
Jeff Brown54bc2812010-06-15 01:31:58 -07001361 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
1362 MotionSample* next = sample->next;
1363 mMotionSamplePool.free(sample);
1364 sample = next;
1365 }
Jeff Browne839a582010-04-22 18:58:52 -07001366 mMotionEntryPool.free(entry);
1367 } else {
1368 assert(entry->refCount > 0);
1369 }
1370}
1371
1372void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
1373 releaseEventEntry(entry->eventEntry);
1374 mDispatchEntryPool.free(entry);
1375}
1376
Jeff Brown54bc2812010-06-15 01:31:58 -07001377void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
1378 mCommandEntryPool.free(entry);
1379}
1380
Jeff Browne839a582010-04-22 18:58:52 -07001381void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
1382 nsecs_t eventTime, int32_t pointerCount, const PointerCoords* pointerCoords) {
1383 MotionSample* sample = mMotionSamplePool.alloc();
1384 sample->eventTime = eventTime;
1385 for (int32_t i = 0; i < pointerCount; i++) {
1386 sample->pointerCoords[i] = pointerCoords[i];
1387 }
1388
1389 sample->next = NULL;
1390 motionEntry->lastSample->next = sample;
1391 motionEntry->lastSample = sample;
1392}
1393
Jeff Browne839a582010-04-22 18:58:52 -07001394// --- InputDispatcher::Connection ---
1395
1396InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
1397 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
1398 nextTimeoutTime(LONG_LONG_MAX),
1399 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX),
1400 lastANRTime(LONG_LONG_MAX) {
1401}
1402
1403InputDispatcher::Connection::~Connection() {
1404}
1405
1406status_t InputDispatcher::Connection::initialize() {
1407 return inputPublisher.initialize();
1408}
1409
Jeff Brown54bc2812010-06-15 01:31:58 -07001410const char* InputDispatcher::Connection::getStatusLabel() const {
1411 switch (status) {
1412 case STATUS_NORMAL:
1413 return "NORMAL";
1414
1415 case STATUS_BROKEN:
1416 return "BROKEN";
1417
1418 case STATUS_NOT_RESPONDING:
1419 return "NOT_RESPONDING";
1420
1421 case STATUS_ZOMBIE:
1422 return "ZOMBIE";
1423
1424 default:
1425 return "UNKNOWN";
1426 }
1427}
1428
Jeff Browne839a582010-04-22 18:58:52 -07001429InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
1430 const EventEntry* eventEntry) const {
1431 for (DispatchEntry* dispatchEntry = outboundQueue.tail.prev;
1432 dispatchEntry != & outboundQueue.head; dispatchEntry = dispatchEntry->prev) {
1433 if (dispatchEntry->eventEntry == eventEntry) {
1434 return dispatchEntry;
1435 }
1436 }
1437 return NULL;
1438}
1439
Jeff Brown54bc2812010-06-15 01:31:58 -07001440// --- InputDispatcher::CommandEntry ---
1441
1442InputDispatcher::CommandEntry::CommandEntry() {
1443}
1444
1445InputDispatcher::CommandEntry::~CommandEntry() {
1446}
1447
Jeff Browne839a582010-04-22 18:58:52 -07001448
1449// --- InputDispatcherThread ---
1450
1451InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
1452 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
1453}
1454
1455InputDispatcherThread::~InputDispatcherThread() {
1456}
1457
1458bool InputDispatcherThread::threadLoop() {
1459 mDispatcher->dispatchOnce();
1460 return true;
1461}
1462
1463} // namespace android