blob: 8db8c421061a02d9fc3b757152c8e7cff50df6e4 [file] [log] [blame]
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001//
2// Copyright 2010 The Android Open Source Project
3//
4// The input dispatcher.
5//
6#define LOG_TAG "InputDispatcher"
7
8//#define LOG_NDEBUG 0
9
10// Log detailed debug messages about each inbound event notification to the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070011#define DEBUG_INBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070012
13// Log detailed debug messages about each outbound event processed by the dispatcher.
Jeff Brown349703e2010-06-22 01:27:15 -070014#define DEBUG_OUTBOUND_EVENT_DETAILS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070015
16// Log debug messages about batching.
Jeff Brown349703e2010-06-22 01:27:15 -070017#define DEBUG_BATCHING 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070018
19// Log debug messages about the dispatch cycle.
Jeff Brown349703e2010-06-22 01:27:15 -070020#define DEBUG_DISPATCH_CYCLE 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070021
Jeff Brown9c3cda02010-06-15 01:31:58 -070022// Log debug messages about registrations.
Jeff Brown349703e2010-06-22 01:27:15 -070023#define DEBUG_REGISTRATION 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070024
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070025// Log debug messages about performance statistics.
Jeff Brown349703e2010-06-22 01:27:15 -070026#define DEBUG_PERFORMANCE_STATISTICS 0
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070027
Jeff Brown7fbdc842010-06-17 20:52:56 -070028// Log debug messages about input event injection.
Jeff Brown349703e2010-06-22 01:27:15 -070029#define DEBUG_INJECTION 0
Jeff Brown7fbdc842010-06-17 20:52:56 -070030
Jeff Brownae9fc032010-08-18 15:51:08 -070031// Log debug messages about input event throttling.
32#define DEBUG_THROTTLING 0
33
Jeff Brownb88102f2010-09-08 11:49:43 -070034// Log debug messages about input focus tracking.
35#define DEBUG_FOCUS 0
36
37// Log debug messages about the app switch latency optimization.
38#define DEBUG_APP_SWITCH 0
39
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070040#include <cutils/log.h>
41#include <ui/InputDispatcher.h>
Jeff Brownb88102f2010-09-08 11:49:43 -070042#include <ui/PowerManager.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070043
44#include <stddef.h>
45#include <unistd.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070046#include <errno.h>
47#include <limits.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070048
49namespace android {
50
Jeff Brownb88102f2010-09-08 11:49:43 -070051// Delay between reporting long touch events to the power manager.
52const nsecs_t EVENT_IGNORE_DURATION = 300 * 1000000LL; // 300 ms
53
54// Default input dispatching timeout if there is no focused application or paused window
55// from which to determine an appropriate dispatching timeout.
56const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
57
58// Amount of time to allow for all pending events to be processed when an app switch
59// key is on the way. This is used to preempt input dispatch and drop input events
60// when an application takes too long to respond and the user has pressed an app switch key.
61const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
62
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070063
Jeff Brown7fbdc842010-06-17 20:52:56 -070064static inline nsecs_t now() {
65 return systemTime(SYSTEM_TIME_MONOTONIC);
66}
67
Jeff Brownb88102f2010-09-08 11:49:43 -070068static inline const char* toString(bool value) {
69 return value ? "true" : "false";
70}
71
Jeff Brown01ce2e92010-09-26 22:20:12 -070072static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
73 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
74 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
75}
76
77static bool isValidKeyAction(int32_t action) {
78 switch (action) {
79 case AKEY_EVENT_ACTION_DOWN:
80 case AKEY_EVENT_ACTION_UP:
81 return true;
82 default:
83 return false;
84 }
85}
86
87static bool validateKeyEvent(int32_t action) {
88 if (! isValidKeyAction(action)) {
89 LOGE("Key event has invalid action code 0x%x", action);
90 return false;
91 }
92 return true;
93}
94
95static bool isValidMotionAction(int32_t action) {
96 switch (action & AMOTION_EVENT_ACTION_MASK) {
97 case AMOTION_EVENT_ACTION_DOWN:
98 case AMOTION_EVENT_ACTION_UP:
99 case AMOTION_EVENT_ACTION_CANCEL:
100 case AMOTION_EVENT_ACTION_MOVE:
101 case AMOTION_EVENT_ACTION_POINTER_DOWN:
102 case AMOTION_EVENT_ACTION_POINTER_UP:
103 case AMOTION_EVENT_ACTION_OUTSIDE:
104 return true;
105 default:
106 return false;
107 }
108}
109
110static bool validateMotionEvent(int32_t action, size_t pointerCount,
111 const int32_t* pointerIds) {
112 if (! isValidMotionAction(action)) {
113 LOGE("Motion event has invalid action code 0x%x", action);
114 return false;
115 }
116 if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
117 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
118 pointerCount, MAX_POINTERS);
119 return false;
120 }
121 for (size_t i = 0; i < pointerCount; i++) {
122 if (pointerIds[i] < 0 || pointerIds[i] > MAX_POINTER_ID) {
123 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
124 pointerIds[i], MAX_POINTER_ID);
125 return false;
126 }
127 }
128 return true;
129}
130
Jeff Brownb88102f2010-09-08 11:49:43 -0700131
132// --- InputWindow ---
133
134bool InputWindow::visibleFrameIntersects(const InputWindow* other) const {
135 return visibleFrameRight > other->visibleFrameLeft
136 && visibleFrameLeft < other->visibleFrameRight
137 && visibleFrameBottom > other->visibleFrameTop
138 && visibleFrameTop < other->visibleFrameBottom;
139}
140
141bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
142 return x >= touchableAreaLeft && x <= touchableAreaRight
143 && y >= touchableAreaTop && y <= touchableAreaBottom;
144}
145
146
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700147// --- InputDispatcher ---
148
Jeff Brown9c3cda02010-06-15 01:31:58 -0700149InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
Jeff Brownb88102f2010-09-08 11:49:43 -0700150 mPolicy(policy),
151 mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
152 mDispatchEnabled(true), mDispatchFrozen(false),
Jeff Brown01ce2e92010-09-26 22:20:12 -0700153 mFocusedWindow(NULL),
Jeff Brownb88102f2010-09-08 11:49:43 -0700154 mFocusedApplication(NULL),
155 mCurrentInputTargetsValid(false),
156 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700157 mLooper = new Looper(false);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700158
Jeff Brownb88102f2010-09-08 11:49:43 -0700159 mInboundQueue.headSentinel.refCount = -1;
160 mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
161 mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700162
Jeff Brownb88102f2010-09-08 11:49:43 -0700163 mInboundQueue.tailSentinel.refCount = -1;
164 mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
165 mInboundQueue.tailSentinel.eventTime = LONG_LONG_MAX;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700166
167 mKeyRepeatState.lastKeyEntry = NULL;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700168
Jeff Brownae9fc032010-08-18 15:51:08 -0700169 int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
170 mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
171 mThrottleState.lastDeviceId = -1;
172
173#if DEBUG_THROTTLING
174 mThrottleState.originalSampleCount = 0;
175 LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
176#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700177}
178
179InputDispatcher::~InputDispatcher() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700180 { // acquire lock
181 AutoMutex _l(mLock);
182
183 resetKeyRepeatLocked();
Jeff Brown54a18252010-09-16 14:07:33 -0700184 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700185 drainInboundQueueLocked();
186 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700187
188 while (mConnectionsByReceiveFd.size() != 0) {
189 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
190 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700191}
192
193void InputDispatcher::dispatchOnce() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700194 nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700195 nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700196
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700197 nsecs_t nextWakeupTime = LONG_LONG_MAX;
198 { // acquire lock
199 AutoMutex _l(mLock);
Jeff Brownb88102f2010-09-08 11:49:43 -0700200 dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700201
Jeff Brownb88102f2010-09-08 11:49:43 -0700202 if (runCommandsLockedInterruptible()) {
203 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700204 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700205 } // release lock
206
Jeff Brownb88102f2010-09-08 11:49:43 -0700207 // Wait for callback or timeout or wake. (make sure we round up, not down)
208 nsecs_t currentTime = now();
209 int32_t timeoutMillis;
210 if (nextWakeupTime > currentTime) {
211 uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
212 timeout = (timeout + 999999LL) / 1000000LL;
213 timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
214 } else {
215 timeoutMillis = 0;
216 }
217
Jeff Brown4fe6c3e2010-09-13 23:17:30 -0700218 mLooper->pollOnce(timeoutMillis);
Jeff Brownb88102f2010-09-08 11:49:43 -0700219}
220
221void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
222 nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
223 nsecs_t currentTime = now();
224
225 // Reset the key repeat timer whenever we disallow key events, even if the next event
226 // is not a key. This is to ensure that we abort a key repeat if the device is just coming
227 // out of sleep.
228 if (keyRepeatTimeout < 0) {
229 resetKeyRepeatLocked();
230 }
231
232 // If dispatching is disabled, drop all events in the queue.
233 if (! mDispatchEnabled) {
234 if (mPendingEvent || ! mInboundQueue.isEmpty()) {
235 LOGI("Dropping pending events because input dispatch is disabled.");
Jeff Brown54a18252010-09-16 14:07:33 -0700236 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700237 drainInboundQueueLocked();
238 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700239 return;
240 }
241
Jeff Brownb88102f2010-09-08 11:49:43 -0700242 // If dispatching is frozen, do not process timeouts or try to deliver any new events.
243 if (mDispatchFrozen) {
244#if DEBUG_FOCUS
245 LOGD("Dispatch frozen. Waiting some more.");
246#endif
247 return;
248 }
249
250 // Optimize latency of app switches.
251 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
252 // been pressed. When it expires, we preempt dispatch and drop all other pending events.
253 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
254 if (mAppSwitchDueTime < *nextWakeupTime) {
255 *nextWakeupTime = mAppSwitchDueTime;
256 }
257
Jeff Brownb88102f2010-09-08 11:49:43 -0700258 // Ready to start a new event.
259 // If we don't already have a pending event, go grab one.
260 if (! mPendingEvent) {
261 if (mInboundQueue.isEmpty()) {
262 if (isAppSwitchDue) {
263 // The inbound queue is empty so the app switch key we were waiting
264 // for will never arrive. Stop waiting for it.
265 resetPendingAppSwitchLocked(false);
266 isAppSwitchDue = false;
267 }
268
269 // Synthesize a key repeat if appropriate.
270 if (mKeyRepeatState.lastKeyEntry) {
271 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
272 mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
273 } else {
274 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
275 *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
276 }
277 }
278 }
279 if (! mPendingEvent) {
280 return;
281 }
282 } else {
283 // Inbound queue has at least one entry.
284 EventEntry* entry = mInboundQueue.headSentinel.next;
285
286 // Throttle the entry if it is a move event and there are no
287 // other events behind it in the queue. Due to movement batching, additional
288 // samples may be appended to this event by the time the throttling timeout
289 // expires.
290 // TODO Make this smarter and consider throttling per device independently.
291 if (entry->type == EventEntry::TYPE_MOTION) {
292 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
293 int32_t deviceId = motionEntry->deviceId;
294 uint32_t source = motionEntry->source;
295 if (! isAppSwitchDue
296 && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
297 && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
298 && deviceId == mThrottleState.lastDeviceId
299 && source == mThrottleState.lastSource) {
300 nsecs_t nextTime = mThrottleState.lastEventTime
301 + mThrottleState.minTimeBetweenEvents;
302 if (currentTime < nextTime) {
303 // Throttle it!
304#if DEBUG_THROTTLING
305 LOGD("Throttling - Delaying motion event for "
306 "device 0x%x, source 0x%08x by up to %0.3fms.",
307 deviceId, source, (nextTime - currentTime) * 0.000001);
308#endif
309 if (nextTime < *nextWakeupTime) {
310 *nextWakeupTime = nextTime;
311 }
312 if (mThrottleState.originalSampleCount == 0) {
313 mThrottleState.originalSampleCount =
314 motionEntry->countSamples();
315 }
316 return;
317 }
318 }
319
320#if DEBUG_THROTTLING
321 if (mThrottleState.originalSampleCount != 0) {
322 uint32_t count = motionEntry->countSamples();
323 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
324 count - mThrottleState.originalSampleCount,
325 mThrottleState.originalSampleCount, count);
326 mThrottleState.originalSampleCount = 0;
327 }
328#endif
329
330 mThrottleState.lastEventTime = entry->eventTime < currentTime
331 ? entry->eventTime : currentTime;
332 mThrottleState.lastDeviceId = deviceId;
333 mThrottleState.lastSource = source;
334 }
335
336 mInboundQueue.dequeue(entry);
337 mPendingEvent = entry;
338 }
339 }
340
341 // Now we have an event to dispatch.
342 assert(mPendingEvent != NULL);
Jeff Brown54a18252010-09-16 14:07:33 -0700343 bool done = false;
Jeff Brownb88102f2010-09-08 11:49:43 -0700344 switch (mPendingEvent->type) {
345 case EventEntry::TYPE_CONFIGURATION_CHANGED: {
346 ConfigurationChangedEntry* typedEntry =
347 static_cast<ConfigurationChangedEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700348 done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -0700349 break;
350 }
351
352 case EventEntry::TYPE_KEY: {
353 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700354 bool appSwitchKey = isAppSwitchKey(typedEntry->keyCode);
355 bool dropEvent = isAppSwitchDue && ! appSwitchKey;
356 done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout, dropEvent,
357 nextWakeupTime);
358 if (done) {
359 if (dropEvent) {
360 LOGI("Dropped key because of pending overdue app switch.");
361 } else if (appSwitchKey) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700362 resetPendingAppSwitchLocked(true);
Jeff Brownb88102f2010-09-08 11:49:43 -0700363 }
364 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700365 break;
366 }
367
368 case EventEntry::TYPE_MOTION: {
369 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
Jeff Brown54a18252010-09-16 14:07:33 -0700370 bool dropEvent = isAppSwitchDue;
371 done = dispatchMotionLocked(currentTime, typedEntry, dropEvent, nextWakeupTime);
372 if (done) {
373 if (dropEvent) {
374 LOGI("Dropped motion because of pending overdue app switch.");
375 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700376 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700377 break;
378 }
379
380 default:
381 assert(false);
Jeff Brownb88102f2010-09-08 11:49:43 -0700382 break;
383 }
384
Jeff Brown54a18252010-09-16 14:07:33 -0700385 if (done) {
386 releasePendingEventLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700387 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
388 }
389}
390
391bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
392 bool needWake = mInboundQueue.isEmpty();
393 mInboundQueue.enqueueAtTail(entry);
394
395 switch (entry->type) {
396 case EventEntry::TYPE_KEY:
397 needWake |= detectPendingAppSwitchLocked(static_cast<KeyEntry*>(entry));
398 break;
399 }
400
401 return needWake;
402}
403
404bool InputDispatcher::isAppSwitchKey(int32_t keyCode) {
405 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
406}
407
408bool InputDispatcher::isAppSwitchPendingLocked() {
409 return mAppSwitchDueTime != LONG_LONG_MAX;
410}
411
412bool InputDispatcher::detectPendingAppSwitchLocked(KeyEntry* inboundKeyEntry) {
413 if (inboundKeyEntry->action == AKEY_EVENT_ACTION_UP
414 && ! (inboundKeyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
415 && isAppSwitchKey(inboundKeyEntry->keyCode)
416 && isEventFromReliableSourceLocked(inboundKeyEntry)) {
417#if DEBUG_APP_SWITCH
418 LOGD("App switch is pending!");
419#endif
420 mAppSwitchDueTime = inboundKeyEntry->eventTime + APP_SWITCH_TIMEOUT;
421 return true; // need wake
422 }
423 return false;
424}
425
426void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
427 mAppSwitchDueTime = LONG_LONG_MAX;
428
429#if DEBUG_APP_SWITCH
430 if (handled) {
431 LOGD("App switch has arrived.");
432 } else {
433 LOGD("App switch was abandoned.");
434 }
435#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700436}
437
Jeff Brown9c3cda02010-06-15 01:31:58 -0700438bool InputDispatcher::runCommandsLockedInterruptible() {
439 if (mCommandQueue.isEmpty()) {
440 return false;
441 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700442
Jeff Brown9c3cda02010-06-15 01:31:58 -0700443 do {
444 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
445
446 Command command = commandEntry->command;
447 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
448
Jeff Brown7fbdc842010-06-17 20:52:56 -0700449 commandEntry->connection.clear();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700450 mAllocator.releaseCommandEntry(commandEntry);
451 } while (! mCommandQueue.isEmpty());
452 return true;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700453}
454
Jeff Brown9c3cda02010-06-15 01:31:58 -0700455InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
456 CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
457 mCommandQueue.enqueueAtTail(commandEntry);
458 return commandEntry;
459}
460
Jeff Brownb88102f2010-09-08 11:49:43 -0700461void InputDispatcher::drainInboundQueueLocked() {
462 while (! mInboundQueue.isEmpty()) {
463 EventEntry* entry = mInboundQueue.dequeueAtHead();
Jeff Brown54a18252010-09-16 14:07:33 -0700464 releaseInboundEventLocked(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700465 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700466}
467
Jeff Brown54a18252010-09-16 14:07:33 -0700468void InputDispatcher::releasePendingEventLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700469 if (mPendingEvent) {
Jeff Brown54a18252010-09-16 14:07:33 -0700470 releaseInboundEventLocked(mPendingEvent);
Jeff Brownb88102f2010-09-08 11:49:43 -0700471 mPendingEvent = NULL;
472 }
473}
474
Jeff Brown54a18252010-09-16 14:07:33 -0700475void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700476 InjectionState* injectionState = entry->injectionState;
477 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700478#if DEBUG_DISPATCH_CYCLE
Jeff Brown01ce2e92010-09-26 22:20:12 -0700479 LOGD("Injected inbound event was dropped.");
Jeff Brownb88102f2010-09-08 11:49:43 -0700480#endif
481 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
482 }
483 mAllocator.releaseEventEntry(entry);
484}
485
486bool InputDispatcher::isEventFromReliableSourceLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700487 InjectionState* injectionState = entry->injectionState;
488 return ! injectionState
489 || injectionState->injectorUid == 0
Jeff Brownb88102f2010-09-08 11:49:43 -0700490 || mPolicy->checkInjectEventsPermissionNonReentrant(
Jeff Brown01ce2e92010-09-26 22:20:12 -0700491 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -0700492}
493
494void InputDispatcher::resetKeyRepeatLocked() {
495 if (mKeyRepeatState.lastKeyEntry) {
496 mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
497 mKeyRepeatState.lastKeyEntry = NULL;
498 }
499}
500
501InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
Jeff Brownb21fb102010-09-07 10:44:57 -0700502 nsecs_t currentTime, nsecs_t keyRepeatDelay) {
Jeff Brown349703e2010-06-22 01:27:15 -0700503 KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
504
Jeff Brown349703e2010-06-22 01:27:15 -0700505 // Reuse the repeated key entry if it is otherwise unreferenced.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700506 uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700507 if (entry->refCount == 1) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700508 mAllocator.recycleKeyEntry(entry);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700509 entry->eventTime = currentTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700510 entry->policyFlags = policyFlags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700511 entry->repeatCount += 1;
512 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700513 KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -0700514 entry->deviceId, entry->source, policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -0700515 entry->action, entry->flags, entry->keyCode, entry->scanCode,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700516 entry->metaState, entry->repeatCount + 1, entry->downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700517
518 mKeyRepeatState.lastKeyEntry = newEntry;
519 mAllocator.releaseKeyEntry(entry);
520
521 entry = newEntry;
522 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700523 entry->syntheticRepeat = true;
524
525 // Increment reference count since we keep a reference to the event in
526 // mKeyRepeatState.lastKeyEntry in addition to the one we return.
527 entry->refCount += 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700528
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700529 if (entry->repeatCount == 1) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700530 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700531 }
532
Jeff Brownb21fb102010-09-07 10:44:57 -0700533 mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
Jeff Brownb88102f2010-09-08 11:49:43 -0700534 return entry;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700535}
536
Jeff Brownb88102f2010-09-08 11:49:43 -0700537bool InputDispatcher::dispatchConfigurationChangedLocked(
538 nsecs_t currentTime, ConfigurationChangedEntry* entry) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700539#if DEBUG_OUTBOUND_EVENT_DETAILS
Jeff Brownb88102f2010-09-08 11:49:43 -0700540 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
541#endif
542
543 // Reset key repeating in case a keyboard device was added or removed or something.
544 resetKeyRepeatLocked();
545
546 // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
547 CommandEntry* commandEntry = postCommandLocked(
548 & InputDispatcher::doNotifyConfigurationChangedInterruptible);
549 commandEntry->eventTime = entry->eventTime;
550 return true;
551}
552
553bool InputDispatcher::dispatchKeyLocked(
554 nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
Jeff Brown54a18252010-09-16 14:07:33 -0700555 bool dropEvent, nsecs_t* nextWakeupTime) {
556 // Give the policy a chance to intercept the key.
557 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
558 bool trusted;
559 if (! dropEvent && mFocusedWindow) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700560 trusted = checkInjectionPermission(mFocusedWindow, entry->injectionState);
Jeff Brown54a18252010-09-16 14:07:33 -0700561 } else {
562 trusted = isEventFromReliableSourceLocked(entry);
563 }
564 if (trusted) {
565 CommandEntry* commandEntry = postCommandLocked(
566 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
567 if (! dropEvent && mFocusedWindow) {
568 commandEntry->inputChannel = mFocusedWindow->inputChannel;
569 }
570 commandEntry->keyEntry = entry;
571 entry->refCount += 1;
572 return false; // wait for the command to run
573 } else {
574 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
575 }
576 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
577 resetTargetsLocked();
578 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
579 return true;
580 }
581
582 // Clean up if dropping the event.
583 if (dropEvent) {
584 resetTargetsLocked();
585 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
586 return true;
587 }
588
Jeff Brownb88102f2010-09-08 11:49:43 -0700589 // Preprocessing.
590 if (! entry->dispatchInProgress) {
591 logOutboundKeyDetailsLocked("dispatchKey - ", entry);
592
593 if (entry->repeatCount == 0
594 && entry->action == AKEY_EVENT_ACTION_DOWN
595 && ! entry->isInjected()) {
596 if (mKeyRepeatState.lastKeyEntry
597 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
598 // We have seen two identical key downs in a row which indicates that the device
599 // driver is automatically generating key repeats itself. We take note of the
600 // repeat here, but we disable our own next key repeat timer since it is clear that
601 // we will not need to synthesize key repeats ourselves.
602 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
603 resetKeyRepeatLocked();
604 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
605 } else {
606 // Not a repeat. Save key down state in case we do see a repeat later.
607 resetKeyRepeatLocked();
608 mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
609 }
610 mKeyRepeatState.lastKeyEntry = entry;
611 entry->refCount += 1;
612 } else if (! entry->syntheticRepeat) {
613 resetKeyRepeatLocked();
614 }
615
616 entry->dispatchInProgress = true;
Jeff Brown54a18252010-09-16 14:07:33 -0700617 resetTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700618 }
619
620 // Identify targets.
621 if (! mCurrentInputTargetsValid) {
Jeff Brown01ce2e92010-09-26 22:20:12 -0700622 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
623 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700624 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
625 return false;
626 }
627
628 setInjectionResultLocked(entry, injectionResult);
629 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
630 return true;
631 }
632
633 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700634 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700635 }
636
637 // Dispatch the key.
638 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
639
640 // Poke user activity.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700641 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
642 pokeUserActivityLocked(entry->eventTime, POWER_MANAGER_BUTTON_EVENT);
643 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700644 return true;
645}
646
647void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
648#if DEBUG_OUTBOUND_EVENT_DETAILS
649 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
650 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
651 "downTime=%lld",
652 prefix,
653 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
654 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
655 entry->downTime);
656#endif
657}
658
659bool InputDispatcher::dispatchMotionLocked(
Jeff Brown54a18252010-09-16 14:07:33 -0700660 nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
661 // Clean up if dropping the event.
662 if (dropEvent) {
663 resetTargetsLocked();
664 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
665 return true;
666 }
667
Jeff Brownb88102f2010-09-08 11:49:43 -0700668 // Preprocessing.
669 if (! entry->dispatchInProgress) {
670 logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
671
672 entry->dispatchInProgress = true;
Jeff Brown54a18252010-09-16 14:07:33 -0700673 resetTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700674 }
675
676 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
677
678 // Identify targets.
679 if (! mCurrentInputTargetsValid) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700680 int32_t injectionResult;
681 if (isPointerEvent) {
682 // Pointer event. (eg. touchscreen)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700683 injectionResult = findTouchedWindowTargetsLocked(currentTime,
684 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700685 } else {
686 // Non touch event. (eg. trackball)
Jeff Brown01ce2e92010-09-26 22:20:12 -0700687 injectionResult = findFocusedWindowTargetsLocked(currentTime,
688 entry, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700689 }
690 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
691 return false;
692 }
693
694 setInjectionResultLocked(entry, injectionResult);
695 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
696 return true;
697 }
698
699 addMonitoringTargetsLocked();
Jeff Brown01ce2e92010-09-26 22:20:12 -0700700 commitTargetsLocked();
Jeff Brownb88102f2010-09-08 11:49:43 -0700701 }
702
703 // Dispatch the motion.
704 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
705
706 // Poke user activity.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700707 if (shouldPokeUserActivityForCurrentInputTargetsLocked()) {
708 int32_t eventType;
709 if (isPointerEvent) {
710 switch (entry->action) {
711 case AMOTION_EVENT_ACTION_DOWN:
Jeff Brownb88102f2010-09-08 11:49:43 -0700712 eventType = POWER_MANAGER_TOUCH_EVENT;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700713 break;
714 case AMOTION_EVENT_ACTION_UP:
715 eventType = POWER_MANAGER_TOUCH_UP_EVENT;
716 break;
717 default:
718 if (entry->eventTime - entry->downTime >= EVENT_IGNORE_DURATION) {
719 eventType = POWER_MANAGER_TOUCH_EVENT;
720 } else {
721 eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
722 }
723 break;
Jeff Brownb88102f2010-09-08 11:49:43 -0700724 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700725 } else {
726 eventType = POWER_MANAGER_BUTTON_EVENT;
Jeff Brownb88102f2010-09-08 11:49:43 -0700727 }
Jeff Brown01ce2e92010-09-26 22:20:12 -0700728 pokeUserActivityLocked(entry->eventTime, eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700729 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700730 return true;
731}
732
733
734void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
735#if DEBUG_OUTBOUND_EVENT_DETAILS
736 LOGD("%seventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -0700737 "action=0x%x, flags=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700738 "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
Jeff Brownb88102f2010-09-08 11:49:43 -0700739 prefix,
Jeff Brown85a31762010-09-01 17:01:00 -0700740 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
741 entry->action, entry->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700742 entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
743 entry->downTime);
744
745 // Print the most recent sample that we have available, this may change due to batching.
746 size_t sampleCount = 1;
Jeff Brownb88102f2010-09-08 11:49:43 -0700747 const MotionSample* sample = & entry->firstSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700748 for (; sample->next != NULL; sample = sample->next) {
749 sampleCount += 1;
750 }
751 for (uint32_t i = 0; i < entry->pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -0700752 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -0700753 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -0700754 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700755 i, entry->pointerIds[i],
Jeff Brown8d608662010-08-30 03:02:23 -0700756 sample->pointerCoords[i].x, sample->pointerCoords[i].y,
757 sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
758 sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
759 sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
760 sample->pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700761 }
762
763 // Keep in mind that due to batching, it is possible for the number of samples actually
764 // dispatched to change before the application finally consumed them.
Jeff Brownc5ed5912010-07-14 18:48:53 -0700765 if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700766 LOGD(" ... Total movement samples currently batched %d ...", sampleCount);
767 }
768#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700769}
770
771void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
772 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
773#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -0700774 LOGD("dispatchEventToCurrentInputTargets - "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700775 "resumeWithAppendedMotionSample=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -0700776 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700777#endif
778
Jeff Brown9c3cda02010-06-15 01:31:58 -0700779 assert(eventEntry->dispatchInProgress); // should already have been set to true
780
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700781 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
782 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
783
Jeff Brown519e0242010-09-15 15:18:56 -0700784 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700785 if (connectionIndex >= 0) {
786 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700787 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700788 resumeWithAppendedMotionSample);
789 } else {
790 LOGW("Framework requested delivery of an input event to channel '%s' but it "
791 "is not registered with the input dispatcher.",
792 inputTarget.inputChannel->getName().string());
793 }
794 }
795}
796
Jeff Brown54a18252010-09-16 14:07:33 -0700797void InputDispatcher::resetTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700798 mCurrentInputTargetsValid = false;
799 mCurrentInputTargets.clear();
Jeff Brownb88102f2010-09-08 11:49:43 -0700800 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
801}
802
Jeff Brown01ce2e92010-09-26 22:20:12 -0700803void InputDispatcher::commitTargetsLocked() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700804 mCurrentInputTargetsValid = true;
805}
806
807int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
808 const EventEntry* entry, const InputApplication* application, const InputWindow* window,
809 nsecs_t* nextWakeupTime) {
810 if (application == NULL && window == NULL) {
811 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
812#if DEBUG_FOCUS
813 LOGD("Waiting for system to become ready for input.");
814#endif
815 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
816 mInputTargetWaitStartTime = currentTime;
817 mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
818 mInputTargetWaitTimeoutExpired = false;
819 }
820 } else {
821 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
822#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700823 LOGD("Waiting for application to become ready for input: %s",
824 getApplicationWindowLabelLocked(application, window).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700825#endif
826 nsecs_t timeout = window ? window->dispatchingTimeout :
827 application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
828
829 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
830 mInputTargetWaitStartTime = currentTime;
831 mInputTargetWaitTimeoutTime = currentTime + timeout;
832 mInputTargetWaitTimeoutExpired = false;
833 }
834 }
835
836 if (mInputTargetWaitTimeoutExpired) {
837 return INPUT_EVENT_INJECTION_TIMED_OUT;
838 }
839
840 if (currentTime >= mInputTargetWaitTimeoutTime) {
Jeff Brown519e0242010-09-15 15:18:56 -0700841 onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
Jeff Brownb88102f2010-09-08 11:49:43 -0700842
843 // Force poll loop to wake up immediately on next iteration once we get the
844 // ANR response back from the policy.
845 *nextWakeupTime = LONG_LONG_MIN;
846 return INPUT_EVENT_INJECTION_PENDING;
847 } else {
848 // Force poll loop to wake up when timeout is due.
849 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
850 *nextWakeupTime = mInputTargetWaitTimeoutTime;
851 }
852 return INPUT_EVENT_INJECTION_PENDING;
853 }
854}
855
Jeff Brown519e0242010-09-15 15:18:56 -0700856void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
857 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700858 if (newTimeout > 0) {
859 // Extend the timeout.
860 mInputTargetWaitTimeoutTime = now() + newTimeout;
861 } else {
862 // Give up.
863 mInputTargetWaitTimeoutExpired = true;
Jeff Brown519e0242010-09-15 15:18:56 -0700864
Jeff Brown01ce2e92010-09-26 22:20:12 -0700865 // Release the touch targets.
866 mTouchState.reset();
Jeff Brown2a95c2a2010-09-16 12:31:46 -0700867
Jeff Brown519e0242010-09-15 15:18:56 -0700868 // Input state will not be realistic. Mark it out of sync.
Jeff Browndc3e0052010-09-16 11:02:16 -0700869 if (inputChannel.get()) {
870 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
871 if (connectionIndex >= 0) {
872 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
873 connection->inputState.setOutOfSync();
874 }
Jeff Brown519e0242010-09-15 15:18:56 -0700875 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700876 }
877}
878
Jeff Brown519e0242010-09-15 15:18:56 -0700879nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
Jeff Brownb88102f2010-09-08 11:49:43 -0700880 nsecs_t currentTime) {
881 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
882 return currentTime - mInputTargetWaitStartTime;
883 }
884 return 0;
885}
886
887void InputDispatcher::resetANRTimeoutsLocked() {
888#if DEBUG_FOCUS
889 LOGD("Resetting ANR timeouts.");
890#endif
891
Jeff Brownb88102f2010-09-08 11:49:43 -0700892 // Reset input target wait timeout.
893 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
894}
895
Jeff Brown01ce2e92010-09-26 22:20:12 -0700896int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
897 const EventEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700898 mCurrentInputTargets.clear();
899
900 int32_t injectionResult;
901
902 // If there is no currently focused window and no focused application
903 // then drop the event.
904 if (! mFocusedWindow) {
905 if (mFocusedApplication) {
906#if DEBUG_FOCUS
907 LOGD("Waiting because there is no focused window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -0700908 "focused application that may eventually add a window: %s.",
909 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -0700910#endif
911 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
912 mFocusedApplication, NULL, nextWakeupTime);
913 goto Unresponsive;
914 }
915
916 LOGI("Dropping event because there is no focused window or focused application.");
917 injectionResult = INPUT_EVENT_INJECTION_FAILED;
918 goto Failed;
919 }
920
921 // Check permissions.
Jeff Brown01ce2e92010-09-26 22:20:12 -0700922 if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700923 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
924 goto Failed;
925 }
926
927 // If the currently focused window is paused then keep waiting.
928 if (mFocusedWindow->paused) {
929#if DEBUG_FOCUS
930 LOGD("Waiting because focused window is paused.");
931#endif
932 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
933 mFocusedApplication, mFocusedWindow, nextWakeupTime);
934 goto Unresponsive;
935 }
936
Jeff Brown519e0242010-09-15 15:18:56 -0700937 // If the currently focused window is still working on previous events then keep waiting.
938 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
939#if DEBUG_FOCUS
940 LOGD("Waiting because focused window still processing previous input.");
941#endif
942 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
943 mFocusedApplication, mFocusedWindow, nextWakeupTime);
944 goto Unresponsive;
945 }
946
Jeff Brownb88102f2010-09-08 11:49:43 -0700947 // Success! Output targets.
948 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brown01ce2e92010-09-26 22:20:12 -0700949 addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -0700950
951 // Done.
952Failed:
953Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -0700954 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
955 updateDispatchStatisticsLocked(currentTime, entry,
956 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -0700957#if DEBUG_FOCUS
Jeff Brown519e0242010-09-15 15:18:56 -0700958 LOGD("findFocusedWindow finished: injectionResult=%d, "
959 "timeSpendWaitingForApplication=%0.1fms",
960 injectionResult, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -0700961#endif
962 return injectionResult;
963}
964
Jeff Brown01ce2e92010-09-26 22:20:12 -0700965int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
966 const MotionEntry* entry, nsecs_t* nextWakeupTime) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700967 enum InjectionPermission {
968 INJECTION_PERMISSION_UNKNOWN,
969 INJECTION_PERMISSION_GRANTED,
970 INJECTION_PERMISSION_DENIED
971 };
972
Jeff Brownb88102f2010-09-08 11:49:43 -0700973 mCurrentInputTargets.clear();
974
975 nsecs_t startTime = now();
976
977 // For security reasons, we defer updating the touch state until we are sure that
978 // event injection will be allowed.
979 //
980 // FIXME In the original code, screenWasOff could never be set to true.
981 // The reason is that the POLICY_FLAG_WOKE_HERE
982 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
983 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was
984 // actually enqueued using the policyFlags that appeared in the final EV_SYN
985 // events upon which no preprocessing took place. So policyFlags was always 0.
986 // In the new native input dispatcher we're a bit more careful about event
987 // preprocessing so the touches we receive can actually have non-zero policyFlags.
988 // Unfortunately we obtain undesirable behavior.
989 //
990 // Here's what happens:
991 //
992 // When the device dims in anticipation of going to sleep, touches
993 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
994 // the device to brighten and reset the user activity timer.
995 // Touches on other windows (such as the launcher window)
996 // are dropped. Then after a moment, the device goes to sleep. Oops.
997 //
998 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
999 // instead of POLICY_FLAG_WOKE_HERE...
1000 //
1001 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1002
1003 int32_t action = entry->action;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001004 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
Jeff Brownb88102f2010-09-08 11:49:43 -07001005
1006 // Update the touch state as needed based on the properties of the touch event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001007 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
1008 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1009 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1010 mTempTouchState.reset();
1011 mTempTouchState.down = true;
1012 } else {
1013 mTempTouchState.copyFrom(mTouchState);
1014 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001015
Jeff Brown01ce2e92010-09-26 22:20:12 -07001016 bool isSplit = mTempTouchState.split && mTempTouchState.down;
1017 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1018 || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
1019 /* Case 1: New splittable pointer going down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001020
Jeff Brown01ce2e92010-09-26 22:20:12 -07001021 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1022 int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
1023 int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
1024 const InputWindow* newTouchedWindow = NULL;
1025 const InputWindow* topErrorWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07001026
1027 // Traverse windows from front to back to find touched window and outside targets.
1028 size_t numWindows = mWindows.size();
1029 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001030 const InputWindow* window = & mWindows.editItemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07001031 int32_t flags = window->layoutParamsFlags;
1032
1033 if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
1034 if (! topErrorWindow) {
1035 topErrorWindow = window;
1036 }
1037 }
1038
1039 if (window->visible) {
1040 if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
1041 bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
1042 | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
1043 if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
1044 if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
1045 newTouchedWindow = window;
Jeff Brownb88102f2010-09-08 11:49:43 -07001046 }
1047 break; // found touched window, exit window loop
1048 }
1049 }
1050
Jeff Brown01ce2e92010-09-26 22:20:12 -07001051 if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1052 && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
1053 mTempTouchState.addOrUpdateWindow(window,
1054 InputTarget::FLAG_OUTSIDE, BitSet32(0));
Jeff Brownb88102f2010-09-08 11:49:43 -07001055 }
1056 }
1057 }
1058
1059 // If there is an error window but it is not taking focus (typically because
1060 // it is invisible) then wait for it. Any other focused window may in
1061 // fact be in ANR state.
1062 if (topErrorWindow && newTouchedWindow != topErrorWindow) {
1063#if DEBUG_FOCUS
1064 LOGD("Waiting because system error window is pending.");
1065#endif
1066 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1067 NULL, NULL, nextWakeupTime);
1068 injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1069 goto Unresponsive;
1070 }
1071
Jeff Brown01ce2e92010-09-26 22:20:12 -07001072 // Figure out whether splitting will be allowed for this window.
1073 if (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
1074 // New window supports splitting.
1075 isSplit = true;
1076 } else if (isSplit) {
1077 // New window does not support splitting but we have already split events.
1078 // Assign the pointer to the first foreground window we find.
1079 // (May be NULL which is why we put this code block before the next check.)
1080 newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
1081 }
1082 int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
1083 if (isSplit) {
1084 targetFlags |= InputTarget::FLAG_SPLIT;
1085 }
1086
Jeff Brownb88102f2010-09-08 11:49:43 -07001087 // If we did not find a touched window then fail.
1088 if (! newTouchedWindow) {
1089 if (mFocusedApplication) {
1090#if DEBUG_FOCUS
1091 LOGD("Waiting because there is no touched window but there is a "
Jeff Brown519e0242010-09-15 15:18:56 -07001092 "focused application that may eventually add a new window: %s.",
1093 getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
Jeff Brownb88102f2010-09-08 11:49:43 -07001094#endif
1095 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1096 mFocusedApplication, NULL, nextWakeupTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001097 goto Unresponsive;
1098 }
1099
1100 LOGI("Dropping event because there is no touched window or focused application.");
1101 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001102 goto Failed;
1103 }
1104
Jeff Brown01ce2e92010-09-26 22:20:12 -07001105 // Update the temporary touch state.
1106 BitSet32 pointerIds;
1107 if (isSplit) {
1108 uint32_t pointerId = entry->pointerIds[pointerIndex];
1109 pointerIds.markBit(pointerId);
Jeff Brownb88102f2010-09-08 11:49:43 -07001110 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001111 mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001112 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001113 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
Jeff Brownb88102f2010-09-08 11:49:43 -07001114
1115 // If the pointer is not currently down, then ignore the event.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001116 if (! mTempTouchState.down) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001117 LOGI("Dropping event because the pointer is not down.");
1118 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001119 goto Failed;
1120 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001121 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001122
Jeff Brown01ce2e92010-09-26 22:20:12 -07001123 // Check permission to inject into all touched foreground windows and ensure there
1124 // is at least one touched foreground window.
1125 {
1126 bool haveForegroundWindow = false;
1127 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1128 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1129 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1130 haveForegroundWindow = true;
1131 if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
1132 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1133 injectionPermission = INJECTION_PERMISSION_DENIED;
1134 goto Failed;
1135 }
1136 }
1137 }
1138 if (! haveForegroundWindow) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001139#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown01ce2e92010-09-26 22:20:12 -07001140 LOGD("Dropping event because there is no touched foreground window to receive it.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001141#endif
1142 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001143 goto Failed;
1144 }
1145
Jeff Brown01ce2e92010-09-26 22:20:12 -07001146 // Permission granted to injection into all touched foreground windows.
1147 injectionPermission = INJECTION_PERMISSION_GRANTED;
1148 }
Jeff Brown519e0242010-09-15 15:18:56 -07001149
Jeff Brown01ce2e92010-09-26 22:20:12 -07001150 // Ensure all touched foreground windows are ready for new input.
1151 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1152 const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
1153 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
1154 // If the touched window is paused then keep waiting.
1155 if (touchedWindow.window->paused) {
1156#if DEBUG_INPUT_DISPATCHER_POLICY
1157 LOGD("Waiting because touched window is paused.");
Jeff Brown519e0242010-09-15 15:18:56 -07001158#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001159 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1160 NULL, touchedWindow.window, nextWakeupTime);
1161 goto Unresponsive;
1162 }
1163
1164 // If the touched window is still working on previous events then keep waiting.
1165 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
1166#if DEBUG_FOCUS
1167 LOGD("Waiting because touched window still processing previous input.");
1168#endif
1169 injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1170 NULL, touchedWindow.window, nextWakeupTime);
1171 goto Unresponsive;
1172 }
1173 }
1174 }
1175
1176 // If this is the first pointer going down and the touched window has a wallpaper
1177 // then also add the touched wallpaper windows so they are locked in for the duration
1178 // of the touch gesture.
1179 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1180 const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
1181 if (foregroundWindow->hasWallpaper) {
1182 for (size_t i = 0; i < mWindows.size(); i++) {
1183 const InputWindow* window = & mWindows[i];
1184 if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
1185 mTempTouchState.addOrUpdateWindow(window, 0, BitSet32(0));
1186 }
1187 }
1188 }
1189 }
1190
1191 // If a touched window has been obscured at any point during the touch gesture, set
1192 // the appropriate flag so we remember it for the entire gesture.
1193 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1194 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1195 if ((touchedWindow.targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) == 0) {
1196 if (isWindowObscuredLocked(touchedWindow.window)) {
1197 touchedWindow.targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
1198 }
Jeff Brown519e0242010-09-15 15:18:56 -07001199 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001200 }
1201
1202 // Success! Output targets.
1203 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
Jeff Brownb88102f2010-09-08 11:49:43 -07001204
Jeff Brown01ce2e92010-09-26 22:20:12 -07001205 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
1206 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
1207 addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
1208 touchedWindow.pointerIds);
Jeff Brownb88102f2010-09-08 11:49:43 -07001209 }
1210
Jeff Brown01ce2e92010-09-26 22:20:12 -07001211 // Drop the outside touch window since we will not care about them in the next iteration.
1212 mTempTouchState.removeOutsideTouchWindows();
1213
Jeff Brownb88102f2010-09-08 11:49:43 -07001214Failed:
1215 // Check injection permission once and for all.
1216 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001217 if (checkInjectionPermission(NULL, entry->injectionState)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001218 injectionPermission = INJECTION_PERMISSION_GRANTED;
1219 } else {
1220 injectionPermission = INJECTION_PERMISSION_DENIED;
1221 }
1222 }
1223
1224 // Update final pieces of touch state if the injector had permission.
1225 if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001226 if (maskedAction == AMOTION_EVENT_ACTION_UP
1227 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
1228 // All pointers up or canceled.
1229 mTempTouchState.reset();
1230 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
1231 // First pointer went down.
1232 if (mTouchState.down) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001233 LOGW("Pointer down received while already down.");
Jeff Brownb88102f2010-09-08 11:49:43 -07001234 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001235 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1236 // One pointer went up.
1237 if (isSplit) {
1238 int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1239 uint32_t pointerId = entry->pointerIds[pointerIndex];
Jeff Brownb88102f2010-09-08 11:49:43 -07001240
Jeff Brown01ce2e92010-09-26 22:20:12 -07001241 for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
1242 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
1243 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
1244 touchedWindow.pointerIds.clearBit(pointerId);
1245 if (touchedWindow.pointerIds.isEmpty()) {
1246 mTempTouchState.windows.removeAt(i);
1247 continue;
1248 }
1249 }
1250 i += 1;
1251 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001252 }
Jeff Brownb88102f2010-09-08 11:49:43 -07001253 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07001254
1255 // Save changes to touch state.
1256 mTouchState.copyFrom(mTempTouchState);
Jeff Brownb88102f2010-09-08 11:49:43 -07001257 } else {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001258#if DEBUG_FOCUS
1259 LOGD("Not updating touch focus because injection was denied.");
1260#endif
Jeff Brownb88102f2010-09-08 11:49:43 -07001261 }
1262
1263Unresponsive:
Jeff Brown519e0242010-09-15 15:18:56 -07001264 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1265 updateDispatchStatisticsLocked(currentTime, entry,
1266 injectionResult, timeSpentWaitingForApplication);
Jeff Brownb88102f2010-09-08 11:49:43 -07001267#if DEBUG_FOCUS
Jeff Brown01ce2e92010-09-26 22:20:12 -07001268 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
1269 "timeSpentWaitingForApplication=%0.1fms",
Jeff Brown519e0242010-09-15 15:18:56 -07001270 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
Jeff Brownb88102f2010-09-08 11:49:43 -07001271#endif
1272 return injectionResult;
1273}
1274
Jeff Brown01ce2e92010-09-26 22:20:12 -07001275void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
1276 BitSet32 pointerIds) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001277 mCurrentInputTargets.push();
1278
1279 InputTarget& target = mCurrentInputTargets.editTop();
1280 target.inputChannel = window->inputChannel;
1281 target.flags = targetFlags;
Jeff Brownb88102f2010-09-08 11:49:43 -07001282 target.xOffset = - window->frameLeft;
1283 target.yOffset = - window->frameTop;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001284 target.windowType = window->layoutParamsType;
1285 target.pointerIds = pointerIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001286}
1287
1288void InputDispatcher::addMonitoringTargetsLocked() {
1289 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1290 mCurrentInputTargets.push();
1291
1292 InputTarget& target = mCurrentInputTargets.editTop();
1293 target.inputChannel = mMonitoringChannels[i];
1294 target.flags = 0;
Jeff Brownb88102f2010-09-08 11:49:43 -07001295 target.xOffset = 0;
1296 target.yOffset = 0;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001297 target.windowType = InputWindow::TYPE_SYSTEM_OVERLAY;
Jeff Brownb88102f2010-09-08 11:49:43 -07001298 }
1299}
1300
1301bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001302 const InjectionState* injectionState) {
1303 if (injectionState
1304 && injectionState->injectorUid > 0
1305 && (window == NULL || window->ownerUid != injectionState->injectorUid)) {
1306 bool result = mPolicy->checkInjectEventsPermissionNonReentrant(
1307 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001308 if (! result) {
1309 if (window) {
1310 LOGW("Permission denied: injecting event from pid %d uid %d to window "
1311 "with input channel %s owned by uid %d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07001312 injectionState->injectorPid, injectionState->injectorUid,
1313 window->inputChannel->getName().string(),
Jeff Brownb88102f2010-09-08 11:49:43 -07001314 window->ownerUid);
1315 } else {
1316 LOGW("Permission denied: injecting event from pid %d uid %d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07001317 injectionState->injectorPid, injectionState->injectorUid);
Jeff Brownb88102f2010-09-08 11:49:43 -07001318 }
1319 return false;
1320 }
1321 }
1322 return true;
1323}
1324
1325bool InputDispatcher::isWindowObscuredLocked(const InputWindow* window) {
1326 size_t numWindows = mWindows.size();
1327 for (size_t i = 0; i < numWindows; i++) {
1328 const InputWindow* other = & mWindows.itemAt(i);
1329 if (other == window) {
1330 break;
1331 }
1332 if (other->visible && window->visibleFrameIntersects(other)) {
1333 return true;
1334 }
1335 }
1336 return false;
1337}
1338
Jeff Brown519e0242010-09-15 15:18:56 -07001339bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
1340 ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
1341 if (connectionIndex >= 0) {
1342 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1343 return connection->outboundQueue.isEmpty();
1344 } else {
1345 return true;
1346 }
1347}
1348
1349String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
1350 const InputWindow* window) {
1351 if (application) {
1352 if (window) {
1353 String8 label(application->name);
1354 label.append(" - ");
1355 label.append(window->name);
1356 return label;
1357 } else {
1358 return application->name;
1359 }
1360 } else if (window) {
1361 return window->name;
1362 } else {
1363 return String8("<unknown application or window>");
1364 }
1365}
1366
Jeff Brown01ce2e92010-09-26 22:20:12 -07001367bool InputDispatcher::shouldPokeUserActivityForCurrentInputTargetsLocked() {
1368 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
1369 if (mCurrentInputTargets[i].windowType == InputWindow::TYPE_KEYGUARD) {
1370 return false;
1371 }
1372 }
1373 return true;
1374}
1375
1376void InputDispatcher::pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001377 CommandEntry* commandEntry = postCommandLocked(
1378 & InputDispatcher::doPokeUserActivityLockedInterruptible);
1379 commandEntry->eventTime = eventTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07001380 commandEntry->userActivityEventType = eventType;
1381}
1382
Jeff Brown7fbdc842010-06-17 20:52:56 -07001383void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
1384 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001385 bool resumeWithAppendedMotionSample) {
1386#if DEBUG_DISPATCH_CYCLE
Jeff Brown519e0242010-09-15 15:18:56 -07001387 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, "
Jeff Brown01ce2e92010-09-26 22:20:12 -07001388 "xOffset=%f, yOffset=%f, "
1389 "windowType=%d, pointerIds=0x%x, "
1390 "resumeWithAppendedMotionSample=%s",
Jeff Brown519e0242010-09-15 15:18:56 -07001391 connection->getInputChannelName(), inputTarget->flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001392 inputTarget->xOffset, inputTarget->yOffset,
Jeff Brown01ce2e92010-09-26 22:20:12 -07001393 inputTarget->windowType, inputTarget->pointerIds.value,
Jeff Brownb88102f2010-09-08 11:49:43 -07001394 toString(resumeWithAppendedMotionSample));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001395#endif
1396
Jeff Brown01ce2e92010-09-26 22:20:12 -07001397 // Make sure we are never called for streaming when splitting across multiple windows.
1398 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1399 assert(! (resumeWithAppendedMotionSample && isSplit));
1400
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001401 // Skip this event if the connection status is not normal.
Jeff Brown519e0242010-09-15 15:18:56 -07001402 // We don't want to enqueue additional outbound events if the connection is broken.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001403 if (connection->status != Connection::STATUS_NORMAL) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001404 LOGW("channel '%s' ~ Dropping event because the channel status is %s",
1405 connection->getInputChannelName(), connection->getStatusLabel());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001406 return;
1407 }
1408
Jeff Brown01ce2e92010-09-26 22:20:12 -07001409 // Split a motion event if needed.
1410 if (isSplit) {
1411 assert(eventEntry->type == EventEntry::TYPE_MOTION);
1412
1413 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
1414 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
1415 MotionEntry* splitMotionEntry = splitMotionEvent(
1416 originalMotionEntry, inputTarget->pointerIds);
1417#if DEBUG_FOCUS
1418 LOGD("channel '%s' ~ Split motion event.",
1419 connection->getInputChannelName());
1420 logOutboundMotionDetailsLocked(" ", splitMotionEntry);
1421#endif
1422 eventEntry = splitMotionEntry;
1423 }
1424 }
1425
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001426 // Resume the dispatch cycle with a freshly appended motion sample.
1427 // First we check that the last dispatch entry in the outbound queue is for the same
1428 // motion event to which we appended the motion sample. If we find such a dispatch
1429 // entry, and if it is currently in progress then we try to stream the new sample.
1430 bool wasEmpty = connection->outboundQueue.isEmpty();
1431
1432 if (! wasEmpty && resumeWithAppendedMotionSample) {
1433 DispatchEntry* motionEventDispatchEntry =
1434 connection->findQueuedDispatchEntryForEvent(eventEntry);
1435 if (motionEventDispatchEntry) {
1436 // If the dispatch entry is not in progress, then we must be busy dispatching an
1437 // earlier event. Not a problem, the motion event is on the outbound queue and will
1438 // be dispatched later.
1439 if (! motionEventDispatchEntry->inProgress) {
1440#if DEBUG_BATCHING
1441 LOGD("channel '%s' ~ Not streaming because the motion event has "
1442 "not yet been dispatched. "
1443 "(Waiting for earlier events to be consumed.)",
1444 connection->getInputChannelName());
1445#endif
1446 return;
1447 }
1448
1449 // If the dispatch entry is in progress but it already has a tail of pending
1450 // motion samples, then it must mean that the shared memory buffer filled up.
1451 // Not a problem, when this dispatch cycle is finished, we will eventually start
1452 // a new dispatch cycle to process the tail and that tail includes the newly
1453 // appended motion sample.
1454 if (motionEventDispatchEntry->tailMotionSample) {
1455#if DEBUG_BATCHING
1456 LOGD("channel '%s' ~ Not streaming because no new samples can "
1457 "be appended to the motion event in this dispatch cycle. "
1458 "(Waiting for next dispatch cycle to start.)",
1459 connection->getInputChannelName());
1460#endif
1461 return;
1462 }
1463
1464 // The dispatch entry is in progress and is still potentially open for streaming.
1465 // Try to stream the new motion sample. This might fail if the consumer has already
1466 // consumed the motion event (or if the channel is broken).
Jeff Brown01ce2e92010-09-26 22:20:12 -07001467 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
1468 MotionSample* appendedMotionSample = motionEntry->lastSample;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001469 status_t status = connection->inputPublisher.appendMotionSample(
1470 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1471 if (status == OK) {
1472#if DEBUG_BATCHING
1473 LOGD("channel '%s' ~ Successfully streamed new motion sample.",
1474 connection->getInputChannelName());
1475#endif
1476 return;
1477 }
1478
1479#if DEBUG_BATCHING
1480 if (status == NO_MEMORY) {
1481 LOGD("channel '%s' ~ Could not append motion sample to currently "
1482 "dispatched move event because the shared memory buffer is full. "
1483 "(Waiting for next dispatch cycle to start.)",
1484 connection->getInputChannelName());
1485 } else if (status == status_t(FAILED_TRANSACTION)) {
1486 LOGD("channel '%s' ~ Could not append motion sample to currently "
Jeff Brown349703e2010-06-22 01:27:15 -07001487 "dispatched move event because the event has already been consumed. "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001488 "(Waiting for next dispatch cycle to start.)",
1489 connection->getInputChannelName());
1490 } else {
1491 LOGD("channel '%s' ~ Could not append motion sample to currently "
1492 "dispatched move event due to an error, status=%d. "
1493 "(Waiting for next dispatch cycle to start.)",
1494 connection->getInputChannelName(), status);
1495 }
1496#endif
1497 // Failed to stream. Start a new tail of pending motion samples to dispatch
1498 // in the next cycle.
1499 motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
1500 return;
1501 }
1502 }
1503
Jeff Brownb88102f2010-09-08 11:49:43 -07001504 // Bring the input state back in line with reality in case it drifted off during an ANR.
1505 if (connection->inputState.isOutOfSync()) {
1506 mTempCancelationEvents.clear();
1507 connection->inputState.synthesizeCancelationEvents(& mAllocator, mTempCancelationEvents);
1508 connection->inputState.resetOutOfSync();
1509
1510 if (! mTempCancelationEvents.isEmpty()) {
1511 LOGI("channel '%s' ~ Generated %d cancelation events to bring channel back in sync "
1512 "with reality.",
1513 connection->getInputChannelName(), mTempCancelationEvents.size());
1514
1515 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
1516 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
1517 switch (cancelationEventEntry->type) {
1518 case EventEntry::TYPE_KEY:
1519 logOutboundKeyDetailsLocked(" ",
1520 static_cast<KeyEntry*>(cancelationEventEntry));
1521 break;
1522 case EventEntry::TYPE_MOTION:
1523 logOutboundMotionDetailsLocked(" ",
1524 static_cast<MotionEntry*>(cancelationEventEntry));
1525 break;
1526 }
1527
1528 DispatchEntry* cancelationDispatchEntry =
1529 mAllocator.obtainDispatchEntry(cancelationEventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07001530 0, inputTarget->xOffset, inputTarget->yOffset); // increments ref
Jeff Brownb88102f2010-09-08 11:49:43 -07001531 connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
1532
1533 mAllocator.releaseEventEntry(cancelationEventEntry);
1534 }
1535 }
1536 }
1537
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001538 // This is a new event.
1539 // Enqueue a new dispatch entry onto the outbound queue for this connection.
Jeff Brownb88102f2010-09-08 11:49:43 -07001540 DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry, // increments ref
Jeff Brown519e0242010-09-15 15:18:56 -07001541 inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
1542 if (dispatchEntry->hasForegroundTarget()) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001543 incrementPendingForegroundDispatchesLocked(eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001544 }
1545
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001546 // Handle the case where we could not stream a new motion sample because the consumer has
1547 // already consumed the motion event (otherwise the corresponding dispatch entry would
1548 // still be in the outbound queue for this connection). We set the head motion sample
1549 // to the list starting with the newly appended motion sample.
1550 if (resumeWithAppendedMotionSample) {
1551#if DEBUG_BATCHING
1552 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
1553 "that cannot be streamed because the motion event has already been consumed.",
1554 connection->getInputChannelName());
1555#endif
1556 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
1557 dispatchEntry->headMotionSample = appendedMotionSample;
1558 }
1559
1560 // Enqueue the dispatch entry.
1561 connection->outboundQueue.enqueueAtTail(dispatchEntry);
1562
1563 // If the outbound queue was previously empty, start the dispatch cycle going.
1564 if (wasEmpty) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001565 activateConnectionLocked(connection.get());
Jeff Brown519e0242010-09-15 15:18:56 -07001566 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001567 }
1568}
1569
Jeff Brown7fbdc842010-06-17 20:52:56 -07001570void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
Jeff Brown519e0242010-09-15 15:18:56 -07001571 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001572#if DEBUG_DISPATCH_CYCLE
1573 LOGD("channel '%s' ~ startDispatchCycle",
1574 connection->getInputChannelName());
1575#endif
1576
1577 assert(connection->status == Connection::STATUS_NORMAL);
1578 assert(! connection->outboundQueue.isEmpty());
1579
Jeff Brownb88102f2010-09-08 11:49:43 -07001580 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001581 assert(! dispatchEntry->inProgress);
1582
Jeff Brownb88102f2010-09-08 11:49:43 -07001583 // Mark the dispatch entry as in progress.
1584 dispatchEntry->inProgress = true;
1585
1586 // Update the connection's input state.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001587 EventEntry* eventEntry = dispatchEntry->eventEntry;
1588 InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001589
1590#if FILTER_INPUT_EVENTS
1591 // Filter out inconsistent sequences of input events.
1592 // The input system may drop or inject events in a way that could violate implicit
1593 // invariants on input state and potentially cause an application to crash
1594 // or think that a key or pointer is stuck down. Technically we make no guarantees
1595 // of consistency but it would be nice to improve on this where possible.
1596 // XXX: This code is a proof of concept only. Not ready for prime time.
1597 if (consistency == InputState::TOLERABLE) {
1598#if DEBUG_DISPATCH_CYCLE
1599 LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
1600 "current input state but that is likely to be tolerated by the application.",
1601 connection->getInputChannelName());
1602#endif
1603 } else if (consistency == InputState::BROKEN) {
1604 LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
1605 "current input state and that is likely to cause the application to crash.",
1606 connection->getInputChannelName());
1607 startNextDispatchCycleLocked(currentTime, connection);
1608 return;
1609 }
1610#endif
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001611
1612 // Publish the event.
1613 status_t status;
Jeff Brown01ce2e92010-09-26 22:20:12 -07001614 switch (eventEntry->type) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001615 case EventEntry::TYPE_KEY: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001616 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001617
1618 // Apply target flags.
1619 int32_t action = keyEntry->action;
1620 int32_t flags = keyEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001621
1622 // Publish the key event.
Jeff Brownc5ed5912010-07-14 18:48:53 -07001623 status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001624 action, flags, keyEntry->keyCode, keyEntry->scanCode,
1625 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
1626 keyEntry->eventTime);
1627
1628 if (status) {
1629 LOGE("channel '%s' ~ Could not publish key event, "
1630 "status=%d", connection->getInputChannelName(), status);
1631 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1632 return;
1633 }
1634 break;
1635 }
1636
1637 case EventEntry::TYPE_MOTION: {
Jeff Brown01ce2e92010-09-26 22:20:12 -07001638 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001639
1640 // Apply target flags.
1641 int32_t action = motionEntry->action;
Jeff Brown85a31762010-09-01 17:01:00 -07001642 int32_t flags = motionEntry->flags;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001643 if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001644 action = AMOTION_EVENT_ACTION_OUTSIDE;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001645 }
Jeff Brown85a31762010-09-01 17:01:00 -07001646 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
1647 flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
1648 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001649
1650 // If headMotionSample is non-NULL, then it points to the first new sample that we
1651 // were unable to dispatch during the previous cycle so we resume dispatching from
1652 // that point in the list of motion samples.
1653 // Otherwise, we just start from the first sample of the motion event.
1654 MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
1655 if (! firstMotionSample) {
1656 firstMotionSample = & motionEntry->firstSample;
1657 }
1658
Jeff Brownd3616592010-07-16 17:21:06 -07001659 // Set the X and Y offset depending on the input source.
1660 float xOffset, yOffset;
1661 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
1662 xOffset = dispatchEntry->xOffset;
1663 yOffset = dispatchEntry->yOffset;
1664 } else {
1665 xOffset = 0.0f;
1666 yOffset = 0.0f;
1667 }
1668
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001669 // Publish the motion event and the first motion sample.
1670 status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
Jeff Brown85a31762010-09-01 17:01:00 -07001671 motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
Jeff Brownd3616592010-07-16 17:21:06 -07001672 xOffset, yOffset,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001673 motionEntry->xPrecision, motionEntry->yPrecision,
1674 motionEntry->downTime, firstMotionSample->eventTime,
1675 motionEntry->pointerCount, motionEntry->pointerIds,
1676 firstMotionSample->pointerCoords);
1677
1678 if (status) {
1679 LOGE("channel '%s' ~ Could not publish motion event, "
1680 "status=%d", connection->getInputChannelName(), status);
1681 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1682 return;
1683 }
1684
1685 // Append additional motion samples.
1686 MotionSample* nextMotionSample = firstMotionSample->next;
1687 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
1688 status = connection->inputPublisher.appendMotionSample(
1689 nextMotionSample->eventTime, nextMotionSample->pointerCoords);
1690 if (status == NO_MEMORY) {
1691#if DEBUG_DISPATCH_CYCLE
1692 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will "
1693 "be sent in the next dispatch cycle.",
1694 connection->getInputChannelName());
1695#endif
1696 break;
1697 }
1698 if (status != OK) {
1699 LOGE("channel '%s' ~ Could not append motion sample "
1700 "for a reason other than out of memory, status=%d",
1701 connection->getInputChannelName(), status);
1702 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1703 return;
1704 }
1705 }
1706
1707 // Remember the next motion sample that we could not dispatch, in case we ran out
1708 // of space in the shared memory buffer.
1709 dispatchEntry->tailMotionSample = nextMotionSample;
1710 break;
1711 }
1712
1713 default: {
1714 assert(false);
1715 }
1716 }
1717
1718 // Send the dispatch signal.
1719 status = connection->inputPublisher.sendDispatchSignal();
1720 if (status) {
1721 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
1722 connection->getInputChannelName(), status);
1723 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1724 return;
1725 }
1726
1727 // Record information about the newly started dispatch cycle.
Jeff Brown01ce2e92010-09-26 22:20:12 -07001728 connection->lastEventTime = eventEntry->eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001729 connection->lastDispatchTime = currentTime;
1730
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001731 // Notify other system components.
1732 onDispatchCycleStartedLocked(currentTime, connection);
1733}
1734
Jeff Brown7fbdc842010-06-17 20:52:56 -07001735void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
1736 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001737#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001738 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001739 "%01.1fms since dispatch",
1740 connection->getInputChannelName(),
1741 connection->getEventLatencyMillis(currentTime),
1742 connection->getDispatchLatencyMillis(currentTime));
1743#endif
1744
Jeff Brown9c3cda02010-06-15 01:31:58 -07001745 if (connection->status == Connection::STATUS_BROKEN
1746 || connection->status == Connection::STATUS_ZOMBIE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001747 return;
1748 }
1749
Jeff Brown519e0242010-09-15 15:18:56 -07001750 // Notify other system components.
1751 onDispatchCycleFinishedLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001752
1753 // Reset the publisher since the event has been consumed.
1754 // We do this now so that the publisher can release some of its internal resources
1755 // while waiting for the next dispatch cycle to begin.
1756 status_t status = connection->inputPublisher.reset();
1757 if (status) {
1758 LOGE("channel '%s' ~ Could not reset publisher, status=%d",
1759 connection->getInputChannelName(), status);
1760 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
1761 return;
1762 }
1763
Jeff Brownb88102f2010-09-08 11:49:43 -07001764 startNextDispatchCycleLocked(currentTime, connection);
1765}
1766
1767void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
1768 const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001769 // Start the next dispatch cycle for this connection.
1770 while (! connection->outboundQueue.isEmpty()) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001771 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001772 if (dispatchEntry->inProgress) {
1773 // Finish or resume current event in progress.
1774 if (dispatchEntry->tailMotionSample) {
1775 // We have a tail of undispatched motion samples.
1776 // Reuse the same DispatchEntry and start a new cycle.
1777 dispatchEntry->inProgress = false;
1778 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
1779 dispatchEntry->tailMotionSample = NULL;
Jeff Brown519e0242010-09-15 15:18:56 -07001780 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001781 return;
1782 }
1783 // Finished.
1784 connection->outboundQueue.dequeueAtHead();
Jeff Brown519e0242010-09-15 15:18:56 -07001785 if (dispatchEntry->hasForegroundTarget()) {
1786 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001787 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001788 mAllocator.releaseDispatchEntry(dispatchEntry);
1789 } else {
1790 // If the head is not in progress, then we must have already dequeued the in
Jeff Brown519e0242010-09-15 15:18:56 -07001791 // progress event, which means we actually aborted it.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001792 // So just start the next event for this connection.
Jeff Brown519e0242010-09-15 15:18:56 -07001793 startDispatchCycleLocked(currentTime, connection);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001794 return;
1795 }
1796 }
1797
1798 // Outbound queue is empty, deactivate the connection.
Jeff Brown7fbdc842010-06-17 20:52:56 -07001799 deactivateConnectionLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001800}
1801
Jeff Brown7fbdc842010-06-17 20:52:56 -07001802void InputDispatcher::abortDispatchCycleLocked(nsecs_t currentTime,
1803 const sp<Connection>& connection, bool broken) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001804#if DEBUG_DISPATCH_CYCLE
Jeff Brown9c3cda02010-06-15 01:31:58 -07001805 LOGD("channel '%s' ~ abortDispatchCycle - broken=%s",
Jeff Brownb88102f2010-09-08 11:49:43 -07001806 connection->getInputChannelName(), toString(broken));
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001807#endif
1808
Jeff Brownb88102f2010-09-08 11:49:43 -07001809 // Input state will no longer be realistic.
1810 connection->inputState.setOutOfSync();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001811
Jeff Brownb88102f2010-09-08 11:49:43 -07001812 // Clear the outbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07001813 drainOutboundQueueLocked(connection.get());
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001814
1815 // Handle the case where the connection appears to be unrecoverably broken.
Jeff Brown9c3cda02010-06-15 01:31:58 -07001816 // Ignore already broken or zombie connections.
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001817 if (broken) {
Jeff Brown519e0242010-09-15 15:18:56 -07001818 if (connection->status == Connection::STATUS_NORMAL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07001819 connection->status = Connection::STATUS_BROKEN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001820
Jeff Brown9c3cda02010-06-15 01:31:58 -07001821 // Notify other system components.
1822 onDispatchCycleBrokenLocked(currentTime, connection);
1823 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001824 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001825}
1826
Jeff Brown519e0242010-09-15 15:18:56 -07001827void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
1828 while (! connection->outboundQueue.isEmpty()) {
1829 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
1830 if (dispatchEntry->hasForegroundTarget()) {
1831 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001832 }
1833 mAllocator.releaseDispatchEntry(dispatchEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07001834 }
1835
Jeff Brown519e0242010-09-15 15:18:56 -07001836 deactivateConnectionLocked(connection);
Jeff Brownb88102f2010-09-08 11:49:43 -07001837}
1838
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001839int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001840 InputDispatcher* d = static_cast<InputDispatcher*>(data);
1841
1842 { // acquire lock
1843 AutoMutex _l(d->mLock);
1844
1845 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
1846 if (connectionIndex < 0) {
1847 LOGE("Received spurious receive callback for unknown input channel. "
1848 "fd=%d, events=0x%x", receiveFd, events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001849 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001850 }
1851
Jeff Brown7fbdc842010-06-17 20:52:56 -07001852 nsecs_t currentTime = now();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001853
1854 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001855 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001856 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. "
1857 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001858 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001859 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001860 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001861 }
1862
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001863 if (! (events & ALOOPER_EVENT_INPUT)) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001864 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
1865 "events=0x%x", connection->getInputChannelName(), events);
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001866 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001867 }
1868
1869 status_t status = connection->inputPublisher.receiveFinishedSignal();
1870 if (status) {
1871 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d",
1872 connection->getInputChannelName(), status);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001873 d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001874 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001875 return 0; // remove the callback
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001876 }
1877
Jeff Brown7fbdc842010-06-17 20:52:56 -07001878 d->finishDispatchCycleLocked(currentTime, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001879 d->runCommandsLockedInterruptible();
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001880 return 1;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001881 } // release lock
1882}
1883
Jeff Brown01ce2e92010-09-26 22:20:12 -07001884InputDispatcher::MotionEntry*
1885InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
1886 assert(pointerIds.value != 0);
1887
1888 uint32_t splitPointerIndexMap[MAX_POINTERS];
1889 int32_t splitPointerIds[MAX_POINTERS];
1890 PointerCoords splitPointerCoords[MAX_POINTERS];
1891
1892 uint32_t originalPointerCount = originalMotionEntry->pointerCount;
1893 uint32_t splitPointerCount = 0;
1894
1895 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
1896 originalPointerIndex++) {
1897 int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
1898 if (pointerIds.hasBit(pointerId)) {
1899 splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
1900 splitPointerIds[splitPointerCount] = pointerId;
1901 splitPointerCoords[splitPointerCount] =
1902 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
1903 splitPointerCount += 1;
1904 }
1905 }
1906 assert(splitPointerCount == pointerIds.count());
1907
1908 int32_t action = originalMotionEntry->action;
1909 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1910 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1911 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
1912 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
1913 int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
1914 if (pointerIds.hasBit(pointerId)) {
1915 if (pointerIds.count() == 1) {
1916 // The first/last pointer went down/up.
1917 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
1918 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
Jeff Brown9a01d052010-09-27 16:35:11 -07001919 } else {
1920 // A secondary pointer went down/up.
1921 uint32_t splitPointerIndex = 0;
1922 while (pointerId != splitPointerIds[splitPointerIndex]) {
1923 splitPointerIndex += 1;
1924 }
1925 action = maskedAction | (splitPointerIndex
1926 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
Jeff Brown01ce2e92010-09-26 22:20:12 -07001927 }
1928 } else {
1929 // An unrelated pointer changed.
1930 action = AMOTION_EVENT_ACTION_MOVE;
1931 }
1932 }
1933
1934 MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
1935 originalMotionEntry->eventTime,
1936 originalMotionEntry->deviceId,
1937 originalMotionEntry->source,
1938 originalMotionEntry->policyFlags,
1939 action,
1940 originalMotionEntry->flags,
1941 originalMotionEntry->metaState,
1942 originalMotionEntry->edgeFlags,
1943 originalMotionEntry->xPrecision,
1944 originalMotionEntry->yPrecision,
1945 originalMotionEntry->downTime,
1946 splitPointerCount, splitPointerIds, splitPointerCoords);
1947
1948 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
1949 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
1950 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
1951 splitPointerIndex++) {
1952 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
1953 splitPointerCoords[splitPointerIndex] =
1954 originalMotionSample->pointerCoords[originalPointerIndex];
1955 }
1956
1957 mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
1958 splitPointerCoords);
1959 }
1960
1961 return splitMotionEntry;
1962}
1963
Jeff Brown9c3cda02010-06-15 01:31:58 -07001964void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001965#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brown9c3cda02010-06-15 01:31:58 -07001966 LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001967#endif
1968
Jeff Brownb88102f2010-09-08 11:49:43 -07001969 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001970 { // acquire lock
1971 AutoMutex _l(mLock);
1972
Jeff Brown7fbdc842010-06-17 20:52:56 -07001973 ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
Jeff Brownb88102f2010-09-08 11:49:43 -07001974 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001975 } // release lock
1976
Jeff Brownb88102f2010-09-08 11:49:43 -07001977 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07001978 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001979 }
1980}
1981
Jeff Brownc5ed5912010-07-14 18:48:53 -07001982void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001983 uint32_t policyFlags, int32_t action, int32_t flags,
1984 int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
1985#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07001986 LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001987 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
Jeff Brownc5ed5912010-07-14 18:48:53 -07001988 eventTime, deviceId, source, policyFlags, action, flags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001989 keyCode, scanCode, metaState, downTime);
1990#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07001991 if (! validateKeyEvent(action)) {
1992 return;
1993 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001994
Jeff Brownb88102f2010-09-08 11:49:43 -07001995 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001996 { // acquire lock
1997 AutoMutex _l(mLock);
1998
Jeff Brown7fbdc842010-06-17 20:52:56 -07001999 int32_t repeatCount = 0;
2000 KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002001 deviceId, source, policyFlags, action, flags, keyCode, scanCode,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002002 metaState, repeatCount, downTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002003
Jeff Brownb88102f2010-09-08 11:49:43 -07002004 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002005 } // release lock
2006
Jeff Brownb88102f2010-09-08 11:49:43 -07002007 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002008 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002009 }
2010}
2011
Jeff Brownc5ed5912010-07-14 18:48:53 -07002012void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
Jeff Brown85a31762010-09-01 17:01:00 -07002013 uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002014 uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
2015 float xPrecision, float yPrecision, nsecs_t downTime) {
2016#if DEBUG_INBOUND_EVENT_DETAILS
Jeff Brownc5ed5912010-07-14 18:48:53 -07002017 LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
Jeff Brown85a31762010-09-01 17:01:00 -07002018 "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
2019 "xPrecision=%f, yPrecision=%f, downTime=%lld",
2020 eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002021 xPrecision, yPrecision, downTime);
2022 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown8d608662010-08-30 03:02:23 -07002023 LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
Jeff Brown85a31762010-09-01 17:01:00 -07002024 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
Jeff Brown8d608662010-08-30 03:02:23 -07002025 "orientation=%f",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002026 i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
Jeff Brown8d608662010-08-30 03:02:23 -07002027 pointerCoords[i].pressure, pointerCoords[i].size,
2028 pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
2029 pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
2030 pointerCoords[i].orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002031 }
2032#endif
Jeff Brown01ce2e92010-09-26 22:20:12 -07002033 if (! validateMotionEvent(action, pointerCount, pointerIds)) {
2034 return;
2035 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002036
Jeff Brownb88102f2010-09-08 11:49:43 -07002037 bool needWake;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002038 { // acquire lock
2039 AutoMutex _l(mLock);
2040
2041 // Attempt batching and streaming of move events.
Jeff Brownc5ed5912010-07-14 18:48:53 -07002042 if (action == AMOTION_EVENT_ACTION_MOVE) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002043 // BATCHING CASE
2044 //
2045 // Try to append a move sample to the tail of the inbound queue for this device.
2046 // Give up if we encounter a non-move motion event for this device since that
2047 // means we cannot append any new samples until a new motion event has started.
Jeff Brownb88102f2010-09-08 11:49:43 -07002048 for (EventEntry* entry = mInboundQueue.tailSentinel.prev;
2049 entry != & mInboundQueue.headSentinel; entry = entry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002050 if (entry->type != EventEntry::TYPE_MOTION) {
2051 // Keep looking for motion events.
2052 continue;
2053 }
2054
2055 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2056 if (motionEntry->deviceId != deviceId) {
2057 // Keep looking for this device.
2058 continue;
2059 }
2060
Jeff Brownc5ed5912010-07-14 18:48:53 -07002061 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
Jeff Brown7fbdc842010-06-17 20:52:56 -07002062 || motionEntry->pointerCount != pointerCount
2063 || motionEntry->isInjected()) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002064 // Last motion event in the queue for this device is not compatible for
2065 // appending new samples. Stop here.
2066 goto NoBatchingOrStreaming;
2067 }
2068
2069 // The last motion event is a move and is compatible for appending.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002070 // Do the batching magic.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002071 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002072#if DEBUG_BATCHING
2073 LOGD("Appended motion sample onto batch for most recent "
2074 "motion event for this device in the inbound queue.");
2075#endif
Jeff Brown9c3cda02010-06-15 01:31:58 -07002076 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002077 }
2078
2079 // STREAMING CASE
2080 //
2081 // There is no pending motion event (of any kind) for this device in the inbound queue.
Jeff Brown519e0242010-09-15 15:18:56 -07002082 // Search the outbound queue for the current foreground targets to find a dispatched
2083 // motion event that is still in progress. If found, then, appen the new sample to
2084 // that event and push it out to all current targets. The logic in
2085 // prepareDispatchCycleLocked takes care of the case where some targets may
2086 // already have consumed the motion event by starting a new dispatch cycle if needed.
Jeff Brown9c3cda02010-06-15 01:31:58 -07002087 if (mCurrentInputTargetsValid) {
Jeff Brown519e0242010-09-15 15:18:56 -07002088 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2089 const InputTarget& inputTarget = mCurrentInputTargets[i];
2090 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2091 // Skip non-foreground targets. We only want to stream if there is at
2092 // least one foreground target whose dispatch is still in progress.
2093 continue;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002094 }
Jeff Brown519e0242010-09-15 15:18:56 -07002095
2096 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2097 if (connectionIndex < 0) {
2098 // Connection must no longer be valid.
2099 continue;
2100 }
2101
2102 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2103 if (connection->outboundQueue.isEmpty()) {
2104 // This foreground target has an empty outbound queue.
2105 continue;
2106 }
2107
2108 DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
2109 if (! dispatchEntry->inProgress
Jeff Brown01ce2e92010-09-26 22:20:12 -07002110 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
2111 || dispatchEntry->isSplit()) {
2112 // No motion event is being dispatched, or it is being split across
2113 // windows in which case we cannot stream.
Jeff Brown519e0242010-09-15 15:18:56 -07002114 continue;
2115 }
2116
2117 MotionEntry* motionEntry = static_cast<MotionEntry*>(
2118 dispatchEntry->eventEntry);
2119 if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
2120 || motionEntry->deviceId != deviceId
2121 || motionEntry->pointerCount != pointerCount
2122 || motionEntry->isInjected()) {
2123 // The motion event is not compatible with this move.
2124 continue;
2125 }
2126
2127 // Hurray! This foreground target is currently dispatching a move event
2128 // that we can stream onto. Append the motion sample and resume dispatch.
2129 mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
2130#if DEBUG_BATCHING
2131 LOGD("Appended motion sample onto batch for most recently dispatched "
2132 "motion event for this device in the outbound queues. "
2133 "Attempting to stream the motion sample.");
2134#endif
2135 nsecs_t currentTime = now();
2136 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2137 true /*resumeWithAppendedMotionSample*/);
2138
2139 runCommandsLockedInterruptible();
2140 return; // done!
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002141 }
2142 }
2143
2144NoBatchingOrStreaming:;
2145 }
2146
2147 // Just enqueue a new motion event.
Jeff Brown7fbdc842010-06-17 20:52:56 -07002148 MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002149 deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002150 xPrecision, yPrecision, downTime,
2151 pointerCount, pointerIds, pointerCoords);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002152
Jeff Brownb88102f2010-09-08 11:49:43 -07002153 needWake = enqueueInboundEventLocked(newEntry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002154 } // release lock
2155
Jeff Brownb88102f2010-09-08 11:49:43 -07002156 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002157 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002158 }
2159}
2160
Jeff Brown7fbdc842010-06-17 20:52:56 -07002161int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
Jeff Brown6ec402b2010-07-28 15:48:59 -07002162 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002163#if DEBUG_INBOUND_EVENT_DETAILS
2164 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002165 "syncMode=%d, timeoutMillis=%d",
2166 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002167#endif
2168
2169 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
2170
Jeff Brown01ce2e92010-09-26 22:20:12 -07002171 InjectionState* injectionState;
Jeff Brownb88102f2010-09-08 11:49:43 -07002172 bool needWake;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002173 { // acquire lock
2174 AutoMutex _l(mLock);
2175
Jeff Brown01ce2e92010-09-26 22:20:12 -07002176 EventEntry* injectedEntry = createEntryFromInjectedInputEventLocked(event);
Jeff Brownb88102f2010-09-08 11:49:43 -07002177 if (! injectedEntry) {
2178 return INPUT_EVENT_INJECTION_FAILED;
2179 }
2180
Jeff Brown01ce2e92010-09-26 22:20:12 -07002181 injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002182 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002183 injectionState->injectionIsAsync = true;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002184 }
2185
Jeff Brown01ce2e92010-09-26 22:20:12 -07002186 injectionState->refCount += 1;
2187 injectedEntry->injectionState = injectionState;
2188
Jeff Brownb88102f2010-09-08 11:49:43 -07002189 needWake = enqueueInboundEventLocked(injectedEntry);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002190 } // release lock
2191
Jeff Brownb88102f2010-09-08 11:49:43 -07002192 if (needWake) {
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002193 mLooper->wake();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002194 }
2195
2196 int32_t injectionResult;
2197 { // acquire lock
2198 AutoMutex _l(mLock);
2199
Jeff Brown6ec402b2010-07-28 15:48:59 -07002200 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
2201 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
2202 } else {
2203 for (;;) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002204 injectionResult = injectionState->injectionResult;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002205 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
2206 break;
2207 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002208
Jeff Brown7fbdc842010-06-17 20:52:56 -07002209 nsecs_t remainingTimeout = endTime - now();
2210 if (remainingTimeout <= 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002211#if DEBUG_INJECTION
2212 LOGD("injectInputEvent - Timed out waiting for injection result "
2213 "to become available.");
2214#endif
Jeff Brown7fbdc842010-06-17 20:52:56 -07002215 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2216 break;
2217 }
2218
Jeff Brown6ec402b2010-07-28 15:48:59 -07002219 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
2220 }
2221
2222 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
2223 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002224 while (injectionState->pendingForegroundDispatches != 0) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002225#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002226 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002227 injectionState->pendingForegroundDispatches);
Jeff Brown6ec402b2010-07-28 15:48:59 -07002228#endif
2229 nsecs_t remainingTimeout = endTime - now();
2230 if (remainingTimeout <= 0) {
2231#if DEBUG_INJECTION
Jeff Brown519e0242010-09-15 15:18:56 -07002232 LOGD("injectInputEvent - Timed out waiting for pending foreground "
Jeff Brown6ec402b2010-07-28 15:48:59 -07002233 "dispatches to finish.");
2234#endif
2235 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
2236 break;
2237 }
2238
2239 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
2240 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002241 }
2242 }
2243
Jeff Brown01ce2e92010-09-26 22:20:12 -07002244 mAllocator.releaseInjectionState(injectionState);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002245 } // release lock
2246
Jeff Brown6ec402b2010-07-28 15:48:59 -07002247#if DEBUG_INJECTION
2248 LOGD("injectInputEvent - Finished with result %d. "
2249 "injectorPid=%d, injectorUid=%d",
2250 injectionResult, injectorPid, injectorUid);
2251#endif
2252
Jeff Brown7fbdc842010-06-17 20:52:56 -07002253 return injectionResult;
2254}
2255
2256void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002257 InjectionState* injectionState = entry->injectionState;
2258 if (injectionState) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002259#if DEBUG_INJECTION
2260 LOGD("Setting input event injection result to %d. "
2261 "injectorPid=%d, injectorUid=%d",
Jeff Brown01ce2e92010-09-26 22:20:12 -07002262 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002263#endif
2264
Jeff Brown01ce2e92010-09-26 22:20:12 -07002265 if (injectionState->injectionIsAsync) {
Jeff Brown6ec402b2010-07-28 15:48:59 -07002266 // Log the outcome since the injector did not wait for the injection result.
2267 switch (injectionResult) {
2268 case INPUT_EVENT_INJECTION_SUCCEEDED:
2269 LOGV("Asynchronous input event injection succeeded.");
2270 break;
2271 case INPUT_EVENT_INJECTION_FAILED:
2272 LOGW("Asynchronous input event injection failed.");
2273 break;
2274 case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
2275 LOGW("Asynchronous input event injection permission denied.");
2276 break;
2277 case INPUT_EVENT_INJECTION_TIMED_OUT:
2278 LOGW("Asynchronous input event injection timed out.");
2279 break;
2280 }
2281 }
2282
Jeff Brown01ce2e92010-09-26 22:20:12 -07002283 injectionState->injectionResult = injectionResult;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002284 mInjectionResultAvailableCondition.broadcast();
2285 }
2286}
2287
Jeff Brown01ce2e92010-09-26 22:20:12 -07002288void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
2289 InjectionState* injectionState = entry->injectionState;
2290 if (injectionState) {
2291 injectionState->pendingForegroundDispatches += 1;
2292 }
2293}
2294
Jeff Brown519e0242010-09-15 15:18:56 -07002295void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002296 InjectionState* injectionState = entry->injectionState;
2297 if (injectionState) {
2298 injectionState->pendingForegroundDispatches -= 1;
Jeff Brown6ec402b2010-07-28 15:48:59 -07002299
Jeff Brown01ce2e92010-09-26 22:20:12 -07002300 if (injectionState->pendingForegroundDispatches == 0) {
2301 mInjectionSyncFinishedCondition.broadcast();
2302 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002303 }
2304}
2305
2306InputDispatcher::EventEntry* InputDispatcher::createEntryFromInjectedInputEventLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002307 const InputEvent* event) {
2308 switch (event->getType()) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07002309 case AINPUT_EVENT_TYPE_KEY: {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002310 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002311 if (! validateKeyEvent(keyEvent->getAction())) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002312 return NULL;
2313 }
2314
Jeff Brown85a31762010-09-01 17:01:00 -07002315 uint32_t policyFlags = POLICY_FLAG_INJECTED;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002316
2317 KeyEntry* keyEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
Jeff Brownc5ed5912010-07-14 18:48:53 -07002318 keyEvent->getDeviceId(), keyEvent->getSource(), policyFlags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002319 keyEvent->getAction(), keyEvent->getFlags(),
2320 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
2321 keyEvent->getRepeatCount(), keyEvent->getDownTime());
2322 return keyEntry;
2323 }
2324
Jeff Brownc5ed5912010-07-14 18:48:53 -07002325 case AINPUT_EVENT_TYPE_MOTION: {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002326 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
Jeff Brown01ce2e92010-09-26 22:20:12 -07002327 if (! validateMotionEvent(motionEvent->getAction(),
2328 motionEvent->getPointerCount(), motionEvent->getPointerIds())) {
Jeff Brownb88102f2010-09-08 11:49:43 -07002329 return NULL;
2330 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002331
Jeff Brown85a31762010-09-01 17:01:00 -07002332 uint32_t policyFlags = POLICY_FLAG_INJECTED;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002333
2334 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
2335 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
2336 size_t pointerCount = motionEvent->getPointerCount();
2337
2338 MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002339 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
Jeff Brown85a31762010-09-01 17:01:00 -07002340 motionEvent->getAction(), motionEvent->getFlags(),
2341 motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
Jeff Brown7fbdc842010-06-17 20:52:56 -07002342 motionEvent->getXPrecision(), motionEvent->getYPrecision(),
2343 motionEvent->getDownTime(), uint32_t(pointerCount),
2344 motionEvent->getPointerIds(), samplePointerCoords);
2345 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
2346 sampleEventTimes += 1;
2347 samplePointerCoords += pointerCount;
2348 mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
2349 }
2350 return motionEntry;
2351 }
2352
2353 default:
2354 assert(false);
2355 return NULL;
2356 }
2357}
2358
Jeff Brown01ce2e92010-09-26 22:20:12 -07002359const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
2360 for (size_t i = 0; i < mWindows.size(); i++) {
2361 const InputWindow* window = & mWindows[i];
2362 if (window->inputChannel == inputChannel) {
2363 return window;
2364 }
2365 }
2366 return NULL;
2367}
2368
Jeff Brownb88102f2010-09-08 11:49:43 -07002369void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
2370#if DEBUG_FOCUS
2371 LOGD("setInputWindows");
2372#endif
2373 { // acquire lock
2374 AutoMutex _l(mLock);
2375
Jeff Brown01ce2e92010-09-26 22:20:12 -07002376 // Clear old window pointers.
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002377 mFocusedWindow = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -07002378 mWindows.clear();
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002379
2380 // Loop over new windows and rebuild the necessary window pointers for
2381 // tracking focus and touch.
Jeff Brownb88102f2010-09-08 11:49:43 -07002382 mWindows.appendVector(inputWindows);
2383
2384 size_t numWindows = mWindows.size();
2385 for (size_t i = 0; i < numWindows; i++) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002386 const InputWindow* window = & mWindows.itemAt(i);
Jeff Brownb88102f2010-09-08 11:49:43 -07002387 if (window->hasFocus) {
2388 mFocusedWindow = window;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002389 break;
Jeff Brownb88102f2010-09-08 11:49:43 -07002390 }
2391 }
Jeff Brown01ce2e92010-09-26 22:20:12 -07002392
2393 for (size_t i = 0; i < mTouchState.windows.size(); ) {
2394 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
2395 const InputWindow* window = getWindowLocked(touchedWindow.channel);
2396 if (window) {
2397 touchedWindow.window = window;
2398 i += 1;
2399 } else {
2400 mTouchState.windows.removeAt(i);
2401 }
2402 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002403
Jeff Brownb88102f2010-09-08 11:49:43 -07002404#if DEBUG_FOCUS
2405 logDispatchStateLocked();
2406#endif
2407 } // release lock
2408
2409 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002410 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002411}
2412
2413void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
2414#if DEBUG_FOCUS
2415 LOGD("setFocusedApplication");
2416#endif
2417 { // acquire lock
2418 AutoMutex _l(mLock);
2419
2420 releaseFocusedApplicationLocked();
2421
2422 if (inputApplication) {
2423 mFocusedApplicationStorage = *inputApplication;
2424 mFocusedApplication = & mFocusedApplicationStorage;
2425 }
2426
2427#if DEBUG_FOCUS
2428 logDispatchStateLocked();
2429#endif
2430 } // release lock
2431
2432 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002433 mLooper->wake();
Jeff Brownb88102f2010-09-08 11:49:43 -07002434}
2435
2436void InputDispatcher::releaseFocusedApplicationLocked() {
2437 if (mFocusedApplication) {
2438 mFocusedApplication = NULL;
2439 mFocusedApplicationStorage.handle.clear();
2440 }
2441}
2442
2443void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
2444#if DEBUG_FOCUS
2445 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
2446#endif
2447
2448 bool changed;
2449 { // acquire lock
2450 AutoMutex _l(mLock);
2451
2452 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
2453 if (mDispatchFrozen && ! frozen) {
2454 resetANRTimeoutsLocked();
2455 }
2456
2457 mDispatchEnabled = enabled;
2458 mDispatchFrozen = frozen;
2459 changed = true;
2460 } else {
2461 changed = false;
2462 }
2463
2464#if DEBUG_FOCUS
2465 logDispatchStateLocked();
2466#endif
2467 } // release lock
2468
2469 if (changed) {
2470 // Wake up poll loop since it may need to make new input dispatching choices.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002471 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002472 }
2473}
2474
Jeff Browne6504122010-09-27 14:52:15 -07002475bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
2476 const sp<InputChannel>& toChannel) {
2477#if DEBUG_FOCUS
2478 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
2479 fromChannel->getName().string(), toChannel->getName().string());
2480#endif
2481 { // acquire lock
2482 AutoMutex _l(mLock);
2483
2484 const InputWindow* fromWindow = getWindowLocked(fromChannel);
2485 const InputWindow* toWindow = getWindowLocked(toChannel);
2486 if (! fromWindow || ! toWindow) {
2487#if DEBUG_FOCUS
2488 LOGD("Cannot transfer focus because from or to window not found.");
2489#endif
2490 return false;
2491 }
2492 if (fromWindow == toWindow) {
2493#if DEBUG_FOCUS
2494 LOGD("Trivial transfer to same window.");
2495#endif
2496 return true;
2497 }
2498
2499 bool found = false;
2500 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2501 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2502 if (touchedWindow.window == fromWindow) {
2503 int32_t oldTargetFlags = touchedWindow.targetFlags;
2504 BitSet32 pointerIds = touchedWindow.pointerIds;
2505
2506 mTouchState.windows.removeAt(i);
2507
2508 int32_t newTargetFlags = 0;
2509 if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
2510 newTargetFlags |= InputTarget::FLAG_FOREGROUND;
2511 if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
2512 newTargetFlags |= InputTarget::FLAG_SPLIT;
2513 }
2514 }
2515 mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
2516
2517 found = true;
2518 break;
2519 }
2520 }
2521
2522 if (! found) {
2523#if DEBUG_FOCUS
2524 LOGD("Focus transfer failed because from window did not have focus.");
2525#endif
2526 return false;
2527 }
2528
2529#if DEBUG_FOCUS
2530 logDispatchStateLocked();
2531#endif
2532 } // release lock
2533
2534 // Wake up poll loop since it may need to make new input dispatching choices.
2535 mLooper->wake();
2536 return true;
2537}
2538
Jeff Brownb88102f2010-09-08 11:49:43 -07002539void InputDispatcher::logDispatchStateLocked() {
2540 String8 dump;
2541 dumpDispatchStateLocked(dump);
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002542
2543 char* text = dump.lockBuffer(dump.size());
2544 char* start = text;
2545 while (*start != '\0') {
2546 char* end = strchr(start, '\n');
2547 if (*end == '\n') {
2548 *(end++) = '\0';
2549 }
2550 LOGD("%s", start);
2551 start = end;
2552 }
Jeff Brownb88102f2010-09-08 11:49:43 -07002553}
2554
2555void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
2556 dump.appendFormat(" dispatchEnabled: %d\n", mDispatchEnabled);
2557 dump.appendFormat(" dispatchFrozen: %d\n", mDispatchFrozen);
2558
2559 if (mFocusedApplication) {
2560 dump.appendFormat(" focusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
2561 mFocusedApplication->name.string(),
2562 mFocusedApplication->dispatchingTimeout / 1000000.0);
2563 } else {
2564 dump.append(" focusedApplication: <null>\n");
2565 }
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002566 dump.appendFormat(" focusedWindow: name='%s'\n",
2567 mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
Jeff Brown01ce2e92010-09-26 22:20:12 -07002568 dump.appendFormat(" touchState: down=%s, split=%s\n", toString(mTouchState.down),
2569 toString(mTouchState.split));
2570 for (size_t i = 0; i < mTouchState.windows.size(); i++) {
2571 const TouchedWindow& touchedWindow = mTouchState.windows[i];
2572 dump.appendFormat(" touchedWindow[%d]: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
2573 i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
2574 touchedWindow.targetFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -07002575 }
2576 for (size_t i = 0; i < mWindows.size(); i++) {
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002577 dump.appendFormat(" windows[%d]: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
2578 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
Jeff Brownb88102f2010-09-08 11:49:43 -07002579 "frame=[%d,%d][%d,%d], "
2580 "visibleFrame=[%d,%d][%d,%d], "
2581 "touchableArea=[%d,%d][%d,%d], "
2582 "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002583 i, mWindows[i].name.string(),
Jeff Brownb88102f2010-09-08 11:49:43 -07002584 toString(mWindows[i].paused),
2585 toString(mWindows[i].hasFocus),
2586 toString(mWindows[i].hasWallpaper),
2587 toString(mWindows[i].visible),
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002588 toString(mWindows[i].canReceiveKeys),
Jeff Brownb88102f2010-09-08 11:49:43 -07002589 mWindows[i].layoutParamsFlags, mWindows[i].layoutParamsType,
Jeff Brown2a95c2a2010-09-16 12:31:46 -07002590 mWindows[i].layer,
Jeff Brownb88102f2010-09-08 11:49:43 -07002591 mWindows[i].frameLeft, mWindows[i].frameTop,
2592 mWindows[i].frameRight, mWindows[i].frameBottom,
2593 mWindows[i].visibleFrameLeft, mWindows[i].visibleFrameTop,
2594 mWindows[i].visibleFrameRight, mWindows[i].visibleFrameBottom,
2595 mWindows[i].touchableAreaLeft, mWindows[i].touchableAreaTop,
2596 mWindows[i].touchableAreaRight, mWindows[i].touchableAreaBottom,
2597 mWindows[i].ownerPid, mWindows[i].ownerUid,
2598 mWindows[i].dispatchingTimeout / 1000000.0);
2599 }
2600
2601 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2602 const sp<InputChannel>& channel = mMonitoringChannels[i];
2603 dump.appendFormat(" monitoringChannel[%d]: '%s'\n",
2604 i, channel->getName().string());
2605 }
2606
Jeff Brown519e0242010-09-15 15:18:56 -07002607 dump.appendFormat(" inboundQueue: length=%u", mInboundQueue.count());
2608
Jeff Brownb88102f2010-09-08 11:49:43 -07002609 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2610 const Connection* connection = mActiveConnections[i];
Jeff Brown519e0242010-09-15 15:18:56 -07002611 dump.appendFormat(" activeConnection[%d]: '%s', status=%s, outboundQueueLength=%u"
Jeff Brownb88102f2010-09-08 11:49:43 -07002612 "inputState.isNeutral=%s, inputState.isOutOfSync=%s\n",
2613 i, connection->getInputChannelName(), connection->getStatusLabel(),
Jeff Brown519e0242010-09-15 15:18:56 -07002614 connection->outboundQueue.count(),
Jeff Brownb88102f2010-09-08 11:49:43 -07002615 toString(connection->inputState.isNeutral()),
2616 toString(connection->inputState.isOutOfSync()));
2617 }
2618
2619 if (isAppSwitchPendingLocked()) {
2620 dump.appendFormat(" appSwitch: pending, due in %01.1fms\n",
2621 (mAppSwitchDueTime - now()) / 1000000.0);
2622 } else {
2623 dump.append(" appSwitch: not pending\n");
2624 }
2625}
2626
2627status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002628#if DEBUG_REGISTRATION
Jeff Brownb88102f2010-09-08 11:49:43 -07002629 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
2630 toString(monitor));
Jeff Brown9c3cda02010-06-15 01:31:58 -07002631#endif
2632
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002633 { // acquire lock
2634 AutoMutex _l(mLock);
2635
Jeff Brown519e0242010-09-15 15:18:56 -07002636 if (getConnectionIndexLocked(inputChannel) >= 0) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002637 LOGW("Attempted to register already registered input channel '%s'",
2638 inputChannel->getName().string());
2639 return BAD_VALUE;
2640 }
2641
2642 sp<Connection> connection = new Connection(inputChannel);
2643 status_t status = connection->initialize();
2644 if (status) {
2645 LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
2646 inputChannel->getName().string(), status);
2647 return status;
2648 }
2649
Jeff Brown2cbecea2010-08-17 15:59:26 -07002650 int32_t receiveFd = inputChannel->getReceivePipeFd();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002651 mConnectionsByReceiveFd.add(receiveFd, connection);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002652
Jeff Brownb88102f2010-09-08 11:49:43 -07002653 if (monitor) {
2654 mMonitoringChannels.push(inputChannel);
2655 }
2656
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002657 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
Jeff Brown2cbecea2010-08-17 15:59:26 -07002658
Jeff Brown9c3cda02010-06-15 01:31:58 -07002659 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002660 } // release lock
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002661 return OK;
2662}
2663
2664status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07002665#if DEBUG_REGISTRATION
Jeff Brown349703e2010-06-22 01:27:15 -07002666 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
Jeff Brown9c3cda02010-06-15 01:31:58 -07002667#endif
2668
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002669 { // acquire lock
2670 AutoMutex _l(mLock);
2671
Jeff Brown519e0242010-09-15 15:18:56 -07002672 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002673 if (connectionIndex < 0) {
2674 LOGW("Attempted to unregister already unregistered input channel '%s'",
2675 inputChannel->getName().string());
2676 return BAD_VALUE;
2677 }
2678
2679 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2680 mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
2681
2682 connection->status = Connection::STATUS_ZOMBIE;
2683
Jeff Brownb88102f2010-09-08 11:49:43 -07002684 for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
2685 if (mMonitoringChannels[i] == inputChannel) {
2686 mMonitoringChannels.removeAt(i);
2687 break;
2688 }
2689 }
2690
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002691 mLooper->removeFd(inputChannel->getReceivePipeFd());
Jeff Brown2cbecea2010-08-17 15:59:26 -07002692
Jeff Brown7fbdc842010-06-17 20:52:56 -07002693 nsecs_t currentTime = now();
2694 abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002695
2696 runCommandsLockedInterruptible();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002697 } // release lock
2698
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002699 // Wake the poll loop because removing the connection may have changed the current
2700 // synchronization state.
Jeff Brown4fe6c3e2010-09-13 23:17:30 -07002701 mLooper->wake();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002702 return OK;
2703}
2704
Jeff Brown519e0242010-09-15 15:18:56 -07002705ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
Jeff Brown2cbecea2010-08-17 15:59:26 -07002706 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
2707 if (connectionIndex >= 0) {
2708 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2709 if (connection->inputChannel.get() == inputChannel.get()) {
2710 return connectionIndex;
2711 }
2712 }
2713
2714 return -1;
2715}
2716
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002717void InputDispatcher::activateConnectionLocked(Connection* connection) {
2718 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2719 if (mActiveConnections.itemAt(i) == connection) {
2720 return;
2721 }
2722 }
2723 mActiveConnections.add(connection);
2724}
2725
2726void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
2727 for (size_t i = 0; i < mActiveConnections.size(); i++) {
2728 if (mActiveConnections.itemAt(i) == connection) {
2729 mActiveConnections.removeAt(i);
2730 return;
2731 }
2732 }
2733}
2734
Jeff Brown9c3cda02010-06-15 01:31:58 -07002735void InputDispatcher::onDispatchCycleStartedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002736 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002737}
2738
Jeff Brown9c3cda02010-06-15 01:31:58 -07002739void InputDispatcher::onDispatchCycleFinishedLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002740 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002741}
2742
Jeff Brown9c3cda02010-06-15 01:31:58 -07002743void InputDispatcher::onDispatchCycleBrokenLocked(
Jeff Brown7fbdc842010-06-17 20:52:56 -07002744 nsecs_t currentTime, const sp<Connection>& connection) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002745 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
2746 connection->getInputChannelName());
2747
Jeff Brown9c3cda02010-06-15 01:31:58 -07002748 CommandEntry* commandEntry = postCommandLocked(
2749 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
Jeff Brown7fbdc842010-06-17 20:52:56 -07002750 commandEntry->connection = connection;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002751}
2752
Jeff Brown519e0242010-09-15 15:18:56 -07002753void InputDispatcher::onANRLocked(
2754 nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
2755 nsecs_t eventTime, nsecs_t waitStartTime) {
2756 LOGI("Application is not responding: %s. "
2757 "%01.1fms since event, %01.1fms since wait started",
2758 getApplicationWindowLabelLocked(application, window).string(),
2759 (currentTime - eventTime) / 1000000.0,
2760 (currentTime - waitStartTime) / 1000000.0);
2761
2762 CommandEntry* commandEntry = postCommandLocked(
2763 & InputDispatcher::doNotifyANRLockedInterruptible);
2764 if (application) {
2765 commandEntry->inputApplicationHandle = application->handle;
2766 }
2767 if (window) {
2768 commandEntry->inputChannel = window->inputChannel;
2769 }
2770}
2771
Jeff Brownb88102f2010-09-08 11:49:43 -07002772void InputDispatcher::doNotifyConfigurationChangedInterruptible(
2773 CommandEntry* commandEntry) {
2774 mLock.unlock();
2775
2776 mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
2777
2778 mLock.lock();
2779}
2780
Jeff Brown9c3cda02010-06-15 01:31:58 -07002781void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
2782 CommandEntry* commandEntry) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07002783 sp<Connection> connection = commandEntry->connection;
Jeff Brown9c3cda02010-06-15 01:31:58 -07002784
Jeff Brown7fbdc842010-06-17 20:52:56 -07002785 if (connection->status != Connection::STATUS_ZOMBIE) {
2786 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002787
Jeff Brown7fbdc842010-06-17 20:52:56 -07002788 mPolicy->notifyInputChannelBroken(connection->inputChannel);
2789
2790 mLock.lock();
2791 }
Jeff Brown9c3cda02010-06-15 01:31:58 -07002792}
2793
Jeff Brown519e0242010-09-15 15:18:56 -07002794void InputDispatcher::doNotifyANRLockedInterruptible(
Jeff Brown9c3cda02010-06-15 01:31:58 -07002795 CommandEntry* commandEntry) {
Jeff Brown519e0242010-09-15 15:18:56 -07002796 mLock.unlock();
Jeff Brown9c3cda02010-06-15 01:31:58 -07002797
Jeff Brown519e0242010-09-15 15:18:56 -07002798 nsecs_t newTimeout = mPolicy->notifyANR(
2799 commandEntry->inputApplicationHandle, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002800
Jeff Brown519e0242010-09-15 15:18:56 -07002801 mLock.lock();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002802
Jeff Brown519e0242010-09-15 15:18:56 -07002803 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07002804}
2805
Jeff Brownb88102f2010-09-08 11:49:43 -07002806void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
2807 CommandEntry* commandEntry) {
2808 KeyEntry* entry = commandEntry->keyEntry;
2809 mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
2810 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
2811 entry->downTime, entry->eventTime);
2812
2813 mLock.unlock();
2814
2815 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
2816 & mReusableKeyEvent, entry->policyFlags);
2817
2818 mLock.lock();
2819
2820 entry->interceptKeyResult = consumed
2821 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
2822 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
2823 mAllocator.releaseKeyEntry(entry);
2824}
2825
2826void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
2827 mLock.unlock();
2828
Jeff Brown01ce2e92010-09-26 22:20:12 -07002829 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
Jeff Brownb88102f2010-09-08 11:49:43 -07002830
2831 mLock.lock();
2832}
2833
Jeff Brown519e0242010-09-15 15:18:56 -07002834void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
2835 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
2836 // TODO Write some statistics about how long we spend waiting.
Jeff Brownb88102f2010-09-08 11:49:43 -07002837}
2838
2839void InputDispatcher::dump(String8& dump) {
2840 dumpDispatchStateLocked(dump);
2841}
2842
Jeff Brown9c3cda02010-06-15 01:31:58 -07002843
Jeff Brown519e0242010-09-15 15:18:56 -07002844// --- InputDispatcher::Queue ---
2845
2846template <typename T>
2847uint32_t InputDispatcher::Queue<T>::count() const {
2848 uint32_t result = 0;
2849 for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
2850 result += 1;
2851 }
2852 return result;
2853}
2854
2855
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002856// --- InputDispatcher::Allocator ---
2857
2858InputDispatcher::Allocator::Allocator() {
2859}
2860
Jeff Brown01ce2e92010-09-26 22:20:12 -07002861InputDispatcher::InjectionState*
2862InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
2863 InjectionState* injectionState = mInjectionStatePool.alloc();
2864 injectionState->refCount = 1;
2865 injectionState->injectorPid = injectorPid;
2866 injectionState->injectorUid = injectorUid;
2867 injectionState->injectionIsAsync = false;
2868 injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
2869 injectionState->pendingForegroundDispatches = 0;
2870 return injectionState;
2871}
2872
Jeff Brown7fbdc842010-06-17 20:52:56 -07002873void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
2874 nsecs_t eventTime) {
2875 entry->type = type;
2876 entry->refCount = 1;
2877 entry->dispatchInProgress = false;
Christopher Tatee91a5db2010-06-23 16:50:30 -07002878 entry->eventTime = eventTime;
Jeff Brown01ce2e92010-09-26 22:20:12 -07002879 entry->injectionState = NULL;
2880}
2881
2882void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
2883 if (entry->injectionState) {
2884 releaseInjectionState(entry->injectionState);
2885 entry->injectionState = NULL;
2886 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07002887}
2888
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002889InputDispatcher::ConfigurationChangedEntry*
Jeff Brown7fbdc842010-06-17 20:52:56 -07002890InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002891 ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002892 initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002893 return entry;
2894}
2895
Jeff Brown7fbdc842010-06-17 20:52:56 -07002896InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
Jeff Brownc5ed5912010-07-14 18:48:53 -07002897 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002898 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
2899 int32_t repeatCount, nsecs_t downTime) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002900 KeyEntry* entry = mKeyEntryPool.alloc();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002901 initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime);
2902
2903 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07002904 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002905 entry->policyFlags = policyFlags;
2906 entry->action = action;
2907 entry->flags = flags;
2908 entry->keyCode = keyCode;
2909 entry->scanCode = scanCode;
2910 entry->metaState = metaState;
2911 entry->repeatCount = repeatCount;
2912 entry->downTime = downTime;
Jeff Brownb88102f2010-09-08 11:49:43 -07002913 entry->syntheticRepeat = false;
2914 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002915 return entry;
2916}
2917
Jeff Brown7fbdc842010-06-17 20:52:56 -07002918InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
Jeff Brown85a31762010-09-01 17:01:00 -07002919 int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
Jeff Brown7fbdc842010-06-17 20:52:56 -07002920 int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
2921 nsecs_t downTime, uint32_t pointerCount,
2922 const int32_t* pointerIds, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002923 MotionEntry* entry = mMotionEntryPool.alloc();
Jeff Brown7fbdc842010-06-17 20:52:56 -07002924 initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime);
2925
2926 entry->eventTime = eventTime;
2927 entry->deviceId = deviceId;
Jeff Brownc5ed5912010-07-14 18:48:53 -07002928 entry->source = source;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002929 entry->policyFlags = policyFlags;
2930 entry->action = action;
Jeff Brown85a31762010-09-01 17:01:00 -07002931 entry->flags = flags;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002932 entry->metaState = metaState;
2933 entry->edgeFlags = edgeFlags;
2934 entry->xPrecision = xPrecision;
2935 entry->yPrecision = yPrecision;
2936 entry->downTime = downTime;
2937 entry->pointerCount = pointerCount;
2938 entry->firstSample.eventTime = eventTime;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002939 entry->firstSample.next = NULL;
Jeff Brown7fbdc842010-06-17 20:52:56 -07002940 entry->lastSample = & entry->firstSample;
2941 for (uint32_t i = 0; i < pointerCount; i++) {
2942 entry->pointerIds[i] = pointerIds[i];
2943 entry->firstSample.pointerCoords[i] = pointerCoords[i];
2944 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002945 return entry;
2946}
2947
2948InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
Jeff Brownb88102f2010-09-08 11:49:43 -07002949 EventEntry* eventEntry,
Jeff Brown519e0242010-09-15 15:18:56 -07002950 int32_t targetFlags, float xOffset, float yOffset) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002951 DispatchEntry* entry = mDispatchEntryPool.alloc();
2952 entry->eventEntry = eventEntry;
2953 eventEntry->refCount += 1;
Jeff Brownb88102f2010-09-08 11:49:43 -07002954 entry->targetFlags = targetFlags;
2955 entry->xOffset = xOffset;
2956 entry->yOffset = yOffset;
Jeff Brownb88102f2010-09-08 11:49:43 -07002957 entry->inProgress = false;
2958 entry->headMotionSample = NULL;
2959 entry->tailMotionSample = NULL;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002960 return entry;
2961}
2962
Jeff Brown9c3cda02010-06-15 01:31:58 -07002963InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
2964 CommandEntry* entry = mCommandEntryPool.alloc();
2965 entry->command = command;
2966 return entry;
2967}
2968
Jeff Brown01ce2e92010-09-26 22:20:12 -07002969void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
2970 injectionState->refCount -= 1;
2971 if (injectionState->refCount == 0) {
2972 mInjectionStatePool.free(injectionState);
2973 } else {
2974 assert(injectionState->refCount > 0);
2975 }
2976}
2977
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07002978void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
2979 switch (entry->type) {
2980 case EventEntry::TYPE_CONFIGURATION_CHANGED:
2981 releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
2982 break;
2983 case EventEntry::TYPE_KEY:
2984 releaseKeyEntry(static_cast<KeyEntry*>(entry));
2985 break;
2986 case EventEntry::TYPE_MOTION:
2987 releaseMotionEntry(static_cast<MotionEntry*>(entry));
2988 break;
2989 default:
2990 assert(false);
2991 break;
2992 }
2993}
2994
2995void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
2996 ConfigurationChangedEntry* entry) {
2997 entry->refCount -= 1;
2998 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07002999 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003000 mConfigurationChangeEntryPool.free(entry);
3001 } else {
3002 assert(entry->refCount > 0);
3003 }
3004}
3005
3006void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
3007 entry->refCount -= 1;
3008 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003009 releaseEventEntryInjectionState(entry);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003010 mKeyEntryPool.free(entry);
3011 } else {
3012 assert(entry->refCount > 0);
3013 }
3014}
3015
3016void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
3017 entry->refCount -= 1;
3018 if (entry->refCount == 0) {
Jeff Brown01ce2e92010-09-26 22:20:12 -07003019 releaseEventEntryInjectionState(entry);
Jeff Brown9c3cda02010-06-15 01:31:58 -07003020 for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
3021 MotionSample* next = sample->next;
3022 mMotionSamplePool.free(sample);
3023 sample = next;
3024 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003025 mMotionEntryPool.free(entry);
3026 } else {
3027 assert(entry->refCount > 0);
3028 }
3029}
3030
3031void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
3032 releaseEventEntry(entry->eventEntry);
3033 mDispatchEntryPool.free(entry);
3034}
3035
Jeff Brown9c3cda02010-06-15 01:31:58 -07003036void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
3037 mCommandEntryPool.free(entry);
3038}
3039
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003040void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
Jeff Brown7fbdc842010-06-17 20:52:56 -07003041 nsecs_t eventTime, const PointerCoords* pointerCoords) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003042 MotionSample* sample = mMotionSamplePool.alloc();
3043 sample->eventTime = eventTime;
Jeff Brown7fbdc842010-06-17 20:52:56 -07003044 uint32_t pointerCount = motionEntry->pointerCount;
3045 for (uint32_t i = 0; i < pointerCount; i++) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003046 sample->pointerCoords[i] = pointerCoords[i];
3047 }
3048
3049 sample->next = NULL;
3050 motionEntry->lastSample->next = sample;
3051 motionEntry->lastSample = sample;
3052}
3053
Jeff Brown01ce2e92010-09-26 22:20:12 -07003054void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
3055 releaseEventEntryInjectionState(keyEntry);
Jeff Brownb88102f2010-09-08 11:49:43 -07003056
Jeff Brown01ce2e92010-09-26 22:20:12 -07003057 keyEntry->dispatchInProgress = false;
3058 keyEntry->syntheticRepeat = false;
3059 keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
Jeff Brownb88102f2010-09-08 11:49:43 -07003060}
3061
3062
Jeff Brownae9fc032010-08-18 15:51:08 -07003063// --- InputDispatcher::MotionEntry ---
3064
3065uint32_t InputDispatcher::MotionEntry::countSamples() const {
3066 uint32_t count = 1;
3067 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
3068 count += 1;
3069 }
3070 return count;
3071}
3072
Jeff Brownb88102f2010-09-08 11:49:43 -07003073
3074// --- InputDispatcher::InputState ---
3075
3076InputDispatcher::InputState::InputState() :
3077 mIsOutOfSync(false) {
3078}
3079
3080InputDispatcher::InputState::~InputState() {
3081}
3082
3083bool InputDispatcher::InputState::isNeutral() const {
3084 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
3085}
3086
3087bool InputDispatcher::InputState::isOutOfSync() const {
3088 return mIsOutOfSync;
3089}
3090
3091void InputDispatcher::InputState::setOutOfSync() {
3092 if (! isNeutral()) {
3093 mIsOutOfSync = true;
3094 }
3095}
3096
3097void InputDispatcher::InputState::resetOutOfSync() {
3098 mIsOutOfSync = false;
3099}
3100
3101InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
3102 const EventEntry* entry) {
3103 switch (entry->type) {
3104 case EventEntry::TYPE_KEY:
3105 return trackKey(static_cast<const KeyEntry*>(entry));
3106
3107 case EventEntry::TYPE_MOTION:
3108 return trackMotion(static_cast<const MotionEntry*>(entry));
3109
3110 default:
3111 return CONSISTENT;
3112 }
3113}
3114
3115InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
3116 const KeyEntry* entry) {
3117 int32_t action = entry->action;
3118 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3119 KeyMemento& memento = mKeyMementos.editItemAt(i);
3120 if (memento.deviceId == entry->deviceId
3121 && memento.source == entry->source
3122 && memento.keyCode == entry->keyCode
3123 && memento.scanCode == entry->scanCode) {
3124 switch (action) {
3125 case AKEY_EVENT_ACTION_UP:
3126 mKeyMementos.removeAt(i);
3127 if (isNeutral()) {
3128 mIsOutOfSync = false;
3129 }
3130 return CONSISTENT;
3131
3132 case AKEY_EVENT_ACTION_DOWN:
3133 return TOLERABLE;
3134
3135 default:
3136 return BROKEN;
3137 }
3138 }
3139 }
3140
3141 switch (action) {
3142 case AKEY_EVENT_ACTION_DOWN: {
3143 mKeyMementos.push();
3144 KeyMemento& memento = mKeyMementos.editTop();
3145 memento.deviceId = entry->deviceId;
3146 memento.source = entry->source;
3147 memento.keyCode = entry->keyCode;
3148 memento.scanCode = entry->scanCode;
3149 memento.downTime = entry->downTime;
3150 return CONSISTENT;
3151 }
3152
3153 default:
3154 return BROKEN;
3155 }
3156}
3157
3158InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
3159 const MotionEntry* entry) {
3160 int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
3161 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3162 MotionMemento& memento = mMotionMementos.editItemAt(i);
3163 if (memento.deviceId == entry->deviceId
3164 && memento.source == entry->source) {
3165 switch (action) {
3166 case AMOTION_EVENT_ACTION_UP:
3167 case AMOTION_EVENT_ACTION_CANCEL:
3168 mMotionMementos.removeAt(i);
3169 if (isNeutral()) {
3170 mIsOutOfSync = false;
3171 }
3172 return CONSISTENT;
3173
3174 case AMOTION_EVENT_ACTION_DOWN:
3175 return TOLERABLE;
3176
3177 case AMOTION_EVENT_ACTION_POINTER_DOWN:
3178 if (entry->pointerCount == memento.pointerCount + 1) {
3179 memento.setPointers(entry);
3180 return CONSISTENT;
3181 }
3182 return BROKEN;
3183
3184 case AMOTION_EVENT_ACTION_POINTER_UP:
3185 if (entry->pointerCount == memento.pointerCount - 1) {
3186 memento.setPointers(entry);
3187 return CONSISTENT;
3188 }
3189 return BROKEN;
3190
3191 case AMOTION_EVENT_ACTION_MOVE:
3192 if (entry->pointerCount == memento.pointerCount) {
3193 return CONSISTENT;
3194 }
3195 return BROKEN;
3196
3197 default:
3198 return BROKEN;
3199 }
3200 }
3201 }
3202
3203 switch (action) {
3204 case AMOTION_EVENT_ACTION_DOWN: {
3205 mMotionMementos.push();
3206 MotionMemento& memento = mMotionMementos.editTop();
3207 memento.deviceId = entry->deviceId;
3208 memento.source = entry->source;
3209 memento.xPrecision = entry->xPrecision;
3210 memento.yPrecision = entry->yPrecision;
3211 memento.downTime = entry->downTime;
3212 memento.setPointers(entry);
3213 return CONSISTENT;
3214 }
3215
3216 default:
3217 return BROKEN;
3218 }
3219}
3220
3221void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
3222 pointerCount = entry->pointerCount;
3223 for (uint32_t i = 0; i < entry->pointerCount; i++) {
3224 pointerIds[i] = entry->pointerIds[i];
3225 pointerCoords[i] = entry->lastSample->pointerCoords[i];
3226 }
3227}
3228
3229void InputDispatcher::InputState::synthesizeCancelationEvents(
3230 Allocator* allocator, Vector<EventEntry*>& outEvents) const {
3231 for (size_t i = 0; i < mKeyMementos.size(); i++) {
3232 const KeyMemento& memento = mKeyMementos.itemAt(i);
3233 outEvents.push(allocator->obtainKeyEntry(now(),
3234 memento.deviceId, memento.source, 0,
3235 AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
3236 memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
3237 }
3238
3239 for (size_t i = 0; i < mMotionMementos.size(); i++) {
3240 const MotionMemento& memento = mMotionMementos.itemAt(i);
3241 outEvents.push(allocator->obtainMotionEntry(now(),
3242 memento.deviceId, memento.source, 0,
3243 AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
3244 memento.xPrecision, memento.yPrecision, memento.downTime,
3245 memento.pointerCount, memento.pointerIds, memento.pointerCoords));
3246 }
3247}
3248
3249void InputDispatcher::InputState::clear() {
3250 mKeyMementos.clear();
3251 mMotionMementos.clear();
3252 mIsOutOfSync = false;
3253}
3254
3255
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003256// --- InputDispatcher::Connection ---
3257
3258InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
3259 status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
Jeff Brown519e0242010-09-15 15:18:56 -07003260 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003261}
3262
3263InputDispatcher::Connection::~Connection() {
3264}
3265
3266status_t InputDispatcher::Connection::initialize() {
3267 return inputPublisher.initialize();
3268}
3269
Jeff Brown9c3cda02010-06-15 01:31:58 -07003270const char* InputDispatcher::Connection::getStatusLabel() const {
3271 switch (status) {
3272 case STATUS_NORMAL:
3273 return "NORMAL";
3274
3275 case STATUS_BROKEN:
3276 return "BROKEN";
3277
Jeff Brown9c3cda02010-06-15 01:31:58 -07003278 case STATUS_ZOMBIE:
3279 return "ZOMBIE";
3280
3281 default:
3282 return "UNKNOWN";
3283 }
3284}
3285
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003286InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
3287 const EventEntry* eventEntry) const {
Jeff Brownb88102f2010-09-08 11:49:43 -07003288 for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
3289 dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003290 if (dispatchEntry->eventEntry == eventEntry) {
3291 return dispatchEntry;
3292 }
3293 }
3294 return NULL;
3295}
3296
Jeff Brownb88102f2010-09-08 11:49:43 -07003297
Jeff Brown9c3cda02010-06-15 01:31:58 -07003298// --- InputDispatcher::CommandEntry ---
3299
Jeff Brownb88102f2010-09-08 11:49:43 -07003300InputDispatcher::CommandEntry::CommandEntry() :
3301 keyEntry(NULL) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07003302}
3303
3304InputDispatcher::CommandEntry::~CommandEntry() {
3305}
3306
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003307
Jeff Brown01ce2e92010-09-26 22:20:12 -07003308// --- InputDispatcher::TouchState ---
3309
3310InputDispatcher::TouchState::TouchState() :
3311 down(false), split(false) {
3312}
3313
3314InputDispatcher::TouchState::~TouchState() {
3315}
3316
3317void InputDispatcher::TouchState::reset() {
3318 down = false;
3319 split = false;
3320 windows.clear();
3321}
3322
3323void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
3324 down = other.down;
3325 split = other.split;
3326 windows.clear();
3327 windows.appendVector(other.windows);
3328}
3329
3330void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
3331 int32_t targetFlags, BitSet32 pointerIds) {
3332 if (targetFlags & InputTarget::FLAG_SPLIT) {
3333 split = true;
3334 }
3335
3336 for (size_t i = 0; i < windows.size(); i++) {
3337 TouchedWindow& touchedWindow = windows.editItemAt(i);
3338 if (touchedWindow.window == window) {
3339 touchedWindow.targetFlags |= targetFlags;
3340 touchedWindow.pointerIds.value |= pointerIds.value;
3341 return;
3342 }
3343 }
3344
3345 windows.push();
3346
3347 TouchedWindow& touchedWindow = windows.editTop();
3348 touchedWindow.window = window;
3349 touchedWindow.targetFlags = targetFlags;
3350 touchedWindow.pointerIds = pointerIds;
3351 touchedWindow.channel = window->inputChannel;
3352}
3353
3354void InputDispatcher::TouchState::removeOutsideTouchWindows() {
3355 for (size_t i = 0 ; i < windows.size(); ) {
3356 if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
3357 windows.removeAt(i);
3358 } else {
3359 i += 1;
3360 }
3361 }
3362}
3363
3364const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
3365 for (size_t i = 0; i < windows.size(); i++) {
3366 if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
3367 return windows[i].window;
3368 }
3369 }
3370 return NULL;
3371}
3372
3373
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07003374// --- InputDispatcherThread ---
3375
3376InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
3377 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
3378}
3379
3380InputDispatcherThread::~InputDispatcherThread() {
3381}
3382
3383bool InputDispatcherThread::threadLoop() {
3384 mDispatcher->dispatchOnce();
3385 return true;
3386}
3387
3388} // namespace android